Compare commits

..

119 Commits

Author SHA1 Message Date
6b31667ee4 Updated changelog. 2018-09-16 10:40:21 +02:00
066c6f685d Fixed failure to build on NetBSD because of undeclared variable 2018-09-16 10:37:49 +02:00
e317a8d93e Updated changelog. 2018-09-15 08:55:07 +02:00
d3c17d0555 Version leap to 1.5.0. 2018-09-15 08:50:35 +02:00
69c8c543a9 Improved message at image load time about hidden El Torito images for EFI 2018-06-10 19:51:47 +02:00
f39d4eefee Putting user defined padding after appended partitions 2018-06-04 09:35:01 +02:00
848e039e6d Preferring Linux include file sys/xattr.h over attr/attr.h 2018-05-18 17:20:24 +02:00
c5a9cc56e3 Changed bug fix 615dc7e997 of Mar 30 13:51:21 2018 +0200 2018-05-01 12:43:11 +02:00
310612174b Bug fix: Long Joliet names with leading dot were mangled one char too short 2018-03-31 18:20:55 +02:00
ad843f1723 Bug fix: Long Joliet names without dot were mangled with one character too many 2018-03-31 14:14:33 +02:00
615dc7e997 Bug fix: Add-on sessions with partition offset claimed too many blocks as size. Regression of version 1.4.8. 2018-03-30 13:51:21 +02:00
a936409a82 Fixed failure to compile with experimental Libisofs_appended_partitions_inlinE 2017-11-22 14:30:08 +01:00
580b154773 Adapted iso_node_merge_xattr to handling of all namespaces 2017-10-31 13:33:53 +01:00
1da3b17233 Changed a comment in Linux OS adapter 2017-10-31 13:30:26 +01:00
633b4d5f72 Updated project mail addresses 2017-10-23 10:39:48 +02:00
4b031b58ea New flag bit7 with iso_local_set_attrs() to avoid unnecessary write attempts. New return value 2 of IsoFileSource.get_aa_string() and iso_local_get_attrs(). New API calls iso_image_was_blind_attrs(), iso_local_set_attrs_errno(). 2017-10-23 10:36:10 +02:00
7d45c88cff New API call iso_image_get_ignore_aclea(),
new iso_image_set_ignore_aclea() and iso_file_source_get_aa_string() flag bit3 to import all xattr namespaces
2017-10-07 16:51:07 +02:00
79baab3fc9 Fixed a harmless lapse with static array initialization 2017-09-22 20:42:57 +02:00
53b2d6dcd7 Bug fix: Reading beyond array end for HFS+ production caused SIGSEGV with FreeBSD 11 CLANG -O2. Thanks ASX of GhostBSD. 2017-09-22 17:26:02 +02:00
874dc16d92 Fixed a message typo found by lintian 2017-09-16 10:40:35 +02:00
34e35865fe Silenced harmless compiler warning -Wimplicit-fallthrough 2017-09-15 22:29:02 +02:00
ce831f111c Updated change log 2017-09-12 21:53:42 +02:00
48ee49a7e0 Version leap to 1.4.9 2017-09-12 21:48:59 +02:00
bdfd4c4a37 Updated changelog. 2017-09-12 12:05:32 +02:00
dfc6de9f79 Version leap to 1.4.8. 2017-09-12 11:58:56 +02:00
7234425502 Updated changelog. 2017-09-12 11:51:16 +02:00
4e5a54c2f9 Swapped at recognition time the precendence of MBR properties "isohybrid" and "protective-msdos-label" 2017-09-09 16:36:43 +02:00
028f9275d3 Throw error if imported_iso interval would be overwritten by multi-session 2017-08-26 11:47:14 +02:00
cace41ec16 Enabled partition intervals with source "imported_iso" with ISO growing 2017-08-24 12:19:54 +02:00
e599a575dc Closed a memory leak about RRIP CL following 2017-08-21 19:43:19 +02:00
78b0a7b111 Disallowed RRIP CL chaining in order to break any endless loops. Debian bug 872761. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-21 19:41:20 +02:00
a7152f5794 Correcting previous commit for supporting multi-session 2017-08-21 12:34:13 +02:00
2a64d89e6e Refuse to read CE data blocks from after the end of ISO filesystem 2017-08-19 16:55:08 +02:00
31088d9acc Avoid to read blocks from start of CE area which do not belong to the given file 2017-08-19 14:54:23 +02:00
91490d5f34 Preventing use of zero sized SUSP CE entry which causes SIGSEGV. Debian bug 872590. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-19 11:08:02 +02:00
661b68ce8c Preventing buffer overflow with AAIP AL entry of insufficient size. Debian bug 872545. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-18 14:56:50 +02:00
16bde11076 Preventing memory leak caused by RRIP SL entry without PX entry that marks the file as symbolic link 2017-08-18 11:11:05 +02:00
36c8800ff3 Preventing buffer underread with empty RRIP SL component. Debian bug 872475. Thanks Jakub Wilk and American Fuzzy Lop. 2017-08-18 10:56:59 +02:00
860a91dd2f Preventing NULL dereference if root directory bears a RRIP RE entry 2017-08-17 08:49:28 +02:00
280108d2d5 Updated change log 2017-08-14 18:08:48 +02:00
1e40ed3fab Bug fix: Keeping and patching of loaded boot images failed. Regression by version 1.4.4. 2017-08-14 17:51:05 +02:00
e19a338a09 Re-added two empty lines which were lost by previous commit 2017-08-13 14:51:39 +02:00
c6e4035918 Added boot sector knowledge gained from Natalia Portillo 2017-08-13 13:34:53 +02:00
18ab6019bc Let ISO size cover appended partitions if --protective-msdos-label or nonzero -partition_offset is given 2017-07-02 15:11:20 +02:00
6282bbc0bc Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with generic MBR 2017-06-29 23:06:07 +02:00
d7737e3ed5 Removed ban on reading El Torito platform ids other than 0 and 0xef 2017-06-03 20:23:54 +02:00
fb8697081b Reacted on harmless compiler warning about uninitialized variable. 2017-04-25 12:11:33 +02:00
0e7300b1a8 Clarified meaning of MBR partition boot flag 2017-04-10 10:02:05 +02:00
94e4bfb42b Adapted recognizing of partition offset to the changes of rev afb10aa / 1348 2017-04-09 20:58:45 +02:00
86f6ffc9c9 Let iso_mbr_part_type 0xee override ban on 0xee without GPT 2017-03-19 11:14:49 +01:00
5600f3d726 When deciding boot flag, consider MBR partition slot empty only if entirely 0 2017-02-27 18:27:59 +01:00
e66b9bfe0c New API call iso_write_opts_set_iso_mbr_part_type() 2017-02-27 09:59:34 +01:00
094b3f7546 Updated copyright year in system_area.c 2017-01-24 13:00:11 +01:00
5c1c5cd964 Bug fix: Appended partitions of size >= 4 GiB led to abort with error message "FATAL : ISO overwrite". Thanks to Sven Haardiek. 2017-01-24 10:43:10 +01:00
215280448f Bug fix: Protective MBR for GPT could emerge with boot flag set. 2017-01-03 12:54:54 +01:00
3043b5f660 Enabled recognition of partition offset of grub-mkrescue-sed.sh mode "gpt_appended" 2016-12-25 15:46:11 +01:00
afb10aac3b Claiming full output size in first PVD if partition offset is non-zero 2016-12-25 10:05:26 +01:00
76181d0aa3 Restricted volume size of PVD with non-zero partition offset to filesystem size even if the first PVD claims the whole output size 2016-12-25 10:00:07 +01:00
8ec75eea6a Bug fix: Non-SUSP data in System Use Area prevented image loading if Rock Ridge was enabled. Thanks to Jonathan Dowland. 2016-11-23 22:52:11 +01:00
01020ef544 Committed missing part of rev dc6cd94/1342 2016-11-23 22:07:21 +01:00
2961bdef9f Updated change log 2016-11-13 10:20:24 +01:00
ed209e0b6e Mentioned Vladimir Serbinenko in libisofs copyright list 2016-11-13 10:13:47 +01:00
dc6cd946ba New API calls el_torito_set_full_load(), el_torito_get_full_load() 2016-11-13 10:05:18 +01:00
c51efce8d1 Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root SUSP 2016-11-13 09:52:25 +01:00
8bf32d8d14 Prepared some of the documentation for move to dev.lovelyhq.com 2016-11-13 09:39:53 +01:00
561e2a6aaa Version leap to 1.4.7 2016-09-16 20:58:19 +02:00
e7dd325ff6 Version leap to 1.4.6. 2016-09-16 11:45:12 +02:00
0447496710 Updated changelog. 2016-09-16 11:07:20 +02:00
496b8051c5 Bug fix: Interpretation of 17 digit timestamps was wrong. 2016-09-13 20:10:17 +02:00
63c074b0aa Changed severity of ISO_FILE_TOO_BIG from WARNING to FAILURE. 2016-09-12 18:01:14 +02:00
2be47f9af8 Bug fix: SIGSEGV by NULL when a data file was larger than ISO level allows. 2016-09-12 17:58:13 +02:00
bf5678c6d4 Removed obsoleted doxygen.conf tags XML_SCHEMA, XML_DTD, SHOW_DIRECTORIES,
HTML_ALIGN_MEMBERS. Corrected EXAMPLE_PATH.
Corrected a few comments which caused valid doxygen complaints.
2016-08-29 17:00:32 +02:00
9d64318502 Corrected understanding of relation of RFC 4122 and UEFI GUID.
Thanks Andrei Borzenkov.
2016-08-14 22:24:53 +02:00
866f647fad New API calls iso_generate_gpt_guid() and +iso_write_opts_set_gpt_guid(). 2016-08-12 18:18:47 +02:00
2f134dcdcb Eased re-enabling of libtool --silent at bootstrap time 2016-08-11 12:08:18 +02:00
b14ee71d51 Setting El torito boot catalog file timestamps to Ecma119Image.now. 2016-08-07 21:11:08 +02:00
c5c9d4e7bf Setting Ecma119Image.now to maximum of effective olume creation date and
volume modification date.
2016-08-07 10:48:03 +02:00
6321ed4d97 Made isohybrid MBR id reproducible if vol_modification_time or vol_uuid are set 2016-08-05 20:59:17 +02:00
188e36178b Reacted on some of the complaints of codespell 2016-07-22 16:03:51 +02:00
cbfa9afcf1 Treating OpenBSD like NetBSD. Thanks to SASANO Takayoshi. 2016-07-21 11:44:49 +02:00
cb519b3692 Reacted on compiler warning of Debian Sid. (By accident the wrong code was
equivalent to the correct code.)
2016-07-03 18:06:40 +02:00
8407d9e936 Updated ChangeLog 2016-07-01 21:19:19 +02:00
d482eb4c96 Version leap to 1.4.5 2016-07-01 19:58:26 +02:00
1786ceb276 Version leap to 1.4.4 2016-07-01 19:53:15 +02:00
f51fc50356 Updated changelog 2016-07-01 09:50:04 +02:00
02de4570d1 Included <unistd.h> in aaip_0_2.h to fix a build time issue with musl libc.
Thanks to Baruch Siach.
2016-05-24 13:07:00 +02:00
2a41b4817c Removed option --silent from libtool runs 2016-04-27 16:44:27 +02:00
9440e3061c Recognizing SUN Sparc Disk Label of ISOs smaller than 300 kB. 2016-04-25 11:55:57 +02:00
122dfe7b87 Re-instated recognition of libisofs PReP which was broken by rev 1295. 2016-04-24 10:38:45 +02:00
03662f0832 Recognizing the newly introduced consequences of protective msdos label
with alternative grub-mkrescue boot layouts.
2016-04-20 20:11:57 +02:00
eb09bcf9e5 Prevented option --version-script with linker run of xorriso. By Matthias Klose. 2016-04-19 09:17:34 +02:00
5880636a50 Prevented appended partition from being marked twice in GPT if it is used as
El Torito boot image.
2016-03-31 20:26:36 +02:00
b5fb98a2a3 Bug fix: Oversized text in ISO_SYSAREA_REPORT_DOC_ALPHA.
Thanks to Etienne Bergeron.
2016-03-30 21:35:53 +02:00
b269557743 Bug fix: At image loading time GRUB2 MBR was not recognized if the partition
table is not the protective one as described by UEFI.
2016-03-23 11:24:36 +01:00
0fd7d4d7eb Added "extern C" to libisofs.h 2016-03-15 21:26:06 +01:00
d8dca37d65 Replaced unused timezone parameter of gettimeofday() by NULL 2016-03-10 21:04:48 +01:00
cd84f0927f Introduced image size tolerance of 300 kB in order to recognize SUN Disk Label
that was generated by genisoimage -B "...".
2016-02-27 15:12:11 +01:00
477bbb89bb Fixed typo "occured" -> "occurred" 2016-02-05 13:52:26 +01:00
31fcdc0ba6 New API calls iso_write_opts_set_appended_as_apm(), iso_write_opts_set_part_like_isohybrid() 2016-02-05 10:47:04 +01:00
7c05d2a865 Enabled use of --interval:appended_partition_ with ISO growing. 2016-01-20 11:35:29 +01:00
3d15642307 Preventing production of surplus isohybrid MBR partition for BIOS boot image.
The problem was introduced by rev 1299.
2016-01-17 16:28:40 +01:00
872b5c6c67 New bit15 with options of iso_write_opts_set_system_area() to enforce
MBR bootable/active flag.
2016-01-01 18:17:40 +01:00
ec35bb21c0 Provisory new pseudo path for El Torito boot images:
--interval:appened_partition_N:all::
2015-12-30 18:56:32 +01:00
93f3cb1823 Another fix for Libisofs_mjg_boot_for_grub2 with original grub-mkrescue options 2015-12-28 11:51:29 +01:00
fea7be5168 Fixed result of Libisofs_mjg_boot_for_grub2 with original grub-mkrescue options 2015-12-28 11:30:53 +01:00
bd25db9283 Experimental macro Libisofs_mjg_boot_for_grub2 for alternative partition layout 2015-12-27 16:07:27 +01:00
97eec6162c Bug fix: HFS+ directories could announce more children than they actually have. 2015-12-26 12:25:28 +01:00
17e8cb6697 Bug fix: The HFS+ filesystem was not marked by in GPT of GRUB2 hybrid layout. 2015-12-23 20:49:13 +01:00
9e01d3654e Experimental macros Libisofs_protective_msdos_plus_boot_dummY and
Libisofs_pmpbd_on_lba0 to test augmentation of GRUB2 protective msdos label.
2015-12-22 14:24:08 +01:00
009ce1be8f Bug fix: When reading an ISO filesystem, the presence of
system area options flag bit0 (-protective-msdos-label)
         was not recognized if a partition is appended.
2015-12-22 12:25:50 +01:00
c79299ba08 Bug fix: Options bit0 of iso_write_opts_set_system_area() was not forwarded
to image production if no system area data were given.
         This prevented xorrisofs option --protective-msdos-label from working.
2015-12-22 12:23:13 +01:00
b3701f0b18 Removed the false prediction that HFS+ would cause GPT. 2015-12-22 11:52:33 +01:00
83b864efd2 Clarified virtual sector size of El Torito. Changed germanoid use of "eventual". 2015-12-21 17:31:30 +01:00
cd0f57dd1a Bug fix: HFS+ production could cause MBR partition of type 0xEE without GPT. 2015-12-20 18:46:44 +01:00
4c9cb6b96b Coordinated expectations of build system and source code in respect to
loacl support for ACL and extended file attributes. (Rev 1288 actually
belongs to this commit.)
2015-12-15 11:04:49 +01:00
9c334891cf Silenced a warning about unused variable if no local extended file attributes
are enabled. (Previous commit should have been part of the next one.)
2015-12-15 11:01:01 +01:00
2f6103b783 Silenced a warning about unused variable if no local extended file attributes
are enabled.
2015-12-15 10:59:23 +01:00
f32ee7da83 Completed update of change log 2015-11-28 22:08:44 +01:00
52972811f8 Version leap to 1.4.3 2015-11-28 21:49:07 +01:00
48 changed files with 2837 additions and 653 deletions

View File

@ -1,7 +1,9 @@
Vreixo Formoso <metalpain2002@yahoo.es>,
Mario Danic <mario.danic@gmail.com>,
Vladimir Serbinenko <phcoder@gmail.com>
Thomas Schmitt <scdbackup@gmx.net>
Copyright (C) 2007-2015 Vreixo Formoso, Mario Danic, Thomas Schmitt
Copyright (C) 2007-2016
Vreixo Formoso, Mario Danic, Vladimir Serbinenko, Thomas Schmitt
This program is free software; you can redistribute it and/or modify

View File

@ -1,3 +1,71 @@
libisofs-1.5.0.tar.gz Sat Sep 15 2018
===============================================================================
* New API call iso_image_get_ignore_aclea(),
new iso_image_set_ignore_aclea() and iso_file_source_get_aa_string()
flag bit3 to import all xattr namespaces
* New API calls iso_image_was_blind_attrs(), iso_local_set_attrs_errno().
* New flag bit7 with iso_local_set_attrs() to avoid unnecessary write attempts.
* New return value 2 of IsoFileSource.get_aa_string() and iso_local_get_attrs().
* Now putting user defined padding after appended partitions.
* Bug fix: Add-on sessions with partition offset claimed too many blocks as
size. Regression of version 1.4.8.
* Bug fix: Long Joliet names without dot were mangled with one character too
many. Long Joliet names with leading dot were mangled one char
too short.
* Bug fix: Reading beyond array end for HFS+ production caused SIGSEGV with
FreeBSD 11 CLANG -O2. Thanks ASX of GhostBSD.
libisofs-1.4.8.tar.gz Tue Sep 12 2017
===============================================================================
* Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root
SUSP.
* Bug fix: Non-SUSP data in System Use Area prevented image loading if
Rock Ridge was enabled. Thanks to Jonathan Dowland.
* Bug fix: Protective MBR for GPT could emerge with boot flag set.
* Bug fix: Appended partitions of size >= 4 GiB led to abort with error message
"FATAL : ISO overwrite". Thanks to Sven Haardiek.
* Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with generic
MBR.
* Bug fix: Keeping and patching of loaded boot images failed.
Regression by version 1.4.4.
* Bug fix: Program crashes by intentionally wrong ISO image input.
Found by American Fuzzy Lop and Jakub Wilk.
Debian bug reports: 872372, 872475, 872545, 872590, 872761.
* New API calls el_torito_set_full_load(), el_torito_get_full_load().
* New API call iso_write_opts_set_iso_mbr_part_type().
libisofs-1.4.6.tar.gz Fri Sep 16 2016
===============================================================================
* Bug fix: SIGSEGV by NULL when a data file was larger than ISO level allows.
* Bug fix: Interpretation of 17 digit timestamps was wrong.
* New API calls iso_generate_gpt_guid() and iso_write_opts_set_gpt_guid().
* Made several pseudo-random ids reproducible by overriding volume modification
time.
libisofs-1.4.4.tar.gz Fri Jul 01 2016
===============================================================================
* Bug fix: HFS+ production could cause MBR partition of type 0xEE without GPT.
* Bug fix: Protective MBR was not produced if no System Area data are given.
* Bug fix: Protective MBR was not recognized if partition is appended.
* Bug fix: The HFS+ filesystem was not marked in GPT of GRUB2 hybrid layout.
* Bug fix: HFS+ directories could announce more children than they actually
have.
* Bug fix: At image loading time GRUB2 MBR was not recognized if the partition
table is not the protective one as described by UEFI.
* Bug fix: Oversized text in ISO_SYSAREA_REPORT_DOC_ALPHA.
Thanks to Etienne Bergeron.
* New pseudo path for El Torito boot images:
--interval:appened_partition_N:all::
* New bit15 with options of iso_write_opts_set_system_area() to enforce
MBR bootable/active flag.
* New API calls iso_write_opts_set_appended_as_apm(),
iso_write_opts_set_part_like_isohybrid().
* Introduced image size tolerance of 300 kB in order to recognize SUN Disk
Label that was generated by genisoimage -B "...".
* Added "extern C" to libisofs.h
* Removed option --silent from libtool runs.
libisofs-1.4.2.tar.gz Sat Nov 28 2015
===============================================================================
* Bug fix: zisofs compression caused SIGSEGV (by reading) with files larger

View File

@ -13,7 +13,7 @@ ACLOCAL_AMFLAGS = -I ./
# Build libraries
libisofs_libisofs_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS)
# Eventually enabling system adapters for ACL and EA.
# ts A90409: Eventually enabling use of zlib.

4
README
View File

@ -4,7 +4,7 @@
Released under GPL (see COPYING file for details).
Copyright (C) 2008 - 2015 Vreixo Formoso,
Copyright (C) 2008 - 2016 Vreixo Formoso,
Mario Danic,
Vladimir Serbinenko,
Thomas Schmitt
@ -14,7 +14,7 @@ libisofs is part of the libburnia project (libburnia-project.org)
Download, Build and Installation
libisofs code is mantained in a Bazaar repository at Launchpad
libisofs code is maintained in a Bazaar repository at Launchpad
(https://launchpad.net/libisofs/). You can download it with:
$ bzr branch lp:libisofs/for-libisoburn

View File

@ -16,15 +16,21 @@ AC_DEFUN([TARGET_SHIZZLE],
AC_MSG_CHECKING([target operating system])
LIBBURNIA_SUPP_ACL=none
LIBBURNIA_SUPP_FATTR=none
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
case $target in
*-*-linux*)
ARCH=linux
LIBBURN_ARCH_LIBS=
LIBBURNIA_SUPP_ACL=libacl
LIBBURNIA_SUPP_FATTR=xattr
LIBBURNIA_LDCONFIG_CMD=ldconfig
;;
*-*-freebsd*)
ARCH=freebsd
LIBBURNIA_SUPP_ACL=libacl
LIBBURNIA_SUPP_FATTR=extattr
LIBBURN_ARCH_LIBS=-lcam
# This may later be overridden by configure --enable-libdir-pkgconfig
@ -141,10 +147,12 @@ AC_DEFUN([LIBISOFS_ASSERT_VERS_LIBS],
LDFLAGS="$LDFLAGS -Wl,--version-script=libisofs/libisofs.ver"
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
[vers_libs_test="yes"], [vers_libs_test="no"])
if test x$vers_libs_test = xno
if test x$vers_libs_test = xyes
then
LDFLAGS="$libburnia_save_LDFLAGS"
LIBLDFLAGS="-Wl,--version-script=libisofs/libisofs.ver"
fi
LDFLAGS="$libburnia_save_LDFLAGS"
AC_SUBST(LIBLDFLAGS)
])

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.4.2], [http://libburnia-project.org])
AC_INIT([libisofs], [1.4.9], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -26,8 +26,8 @@ dnl
dnl LT_CURRENT, LT_REVISION and LT_AGE get set directly now.
dnl
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
dnl The linker will do no finer checks. Especially no age range check for
dnl the cdrskin binary. If SONAME matches, then the couple starts.
dnl The linker will do no finer checks. If SONAME matches, then the couple
dnl starts.
dnl
dnl Therefore a run time check is provided by libisofs function
dnl iso_lib_version(). It returns the major, minor and micro revision of the
@ -41,7 +41,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=4
LIBISOFS_MICRO_VERSION=2
LIBISOFS_MICRO_VERSION=9
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2015.11.28 development jump has not yet happened
# SONAME = 84 - 78 = 6 . Library name = libisofs.6.78.0
LT_CURRENT=84
LT_AGE=78
# 2017.09.12 development jump has not yet happened
# SONAME = 90 - 84 = 6 . Library name = libisofs.6.84.0
LT_CURRENT=90
LT_AGE=84
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -92,7 +92,7 @@ LIBBURNIA_ASSERT_ICONV
AC_PROG_LIBTOOL
AC_SUBST(LIBTOOL_DEPS)
LIBTOOL="$LIBTOOL --silent"
# LIBTOOL="$LIBTOOL --silent"
AC_PROG_INSTALL
@ -172,40 +172,118 @@ dnl Add compiler-specific flags
AC_ARG_ENABLE(libacl,
[ --enable-libacl Enable use of ACL functions by libisofs, default=yes],
, enable_libacl=yes)
if test "x$enable_libacl" = xyes; then
LIBACL_DEF=
has_acl_h_but_no_func=0
if test x$LIBBURNIA_SUPP_ACL = xlibacl
then
if test x$enable_libacl = xyes; then
dnl Check whether there is libacl-devel and libacl-runtime.
dnl If not, erase this macro which would enable use of acl_to_text and others
LIBACL_DEF="-DLibisofs_with_aaip_acL"
LIBACL_DEF="-DLibisofs_with_aaip_acL"
dnl The empty yes case obviously causes -lacl to be linked
has_acl_h_but_no_func=0
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , has_acl_h_but_no_libacl=1 ), LIBACL_DEF= )
if test "$has_acl_h_but_no_libacl" = 1
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , has_acl_h_but_no_libacl=1 ), LIBACL_DEF= )
if test "$has_acl_h_but_no_libacl" = 1
then
AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= )
fi
fi
fi
if test x$LIBACL_DEF = x-DLibisofs_with_aaip_acL
then
if test x$has_acl_h_but_no_libacl = x1
then
AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= )
fi
echo "enabled local processing of ACL"
else
echo "enabled libacl, local processing of ACL"
fi
else
LIBACL_DEF=
echo "disabled local processing of ACL"
fi
AC_SUBST(LIBACL_DEF)
dnl ts A90123
dnl ts A90123 - B80508
AC_ARG_ENABLE(xattr,
[ --enable-xattr Enable use of xattr by libisofs, default=yes],
, enable_xattr=yes)
if test "x$enable_xattr" = xyes; then
[ --enable-xattr Enable use of extended file attributes by libisofs, default=yes],
, enable_xattr=yes)
AC_ARG_ENABLE(xattr_h_pref_attr,
[ --enable-xattr-h-pref-attr Prefer include file attr/xattr.h over sys/xattr.h, default=no],
, enable_xattr_h_pref_attr=no)
XATTR_DEF=
XATTR_ADDON_DEF=
if test x"$LIBBURNIA_SUPP_FATTR" = xxattr
then
if test "x$enable_xattr" = xyes; then
dnl Check whether there is the header for Linux xattr.
dnl If not, erase this macro which would enable use of listxattr and others
XATTR_DEF="-DLibisofs_with_aaip_xattR"
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= , XATTR_DEF= ), XATTR_DEF= )
if test "x$XATTR_DEF" = x
then
XATTR_DEF="-DLibisofs_with_freebsd_extattR"
AC_CHECK_HEADER(sys/extattr.h, AC_CHECK_LIB(c, extattr_list_file, X=, XATTR_DEF= ), XATTR_DEF= )
XATTR_A_DEF=
XATTR_S_DEF=
if test x"$enable_xattr_h_pref_attr" = xyes
then
echo "prefering include file attr/xattr.h over sys/attr.h"
XATTR_A_DEF=1
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
XATTR_A_DEF= ), XATTR_A_DEF= )
if test x"$XATTR_A_DEF" = x1
then
XATTR_DEF="-DLibisofs_with_aaip_xattR"
else
XATTR_S_DEF=1
AC_CHECK_HEADER(sys/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
XATTR_S_DEF= ), XATTR_S_DEF= )
if test x"$XATTR_S_DEF" = x1
then
XATTR_DEF="-DLibisofs_with_aaip_xattR"
XATTR_ADDON_DEF="-DLibisofs_with_sys_xattR"
fi
fi
else
XATTR_S_DEF=1
AC_CHECK_HEADER(sys/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
XATTR_S_DEF= ), XATTR_S_DEF= )
if test x"$XATTR_S_DEF" = x1
then
XATTR_DEF="-DLibisofs_with_aaip_xattR"
XATTR_ADDON_DEF="-DLibisofs_with_sys_xattR"
else
XATTR_A_DEF=1
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
XATTR_A_DEF= ), XATTR_A_DEF= )
if test x"$XATTR_A_DEF" = x1
then
XATTR_DEF="-DLibisofs_with_aaip_xattR"
fi
fi
fi
if test x"$XATTR_S_DEF" = x1
then
echo "decided to include file sys/attr.h"
elif test x"$XATTR_A_DEF" = x1
then
echo "decided to include file attr/xattr.h"
fi
fi
elif test x"$LIBBURNIA_SUPP_FATTR" = xextattr
then
if test "x$enable_xattr" = xyes; then
XATTR_DEF="-DLibisofs_with_freebsd_extattR"
AC_CHECK_HEADER(sys/extattr.h, AC_CHECK_LIB(c, extattr_list_file, X=,
XATTR_DEF= ), XATTR_DEF= )
fi
else
XATTR_DEF=
fi
if test x$XATTR_DEF = x-DLibisofs_with_aaip_xattR
then
echo "enabled xattr, local processing of extended file attributes Linux style"
elif test x$XATTR_DEF = x-DLibisofs_with_freebsd_extattR
then
echo "enabled extattr, local processing of extended file attributes FreeBSD style"
else
echo "disabled local processing of extended file attributes"
fi
XATTR_DEF="$XATTR_DEF $XATTR_ADDON_DEF"
AC_SUBST(XATTR_DEF)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 - 2015 Vreixo Formoso, Thomas Schmitt
* Copyright (c) 2007 - 2016 Vreixo Formoso, Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -375,7 +375,7 @@ int gesture_iso(int argc, char **argv)
result = iso_write_opts_new(&opts, 0);
if (result < 0) {
printf ("Cant create write opts, error %d\n", result);
printf ("Cannot create write opts, error %d\n", result);
goto ex;
}
iso_write_opts_set_iso_level(opts, level);
@ -385,7 +385,7 @@ int gesture_iso(int argc, char **argv)
result = iso_image_create_burn_source(image, opts, &burn_src);
if (result < 0) {
printf ("Cant create image, error %d\n", result);
printf ("Cannot create image, error %d\n", result);
goto ex;
}
@ -904,7 +904,7 @@ int gesture_iso_ms(int argc, char **argv)
result = iso_image_create_burn_source(image, opts, &burn_src);
if (result < 0) {
printf ("Cant create image, error %d\n", result);
printf ("Cannot create image, error %d\n", result);
goto ex;
}
iso_write_opts_free(opts);

View File

@ -4,8 +4,9 @@
Collection of Boot Sector Formats for ISO 9660 Images
by Thomas Schmitt - mailto:scdbackup@gmx.net
Libburnia project - mailto:libburn-hackers@pykix.org
by Thomas Schmitt - scdbackup@gmx.net
Libburnia project - bug-xorriso@gnu.org
pkg-libburnia-devel@lists.alioth.debian.org
This information is collected from various sources. Some is backed by
specifications, some is just rumor which happens to work (maybe not even that).
@ -68,9 +69,9 @@ intervals for:
- Directory trees, tables, boot catalog, embedded partitions and filesystems.
- Data file content, including content of El Torito boot images.
The Boot Record is an ECMA-119 Volume Descriptor which is eventually located
at 2 kB block number 17 (decimal). Its content points to the location of the
Boot Catalog.
The Boot Record is an ECMA-119 Volume Descriptor which is located at 2 kB block
number 17 (decimal), if present at all. Its content points to the location of
the Boot Catalog.
The format is described in part by ECMA-119 8.2 "Boot Record" and further
specified by El Torito figure 7.
@ -177,7 +178,7 @@ Byte Range | Value | Meaning
| |
5 - 5 | 0 | Unused
| |
6 - 7 | sec_count | Sector Count.
6 - 7 | sec_count | Sector Count. Sector size 512:
| | "the number of virtual/emulated sectors the system
| | will store at Load Segment during the initial boot
| | procedure."
@ -232,7 +233,7 @@ Byte Range | Value | Meaning
| | 0 if not emulation == 4.
5 - 5 | 0 | Unused
| |
6 - 7 | sec_count | Sector Count.
6 - 7 | sec_count | Sector Count. Sector size 512.
| | See above Initial/Default Entry
| | libisofs stores 1 for emulated boot_media and a
| | user defined value for boot_media == 0. Often: 4.
@ -301,28 +302,44 @@ Byte Range | Value | Meaning
Sources:
http://en.wikipedia.org/wiki/Master_boot_record
https://en.wikipedia.org/wiki/INT_13H
Mailing list conversations with H. Peter Anvin and Vladimir Serbinenko.
Mail conversations with Natalia Portillo.
The candidates for MBR booting will normally use El Torito rather than MBR
if the ISO image is presented on CD, DVD, or BD media.
The eventual MBR comes into effect if the image is on a media that is
interpreted by the BIOS as some kind of hard disk. Usually real hard disks,
floppy disks, USB sticks, memory cards.
The MBR comes into effect if the image is on a media that is interpreted by
the BIOS as some kind of hard disk. Usually real hard disks, floppy disks,
USB sticks, memory cards.
An important part of an MBR is the DOS style partition table. It describes up
to four primary partitions. There are two formats used for block address:
Cylinder/Head/Sector (C/H/S) and Logical Block Address (LBA). Both are based
on units of 512 bytes. So MBR_LBA = ISO_LBA * 4.
Contemporary x86 BIOS normally supports LBA addressing directly.
If INT 0x13 AH 0x41 returns with CX bit0 set, then INT 0x13 AH 0x42 may be used
for reading. (Sometimes even if the bit is not set to indicate the capability.)
For C/H/S, the sector address is broken up into whole cylinders, remaining
heads, and remaining sectors + 1. The nomenclature seems to stem from antique
drum storage.
There are two parameters, sectors_per_head and heads_per_cylinder which are not
stored in the MBR. So it is more or less arbitray how to convert a LBA into
a C/H/S address and vice versa. For maximum range of C/H/S addresses one
may use sectors_per_head = 63 , heads_per_cylinder = 255.
stored in the MBR. So at ISO production time it is more or less arbitray how
to convert a LBA into a C/H/S address and vice versa.
At boot time the x86 BIOS decides about the two parameters. The boot loader may
inquire these values by INT 0x13 AH 0x08 and use them to convert LBA to C/H/S
for the read operation INT 0x13 AH 0x02. So the C/H/S values in an ISO's
partition table are quite fictional and of few impact on boot loaders.
More important seems to align partition ends to a consistent cylinder size,
because some partition editors deduce their idea of disk geometry from there
and raise protest if they deem it inconsistent.
For maximum range of C/H/S addresses one may use sectors_per_head = 63 ,
heads_per_cylinder = 255. But that is not divisible by 4 and imposes alignment
problems with ISO 9660 filesystems. So (32,64) for images up to 1 GiB
or (63,252) for larger images are better.
Words are composed little-endian style.
@ -331,8 +348,9 @@ Byte Range | Value | Meaning
0 - 439 | = opaque = | Code Area filled with bytes for some boot system,
| | typically machine code.
| |
440 - 443 | disk_sgntr | Disc signature, an individual disk id of obscure
| | usability.
440 - 443 | disk_sgntr | Disc signature: An individual disk id. Some software
| | might use it to recognize the same storage medium
| | at different device addresses.
| | (The Code Area might extend up to this field.)
| |
444 - 445 | 0 | "usually nulls"
@ -340,8 +358,11 @@ Byte Range | Value | Meaning
| |
446 - 461 | ========== | Partition Table Entry for partition 1
| |
446 - 446 | status | Governs bootability:
| | 0x80 = bootable/active , 0x00 non-bootable/inactive
446 - 446 | status | For some generic MBRs this marks the one partition
| | from which the MBR should load and run more code.
| | 0x80 = bootflag/active , 0x00 = noboot/inactive
| | Some BIOSes ignore MBRs with no bootflag in any of
| | their partition table entries.
| |
447 - 449 | ========== | C/H/S address of partition start
447 - 447 | start_head | Heads part of start address.
@ -404,6 +425,8 @@ Sources:
http://www.informit.com/articles/article.aspx?p=376123&seqNum=3
syslinux-4.05/utils/isohybrid.c
Mail conversations with Vladimir Serbinenko.
Mail conversations with Natalia Portillo of DiskImageChef,
who quoted "Inside Macintosh" Volumes IV and V.
APM has an adjustable block size. Because the ISO images shall always work
@ -412,11 +435,19 @@ additional GPT, only block size 2048 is considered here.
The role of APM in the boot process is to guide the firmware to a
HFS+ filesystem.
Block0 of an APM begins at byte 0 of the medium. Thus it collides with MBR and
other boot sector formats. By lucky coincidence it is possible to compose
a mock-up of a Block0 which is acceptable to firmware which expects APM,
and is also harmless x86 machine code with no negative side effects.
So it is possible to combine APM with an especially prepared MBR.
Block0 (aka Driver Descriptor Map) of an APM begins at byte 0 of the medium.
Thus it collides with MBR and other boot sector formats. By lucky coincidence
it is possible to compose a mock-up of a Block0 which is acceptable to firmware
which expects APM, and is also harmless x86 machine code with no negative
side effects. So it is possible to combine APM with an especially prepared MBR.
Block0 is optional. But in the context of bootable hybrid ISOs it is not only
needed to announce block size 2048, but also it is much better suited for
staging as harmless x86 machine code than is an APM partition entry.
Usually there is no Device Partition Map block (signature "TS"), although it
is demanded by the book "Inside Macintosh". It would sit where GPT has its
header block. So DPM is not described here.
The layout of a Block0 of an APM is:
@ -427,13 +458,17 @@ Byte Range | Value | Meaning (all numbers are stored big endian)
4 - 7 | block_count| Number of blocks covered by APM
| | Often some x86-harmless dummy. E.g. 0x9090 = 37008
| | or 0xeb02ffff = 3,942,842,367
8 - 9 | dev_type | obscure: "device type"
10 - 11 | dev_id | obscure: "device id"
12 - 15 | drv_data | obscure: "driver data"
16 - 17 | drv_count | obscure: "driver descriptor count"
18 - 81 | drv_map | obscure: "driver descriptor table"
| | with 8 entries of 16 bytes each
82 - 511 | reserved |
8 - 9 | dev_type | Device type: The id of the Mac driver which is in
| | charge of the storage device.
10 - 11 | dev_id | Device id: Address in an i/o bus system.
12 - 15 | drv_data | Driver data: Not used.
16 - 17 | drv_count | Driver count: Count of entries in drv_map.
18 - 505 | drv_map | Driver descriptor table:
| | Up to 61 entries of 8 bytes each.
| | They contain the 32 bit 512-byte LBA of the driver's
| | storage location, its 16 bit size in 512-byte blocks,
| | and value 0x0001.
506 - 511 | reserved |
---------- | ---------- | ----------------------------------------------------
The SYSLINUX program isohybrid.c overwrites the first 32 bytes of this
@ -463,9 +498,12 @@ Byte Range | Value | Meaning (all numbers are stored big endian)
84 - 87 | lb_count | Logical block count (same as block_count)
88 - 91 | flags | Status flags
| | bit0= entry is valid
| | bit1= entry is allocated
| | bit1= partition is allocated
| | bit2= partition is in use
| | bit3= partition contains valid boot information
| | bit4= partition is readable
| | bit5= partition is writable
| | bit7= boot code is position independent
| | bit30= automatic mount (legacy Mac)
92 - 95 | boot_block | Logical start block number of boot code = 0
96 - 99 | boot_bytes | Number of bytes in boot code = 0
@ -649,6 +687,7 @@ Sources:
There are traces in the web which relate this to specs by
MIPS Computer Systems, Inc. , 1985
Silicon Graphics Computer Systems, Inc. , 2000
Mail conversations with Natalia Portillo.
The first 512 bytes of the media constitute the Volume Header.
@ -659,7 +698,11 @@ Byte Range | Value | Meaning
0 - 3 | 0x0be5a941 | Magic number
4 - 5 | 0 | Root partition number
6 - 7 | 0 | Swap partition number
8 - 23 | 0 | Name of file to boot (unclear what this means)
8 - 23 | 0 | One of the boot_name items from the Volume Directory
| | may be put here to choose for booting the entry with
| | that name.
| | (Obviously it may be empty if only one non-zero entry
| | exists in the Volume Directory.)
| |
24 - 71 | ========== | Device Parameters
| |

View File

@ -189,7 +189,7 @@ With tag type 2:
Keep the original MD5 context of the data blocks and clone one for obtaining
the MD5 bytes.
If the MD5s match, then compute the checksum block and all folowing ones into
If the MD5s match, then compute the checksum block and all following ones into
the kept MD5 context and go on with reading and computing for the tree checksum
tag. This will be found at block address next_tag, verified and parsed by:
iso_util_decode_md5_tag(block, &tag_type, &pos,
@ -211,7 +211,7 @@ next_tag. Go on by looking for tag type 2 and follow above prescription.
Checking the Data Part of the Session
In order to check the trustworthyness of a whole session, continue reading
In order to check the trustworthiness of a whole session, continue reading
and checksumming after the tree was verified.
Read and checksum the blocks. When reaching block address next_tag (from the

View File

@ -394,12 +394,6 @@ MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
# If the sources in your project are distributed over multiple directories
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
# in the documentation. The default is NO.
SHOW_DIRECTORIES = NO
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from the
# version control system). Doxygen will invoke the program by executing (via
@ -527,7 +521,7 @@ EXCLUDE_SYMBOLS =
# directories that contain example code fragments that are included (see
# the \include command).
EXAMPLE_PATH = test
EXAMPLE_PATH = demo/demo.c
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
@ -698,12 +692,6 @@ HTML_FOOTER =
HTML_STYLESHEET =
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
# files or namespaces will be aligned in HTML using tables. If set to
# NO a bullet list will be used.
HTML_ALIGN_MEMBERS = YES
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
# will be generated that can be used as input for tools like the
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
@ -938,18 +926,6 @@ GENERATE_XML = NO
XML_OUTPUT = xml
# The XML_SCHEMA tag can be used to specify an XML schema,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_SCHEMA =
# The XML_DTD tag can be used to specify an XML DTD,
# which can be used by a validating XML parser to check the
# syntax of the XML files.
XML_DTD =
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
# dump the program listings (including syntax highlighting
# and cross-referencing information) to the XML output. Note that

View File

@ -235,7 +235,7 @@ An eventually needed qualifier is stored in one or more Qualifier Records.
[b] "BP 2 - Qualifier Record Head" shall be present only if QUALIFIER is set
to 1. It shall give the number of Qualifier Bytes and eventually
indicate that the qualifier continues in a Qualifier Record which comes
imediately after this record.
immediately after this record.
0 to 127 Q_LENGTH, the qualifier is complete by this record
128 to 255 Q_LENGTH+128, the qualifier is continued by next record
So a Qualifier Record can contain at most 127 Qualifier Bytes.

View File

@ -4,7 +4,7 @@
Directory of Namespace "isofs."
by Thomas Schmitt - mailto:scdbackup@gmx.net
Libburnia project - mailto:libburn-hackers@pykix.org
Libburnia project - mailto:bug-xorriso@gnu.org
The following names are defined for AAIP namespace "isofs." as mentioned in
@ -227,7 +227,7 @@ This text is under
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
It shall only be modified in sync with libisofs and other software which
makes use of AAIP. Please mail change requests to mailing list
<libburn-hackers@pykix.org> or to the copyright holder in private.
<bug-xorriso@gnu.org> or to the copyright holder in private.
Only if you cannot reach the copyright holder for at least one month it is
permissible to modify this text under the same license as the affected
copy of libisofs.

View File

@ -99,10 +99,14 @@ int aaip_set_acl_text(char *path, char *text, int flag)
-7 support of ACL not enabled at compile time
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
size_t *value_lengths, char **values, int *errnos,
int flag)
{
size_t i;
for(i= 0; i < num_attrs; i++)
errnos[i]= 0;
for(i= 0; i < num_attrs; i++) {
if(names[i] == NULL || values[i] == NULL)
continue;

View File

@ -5,9 +5,9 @@
Arbitrary Attribute Interchange Protocol , system adapter for getting and
setting of ACLs and xattr.
To be included by aaip_0_2.c for FreeBSD and NetBSD
To be included by aaip_0_2.c for FreeBSD, NetBSD, and OpenBSD
Copyright (c) 2009 - 2014 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2016 Thomas Schmitt, libburnia project, GPLv2+
*/
@ -228,6 +228,10 @@ static int aaip_extattr_make_list(char *path, int attrnamespace,
*list_size = 0;
return(2);
}
if(errno == EPERM && attrnamespace == EXTATTR_NAMESPACE_SYSTEM) {
*list_size = 0;
return(3);
}
return(0);
}
if(*list_size == 0)
@ -312,6 +316,54 @@ static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
return(1);
}
static int get_single_attr(char *path, char *name, size_t *value_length,
char **value_bytes, int flag)
{
char *namept;
int attrnamespace;
ssize_t value_ret;
*value_bytes= NULL;
*value_length= 0;
if(strncmp(name, "user.", 5) == 0) {
attrnamespace= EXTATTR_NAMESPACE_USER;
namept= name + 5;
} else {
if(!(flag & 8))
return(0);
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
namept= name + 7;
}
/* Predict length of value */
if(flag & 32) /* follow link */
value_ret= extattr_get_file(path, attrnamespace, namept, NULL, (size_t) 0);
else
value_ret= extattr_get_link(path, attrnamespace, namept, NULL, (size_t) 0);
if(value_ret == -1)
return(0);
*value_bytes= calloc(value_ret + 1, 1);
if(*value_bytes == NULL)
return(-1);
/* Obtain value */
if(flag & 32) /* follow link */
value_ret= extattr_get_file(path, attrnamespace, namept,
*value_bytes, (size_t) value_ret);
else
value_ret= extattr_get_link(path, attrnamespace, namept,
*value_bytes, (size_t) value_ret);
if(value_ret == -1) {
free(*value_bytes);
*value_bytes= NULL;
*value_length= 0;
return(0);
}
*value_length= value_ret;
return(1);
}
#endif /* Libisofs_with_freebsd_extattR */
@ -332,7 +384,8 @@ static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target
bit15= free memory of names, value_lengths, values
@return >0 ok
@return 1 ok
2 ok, no permission to inspect non-user namespaces
<=0 error
-1= out of memory
-2= program error with prediction of result size
@ -342,7 +395,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag)
{
int ret;
ssize_t i, num_names= 0, acl_names= 0;
ssize_t i, num_names= 0;
#ifdef Libisofs_with_aaip_acL
unsigned char *a_acl= NULL;
@ -350,11 +403,12 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
size_t a_acl_len= 0;
#endif
#ifdef Libisofs_with_freebsd_extattR
char *list= NULL, *user_list= NULL, *sys_list= NULL, *namept;
ssize_t value_ret, retry= 0, list_size= 0, user_list_size= 0;
char *list= NULL, *user_list= NULL, *sys_list= NULL;
ssize_t value_ret, list_size= 0, user_list_size= 0;
ssize_t sys_list_size= 0;
int attrnamespace;
int acl_names= 0;
#endif
int no_perm_for_system= 0;
if(flag & (1 << 15)) { /* Free memory */
{ret= 1; goto ex;}
@ -390,6 +444,8 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
&sys_list, &sys_list_size, flag & 32);
if(ret <= 0)
{ret= -1; goto ex;}
if(ret == 3)
no_perm_for_system= 1;
}
/* Check for NUL in names, convert into a linuxish list of namespace.name */
@ -408,7 +464,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
#ifdef Libisofs_with_aaip_acL
if(flag & 1) {
num_names++;
#ifdef Libisofs_with_freebsd_extattR
acl_names= 1;
#endif
}
#endif
@ -440,45 +500,10 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
}
for(i= 0; (size_t) i < *num_attrs; i++) {
if(strncmp((*names)[i], "user.", 5) == 0) {
attrnamespace= EXTATTR_NAMESPACE_USER;
namept= (*names)[i] + 5;
} else {
if(!(flag & 8))
continue;
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
namept= (*names)[i] + 7;
}
/* Predict length of value */
if(flag & 32) /* follow link */
value_ret= extattr_get_file(path, attrnamespace, namept,
NULL, (size_t) 0);
else
value_ret= extattr_get_link(path, attrnamespace, namept,
NULL, (size_t) 0);
if(value_ret == -1)
continue;
(*values)[i]= calloc(value_ret + 1, 1);
if((*values)[i] == NULL)
value_ret= get_single_attr(path, (*names)[i], *value_lengths + i,
*values + i, flag & (8 | 32));
if(value_ret <= 0)
{ret= -1; goto ex;}
/* Obtain value */
if(flag & 32) /* follow link */
value_ret= extattr_get_file(path, attrnamespace, namept,
(*values)[i], (size_t) value_ret);
else
value_ret= extattr_get_link(path, attrnamespace, namept,
(*values)[i], (size_t) value_ret);
if(value_ret == -1) { /* there could be a race condition */
if(retry++ > 5)
{ret= -1; goto ex;}
i--;
continue;
}
(*value_lengths)[i]= value_ret;
retry= 0;
}
}
@ -489,8 +514,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
if(flag & 1) { /* Obtain ACL */
/* access-ACL */
aaip_get_acl_text(path, &a_acl_text, flag & (16 | 32));
if(a_acl_text == NULL)
{ret= 1; goto ex;} /* empty ACL / only st_mode info was found in ACL */
if(a_acl_text == NULL) {
/* empty ACL / only st_mode info was found in ACL */
ret= 1 + no_perm_for_system;
goto ex;
}
ret= aaip_encode_acl(a_acl_text, (mode_t) 0, &a_acl_len, &a_acl, flag & 2);
if(ret <= 0)
goto ex;
@ -509,7 +537,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
#endif /* Libisofs_with_aaip_acL */
ret= 1;
ret= 1 + no_perm_for_system;
ex:;
#ifdef Libisofs_with_aaip_acL
if(a_acl != NULL)
@ -768,6 +796,15 @@ static int aaip_extattr_delete_names(char *path, int attrnamespace,
#endif /* Libisofs_with_freebsd_extattR */
static void register_errno(int *errnos, int i, int in_errno)
{
if(in_errno > 0)
errnos[i]= in_errno;
else
errnos[i]= -1;
}
/* Bring the given attributes and/or ACLs into effect with the given file.
@param flag Bitfield for control purposes
bit0= decode and set ACLs
@ -779,6 +816,8 @@ static int aaip_extattr_delete_names(char *path, int attrnamespace,
bit5= in case of symbolic link: manipulate link target
bit6= tolerate inappropriate presence or absence of
directory default ACL
bit7= void setting a name value pair if it already
exists and has the desired value.
@return 1 success
-1 error memory allocation
-2 error with decoding of ACL
@ -791,17 +830,23 @@ static int aaip_extattr_delete_names(char *path, int attrnamespace,
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
size_t *value_lengths, char **values,
int *errnos, int flag)
{
int ret, has_default_acl= 0;
int ret, has_default_acl= 0, end_ret= 1;
size_t i, consumed, acl_text_fill, acl_idx= 0;
char *acl_text= NULL;
#ifdef Libisofs_with_freebsd_extattR
char *user_list= NULL, *sys_list= NULL, *namept;
ssize_t user_list_size= 0, sys_list_size= 0;
char *user_list= NULL, *sys_list= NULL, *namept, *old_value;
ssize_t user_list_size= 0, sys_list_size= 0, value_ret;
int attrnamespace;
size_t old_value_l;
int skip;
#endif
for(i= 0; i < num_attrs; i++)
errnos[i]= 0;
#ifdef Libisofs_with_freebsd_extattR
if(flag & 2) { /* Delete all file attributes */
@ -850,16 +895,35 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
namept= names[i] + 7;
} else {
{ret= -8; goto ex;}
register_errno(errnos, i, (int) EFAULT);
end_ret= -8;
continue;
}
skip= 0;
if(flag & 128) {
value_ret= get_single_attr(path, names[i], &old_value_l,
&old_value, flag & (8 | 32));
if(value_ret > 0 && old_value_l == value_lengths[i]) {
if(memcmp(old_value, values[i], value_lengths[i]) == 0)
skip= 1;
}
if(old_value != NULL)
free(old_value);
}
if(!skip) {
if(flag & 32)
ret= extattr_set_file(path, attrnamespace, namept,
values[i], value_lengths[i]);
else
ret= extattr_set_link(path, attrnamespace, namept,
values[i], value_lengths[i]);
if(ret == -1) {
register_errno(errnos, i, errno);
if(end_ret != 1)
end_ret= -4;
continue;
}
}
if(flag & 32)
ret= extattr_set_file(path, attrnamespace, namept,
values[i], value_lengths[i]);
else
ret= extattr_set_link(path, attrnamespace, namept,
values[i], value_lengths[i]);
if(ret == -1)
{ret= -4; goto ex;}
#else
@ -874,8 +938,12 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
}
/* Decode ACLs */
/* It is important that this happens after restoring xattr which might be
representations of ACL, too. If isofs ACL are enabled, then they shall
override the xattr ones.
*/
if(acl_idx == 0)
{ret= 1; goto ex;}
{ret= end_ret; goto ex;}
i= acl_idx - 1;
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
@ -897,6 +965,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
#ifdef Libisofs_with_aaip_acL
ret= aaip_set_acl_text(path, acl_text, flag & (32 | 64));
if(ret == -1)
register_errno(errnos, i, errno);
if(ret <= 0)
{ret= -3; goto ex;}
#else
@ -906,7 +976,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
if(has_default_acl && !(flag & 64))
{ret= -3; goto ex;}
ret= 1;
ret= end_ret;
ex:;
if(acl_text != NULL)
free(acl_text);

View File

@ -7,7 +7,7 @@
To be included by aaip_0_2.c for Linux
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2018 Thomas Schmitt, libburnia project, GPLv2+
*/
@ -30,8 +30,12 @@
#endif
#ifdef Libisofs_with_aaip_xattR
#ifdef Libisofs_with_sys_xattR
#include <sys/xattr.h>
#else
#include <attr/xattr.h>
#endif
#endif
/* ------------------------------ Inquiry --------------------------------- */
@ -159,6 +163,41 @@ int aaip_get_acl_text(char *path, char **text, int flag)
}
#ifdef Libisofs_with_aaip_xattR
static int get_single_attr(char *path, char *name, size_t *value_length,
char **value_bytes, int flag)
{
ssize_t value_ret;
*value_bytes= NULL;
*value_length= 0;
if(flag & 32)
value_ret= getxattr(path, name, NULL, 0);
else
value_ret= lgetxattr(path, name, NULL, 0);
if(value_ret == -1)
return(0);
*value_bytes= calloc(value_ret + 1, 1);
if(*value_bytes == NULL)
return(-1);
if(flag & 32)
value_ret= getxattr(path, name, *value_bytes, value_ret);
else
value_ret= lgetxattr(path, name, *value_bytes, value_ret);
if(value_ret == -1) {
free(*value_bytes);
*value_bytes= NULL;
*value_length= 0;
return(0);
}
*value_length= value_ret;
return(1);
}
#endif /* Libisofs_with_aaip_xattR */
/* Obtain the Extended Attributes and/or the ACLs of the given file in a form
that is ready for aaip_encode().
@param path Path to the file
@ -176,7 +215,9 @@ int aaip_get_acl_text(char *path, char **text, int flag)
bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target
bit15= free memory of names, value_lengths, values
@return >0 ok
@return 1 ok
(reserved for FreeBSD: 2 ok, no permission to inspect
non-user namespaces.)
<=0 error
-1= out of memory
-2= program error with prediction of result size
@ -195,7 +236,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
#endif
#ifdef Libisofs_with_aaip_xattR
char *list= NULL;
ssize_t value_ret, retry= 0, list_size= 0;
ssize_t value_ret, list_size= 0;
#define Libisofs_aaip_get_attr_activE yes
#endif
#ifdef Libisofs_aaip_get_attr_activE
@ -288,27 +329,10 @@ ex:;
if(!(flag & 8))
if(strncmp((*names)[i], "user.", 5))
continue;
if(flag & 32)
value_ret= getxattr(path, (*names)[i], NULL, 0);
else
value_ret= lgetxattr(path, (*names)[i], NULL, 0);
if(value_ret == -1)
continue;
(*values)[i]= calloc(value_ret + 1, 1);
if((*values)[i] == NULL)
value_ret= get_single_attr(path, (*names)[i], *value_lengths + i,
*values + i, flag & 32);
if(value_ret <= 0)
{ret= -1; goto ex;}
if(flag & 32)
value_ret= getxattr(path, (*names)[i], (*values)[i], value_ret);
else
value_ret= lgetxattr(path, (*names)[i], (*values)[i], value_ret);
if(value_ret == -1) { /* there could be a race condition */
if(retry++ > 5)
{ret= -1; goto ex;}
i--;
continue;
}
(*value_lengths)[i]= value_ret;
retry= 0;
}
}
@ -434,6 +458,15 @@ ex:
}
static void register_errno(int *errnos, int i)
{
if(errno > 0)
errnos[i]= errno;
else
errnos[i]= -1;
}
/* Bring the given attributes and/or ACLs into effect with the given file.
@param flag Bitfield for control purposes
bit0= decode and set ACLs
@ -443,8 +476,10 @@ ex:
I.e. those with a name which does not begin
by "user."
bit5= in case of symbolic link: manipulate link target
bit6= tolerate inappropriate presence or absense of
bit6= tolerate inappropriate presence or absence of
directory default ACL
bit7= avoid setting a name value pair if it already
exists and has the desired value.
@return 1 success
-1 error memory allocation
-2 error with decoding of ACL
@ -457,20 +492,25 @@ ex:
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
size_t *value_lengths, char **values,
int *errnos, int flag)
{
int ret;
int ret, end_ret= 1;
size_t i, consumed, acl_text_fill, acl_idx= 0;
char *acl_text= NULL;
#ifdef Libisofs_with_aaip_xattR
char *list= NULL;
ssize_t list_size= 0;
char *list= NULL, *old_value;
ssize_t list_size= 0, value_ret;
size_t old_value_l;
int skip;
#endif
#ifdef Libisofs_with_aaip_acL
size_t h_consumed;
int has_default_acl= 0;
#endif
for(i= 0; i < num_attrs; i++)
errnos[i]= 0;
#ifdef Libisofs_with_aaip_xattR
@ -525,12 +565,28 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
#ifdef Libisofs_with_aaip_xattR
if(flag & 32)
ret= setxattr(path, names[i], values[i], value_lengths[i], 0);
else
ret= lsetxattr(path, names[i], values[i], value_lengths[i], 0);
if(ret == -1)
{ret= -4; goto ex;}
skip= 0;
if(flag & 128) {
value_ret= get_single_attr(path, names[i], &old_value_l,
&old_value, flag & 32);
if(value_ret > 0 && old_value_l == value_lengths[i]) {
if(memcmp(old_value, values[i], value_lengths[i]) == 0)
skip= 1;
}
if(old_value != NULL)
free(old_value);
}
if(!skip) {
if(flag & 32)
ret= setxattr(path, names[i], values[i], value_lengths[i], 0);
else
ret= lsetxattr(path, names[i], values[i], value_lengths[i], 0);
if(ret == -1) {
register_errno(errnos, i);
end_ret= -4;
continue;
}
}
#else
@ -540,9 +596,13 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
}
/* Decode ACLs */
/* Decode ACLs */
/* It is important that this happens after restoring xattr which might be
representations of ACL, too. If isofs ACL are enabled, then they shall
override the xattr ones.
*/
if(acl_idx == 0)
{ret= 1; goto ex;}
{ret= end_ret; goto ex;}
i= acl_idx - 1;
/* "access" ACL */
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
@ -566,6 +626,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
has_default_acl= (ret == 2);
ret= aaip_set_acl_text(path, acl_text, flag & 32);
if(ret == -1)
register_errno(errnos, i);
if(ret <= 0)
{ret= -3; goto ex;}
/* "default" ACL */
@ -590,6 +652,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
if(ret <= 0)
{ret= -2; goto ex;}
ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
if(ret == -1)
register_errno(errnos, i);
if(ret <= 0)
{ret= -3; goto ex;}
} else {
@ -601,7 +665,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
}
}
ret= 1;
ret= end_ret;
#else

View File

@ -7,7 +7,7 @@
See libisofs/aaip_0_2.h
http://libburnia-project.org/wiki/AAIP
Copyright (c) 2009 - 2015 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2016 Thomas Schmitt, libburnia project, GPLv2+
*/
@ -648,7 +648,7 @@ ex:;
mission bits.
*/
/* Analyze occurence of ACL tag types in long text form. If not disabled by
/* Analyze occurrence of ACL tag types in long text form. If not disabled by
parameter flag remove the entries of type "user::" , "group::" , "other::" ,
or "other:" from an ACL in long text form if they match the bits in st_mode
as described by man 2 stat and man 5 acl.
@ -2188,15 +2188,41 @@ ex:;
/* ----------------------- Adapter for operating systems ----------------- */
#ifdef Libisofs_use_os_dummY
#include "aaip-os-dummy.c"
#else
#ifdef __FreeBSD__
#include "aaip-os-freebsd.c"
#else
#ifdef __FreeBSD_kernel__
#ifdef NIX
#ifdef Libisofs_with_aaip_xattR
/* ts B51213: xattr system library calls are only stubs */
#include "aaip-os-linux.c"
#else
/* ts B51213: extattr system library calls are not even present */
#include "aaip-os-freebsd.c"
#endif /* ! Libisofs_with_aaip_xattR */
#else /* NIX */
/* ts B51213: so we still end up at the dummy */
#include "aaip-os-dummy.c"
#endif /* ! NIX */
#else
#ifdef __NetBSD__
#include "aaip-os-freebsd.c"
#else
#ifdef __OpenBSD__
#include "aaip-os-freebsd.c"
#else
#ifdef __linux
@ -2214,6 +2240,9 @@ ex:;
#include "aaip-os-dummy.c"
#endif /* ! __linux */
#endif /* ! __OpenBSD__ */
#endif /* ! __NetBSD__ */
#endif /* ! __FreeBSD_kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! Libisofs_use_os_dummY */

View File

@ -9,13 +9,16 @@
test/aaip_0_2.h - Public declarations
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2016 Thomas Schmitt, libburnia project, GPLv2+
*/
#ifndef Aaip_h_is_includeD
#define Aaip_h_is_includeD yes
/* For ssize_t */
#include <unistd.h>
/* --------------------------------- Encoder ---------------------------- */
@ -90,7 +93,7 @@ int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode,
size_t *result_len, unsigned char **result, int flag);
/* Analyze occurence of ACL tag types in long text form. If not disabled by
/* Analyze occurrence of ACL tag types in long text form. If not disabled by
parameter flag remove the entries of type "user::" , "group::" , "other::" ,
or "other:" from an ACL in long text form if they match the bits in st_mode
as described by man 2 stat and man 5 acl.
@ -504,7 +507,8 @@ int aaip_set_acl_text(char *path, char *text, int flag);
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag);
size_t *value_lengths, char **values,
int *errnos, int flag);
#endif /* ! Aaip_h_is_includeD */

View File

@ -252,8 +252,11 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
/* Obtain ownership of eventual AAIP string */
ret = iso_file_source_get_aa_string(src, &aa_string,
1 | (image->builder_ignore_acl << 1) |
(image->builder_ignore_ea << 2 ));
if (ret == 1 && aa_string != NULL) {
(image->builder_ignore_ea << 2) |
(image->builder_take_all_ea << 3));
if(ret == 2)
image->blind_on_local_get_attrs = 1;
if (ret > 0 && aa_string != NULL) {
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
if (ret < 0)
goto ex;

366
libisofs/changelog.txt Normal file
View File

@ -0,0 +1,366 @@
------------------------------------------------------------------------------
libburnia-project.org / dev.lovelyhq.com libisofs
------------------------------------------------------------------------------
------------------------------------------------------------------------------
Changelog
------------------------------------------------------------------------------
13 Nov 2016 [8bf32d8] [1340]
doc/susp_aaip_isofs_names.txt
Prepared some of the documentation for move to dev.lovelyhq.com
13 Nov 2016 [c51efce] [1341]
libisofs/fs_image.c
Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root SUSP
13 Nov 2016 [dc6cd94] [1342]
libisofs/libisofs.h
libisofs/eltorito.c
libisofs/libisofs.ver
New API calls el_torito_set_full_load(), el_torito_get_full_load()
13 Nov 2016 [ed209e0] [1343]
COPYRIGHT
Mentioned Vladimir Serbinenko in libisofs copyright list
13 Nov 2016 [2961bde] [1344]
ChangeLog
+ libisofs/changelog.txt
Updated change log
23 Nov 2016 [01020ef] [1345]
libisofs/eltorito.h
Committed missing part of rev dc6cd94/1342
23 Nov 2016 [8ec75ee] [1346]
libisofs/fs_image.c
libisofs/rockridge.h
libisofs/rockridge_read.c
Bug fix: Non-SUSP data in System Use Area prevented image loading if Rock Ridge was enabled. Thanks to Jonathan Dowland.
25 Dec 2016 [76181d0] [1347]
libisofs/ecma119.c
Restricted volume size of PVD with non-zero partition offset to filesystem
size even if the first PVD claims the whole output size
25 Dec 2016 [afb10aa] [1348]
libisofs/eltorito.c
Claiming full output size in first PVD if partition offset is non-zero
25 Dec 2016 [3043b5f] [1349]
libisofs/fs_image.c
Enabled recognition of partition offset of grub-mkrescue-sed.sh mode "gpt_appended"
03 Jan 2017 [2152804] [1350]
libisofs/system_area.c
Bug fix: Protective MBR for GPT could emerge with boot flag set.
24 Jan 2014 [5c1c5cd] [1351]
libisofs/system_area.c
Bug fix: Appended partitions of size >= 4 GiB led to abort with error message
"FATAL : ISO overwrite". Thanks to Sven Haardiek.
24 Jan 2014 [094b3f7] [1352]
libisofs/system_area.c
Updated copyright year in system_area.c
27 Feb 2014 [e66b9bf] [1353]
libisofs/libisofs.h
libisofs/ecma119.h
libisofs/ecma119.c
libisofs/system_area.c
libisofs/libisofs.ver
New API call iso_write_opts_set_iso_mbr_part_type()
27 Feb 2014 [5600f3d] [1354]
libisofs/system_area.c
When deciding boot flag, consider MBR partition slot empty only if entirely 0
19 Mar 2017 [86f6ffc] [1355]
libisofs/system_area.c
Let iso_mbr_part_type 0xee override ban on 0xee without GPT
09 Apr 2017 [94e4bfb] [1356]
libisofs/fs_image.c
Adapted recognizing of partition offset to the changes of rev afb10aa / 1348
10 Apr 2017 [0e7300b] [1357]
doc/boot_sectors.txt
Clarified meaning of MBR partition boot flag
25 Apr 2017 [fb86970] [1358]
libisofs/system_area.c
Reacted on harmless compiler warning about uninitialized variable.
03 Jun 2017 [d7737e3] []
libisofs/fs_image.c
Removed ban on reading El Torito platform ids other than 0 and 0xef
29 Jun 2017 [6282bbc]
libisofs/system_area.c
Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with generic MBR
01 Jul 2017 [18ab601]
libisofs/eltorito.c
libisofs/system_area.c
Let ISO size cover appended partitions if --protective-msdos-label or nonzero -partition_offset is given
13 Aug 2017 [c6e4035]
doc/boot_sectors.txt
Added boot sector knowledge gained from Natalia Portillo
13 Aug 2017 [e19a338]
doc/boot_sectors.txt
Re-added two empty lines which were lost by previous commit
14 Aug 2014 [1e40ed3]
libisofs/fs_image.c
Bug fix: Keeping and patching of loaded boot images failed. Regression by version 1.4.4.
14 Aug 2017 [280108d]
ChangeLog
libisofs/changelog.txt
Updated change log
17 Aug 2017 [860a91d]
libisofs/libisofs.h
libisofs/fs_image.c
libisofs/messages.c
Preventing NULL dereference if root directory bears a RRIP RE entry
18 Aug 2017 [36c8800]
libisofs/rockridge_read.c
Preventing buffer underread with empty RRIP SL component.
Debian bug 872475. Thanks Jakub Wilk and American Fuzzy Lop.
18 Aug 2017 [16bde11]
libisofs/fs_image.c
Preventing memory leak caused by RRIP SL entry without PX entry that marks
the file as symbolic link
18 Aug 2017 [661b68c]
libisofs/rockridge_read.c
Preventing buffer overflow with AAIP AL entry of insufficient size.
Debian bug 872545. Thanks Jakub Wilk and American Fuzzy Lop.
19 Aug 2017 [91490d5]
libisofs/libisofs.h
libisofs/messages.c
libisofs/rockridge_read.c
Preventing use of zero sized SUSP CE entry which causes SIGSEGV.
Debian bug 872590. Thanks Jakub Wilk and American Fuzzy Lop.
19 Aug 2017 [31088d9]
libisofs/rockridge_read.c
Avoid to read blocks from start of CE area which do not belong to the given file
19 Aug 2017 [2a64d89]
libisofs/libisofs.h
libisofs/rockridge.h
libisofs/fs_image.c
libisofs/rockridge_read.c
libisofs/messages.c
Refuse to read CE data blocks from after the end of ISO filesystem
21 Aug 2017 [a7152f5]
libisofs/fs_image.c
Correcting previous commit for supporting multi-session
21 Aug 2017 [78b0a7b]
libisofs/fs_image.c
Disallowed RRIP CL chaining in order to break any endless loops.
Debian bug 872761. Thanks Jakub Wilk and American Fuzzy Lop.
21 Aug 2017 [e599a57]
libisofs/fs_image.c
Closed a memory leak about RRIP CL following
24 Aug 2017 [cace41e]
libisofs/ecma119.h
libisofs/ecma119.c
libisofs/system_area.c
Enabled partition intervals with source "imported_iso" with ISO growing
26 Aug 2017 [028f927]
libisofs/libisofs.h
libisofs/ecma119.c
libisofs/system_area.c
libisofs/messages.c
Throw error if imported_iso interval would be overwritten by multi-session
09 Sep 2017 [4e5a54c]
libisofs/fs_image.c
Swapped at recognition time the precendence of MBR properties "isohybrid"
and "protective-msdos-label"
12 Sep 2017 [7234425]
ChangeLog
Updated change log
12 Sep 2017 [dfc6de9]
configure.ac
libisofs/libisofs.h
Version leap to 1.4.8.
12 Sep 2017 [bdfd4c4]
libisofs/changelog.txt
Updated change log
------------------------------------ release - libisofs-1.4.8 - 12 Sep 2017
* Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root SUSP
* Bug fix: Non-SUSP data in System Use Area prevented image loading if
Rock Ridge was enabled. Thanks to Jonathan Dowland.
* Bug fix: Protective MBR for GPT could emerge with boot flag set.
* Bug fix: Appended partitions of size >= 4 GiB led to abort with error message
"FATAL : ISO overwrite". Thanks to Sven Haardiek.
* Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with
generic MBR.
* Bug fix: Keeping and patching of loaded boot images failed.
Regression by version 1.4.4.
* Bug fix: Program crashes by intentionally wrong ISO image input.
Found by American Fuzzy Lop and Jakub Wilk.
Debian bug reports: 872372, 872475, 872545, 872590, 872761.
* New API calls el_torito_set_full_load(), el_torito_get_full_load().
* New API call iso_write_opts_set_iso_mbr_part_type().
12 Sep 2017 [48ee49a]
configure.ac
libisofs/libisofs.h
Version leap to 1.4.9
12 Sep 2017 [ce831f1]
ChangeLog
libisofs/changelog.txt
Updated change log
15 Sep 2017 [34e3586]
libisofs/node.c
Silenced harmless compiler warning -Wimplicit-fallthrough
16 Sep 2017 [874dc16]
libisofs/hfsplus.c
Fixed a message typo found by lintian
22 Sep 2017 [53b2d6d]
libisofs/hfsplus_classes.c
Bug fix: Reading beyond array end for HFS+ production caused SIGSEGV with
FreeBSD 11 CLANG -O2. Thanks ASX of GhostBSD.
22 Sep 2017 [79baab3]
libisofs/hfsplus_classes.c
Fixed a harmless lapse with static array initialization
07 Oct 2017 [7d45c88]
libisofs/libisofs.h
libisofs/image.h
libisofs/image.c
libisofs/builder.c
libisofs/fs_local.c
libisofs/libisofs.ver
New API call iso_image_get_ignore_aclea(),
new iso_image_set_ignore_aclea() and iso_file_source_get_aa_string() flag bit3
to import all xattr namespaces
23 Oct 2017 [4b031b5]
libisofs/libisofs.h
libisofs/image.h
libisofs/image.c
libisofs/fs_local.c
libisofs/builder.c
libisofs/aaip_0_2.h
libisofs/aaip_0_2.c
libisofs/aaip-os-linux.c
libisofs/aaip-os-freebsd.c
libisofs/aaip-os-dummy.c
libisofs/libisofs.ver
New flag bit7 with iso_local_set_attrs() to avoid unnecessary write attempts.
New return value 2 of IsoFileSource.get_aa_string() and iso_local_get_attrs().
New API calls iso_image_was_blind_attrs(), iso_local_set_attrs_errno().
23 Oct 2017 [633b4d5]
doc/boot_sectors.txt
Updated project mail addresses
31 Oct 2017 [1da3b17]
libisofs/aaip-os-linux.c
Changed a comment in Linux OS adapter
31 Oct 2017 [580b154]
libisofs/node.c
Adapted iso_node_merge_xattr to handling of all namespaces
22 Nov 2017 [a936409]
libisofs/system_area.c
Fixed failure to compile with experimental Libisofs_appended_partitions_inlinE
30 Mar 2018 [615dc7e]
libisofs/ecma119.h
libisofs/ecma119.c
libisofs/system_area.c
Bug fix: Add-on sessions with partition offset claimed too many blocks as size.
Regression of version 1.4.8.
31 Mar 2018 [ad843f1]
libisofs/joliet.c
Bug fix: Long Joliet names without dot were mangled with one character too many
31 Mar 2018 [3106121]
libisofs/joliet.c
Bug fix: Long Joliet names with leading dot were mangled one char too short
01 May 2018 [c5a9cc5]
libisofs/ecma119.h
libisofs/ecma119.c
libisofs/system_area.c
Changed bug fix 615dc7e9978ea0ba1eed7b4b661fe4e9f6f2769e of Mar 30 13:51:21 2018 +0200
18 May 2018 [848e039]
configure.ac
libisofs/aaip-os-linux.c
Preferring Linux include file sys/xattr.h over attr/attr.h
04 Jun 2018 [f39d4ee]
libisofs/ecma119.h
libisofs/system_area.h
libisofs/ecma119.c
libisofs/system_area.c
Putting user defined padding after appended partitions
10 Jun 2018 [69c8c54]
libisofs/libisofs.h
libisofs/messages.c
libisofs/fs_image.c
Improved message at image load time about hidden El Torito images for EFI
15 Sep 2018 [d3c17d0]
libisofs/libisofs.h
Version leap to 1.5.0.
15 Sep 2018 [e317a8d]
ChangeLog
libisofs/changelog.txt
Updated change log
16 Sep 2018 [066c6f6]
libisofs/aaip-os-freebsd.c
Fixed failure to build on NetBSD because of undeclared variable
------------------------------------ release - libisofs-1.5.0 - 15 Sep 2018
* New API call iso_image_get_ignore_aclea(),
new iso_image_set_ignore_aclea() and iso_file_source_get_aa_string()
flag bit3 to import all xattr namespaces
* New API calls iso_image_was_blind_attrs(), iso_local_set_attrs_errno().
* New flag bit7 with iso_local_set_attrs() to avoid unnecessary write attempts.
* New return value 2 of IsoFileSource.get_aa_string() and iso_local_get_attrs().
* Now putting user defined padding after appended partitions.
* Bug fix: Add-on sessions with partition offset claimed too many blocks as
size. Regression of version 1.4.8.
* Bug fix: Long Joliet names without dot were mangled with one character too
many. Long Joliet names with leading dot were mangled one char
too short.
* Bug fix: Reading beyond array end for HFS+ production caused SIGSEGV with
FreeBSD 11 CLANG -O2. Thanks ASX of GhostBSD.

View File

@ -145,7 +145,7 @@ void ds_free_data(IsoDataSource *src)
/**
* Create a new IsoDataSource from a local file. This is suitable for
* accessing regular .iso images, or to acces drives via its block device
* accessing regular .iso images, or to access drives via its block device
* and standard POSIX I/O calls.
*
* @param path

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2015 Thomas Schmitt
* Copyright (c) 2009 - 2018 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -104,6 +104,12 @@ void ecma119_image_free(Ecma119Image *t)
free(t->output_charset);
if (t->bootsrc != NULL)
free(t->bootsrc);
if (t->boot_appended_idx != NULL)
free(t->boot_appended_idx);
if (t->boot_intvl_start != NULL)
free(t->boot_intvl_start);
if (t->boot_intvl_size != NULL)
free(t->boot_intvl_size);
if (t->system_area_data != NULL)
free(t->system_area_data);
if (t->checksum_ctx != NULL) { /* dispose checksum context */
@ -187,7 +193,7 @@ size_t calc_dirent_len(Ecma119Image *t, Ecma119Node *n)
/**
* Computes the total size of all directory entries of a single dir,
* acording to ECMA-119 6.8.1.1
* according to ECMA-119 6.8.1.1
*
* This also take into account the size needed for RR entries and
* SUSP continuation areas (SUSP, 5.1).
@ -567,8 +573,12 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
vol.vol_desc_version[0] = 1;
strncpy_pad((char*)vol.system_id, system_id, 32);
strncpy_pad((char*)vol.volume_id, vol_id, 32);
iso_bb(vol.vol_space_size, t->vol_space_size - t->eff_partition_offset,
4);
if (t->pvd_size_is_total_size && t->eff_partition_offset <= 0) {
iso_bb(vol.vol_space_size, t->total_size / 2048, 4);
} else {
iso_bb(vol.vol_space_size,
t->vol_space_size - t->eff_partition_offset, 4);
}
iso_bb(vol.vol_set_size, (uint32_t) 1, 2);
iso_bb(vol.vol_seq_number, (uint32_t) 1, 2);
iso_bb(vol.block_size, (uint32_t) BLOCK_SIZE, 2);
@ -1178,6 +1188,13 @@ int tail_writer_compute_data_blocks(IsoImageWriter *writer)
{
int ret;
Ecma119Image *target;
#ifdef Libisofs_part_align_writeR
target = writer->target;
#else
struct iso_zero_writer_data_struct *data;
char msg[80];
@ -1192,21 +1209,57 @@ int tail_writer_compute_data_blocks(IsoImageWriter *writer)
iso_msgs_submit(0, msg, 0, "NOTE", 0);
data->num_blocks = target->opts->tail_blocks;
}
#endif /* ! Libisofs_part_align_writeR */
if (target->opts->tail_blocks <= 0)
return ISO_SUCCESS;
ret = zero_writer_compute_data_blocks(writer);
return ret;
}
static
int part_align_writer_compute_data_blocks(IsoImageWriter *writer)
{
int ret;
Ecma119Image *target;
struct iso_zero_writer_data_struct *data;
char msg[80];
target = writer->target;
/* Default setting in case no alignment is needed */
target->alignment_end_block = target->curblock;
ret = iso_align_isohybrid(target, 0);
if (ret < 0)
return ret;
data = (struct iso_zero_writer_data_struct *) writer->data;
if (target->part_align_blocks != 0) {
sprintf(msg, "Aligned image size to cylinder size by %d blocks",
target->part_align_blocks);
iso_msgs_submit(0, msg, 0, "NOTE", 0);
data->num_blocks = target->part_align_blocks;
}
if (target->part_align_blocks <= 0)
return ISO_SUCCESS;
ret = zero_writer_compute_data_blocks(writer);
target->alignment_end_block = target->curblock;
return ret;
}
/*
@param flag bit0= use tail_writer_compute_data_blocks rather than
zero_writer_compute_data_blocks
@param flag bit0-3= compute_data_blocks mode:
0= zero_writer_compute_data_blocks
1= tail_writer_compute_data_blocks
2= part_align_writer_compute_data_blocks
*/
static
int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
{
IsoImageWriter *writer;
struct iso_zero_writer_data_struct *data;
int mode;
writer = malloc(sizeof(IsoImageWriter));
if (writer == NULL) {
@ -1219,8 +1272,11 @@ int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
}
data->num_blocks = num_blocks;
if (flag & 1) {
mode = (flag & 15);
if (mode == 1) {
writer->compute_data_blocks = tail_writer_compute_data_blocks;
} else if (mode == 2) {
writer->compute_data_blocks = part_align_writer_compute_data_blocks;
} else {
writer->compute_data_blocks = zero_writer_compute_data_blocks;
}
@ -1405,6 +1461,7 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
target->partiton_offset from any LBA pointer.
*/
target->eff_partition_offset = target->opts->partition_offset;
target->pvd_size_is_total_size = 0;
for (i = 0; i < (int) target->nwriters; ++i) {
writer = target->writers[i];
/* Not all writers have an entry in the partion volume descriptor set.
@ -1485,9 +1542,6 @@ static int finish_libjte(Ecma119Image *target)
}
/* >>> need opportunity to just mark a partition in the older sessions
*/
struct iso_interval_zeroizer {
int z_type; /* 0= $zero_start"-"$zero_end ,
@ -1988,6 +2042,50 @@ process_pending:;
}
/* Tells whether ivr is a reader from imported_iso in a multi-session
add-on situation, and thus to be kept in place.
*/
int iso_interval_reader_keep(Ecma119Image *target,
struct iso_interval_reader *ivr,
int flag)
{
/* Source must be "imported_iso" */
if (!(ivr->flags & 1))
return 0;
/* It must not be a new ISO */
if (!target->opts->appendable)
return 0;
/* --- From here on return either 1 or <0 --- */
/* multi-session write offset must be larger than interval end */
if (target->opts->ms_block <= ivr->end_byte / BLOCK_SIZE)
return ISO_MULTI_OVER_IMPORTED;
return 1;
}
int iso_interval_reader_start_size(Ecma119Image *t, char *path,
off_t *start_byte, off_t *byte_count,
int flag)
{
struct iso_interval_reader *ivr;
int keep, ret;
ret = iso_interval_reader_new(t->image, path, &ivr, byte_count, 0);
if (ret < 0)
return ret;
*start_byte = ivr->start_byte;
keep = iso_interval_reader_keep(t, ivr, 0);
if (keep < 0)
return(keep);
iso_interval_reader_destroy(&ivr, 0);
return ISO_SUCCESS + (keep > 0);
}
int iso_write_partition_file(Ecma119Image *target, char *path,
uint32_t prepad, uint32_t blocks, int flag)
{
@ -2013,6 +2111,14 @@ int iso_write_partition_file(Ecma119Image *target, char *path,
&ivr, &byte_count, 0);
if (ret < 0)
goto ex;
ret = iso_interval_reader_keep(target, ivr, 0);
if (ret < 0)
goto ex;
if (ret > 0) {
/* From imported_iso and for add-on session. Leave it in place. */
ret = ISO_SUCCESS;
goto ex;
}
for (i = 0; i < blocks; i++) {
ret = iso_interval_reader_read(ivr, buf, &buf_fill, 0);
if (ret < 0)
@ -2072,7 +2178,7 @@ void *write_function(void *arg)
{
int res, i;
#ifndef Libisofs_appended_partitions_inlinE
int first_partition = 1, last_partition = 0, sa_type;
int first_partition = 1, last_partition = 0;
#endif
IsoImageWriter *writer;
@ -2101,14 +2207,7 @@ void *write_function(void *arg)
#ifndef Libisofs_appended_partitions_inlinE
/* Append partition data */
sa_type = (target->system_area_options >> 2) & 0x3f;
if (sa_type == 0) { /* MBR */
first_partition = 1;
last_partition = 4;
} else if (sa_type == 3) { /* SUN Disk Label */
first_partition = 2;
last_partition = 8;
}
iso_count_appended_partitions(target, &first_partition, &last_partition);
for (i = first_partition - 1; i <= last_partition - 1; i++) {
if (target->opts->appended_partitions[i] == NULL)
continue;
@ -2308,6 +2407,73 @@ ex:;
return ret;
}
/* Determine the alleged time of image production by predicting the volume
creation and modification timestamps and taking the maximum of both.
*/
static
void ecma119_determine_now_time(Ecma119Image *target)
{
IsoWriteOpts *o;
time_t now = 0, t, t0;
uint8_t time_text[18];
int i;
t0 = time(NULL);
o = target->opts;
if (o->vol_uuid[0]) {
for(i = 0; i < 16; i++)
if(o->vol_uuid[i] < '0' || o->vol_uuid[i] > '9')
break;
else
time_text[i] = o->vol_uuid[i];
for(; i < 16; i++)
time_text[i] = '1';
time_text[16] = time_text[17] = 0;
t = iso_datetime_read_17(time_text);
if (t > now)
now = t;
} else {
if (o->vol_creation_time > 0) {
if (o->vol_creation_time > now)
now = o->vol_creation_time;
} else if (t0 > now) {
now = t0;
}
if (o->vol_modification_time > 0) {
if (o->vol_modification_time > now)
now = o->vol_modification_time;
} else if (t0 > now) {
now = t0;
}
}
target->now = now;
}
static
int gpt_disk_guid_setup(Ecma119Image *target)
{
if (target->opts->gpt_disk_guid_mode == 0) {
/* Random UUID production delayed until really needed */
return ISO_SUCCESS;
} else if (target->opts->gpt_disk_guid_mode == 1) {
memcpy(target->gpt_uuid_base, target->opts->gpt_disk_guid, 16);
} else if (target->opts->gpt_disk_guid_mode == 2) {
if (target->opts->vol_uuid[0] == 0)
return ISO_GPT_NO_VOL_UUID;
/* Move centi-seconds part to byte 9 and 10 */
memcpy(target->gpt_uuid_base, target->opts->vol_uuid, 9);
memcpy(target->gpt_uuid_base + 9, target->opts->vol_uuid + 14, 2);
memcpy(target->gpt_uuid_base + 11, target->opts->vol_uuid + 9, 5);
iso_mark_guid_version_4(target->gpt_uuid_base);
} else {
return ISO_BAD_GPT_GUID_MODE;
}
memcpy(target->gpt_disk_guid, target->gpt_uuid_base, 16);
target->gpt_disk_guid_set = 1;
target->gpt_uuid_counter = 1;
return ISO_SUCCESS;
}
static
int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
{
@ -2320,13 +2486,19 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
int system_area_options = 0;
char *system_area = NULL;
int write_count = 0, write_count_mem;
uint32_t vol_space_size_mem;
off_t total_size_mem;
#ifdef Libisofs_appended_partitions_inlinE
int fap, lap, app_part_count;
#endif
/* 1. Allocate target and attach a copy of in_opts there */
target = calloc(1, sizeof(Ecma119Image));
if (target == NULL) {
return ISO_OUT_OF_MEM;
}
/* This reference will be transfered to the burn_source and released by
/* This reference will be transferred to the burn_source and released by
bs_free_data.
*/
target->refcount = 1;
@ -2363,7 +2535,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
target->dir_mode = opts->replace_dir_mode == 2 ? opts->dir_mode : 0555;
target->file_mode = opts->replace_file_mode == 2 ? opts->file_mode : 0444;
target->now = time(NULL);
ecma119_determine_now_time(target);
target->replace_timestamps = opts->replace_timestamps ? 1 : 0;
target->timestamp = opts->replace_timestamps == 2 ?
@ -2376,12 +2548,34 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
target->num_bootsrc = target->catalog->num_bootimages;
target->bootsrc = calloc(target->num_bootsrc + 1,
sizeof(IsoFileSrc *));
if (target->bootsrc == NULL) {
target->boot_appended_idx = calloc(target->num_bootsrc + 1,
sizeof(int));
target->boot_intvl_start = calloc(target->num_bootsrc + 1,
sizeof(uint32_t));
target->boot_intvl_size = calloc(target->num_bootsrc + 1,
sizeof(uint32_t));
if (target->bootsrc == NULL || target->boot_appended_idx == NULL ||
target->boot_intvl_start == NULL ||
target->boot_intvl_size == NULL) {
ret = ISO_OUT_OF_MEM;
goto target_cleanup;
}
for (i= 0; i < target->num_bootsrc; i++)
for (i= 0; i < target->num_bootsrc; i++) {
target->bootsrc[i] = NULL;
target->boot_appended_idx[i] = -1;
target->boot_intvl_start[i] = 0;
target->boot_intvl_size[i] = 0;
}
/* It is not easy to predict when the node gets created and can be
manipulated. So it is better for reproducibility to derive its
timestamps from the well controllable now-time.
*/
if (target->catalog->node != NULL) {
iso_node_set_mtime((IsoNode *) target->catalog->node, target->now);
iso_node_set_atime((IsoNode *) target->catalog->node, target->now);
iso_node_set_ctime((IsoNode *) target->catalog->node, target->now);
}
} else {
target->num_bootsrc = 0;
target->bootsrc = NULL;
@ -2394,7 +2588,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
system_area = src->system_area_data;
system_area_options = src->system_area_options;
} else {
system_area_options = opts->system_area_options & 0xfffffffc;
system_area_options = opts->system_area_options & 0xfffffffd;
}
sa_type = (system_area_options >> 2) & 0x3f;
if (sa_type != 0 && sa_type != 3)
@ -2448,6 +2642,10 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
goto target_cleanup;
}
target->total_size = 0;
target->vol_space_size = 0;
target->pvd_size_is_total_size = 0;
target->checksum_idx_counter = 0;
target->checksum_ctx = NULL;
target->checksum_counter = 0;
@ -2488,6 +2686,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
target->wthread_is_running = 0;
target->part_align_blocks = 0;
target->alignment_end_block = 0;
target->post_iso_part_pad = 0;
target->prep_part_size = 0;
target->efi_boot_part_size = 0;
@ -2517,7 +2717,12 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
target->gpt_req_count = 0;
target->gpt_req_flags = 0;
target->gpt_backup_outside = 0;
memset(target->gpt_uuid_base, 0, 16);
target->gpt_uuid_counter = 0;
target->gpt_disk_guid_set = 0;
ret = gpt_disk_guid_setup(target);
if (ret < 0)
goto target_cleanup;
target->gpt_part_start = 0;
target->gpt_backup_end = 0;
target->gpt_backup_size = 0;
@ -2581,6 +2786,12 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
nwriters+= 2;
}
#ifdef Libisofs_part_align_writeR
nwriters++; /* part_align_blocks writer */
#endif
#ifdef Libisofs_appended_partitions_inlinE
nwriters++; /* Inline Partition Append Writer */
@ -2707,34 +2918,26 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
goto target_cleanup;
#endif /* ! Libisofs_gpt_writer_lasT */
/* >>> Should not the checksum writer come before the zero writer ?
*/
#define Libisofs_checksums_before_paddinG yes
#ifndef Libisofs_checksums_before_paddinG
/* >>> ??? Why is this important ? */
/* IMPORTANT: This must be the last writer before the checksum writer */
ret = zero_writer_create(target, opts->tail_blocks, 1);
if (ret < 0)
goto target_cleanup;
#endif /* !Libisofs_checksums_before_paddinG */
if ((opts->md5_file_checksums & 1) || opts->md5_session_checksum) {
ret = checksum_writer_create(target);
if (ret < 0)
goto target_cleanup;
}
#ifdef Libisofs_checksums_before_paddinG
#ifdef Libisofs_part_align_writeR
/* Alignment padding before appended partitions */
ret = zero_writer_create(target, 0, 2);
#else
ret = zero_writer_create(target, opts->tail_blocks, 1);
#endif /* ! Libisofs_part_align_writeR */
if (ret < 0)
goto target_cleanup;
#endif /* Libisofs_checksums_before_paddinG */
#ifdef Libisofs_appended_partitions_inlinE
ret = partappend_writer_create(target);
@ -2743,9 +2946,18 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
#endif /* Libisofs_appended_partitions_inlinE */
#ifdef Libisofs_part_align_writeR
ret = zero_writer_create(target, opts->tail_blocks, 0);
if (ret < 0)
goto target_cleanup;
#endif /* Libisofs_part_align_writeR */
#ifdef Libisofs_gpt_writer_lasT
/* This writer shall be the last one in the list, because it protects the
image on media which are seen as GPT partitioned.
/* This writer shall be the last one in the list of writers of valuable
data, because it protects the image on media which are seen as GPT
partitioned.
In any case it has to come after any writer which might request
production of APM or GPT partition entries by its compute_data_blocks()
method.
@ -2829,13 +3041,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
goto target_cleanup;
}
#ifdef Libisofs_appended_partitions_inlinE
target->vol_space_size = target->curblock - opts->ms_block;
target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE;
#endif
}
ret = iso_patch_eltoritos(target);
@ -2847,12 +3052,24 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
goto target_cleanup;
}
#ifndef Libisofs_appended_partitions_inlinE
/*
* The volume space size is just the size of the last session, in
* case of ms images.
*/
#ifdef Libisofs_appended_partitions_inlinE
app_part_count = iso_count_appended_partitions(target, &fap, &lap);
if (app_part_count == 0)
target->vol_space_size = target->curblock - opts->ms_block;
else
target->vol_space_size = target->alignment_end_block - opts->ms_block;
target->total_size = (off_t) (target->curblock - opts->ms_block) *
BLOCK_SIZE;
#else /* Libisofs_appended_partitions_inlinE */
target->vol_space_size = target->curblock - opts->ms_block;
target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE;
@ -2889,6 +3106,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
}
/* check if we need to provide a copy of volume descriptors */
vol_space_size_mem = target->vol_space_size;
if (opts->overwrite != NULL) {
/* opts->overwrite must be larger by partion_offset
@ -2900,12 +3118,15 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
* In the PVM to be written in the 16th sector of the disc, we
* need to specify the full size.
*/
target->vol_space_size = target->curblock;
target->vol_space_size += opts->ms_block;
/* System area and volume descriptors */
target->opts_overwrite = (char *) opts->overwrite;
total_size_mem = target->total_size;
target->total_size += target->opts->ms_block * BLOCK_SIZE;
ret = write_head_part1(target, &write_count, 1 | 2);
target->opts_overwrite = NULL;
target->total_size = total_size_mem;
if (ret < 0)
goto target_cleanup;
@ -2967,10 +3188,11 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
"Error reading overwrite volume descriptors");
goto target_cleanup;
}
}
/* This was possibly altered by above overwrite buffer production */
target->vol_space_size = target->curblock - opts->ms_block;
target->vol_space_size = vol_space_size_mem;
/*
*/
@ -3134,11 +3356,6 @@ int bs_set_size(struct burn_source *bs, off_t size)
{
Ecma119Image *target = (Ecma119Image*)bs->data;
/*
* just set the value to be returned by get_size. This is not used at
* all by libisofs, it is here just for helping libburn to correctly pad
* the image if needed.
*/
target->total_size = size;
return 1;
}
@ -3350,7 +3567,7 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->vol_modification_time = 0;
wopts->vol_expiration_time = 0;
wopts->vol_effective_time = 0;
wopts->vol_uuid[0] = 0;
memset(wopts->vol_uuid, 0, 17);
wopts->partition_offset = 0;
wopts->partition_secs_per_head = 0;
wopts->partition_heads_per_cyl = 0;
@ -3370,6 +3587,9 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->appended_part_flags[i] = 0;
}
wopts->appended_as_gpt = 0;
wopts->appended_as_apm = 0;
wopts->part_like_isohybrid = 0;
wopts->iso_mbr_part_type = -1;
wopts->ascii_disc_label[0] = 0;
wopts->will_cancel = 0;
wopts->allow_dir_id_ext = 0;
@ -3379,6 +3599,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->hfsp_serial_number[i] = 0;
wopts->apm_block_size = 0;
wopts->hfsp_block_size = 0;
memset(wopts->gpt_disk_guid, 0, 16);
wopts->gpt_disk_guid_mode = 0;
*opts = wopts;
return ISO_SUCCESS;
@ -3975,7 +4197,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
opts->system_area_size = 32768;
}
if (!(flag & 4))
opts->system_area_options = options & 0x7fff;
opts->system_area_options = options & 0xffff;
return ISO_SUCCESS;
}
@ -4091,6 +4313,26 @@ int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt)
return ISO_SUCCESS;
}
int iso_write_opts_set_appended_as_apm(IsoWriteOpts *opts, int apm)
{
opts->appended_as_apm = !!apm;
return ISO_SUCCESS;
}
int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike)
{
opts->part_like_isohybrid = !!alike;
return ISO_SUCCESS;
}
int iso_write_opts_set_iso_mbr_part_type(IsoWriteOpts *opts, int part_type)
{
if (part_type < -1 || part_type > 255)
part_type = -1;
opts->iso_mbr_part_type = part_type;
return ISO_SUCCESS;
}
int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label)
{
strncpy(opts->ascii_disc_label, label, ISO_DISC_LABEL_SIZE - 1);
@ -4118,6 +4360,16 @@ int iso_write_opts_set_hfsp_block_size(IsoWriteOpts *opts,
return ISO_SUCCESS;
}
int iso_write_opts_set_gpt_guid(IsoWriteOpts *opts, uint8_t guid[16], int mode)
{
if (mode < 0 || mode > 2)
return ISO_BAD_GPT_GUID_MODE;
opts->gpt_disk_guid_mode = mode;
if (opts->gpt_disk_guid_mode == 1)
memcpy(opts->gpt_disk_guid, guid, 16);
return ISO_SUCCESS;
}
/*
* @param flag
@ -4345,3 +4597,30 @@ ex: /* LIBISO_ALLOC_MEM failed */
return NULL;
}
/* Obtains start and end number of appended partition range and returns
the number of valid entries in the list of appended partitions.
*/
int iso_count_appended_partitions(Ecma119Image *target,
int *first_partition, int *last_partition)
{
int sa_type, i, count= 0;
sa_type = (target->system_area_options >> 2) & 0x3f;
if (sa_type == 3) { /* SUN Disk Label */
*first_partition = 2;
*last_partition = 8;
} else {
*first_partition = 1;
*last_partition = 4;
}
for (i = *first_partition - 1; i <= *last_partition - 1; i++) {
if (target->opts->appended_partitions[i] == NULL)
continue;
if (target->opts->appended_partitions[i][0] == 0)
continue;
count++;
}
return(count);
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2015 Thomas Schmitt
* Copyright (c) 2009 - 2018 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -59,7 +59,7 @@
#define ISO_DISC_LABEL_SIZE 129
/* The maximum lenght of an specs violating ECMA-119 file identifier.
/* The maximum length of an specs violating ECMA-119 file identifier.
The theoretical limit is 254 - 34 - 28 (len of SUSP CE entry) = 192
Currently the practical limit is 254 - 34 - 96 (non-CE RR entries) - 28 (CE)
*/
@ -223,7 +223,7 @@ struct iso_write_opts {
/**
* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12.
* I.e. without announcing it by an ER field and thus without the need
* to preceed the RRIP fields by an ES and to preceed the AA field by ES.
* to precede the RRIP fields by an ES and to precede the AA field by ES.
* This saves bytes and might avoid problems with readers which dislike
* ER fields other than the ones for RRIP.
* On the other hand, SUSP 1.12 frowns on such unannounced extensions
@ -487,6 +487,23 @@ struct iso_write_opts {
*/
int appended_as_gpt;
/* If 1: With appended partitions: mark by APM partition
*/
int appended_as_apm;
/* If 1: Obey struct el_torito_boot_image.isolinux_options bit2-7 and bit8.
I.e. mention boot image as partition in GPT and/or APM.
*/
int part_like_isohybrid;
/* The type to use for the mountable ISO partition if there is any and if
the type is not mandatorily determined for particular circumstances like
compliant GPT, CHRP, or PReP.
-1 = use the default value (e.g. 0xcd, 0x83, 0x17)
0x00 to 0xff = value to use if possible
*/
int iso_mbr_part_type;
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
*/
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
@ -504,6 +521,13 @@ struct iso_write_opts {
*/
int apm_block_size;
/* User defined GUID for GPT header and base of reproducible partition
GUIDs. (Not to be confused with volume "UUID", which is actually a
timestamp.)
See API call iso_write_opts_set_gpt_guid().
*/
uint8_t gpt_disk_guid[16];
int gpt_disk_guid_mode;
};
typedef struct ecma119_image Ecma119Image;
@ -554,10 +578,19 @@ struct ecma119_image
time_t now; /**< Time at which writing began. */
/** Total size of the output. This only includes the current volume. */
/* Total size of the output. Counted in bytes.
* Includes ISO filesystem and appended data.
*/
off_t total_size;
/** Size actually governed by the ISO filesystem part of the output */
uint32_t vol_space_size;
/* 1= write the total size into the PVD of the ISO,
* 0= write vol_space_size
*/
int pvd_size_is_total_size;
/* Bytes already written to image output */
off_t bytes_written;
/* just for progress notification */
@ -640,6 +673,11 @@ struct ecma119_image
int num_bootsrc;
IsoFileSrc **bootsrc; /* location of the boot images in the new image */
int *boot_appended_idx; /* Appended partition which serve as boot images */
uint32_t *boot_intvl_start; /* In blocks of 2048 bytes */
uint32_t *boot_intvl_size; /* In blocks of 512 bytes */
/*
* System Area related information
*/
@ -761,6 +799,11 @@ struct ecma119_image
*/
IsoFileSrc *sparc_core_src;
/* Trailing padding of ISO filesystem partition for cylinder alignment */
/* Only in effect with Libisofs_part_align_writeR */
uint32_t part_align_blocks;
uint32_t alignment_end_block;
/* Counted in blocks of 2048 */
uint32_t appended_part_prepad[ISO_MAX_PARTITIONS];
uint32_t appended_part_start[ISO_MAX_PARTITIONS];
@ -821,6 +864,11 @@ struct ecma119_image
/* Whether the eventual backup GPT is not part of the ISO filesystem */
int gpt_backup_outside;
/* The base UUID for the generated GPT UUIDs */
uint8_t gpt_uuid_base[16];
/* The counter which distinguishes the GPT UUIDs */
uint32_t gpt_uuid_counter;
uint32_t efi_boot_part_size;
IsoFileSrc *efi_boot_part_filesrc; /* Just a pointer. Do not free. */
@ -989,5 +1037,22 @@ int iso_write_partition_file(Ecma119Image *target, char *path,
void issue_ucs2_warning_summary(size_t failures);
/* Tells whether ivr is a reader from imported_iso in a multi-session
add-on situation, and thus to be kept in place.
*/
int iso_interval_reader_keep(Ecma119Image *target,
struct iso_interval_reader *ivr,
int flag);
/* @return: ISO_SUCCESS = ok, ISO_SUCCESS + 1 = keep , < 0 = error */
int iso_interval_reader_start_size(Ecma119Image *t, char *path,
off_t *start_byte, off_t *byte_count,
int flag);
/* Obtains start and end number of appended partition range and returns
the number of valid entries in the list of appended partitions.
*/
int iso_count_appended_partitions(Ecma119Image *target,
int *first_partition, int *last_partition);
#endif /*LIBISO_ECMA119_H_*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2014 Thomas Schmitt
* Copyright (c) 2009 - 2016 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -241,11 +241,11 @@ int create_file_src(Ecma119Image *img, IsoFile *iso, IsoFileSrc **src)
size = iso_stream_get_size(iso->stream);
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && img->opts->iso_level != 3) {
char *ipath = iso_tree_get_node_path(ISO_NODE(iso));
ret = iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0,
"File \"%s\" can't be added to image because "
"is greater than 4GB", ipath);
iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0,
"File \"%s\" cannot be added to image because "
"its size is 4 GiB or larger", ipath);
free(ipath);
return ret;
return ISO_FILE_TOO_BIG;
}
ret = iso_file_src_create(img, iso, src);
if (ret < 0) {
@ -597,7 +597,7 @@ int cmp_node_name(const void *f1, const void *f2)
/**
* Sorts a the children of each directory in the ECMA-119 tree represented
* by \p root, acording to the order specified in ECMA-119, section 9.3.
* by \p root, according to the order specified in ECMA-119, section 9.3.
*/
static
void sort_tree(Ecma119Node *root)
@ -1270,7 +1270,7 @@ int ecma119_tree_create(Ecma119Image *img)
if (img->opts->rockridge && !img->opts->allow_deep_paths) {
/* Relocate deep directories, acording to RRIP, 4.1.5 */
/* Relocate deep directories, according to RRIP, 4.1.5 */
ret = reorder_tree(img, root, 1, 0);
if (ret < 0) {
return ret;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 - 2014 Thomas Schmitt
* Copyright (c) 2010 - 2016 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -19,6 +19,7 @@
#include "image.h"
#include "messages.h"
#include "writer.h"
#include "ecma119.h"
#include <stdlib.h>
#include <string.h>
@ -112,9 +113,24 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors)
/* API */
int el_torito_get_load_size(ElToritoBootImage *bootimg)
{
return (int) bootimg->load_size;
return (int) bootimg->load_size;
}
/* API */
void el_torito_set_full_load(ElToritoBootImage *bootimg, int mode)
{
if (bootimg->type != 0)
return;
bootimg->load_size_full= !!mode;
}
/* API */
int el_torito_get_full_load(ElToritoBootImage *bootimg)
{
return bootimg->load_size_full;
}
/**
* Marks the specified boot image as not bootable
*/
@ -289,7 +305,7 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
node->size = 0;
node->content = NULL;
/* atributes from parent */
/* attributes from parent */
node->node.mode = S_IFREG | (parent->node.mode & 0444);
node->node.uid = parent->node.uid;
node->node.gid = parent->node.gid;
@ -312,6 +328,35 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
return ++parent->nchildren;
}
/* Get start and size from "%d_start_%lus_size_%lud" */
static
void iso_parse_start_size(char *text, unsigned long *part_start,
unsigned long *part_size)
{
char *cpt;
unsigned long start, size;
cpt = strchr(text, '_');
if (cpt == NULL)
return;
if (strncmp(cpt, "_start_", 7) != 0)
return;
sscanf(cpt + 7, "%lu", &start);
cpt = strchr(cpt + 7, '_');
if (cpt == NULL)
return;
if (*(cpt - 1) != 's')
return;
if (strncmp(cpt, "_size_", 6) != 0)
return;
sscanf(cpt + 6, "%lu", &size);
for (cpt = cpt + 6; *cpt >= '0' && *cpt <= '9'; cpt++);
if (*cpt != 'd')
return;
*part_start = start;
*part_size = size;
}
static
int create_image(IsoImage *image, const char *image_path,
@ -323,36 +368,64 @@ int create_image(IsoImage *image, const char *image_path,
struct el_torito_boot_image *boot;
int boot_media_type = 0;
int load_sectors = 0; /* number of sector to load */
int part_idx = -1;
unsigned long part_start = 0, part_size = 0;
unsigned char partition_type = 0;
off_t size;
IsoNode *imgfile;
IsoStream *stream;
IsoNode *imgfile = NULL;
IsoStream *stream = NULL;
*bootnode = NULL;
ret = iso_tree_path_to_node(image, image_path, &imgfile);
if (ret < 0) {
return ret;
}
if (ret == 0) {
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
if (strncmp(image_path, "--interval:appended_partition_", 30) == 0) {
/* --interval:appended_partition_N... */
if (type != ELTORITO_NO_EMUL) {
/* >>> ??? lift this ban by making a temporary IsoStream from
partition source, determine size,
and read ELTORITO_HARD_DISC_EMUL MBR ?
*/
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Appended partition cannot serve as El Torito boot image with FD/HD emulation");
return ISO_BOOT_IMAGE_NOT_VALID;
}
sscanf(image_path + 30, "%d", &part_idx);
if (part_idx < 1 || part_idx > ISO_MAX_PARTITIONS) {
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Appended partition index for El Torito boot image is out of range");
return ISO_BOOT_IMAGE_NOT_VALID;
}
iso_parse_start_size((char *) (image_path + 30),
&part_start, &part_size);
part_idx--;
size = 1;
} else {
ret = iso_tree_path_to_node(image, image_path, &imgfile);
if (ret < 0) {
return ret;
}
if (ret == 0) {
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
"El Torito boot image file missing in ISO image: '%s'",
image_path);
return ISO_NODE_DOESNT_EXIST;
return ISO_NODE_DOESNT_EXIST;
}
if (imgfile->type != LIBISO_FILE) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
*bootnode = (IsoFile *) imgfile;
stream = ((IsoFile*)imgfile)->stream;
/* we need to read the image at least two times */
if (!iso_stream_is_repeatable(stream)) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
size = iso_stream_get_size(stream);
}
if (imgfile->type != LIBISO_FILE) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
*bootnode = (IsoFile *) imgfile;
stream = ((IsoFile*)imgfile)->stream;
/* we need to read the image at least two times */
if (!iso_stream_is_repeatable(stream)) {
return ISO_BOOT_IMAGE_NOT_VALID;
}
size = iso_stream_get_size(stream);
if (size <= 0) {
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Boot image file is empty");
@ -441,7 +514,11 @@ int create_image(IsoImage *image, const char *image_path,
return ISO_OUT_OF_MEM;
}
boot->image = (IsoFile*)imgfile;
iso_node_ref(imgfile); /* get our ref */
boot->appended_idx = part_idx;
boot->appended_start = part_start;
boot->appended_size = part_size;
if (imgfile != NULL)
iso_node_ref(imgfile); /* get our ref */
boot->bootable = 1;
boot->seems_boot_info_table = 0;
boot->seems_grub2_boot_info = 0;
@ -451,6 +528,7 @@ int create_image(IsoImage *image, const char *image_path,
boot->partition_type = partition_type;
boot->load_seg = 0;
boot->load_size = load_sectors;
boot->load_size_full = 0;
boot->platform_id = 0; /* 80x86 */
memset(boot->id_string, 0, sizeof(boot->id_string));
memset(boot->selection_crit, 0, sizeof(boot->selection_crit));
@ -538,8 +616,9 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
catalog->bootimages[i] = NULL;
catalog->node = cat_node;
catalog->sort_weight = 1000000000; /* very high */
if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
if (boot_node != NULL)
if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
iso_node_ref((IsoNode*)cat_node);
image->bootcat = catalog;
@ -555,7 +634,8 @@ boot_image_cleanup:;
iso_node_unref((IsoNode*)cat_node);
}
if (boot_image) {
iso_node_unref((IsoNode*)boot_image->image);
if (boot_image->image != NULL)
iso_node_unref((IsoNode*)boot_image->image);
free(boot_image);
}
return ret;
@ -719,8 +799,9 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
ret = create_image(image, image_path, type, &boot_img, &boot_node);
if (ret < 0)
return ret;
if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
if (boot_node != NULL)
if (!(boot_node->explicit_weight || boot_node->from_old_session))
boot_node->sort_weight = 2;
catalog->bootimages[catalog->num_bootimages] = boot_img;
catalog->num_bootimages++;
if (boot != NULL)
@ -822,17 +903,44 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
sizeof(e->id_string));
}
static int
write_section_load_size(struct el_torito_boot_image *img,
struct el_torito_section_entry *se,
uint16_t load_size, off_t full_byte_size, int flag)
{
uint16_t size;
off_t blocks;
size= load_size;
if(img->type == 0 && img->load_size_full) {
blocks= ((full_byte_size + 2047) / 2048) * 4;
if (blocks > 65535) {
if (img->platform_id == 0xef)
size= 0;
else
size= 65535;
} else if(blocks <= 0) {
size= 1;
} else {
size= blocks;
}
}
iso_lsb(se->sec_count, size, 2);
return(1);
}
/**
* Write one section entry.
* Usable for the Default Entry
* and for Section Entries with Selection criteria type == 0
*/
static void
write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
static
int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
{
struct el_torito_boot_image *img;
struct el_torito_section_entry *se =
(struct el_torito_section_entry*)buf;
int app_idx, mode = 0;
img = t->catalog->bootimages[idx];
@ -840,16 +948,75 @@ write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
se->boot_media_type[0] = img->type;
iso_lsb(se->load_seg, img->load_seg, 2);
se->system_type[0] = img->partition_type;
iso_lsb(se->sec_count, img->load_size, 2);
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4);
if (t->boot_appended_idx[idx] >= 0)
if (t->appended_part_size[t->boot_appended_idx[idx]] > 0)
mode = 2; /* appended partition */
if (mode == 0 && t->opts->appendable &&
(t->boot_intvl_start[idx] > 0 || t->boot_intvl_size[idx] > 0) &&
t->boot_intvl_start[idx] + (t->boot_intvl_size[idx] + 3) / 4 <=
t->opts->ms_block)
mode = 1; /* image interval */
if (mode == 0 && t->boot_appended_idx[idx] >= 0) {
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Appended partition which shall serve as boot image does not exist");
return ISO_BOOT_IMAGE_NOT_VALID;
}
if (mode == 1) {
if (t->boot_intvl_start[idx] + (t->boot_intvl_size[idx] + 3) / 4 >
t->total_size / 2048 + t->opts->ms_block - t->eff_partition_offset
) {
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Block interval which shall serve as boot image is outside result range");
return ISO_BOOT_IMAGE_NOT_VALID;
}
/* >>> check for non-automatic load size */;
if (t->boot_intvl_size[idx] > 65535) {
if (img->platform_id == 0xef)
iso_lsb(se->sec_count, 0, 2);
else
iso_lsb(se->sec_count, 65535, 2);
} else {
if (t->boot_intvl_size[idx] == 0) {
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Block interval which shall serve as boot image has zero size");
return ISO_BOOT_IMAGE_NOT_VALID;
}
iso_lsb(se->sec_count, t->boot_intvl_size[idx], 2);
}
iso_lsb(se->block, t->boot_intvl_start[idx], 4);
} else if (mode == 2) {
app_idx = t->boot_appended_idx[idx];
/* >>> check for non-automatic load size */;
if (t->appended_part_size[app_idx] * 4 > 65535) {
if (img->platform_id == 0xef)
iso_lsb(se->sec_count, 0, 2);
else
iso_lsb(se->sec_count, 65535, 2);
} else {
iso_lsb(se->sec_count, t->appended_part_size[app_idx] * 4, 2);
}
iso_lsb(se->block, t->appended_part_start[app_idx], 4);
} else {
write_section_load_size(img, se, (uint16_t) img->load_size,
(off_t) t->bootsrc[idx]->sections[0].size, 0);
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4);
}
se->selec_criteria[0] = img->selection_crit[0];
memcpy(se->vendor_sc, img->selection_crit + 1, 19);
return ISO_SUCCESS;
}
static
int catalog_open(IsoStream *stream)
{
int i, j, k, num_entries;
int i, j, k, num_entries, ret;
struct catalog_stream *data;
uint8_t *wpt;
struct el_torito_boot_catalog *cat;
@ -873,7 +1040,9 @@ int catalog_open(IsoStream *stream)
boots[0]->platform_id, boots[0]->id_string);
/* write default entry = first boot image */
write_section_entry(data->buffer + 32, data->target, 0);
ret = write_section_entry(data->buffer + 32, data->target, 0);
if (ret < 0)
return ret;
/* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */
wpt = data->buffer + 64;
@ -894,7 +1063,9 @@ int catalog_open(IsoStream *stream)
write_section_header(wpt, data->target, i, num_entries);
wpt += 32;
for (j = 0; j < num_entries; j++) {
write_section_entry(wpt, data->target, i);
ret = write_section_entry(wpt, data->target, i);
if (ret < 0)
return ret;
wpt += 32;
i++;
}
@ -1132,6 +1303,9 @@ int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small. We won't patch it.");
}
if (t->bootsrc[idx] == NULL)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Cannot apply ISOLINUX patching outside of ISO 9660 filesystem.");
ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16,
t->bootsrc[idx]->sections[0].block,
(uint32_t) imgsize);
@ -1151,7 +1325,10 @@ int patch_grub2_boot_image(uint8_t *buf, Ecma119Image *t,
if (imgsize < pos + 8)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Isolinux image too small for GRUB2. Will not patch it.");
"Boot image too small for GRUB2. Will not patch it.");
if (t->bootsrc[idx] == NULL)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Cannot apply GRUB2 patching outside of ISO 9660 filesystem.");
blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst;
iso_lsb((buf + pos), blk & 0xffffffff, 4);
iso_lsb((buf + pos + 4), blk >> 32, 4);
@ -1174,6 +1351,10 @@ int iso_patch_eltoritos(Ecma119Image *t)
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
continue;
if (t->bootsrc[idx] == NULL)
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
"Cannot apply boot image patching outside of ISO 9660 filesystem");
original = t->bootsrc[idx]->stream;
size = (size_t) iso_stream_get_size(original);
if (size > Libisofs_elto_max_patchablE)
@ -1281,8 +1462,8 @@ int eltorito_writer_create(Ecma119Image *target)
{
int ret, idx, outsource_efi = 0;
IsoImageWriter *writer;
IsoFile *bootimg;
IsoFileSrc *src;
IsoFile *bootimg = NULL;
IsoFileSrc *src = NULL;
writer = calloc(1, sizeof(IsoImageWriter));
if (writer == NULL) {
@ -1315,6 +1496,18 @@ int eltorito_writer_create(Ecma119Image *target)
if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0)
outsource_efi = 1;
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
target->bootsrc[idx] = NULL;
if (target->catalog->bootimages[idx]->appended_idx >= 0) {
/* Use an appended partition as boot image rather than IsoFile */
target->boot_appended_idx[idx] =
target->catalog->bootimages[idx]->appended_idx;
target->boot_intvl_start[idx] =
target->catalog->bootimages[idx]->appended_start;
target->boot_intvl_size[idx] =
target->catalog->bootimages[idx]->appended_size;
continue;
}
bootimg = target->catalog->bootimages[idx]->image;
ret = iso_file_src_create(target, bootimg, &src);
if (ret < 0) {

View File

@ -53,6 +53,11 @@ struct el_torito_boot_catalog {
struct el_torito_boot_image {
IsoFile *image;
/* Overrides .image if >= 0 : array index of appended partition */
int appended_idx;
uint32_t appended_start; /* In blocks of 2048 bytes */
uint32_t appended_size; /* In blocks of 512 bytes */
unsigned int bootable:1; /**< If the entry is bootable. */
/**
* Whether the boot image seems to contain a boot_info_table
@ -80,6 +85,7 @@ struct el_torito_boot_image {
unsigned char partition_type; /**< type of partition for HD-emul images */
uint16_t load_seg; /**< Load segment for the initial boot image. */
uint16_t load_size; /**< Number of sectors to load. */
int load_size_full; /* 1= override load_size by image size */
/* Byte 1 of Validation Entry or Section Header Entry:
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2015 Thomas Schmitt
* Copyright (c) 2009 - 2016 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -325,6 +325,11 @@ typedef struct
*/
int aaip_version;
/**
* Start block of loaded session.
*/
uint32_t session_lba;
/**
* Number of blocks of the volume, as reported in the PVM.
*/
@ -364,14 +369,14 @@ typedef struct
*/
int px_ino_status;
/* Which Rock Ridge error messages already have occured
/* Which Rock Ridge error messages already have occurred
bit0= Invalid PX entry
bit1= Invalid TF entry
bit2= New NM entry found without previous CONTINUE flag
bit3= Invalid NM entry
bit4= New SL entry found without previous CONTINUE flag
bit5= Invalid SL entry
bit6= Invalid SL entry, no child location
bit6= Invalid CL entry, no child location / found in CL target
bit7= Invalid PN entry
bit8= Sparse files not supported
bit9= SP entry found in a directory entry other than '.' entry of root
@ -384,6 +389,7 @@ typedef struct
bit16= Incomplete SL
bit17= Charset conversion error
bit18= Link without destination
bit19= SL with a non-link file
*/
int rr_err_reported;
int rr_err_repeated;
@ -1415,6 +1421,7 @@ int iso_rr_msg_submit(_ImageFsData *fsdata, int rr_err_bit,
* @param flag
* bit0= this is the root node attribute load call
* (parameter parent is not reliable for this)
* bit1= this is a call caused by CL. Do not obey CL again.
* @return
* 2 node is still incomplete (multi-extent)
* 1 success, 0 record ignored (not an error, can be a relocated dir),
@ -1576,13 +1583,14 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
SuspIterator *iter;
iter = susp_iter_new(fsdata->src, record, fsdata->len_skp,
fsdata->msgid);
iter = susp_iter_new(fsdata->src, record,
fsdata->session_lba + fsdata->nblocks,
fsdata->len_skp, fsdata->msgid);
if (iter == NULL) {
{ret = ISO_OUT_OF_MEM; goto ex;}
}
while ((ret = susp_iter_next(iter, &sue)) > 0) {
while ((ret = susp_iter_next(iter, &sue, 0)) > 0) {
/* ignore entries from different version */
if (sue->version[0] != 1)
@ -1699,7 +1707,17 @@ if (name != NULL && !namecont) {
*/
susp_iter_free(iter);
free(name);
if (flag & 1) {
ret = iso_rr_msg_submit(fsdata, 3, ISO_NO_ROOT_DIR, 0,
"Root directory is marked by RRIP RE as relocated");
ret= ISO_NO_ROOT_DIR;
goto ex;
}
{ret = 0; goto ex;} /* it's not an error */
} else if (SUSP_SIG(sue, 'C', 'L') && (flag & 2)) {
ret = iso_rr_msg_submit(fsdata, 6, ISO_WRONG_RR, 0,
"Invalid CL entry, found in CL target");
} else if (SUSP_SIG(sue, 'C', 'L')) {
/*
* This entry is a placeholder for a relocated dir.
@ -1710,7 +1728,7 @@ if (name != NULL && !namecont) {
relocated_dir = iso_read_bb(sue->data.CL.child_loc, 4, NULL);
if (relocated_dir == 0) {
ret = iso_rr_msg_submit(fsdata, 6, ISO_WRONG_RR, 0,
"Invalid SL entry, no child location");
"Invalid CL entry, no child location");
break;
}
} else if (SUSP_SIG(sue, 'P', 'N')) {
@ -1979,14 +1997,17 @@ if (name != NULL && !namecont) {
goto ex;
}
/* Call with flag bit1 to prevent further CL relocation */
ret = iso_file_source_new_ifs(fs, parent, (struct ecma119_dir_record*)
buffer, src, 0);
buffer, src, flag | 2);
if (ret <= 0) {
goto ex;
}
/* but the real name is the name of the placeholder */
ifsdata = (ImageFileSourceData*) (*src)->data;
if (ifsdata->name != NULL)
free(ifsdata->name);
ifsdata->name = name;
{ret = ISO_SUCCESS; goto ex;}
@ -2087,6 +2108,11 @@ if (name != NULL && !namecont) {
if (S_ISLNK(atts.st_mode)) {
ifsdata->data.content = linkdest;
} else if (linkdest != NULL) {
ret = iso_rr_msg_submit(fsdata, 19, ISO_WRONG_RR_WARN, 0,
"RRIP SL link destination with file that is not a link.");
free(linkdest);
linkdest = NULL;
}
ifsrc->class = &ifs_class;
@ -2392,13 +2418,14 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
* In that case, we need to set info->len_skp to 15!!
*/
iter = susp_iter_new(data->src, record, data->len_skp, data->msgid);
iter = susp_iter_new(data->src, record, data->session_lba + data->nblocks,
data->len_skp, data->msgid);
if (iter == NULL) {
ret = ISO_OUT_OF_MEM; goto ex;
}
/* first entry must be an SP system use entry */
ret = susp_iter_next(iter, &sue);
ret = susp_iter_next(iter, &sue, 1);
if (ret < 0) {
/* error */
susp_iter_free(iter);
@ -2442,7 +2469,7 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
* no?), but if we finally need it, it can be easily implemented in
* the iterator, transparently for the rest of the code.
*/
while ((ret = susp_iter_next(iter, &sue)) > 0) {
while ((ret = susp_iter_next(iter, &sue, 0)) > 0) {
/* ignore entries from different version */
if (sue->version[0] != 1)
@ -2589,6 +2616,9 @@ int read_pvm(_ImageFsData *data, uint32_t block)
data->effective_time =
iso_util_strcopy_untail((char*) pvm->vol_effective_time, 17);
data->session_lba = 0;
if (block >= 16) /* The session begins 16 blocks before the PVD */
data->session_lba = block - 16;
data->nblocks = iso_read_bb(pvm->vol_space_size, 4, NULL);
rootdr = (struct ecma119_dir_record*) pvm->root_dir_record;
@ -2641,14 +2671,6 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
{ret = ISO_WRONG_EL_TORITO; goto ex;}
}
/* check for a valid platform */
if (ve->platform_id[0] != 0 && ve->platform_id[0] != 0xef) {
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
"Unsupported El-Torito platform. Only 80x86 and EFI are "
"supported. El-Torito info will be ignored.");
{ret = ISO_UNSUPPORTED_EL_TORITO; goto ex;}
}
/* ok, once we are here we assume it is a valid catalog */
/* parse the default entry */
@ -3017,15 +3039,14 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
} while (buffer[0] != 255);
/* 4. check if RR extensions are being used */
ret = read_root_susp_entries(data, data->pvd_root_block);
if (ret < 0) {
goto fs_cleanup;
}
/* user doesn't want to read RR extensions */
if (opts->norock) {
/* user doesn't want to read RR extensions */
data->rr = RR_EXT_NO;
} else {
ret = read_root_susp_entries(data, data->pvd_root_block);
if (ret < 0) {
goto fs_cleanup;
}
data->rr = data->rr_version;
}
@ -3598,7 +3619,7 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
boot_pvd_found = iso_read_lsb(boot_info_found, 4);
image_pvd = (uint32_t) (opts->block + 16);
/* Accomodate to eventually relocated superblock */
/* Accommodate to eventually relocated superblock */
if (image_pvd != boot_pvd_found &&
image_pvd == 16 && boot_pvd_found < iso_image_size) {
/* Check whether there is a PVD at boot_pvd_found
@ -3906,10 +3927,12 @@ try_grub2_mbr:;
static
int iso_analyze_partition_offset(IsoImage *image, IsoDataSource *src,
uint64_t start_block, int flag)
uint64_t start_block, uint64_t block_count,
int flag)
{
int ret;
uint8_t *buf = NULL;
uint32_t iso_size;
off_t p_offset;
struct ecma119_pri_vol_desc *pvm;
struct iso_imported_sys_area *sai;
@ -3922,11 +3945,14 @@ int iso_analyze_partition_offset(IsoImage *image, IsoDataSource *src,
ret = src->read_block(src, p_offset + 16, buf);
if (ret > 0) {
pvm = (struct ecma119_pri_vol_desc *) buf;
iso_size = iso_read_lsb(pvm->vol_space_size, 4);
if (strncmp((char*) pvm->std_identifier, "CD001", 5) == 0 &&
pvm->vol_desc_type[0] == 1 &&
pvm->vol_desc_version[0] == 1 &&
pvm->file_structure_version[0] == 1 &&
iso_read_lsb(pvm->vol_space_size, 4) + p_offset == sai->image_size)
(iso_size + p_offset == sai->image_size ||
iso_size == block_count / 4))
sai->partition_offset = p_offset;
}
ret = 1;
@ -3940,6 +3966,7 @@ int iso_analyze_mbr(IsoImage *image, IsoDataSource *src, int flag)
{
int sub_type = 2, ret, is_isohybrid = 0, is_grub2_mbr = 0;
int is_protective_label = 0;
uint64_t part2_start;
char *sad;
struct iso_imported_sys_area *sai;
struct iso_mbr_partition_request *part;
@ -3963,34 +3990,11 @@ int iso_analyze_mbr(IsoImage *image, IsoDataSource *src, int flag)
sub_type = 0;
is_isohybrid = 1;
} else if(ret == 2) {
sub_type = 0;
/* will become sub_type 0 if protective_label */
is_grub2_mbr = 1;
}
if (sai->mbr_req_count == 1 && !is_isohybrid) {
part = sai->mbr_req[0];
if (part->start_block == 1 &&
part->block_count + 1 == ((uint64_t) sai->image_size) * 4) {
/* libisofs protective msdos label for GRUB2 */
is_protective_label = 1;
sub_type = 0;
} else if (part->start_block == 0 &&
part->block_count <= ((uint64_t) sai->image_size) * 4 &&
part->block_count + 600 >= ((uint64_t) sai->image_size) * 4 &&
part->type_byte == 0x96) {
/* CHRP (possibly without padding) */
sub_type = 1;
} else if (sai->mbr_req[0]->start_block > 0 &&
(sai->mbr_req[0]->start_block % 4) == 0 &&
(sai->mbr_req[0]->start_block +
sai->mbr_req[0]->block_count) / 4 <= sai->image_size &&
part->type_byte == 0x41) {
/* mkisofs PReP partition */
sai->prep_part_start = sai->mbr_req[0]->start_block / 4;
sai->prep_part_size = (sai->mbr_req[0]->block_count + 3) / 4;
sub_type = 0;
}
} else if (sai->mbr_req_count == 3 && !is_isohybrid) {
if (sai->mbr_req_count == 3 && !is_isohybrid) {
/* Check for libisofs PReP partitions :
0xee or 0xcd from 0 to a-1
0x41 from a to b
@ -4013,6 +4017,42 @@ int iso_analyze_mbr(IsoImage *image, IsoDataSource *src, int flag)
sub_type = 0;
}
}
if (sai->mbr_req_count >= 1 &&
(sai->mbr_req[0]->type_byte == 0xee || !is_isohybrid) &&
!(sai->prep_part_start > 0)) {
part = sai->mbr_req[0];
part2_start = 0;
if (sai->mbr_req_count >= 2)
part2_start = sai->mbr_req[1]->start_block;
if (part->start_block == 1 &&
(part->block_count + 1 == ((uint64_t) sai->image_size) * 4 ||
(part->type_byte == 0xee &&
part->block_count + 1 >= ((uint64_t) sai->image_size) * 4 &&
(sai->mbr_req_count == 1 ||
(sai->mbr_req_count == 2 &&
sai->mbr_req[1]->type_byte == 0x00))) ||
part->block_count + 1 == part2_start)) {
/* libisofs protective msdos label for GRUB2 */
is_protective_label = 1;
sub_type = 0;
} else if (sai->mbr_req_count == 1 && part->start_block == 0 &&
part->block_count <= ((uint64_t) sai->image_size) * 4 &&
part->block_count + 600 >= ((uint64_t) sai->image_size) * 4 &&
part->type_byte == 0x96) {
/* CHRP (possibly without padding) */
sub_type = 1;
} else if (sai->mbr_req_count == 1 &&
sai->mbr_req[0]->start_block > 0 &&
(sai->mbr_req[0]->start_block % 4) == 0 &&
(sai->mbr_req[0]->start_block +
sai->mbr_req[0]->block_count) / 4 <= sai->image_size &&
part->type_byte == 0x41) {
/* mkisofs PReP partition */
sai->prep_part_start = sai->mbr_req[0]->start_block / 4;
sai->prep_part_size = (sai->mbr_req[0]->block_count + 3) / 4;
sub_type = 0;
}
}
/* Check for partition offset with extra set of meta data */
if (sai->mbr_req_count > 0) {
@ -4021,10 +4061,10 @@ int iso_analyze_mbr(IsoImage *image, IsoDataSource *src, int flag)
part->start_block >= 64 && part->block_count >= 72 &&
part->start_block <= 2048 &&
part->start_block % 4 == 0 && part->block_count % 4 == 0 &&
(part->start_block + part->block_count) / 4 == sai->image_size) {
(part->start_block + part->block_count) / 4 <= sai->image_size) {
ret = iso_analyze_partition_offset(image, src, part->start_block,
0);
part->block_count, 0);
if (ret < 0)
goto ex;
}
@ -4329,10 +4369,10 @@ int iso_analyze_gpt(IsoImage *image, IsoDataSource *src, int flag)
block_count = sai->gpt_req[0]->block_count;
if (start_block >= 64 && block_count >= 72 &&
start_block <= 2048 && start_block % 4 == 0 &&
block_count % 4 == 0 &&
(start_block + block_count) / 4 == sai->image_size) {
block_count % 4 == 0) {
ret = iso_analyze_partition_offset(image, src, start_block, 0);
ret = iso_analyze_partition_offset(image, src, start_block,
block_count, 0);
if (ret < 0)
return ret;
}
@ -4572,7 +4612,8 @@ int iso_analyze_sun(IsoImage *image, IsoDataSource *src, int flag)
iso_read_msb(usad + 144, 2) != 0x10 ||
iso_read_msb(usad + 444, 4) != 0 ||
sai->image_size > 0x3fffffff ||
iso_read_msb(usad + 448, 4) != sai->image_size * 4)
iso_read_msb(usad + 448, 4) < ((int64_t) sai->image_size * 4) - 600 ||
iso_read_msb(usad + 448, 4) > sai->image_size * 4)
return 0;
checksum[0] = checksum[1] = 0;
for (i = 0; i < 510; i += 2) {
@ -4960,12 +5001,13 @@ int iso_impsysa_report(IsoImage *image, struct iso_impsysa_result *target,
if (sa_type == 0) {
if ((sao & 3) || sa_sub == 1 || sa_sub == 2) {
strcat(msg, " MBR");
if (sao & 1)
strcat(msg, " protective-msdos-label");
else if (sao & 2)
if (sao & 2)
strcat(msg, " isohybrid");
else if (sa_sub == 1)
else if (sao & 1)
strcat(msg, " protective-msdos-label");
else if (sa_sub == 1) {
strcat(msg, " CHRP");
}
if ((sao & (1 << 14)) && !(sao & 2))
strcat(msg, " grub2-mbr");
sprintf(msg + strlen(msg), " cyl-align-%s",
@ -5723,6 +5765,10 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
iso_filesystem_unref(fs);
return ret;
}
if (newroot == NULL) {
iso_filesystem_unref(fs);
return ISO_NO_ROOT_DIR;
}
/* Lookup character set even if no AAIP loading is enabled */
ret = iso_file_source_get_aa_string(newroot, &aa_string, 2);
@ -5838,6 +5884,8 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
boot_image->platform_id = data->platform_ids[idx];
memcpy(boot_image->id_string, data->id_strings[idx], 28);
memcpy(boot_image->selection_crit, data->selection_crits, 20);
boot_image->appended_idx = -1;
boot_image->appended_start = data->bootblocks[idx];
catalog->bootimages[catalog->num_bootimages] = boot_image;
boot_image = NULL;
@ -5909,10 +5957,21 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
/* warn about hidden images */
iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0,
if (image->bootcat->bootimages[idx]->platform_id == 0xef) {
iso_msg_submit(image->id, ISO_ELTO_EFI_HIDDEN, 0,
"Found hidden El-Torito image for EFI.");
iso_msg_submit(image->id, ISO_GENERAL_NOTE, 0,
"EFI image start and size: %lu * 2048 , %lu * 512",
(unsigned long int)
image->bootcat->bootimages[idx]->appended_start,
(unsigned long int)
image->bootcat->bootimages[idx]->load_size);
} else {
iso_msg_submit(image->id, ISO_EL_TORITO_HIDDEN, 0,
"Found hidden El-Torito image. Its size could not "
"be figured out, so image modify or boot image "
"patching may lead to bad results.");
}
}
if (image->bootcat->node == NULL) {
IsoNode *node;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2017 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -499,7 +499,7 @@ void lfs_free(IsoFileSource *src)
static
int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
{
int ret;
int ret, no_non_user_perm= 0;
size_t num_attrs = 0, *value_lengths = NULL, result_len;
ssize_t sret;
char *path = NULL, **names = NULL, **values = NULL;
@ -507,7 +507,7 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
*aa_string = NULL;
if ((flag & 3 ) == 3) {
if ((flag & 6 ) == 6) { /* Neither ACL nor xattr shall be read */
ret = 1;
goto ex;
}
@ -521,7 +521,7 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
}
ret = aaip_get_attr_list(path, &num_attrs, &names,
&value_lengths, &values,
(!(flag & 2)) | 2 | (flag & 4) | 16);
(!(flag & 2)) | 2 | (flag & 4) | (flag & 8) | 16);
if (ret <= 0) {
if (ret == -2)
ret = ISO_AAIP_NO_GET_LOCAL;
@ -529,6 +529,9 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
ret = ISO_FILE_ERROR;
goto ex;
}
if(ret == 2)
no_non_user_perm= 1;
if (num_attrs == 0)
result = NULL;
else {
@ -540,7 +543,7 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
}
}
*aa_string = result;
ret = 1;
ret = 1 + no_non_user_perm;
ex:;
if (path != NULL)
free(path);
@ -867,17 +870,19 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
(flag & (1 | 4 | 8 | 32 | (1 << 15))) | 2 | 16);
if (ret <= 0)
return ISO_AAIP_NO_GET_LOCAL;
return 1;
return 1 + (ret == 2);
}
int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
int iso_local_set_attrs_errno(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values,
int *errnos, int flag)
{
int ret;
ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths,
values, (flag & (8 | 32 | 64)) | !(flag & 1));
values, errnos,
(flag & (8 | 32 | 64 | 128)) | !(flag & 1));
if (ret <= 0) {
if (ret == -1)
return ISO_OUT_OF_MEM;
@ -895,6 +900,25 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
}
int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
{
int ret;
int *errnos = NULL;
if(num_attrs > 0) {
errnos= calloc(num_attrs, sizeof(int));
if(errnos == NULL)
return ISO_OUT_OF_MEM;
}
ret= iso_local_set_attrs_errno(disk_path, num_attrs, names, value_lengths,
values, errnos, flag);
if(errnos != NULL)
free(errnos);
return ret;
}
int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag)
{
struct stat stbuf;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2015 Thomas Schmitt
* Copyright (c) 2009 - 2016 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -28,7 +28,7 @@
* Create a new IsoFilesystem to deal with local filesystem.
*
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
*/
int iso_local_filesystem_new(IsoFilesystem **fs);

View File

@ -91,7 +91,7 @@ int filesrc_block_and_size(Ecma119Image *t, IsoFileSrc *src,
*total_size += src->sections[i].size;
if (pos != src->sections[i].block) {
iso_msg_submit(t->image->id, ISO_SECT_SCATTERED, 0,
"File sections do not form consequtive array of blocks");
"File sections do not form consecutive array of blocks");
return ISO_SECT_SCATTERED;
}
/* If .size is not aligned to blocks then there is a byte gap.
@ -405,7 +405,8 @@ int create_tree(Ecma119Image *t, IsoNode *iso, uint32_t parent_id)
if (cret < 0)
return cret;
pos = pos->next;
t->hfsp_leafs[cleaf].nchildren++;
if (cret > 0)
t->hfsp_leafs[cleaf].nchildren++;
}
}
return ISO_SUCCESS;
@ -1667,7 +1668,8 @@ int hfsplus_writer_create(Ecma119Image *target)
goto ex;
}
pos = pos->next;
target->hfsp_leafs[0].nchildren++;
if (cret > 0)
target->hfsp_leafs[0].nchildren++;
}
qsort(target->hfsp_leafs, target->hfsp_nleafs,

View File

@ -422,6 +422,10 @@ static uint16_t class_page_data[] = {
0x21, 0x230,
0x22, 0x230,
0x23, 0x230,
0x00,
/* End of list */
0x00
};
uint16_t *hfsplus_class_pages[256];
@ -434,7 +438,7 @@ void make_hfsplus_class_pages()
uint16_t *rpt, *page_pt;
int page_count = 0;
memset(class_pages, 0, 19 * 256);
memset(class_pages, 0, 19 * 256 * sizeof(uint16_t));
for (i = 0; i < 256; i++)
hfsplus_class_pages[i] = NULL;

View File

@ -203,6 +203,7 @@ int iso_image_new(const char *name, IsoImage **image)
img->hfsplus_blessed[i] = NULL;
img->collision_warnings = 0;
img->imported_sa_info = NULL;
img->blind_on_local_get_attrs = 0;
*image = img;
return ISO_SUCCESS;
@ -610,6 +611,15 @@ void iso_image_set_ignore_aclea(IsoImage *image, int what)
{
image->builder_ignore_acl = (what & 1);
image->builder_ignore_ea = !!(what & 2);
image->builder_take_all_ea = !!(what & 8);
}
int iso_image_get_ignore_aclea(IsoImage *image)
{
return image->builder_ignore_acl |
(image->builder_ignore_ea << 1) |
(image->builder_take_all_ea << 3);
}
@ -1128,3 +1138,15 @@ int iso_image_truncate_name(IsoImage *image, const char *name, char **namept,
return ret;
}
/* API */
int iso_image_was_blind_attrs(IsoImage *image, int flag)
{
int ret;
ret = image->blind_on_local_get_attrs;
if (flag & 1)
image->blind_on_local_get_attrs = 0;
return ret;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2015 Thomas Schmitt
* Copyright (c) 2009 - 2017 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -31,7 +31,7 @@
* Global objects such as the message_queues must belogn to that
* context. Thus we will have, for example, a msg queue per image,
* so images are completelly independent and can be managed together.
* (Usefull, for example, in Multiple-Document-Interface GUI apps.
* (Useful, for example, in Multiple-Document-Interface GUI apps.
* [The stuff we have in init belongs really to image!]
*/
@ -145,6 +145,12 @@ struct Iso_Image
*/
unsigned int builder_ignore_ea : 1;
/**
* If not builder_ignore_ea : import all xattr namespaces from local
* filesystem, not only "user.
*/
unsigned int builder_take_all_ea : 1;
/**
* Files to exclude. Wildcard support is included.
*/
@ -241,6 +247,11 @@ struct Iso_Image
/* Contains the assessment of boot aspects of the loaded image */
struct iso_imported_sys_area *imported_sa_info;
/* Whether some local filesystem xattr namespace could not be explored
* during node building.
*/
int blind_on_local_get_attrs;
};

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2011-2014 Thomas Schmitt
* Copyright (c) 2011-2018 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -401,6 +401,20 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
return ISO_SUCCESS;
}
/*
* From Joliet specs:
* "ISO 9660 (Section 7.5.1) states that the sum of the following shall not
* exceed 30:
* - If there is a file name, the length of the file name.
* - If there is a file name extension, the length of the file name extension.
* On Joliet compliant media, however, the sum as calculated above shall not
* exceed 128 [bytes], to allow for longer file identifiers."
*
* I.e. the dot does not count.
*
* (We have an option to lift the limit from 64*2 to 103*2, which is the
* maximum to fit into an ISO 9660 directory record.)
*/
static
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
{
@ -481,25 +495,26 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ext = dot + 1;
extlen = ucslen(ext);
max = maxchar + 1 - extlen - 1 - digits;
max = maxchar - extlen - digits;
if (max <= 0) {
/* this can happen if extension is too long */
if (extlen + max > 3) {
/*
* This can happen if the extension is too long.
* Reduce its length, to give name at least one
* original character, if it has any.
*/
max = (dot > full_name);
extlen = maxchar - max - digits;
if (extlen < 3) {
/*
* reduce extension len, to give name an extra char
* note that max is negative or 0
*/
extlen = extlen + max - 1;
ext[extlen] = 0;
max = maxchar + 2 - extlen - 1 - digits;
} else {
/*
* error, we don't support extensions < 3
* This can't happen with current limit of digits.
* error, we do not reduce extensions to length < 3
*
* This cannot happen with current limit of digits
* because maxchar is at least 64 and digits at most 7.
*/
ret = ISO_ERROR;
goto mangle_cleanup;
}
ext[extlen] = 0;
}
/* ok, reduce name by digits */
if (name + max < dot) {
@ -508,10 +523,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
} else {
/* Directory, or file without extension */
if (children[i]->type == JOLIET_DIR) {
max = maxchar + 1 - digits;
max = maxchar - digits;
dot = NULL; /* dots have no meaning in dirs */
} else {
max = maxchar + 1 - digits;
max = maxchar - digits;
}
name = full_name;
if ((size_t) max < ucslen(name)) {

View File

@ -1,7 +1,7 @@
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
Message handling facility of libisofs.
Copyright (C) 2006 - 2008 Thomas Schmitt <scdbackup@gmx.net>,
Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later
*/
@ -33,14 +33,13 @@ static int libiso_msgs_item_new(struct libiso_msgs_item **item,
int ret;
struct libiso_msgs_item *o;
struct timeval tv;
struct timezone tz;
(*item)= o=
(struct libiso_msgs_item *) malloc(sizeof(struct libiso_msgs_item));
if(o==NULL)
return(-1);
o->timestamp= 0.0;
ret= gettimeofday(&tv,&tz);
ret= gettimeofday(&tv, NULL);
if(ret==0)
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
o->process_id= getpid();

View File

@ -1,7 +1,7 @@
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
Message handling facility of libisofs.
Copyright (C) 2006-2008 Thomas Schmitt <scdbackup@gmx.net>,
Copyright (C) 2006-2016 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later
*/
@ -266,8 +266,9 @@ int libiso_msgs_new(struct libiso_msgs **m, int flag);
/** Destroy a message handling facility and all its eventual messages.
The submitted pointer gets set to NULL.
Actually only the last destroy call of all offical references to the object
will really dispose it. All others just decrement the reference counter.
Actually only the last destroy call of all official references to the
object will really dispose it. All others just decrement the reference
counter.
Call this function only with official reference pointers obtained by
libiso_msgs_new() or libiso_msgs_refer(), and only once per such pointer.
@param flag Bitfield for control purposes (unused yet, submit 0)

View File

@ -4,7 +4,7 @@
/*
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
* Copyright (c) 2009-2015 Thomas Schmitt
* Copyright (c) 2009-2017 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -16,6 +16,10 @@
libisofs/libisofs.ver
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
*
* Applications must use 64 bit off_t.
@ -89,8 +93,8 @@
* @since 0.6.2
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 4
#define iso_lib_header_version_micro 2
#define iso_lib_header_version_minor 5
#define iso_lib_header_version_micro 0
/**
* Get version of the libisofs library at runtime.
@ -163,7 +167,7 @@ typedef struct Iso_Image IsoImage;
* A node in the iso tree, i.e. a file that will be written to image.
*
* It can represent any kind of files. When needed, you can get the type with
* iso_node_get_type() and cast it to the appropiate subtype. Useful macros
* iso_node_get_type() and cast it to the appropriate subtype. Useful macros
* are provided, see below.
*
* @since 0.6.2
@ -863,6 +867,10 @@ struct IsoFileSource_Iface
* The caller is responsible for finally calling free()
* on non-NULL results.
* @return 1 means success (*aa_string == NULL is possible)
* 2 means success, but it is possible that attributes
* exist in non-user namespaces which could not be
* explored due to lack of permission.
* @since 1.5.0
* <0 means failure and must b a valid libisofs error code
* (e.g. ISO_FILE_ERROR if no better one can be found).
* @since 0.6.14
@ -1253,7 +1261,7 @@ char *iso_get_local_charset(int flag);
* @param image
* Location where the image pointer will be stored.
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
*
* @since 0.6.2
*/
@ -1276,6 +1284,8 @@ int iso_image_new(const char *name, IsoImage **image);
* A bit field which sets the behavior:
* bit0= ignore ACLs if the external file object bears some
* bit1= ignore xattr if the external file object bears some
* bit3= if not bit1: import all xattr namespaces, not only "user."
* @since 1.5.0
* all other bits are reserved
*
* @since 0.6.14
@ -1283,6 +1293,19 @@ int iso_image_new(const char *name, IsoImage **image);
void iso_image_set_ignore_aclea(IsoImage *image, int what);
/**
* Obtain the current setting of iso_image_set_ignore_aclea().
*
* @param image
* The image to be inquired
* @return
* The currently set value.
*
* @since 1.5.0
*/
int iso_image_get_ignore_aclea(IsoImage *image);
/**
* Creates an IsoWriteOpts for writing an image. You should set the options
* desired with the correspondent setters.
@ -1372,7 +1395,7 @@ int iso_write_opts_set_iso_level(IsoWriteOpts *opts, int level);
* resulting image will have long filenames (up to 255 characters), deeper
* directory structure, POSIX permissions and owner info on files and
* directories, support for symbolic links or special files... All that
* attributes can be modified/setted with the appropiate function.
* attributes can be modified/set with the appropriate function.
*
* @param opts
* The option set to be manipulated.
@ -1481,7 +1504,7 @@ int iso_write_opts_set_hfsp_serial_number(IsoWriteOpts *opts,
* @param hfsp_block_size
* The allocation block size to be used by the HFS+ fileystem.
* 0, 512, or 2048
* @param hfsp_block_size
* @param apm_block_size
* The block size to be used for and within the Apple Partition Map.
* 0, 512, or 2048.
* Size 512 is not compatible with options which produce GPT.
@ -1666,7 +1689,7 @@ int iso_write_opts_set_allow_deep_paths(IsoWriteOpts *opts, int allow);
* The name given by this call will be compared with iso_node_get_name()
* of the directories in the root directory, not with the final ECMA-119
* names of those directories.
* @parm flags
* @param flags
* Bitfield for control purposes.
* bit0= Mark the relocation directory by a Rock Ridge RE entry, if it
* gets created during iso_image_create_burn_source(). This will
@ -1808,7 +1831,7 @@ int iso_write_opts_set_rrip_1_10_px_ino(IsoWriteOpts *opts, int enable);
/**
* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12.
* I.e. without announcing it by an ER field and thus without the need
* to preceed the RRIP fields and the AAIP field by ES fields.
* to precede the RRIP fields and the AAIP field by ES fields.
* This saves 5 to 10 bytes per file and might avoid problems with readers
* which dislike ER fields other than the ones for RRIP.
* On the other hand, SUSP 1.12 frowns on such unannounced extensions
@ -2215,8 +2238,10 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* @since 1.2.6
* bit10-13= System area sub type
* @since 1.2.4
* With type 0 = MBR:
* Gets overridden by bit0 and bit1.
* With type 0:
* if options bit0 ... MBR with partition start at block 1
* if options bit1 ... ISOLINUX isohybrid MBR
* else:
* 0 = no particular sub type, use unaltered
* 1 = CHRP: A single MBR partition of type 0x96 covers the
* ISO image. Not compatible with any other feature
@ -2228,8 +2253,12 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* Patch system area at byte 0x1b0 to 0x1b7 with
* (512-block address + 4) of the first boot image file.
* Little-endian 8-byte.
* Should be combined with options bit0.
* Is normally combined with options bit0.
* Will not be in effect if options bit1 is set.
* bit15= Only with System area type MBR but not with CHRP
* Enforce MBR "bootable/active" flag. In worst case by dummy
* partition of type 0x00 which occupies block 0.
* @since 1.4.4
* @param flag
* bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data.
@ -2348,7 +2377,7 @@ int iso_write_opts_set_part_offset(IsoWriteOpts *opts,
#define iso_libjte_req_micro 0
/**
* Associate a libjte environment object to the upcomming write run.
* Associate a libjte environment object to the upcoming write run.
* libjte implements Jigdo Template Extraction as of Steve McIntyre and
* Richard Atterer.
* The call will fail if no libjte support was enabled at compile time.
@ -2488,6 +2517,8 @@ int iso_interval_reader_new(IsoImage *img, char *path,
*
* @param ivr
* The reader object to be disposed. *ivr will be set to NULL.
* @param flag
* Unused yet. Submit 0.
* @return
* ISO_SUCCESS or error (which is < 0)
*
@ -2505,7 +2536,7 @@ int iso_interval_reader_destroy(struct iso_interval_reader **ivr, int flag);
* Pointer to memory for filling in at least 2048 bytes.
* @param buf_fill
* Will in case of success return the number of valid bytes.
* If this is smaller than 2048, then end-of-interval has occured.
* If this is smaller than 2048, then end-of-interval has occurred.
* @param flag
* Unused yet. Submit 0.
* @return
@ -2585,6 +2616,52 @@ int iso_write_opts_set_prep_img(IsoWriteOpts *opts, char *image_path,
int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
int flag);
/**
* Control whether the emerging GPT gets a pseudo-randomly generated disk GUID
* or whether it gets a user supplied GUID.
* The partition GUIDs will be generated in a reproducible way by exoring the
* little-endian 32 bit partion number with the disk GUID beginning at byte
* offset 9.
*
* @param opts
* The option set to be manipulated.
* @param guid
* 16 bytes of user supplied GUID. Readily byte-swapped as prescribed by
* UEFI specs: 4 byte, 2 byte, 2 byte as little-endian. The rest as
* big-endian.
* The upper 4 bit of guid[7] should bear the value 4 to express the
* RFC 4122 version 4. Bit 7 of byte[8] should be set to 1 and bit 6
* be set to 0, in order to express the RFC 4122 variant of UUID,
* where version 4 means "pseudo-random uuid".
* @param mode
* 0 = ignore parameter guid and produce the GPT disk GUID by a
* pseudo-random algorithm. This is the default setting.
* 1 = use parameter guid as GPT disk GUID
* 2 = ignore parameter guid and derive the GPT disk GUID from
* parameter vol_uuid of iso_write_opts_set_pvd_times().
* The 16 bytes of vol_uuid get copied and bytes 7, 8 get their
* upper bits changed to comply to RFC 4122 and UEFI.
* Error ISO_GPT_NO_VOL_UUID will occur if image production begins
* before vol_uuid was set.
*
* @return
* ISO_SUCCESS or ISO_BAD_GPT_GUID_MODE
*
* @since 1.4.6
*/
int iso_write_opts_set_gpt_guid(IsoWriteOpts *opts, uint8_t guid[16],
int mode);
/**
* Generate a pseudo-random GUID suitable for iso_write_opts_set_gpt_guid().
*
* @param guid
* Will be filled by 16 bytes of generated GUID.
*
* @since 1.4.6
*/
void iso_generate_gpt_guid(uint8_t guid[16]);
/**
* Cause an arbitrary data file to be appended to the ISO image and to be
* described by a partition table entry in an MBR or SUN Disk Label at the
@ -2603,15 +2680,15 @@ int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
* Range with MBR: 1 to 4. 1 will cause the whole ISO image to be
* unclaimable space before partition 1.
* Range with SUN Disk Label: 2 to 8.
* @param partition_type
* The MBR partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06,
* Linux Native Partition = 0x83. See fdisk command L.
* This parameter is ignored with SUN Disk Label.
* @param image_path
* File address in the local file system or instructions for interval
* reader. See flag bit0.
* With SUN Disk Label: an empty name causes the partition to become
* a copy of the next lower partition.
* @param image_type
* The MBR partition type. E.g. FAT12 = 0x01 , FAT16 = 0x06,
* Linux Native Partition = 0x83. See fdisk command L.
* This parameter is ignored with SUN Disk Label.
* @param flag
* bit0= The path contains instructions for the interval reader
* See above.
@ -2644,6 +2721,69 @@ int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
*/
int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt);
/**
* Control whether partitions created by iso_write_opts_set_partition_img()
* are to be represented in Apple Partition Map.
*
* @param opts
* The option set to be manipulated.
* @param apm
* 0= do not represent appended partitions in APM
* 1= represent in APM, even if not
* iso_write_opts_set_part_like_isohybrid() enables it and no
* other APM partitions emerge.
* @return
* ISO_SUCCESS or error
*
* @since 1.4.4
*/
int iso_write_opts_set_appended_as_apm(IsoWriteOpts *opts, int apm);
/**
* Control whether bits 2 to 8 of el_torito_set_isolinux_options()
* shall apply even if not isohybrid MBR patching is enabled (bit1 of
* parameter options of iso_write_opts_set_system_area()):
* - Mentioning of El Torito boot images in GPT.
* - Mentioning of El Torito boot images in APM.
*
* In this case some other behavior from isohybrid processing will apply too:
* - No MBR partition of type 0xee emerges, even if GPT gets produced.
* - Gaps between GPT and APM partitions will not be filled by more partitions.
*
* An extra feature towards isohybrid is enabled:
* - Appended partitions get mentioned in APM if other APM partitions emerge.
*
* @param opts
* The option set to be manipulated.
* @param alike
* 0= Apply the described behavior only with ISOLINUX isohybrid.
* Do not mention appended partitions in APM unless
* iso_write_opts_set_appended_as_apm() is enabled.
* 1= Apply the described behavior even without ISOLINUX isohybrid.
*
* @return
* ISO_SUCCESS or error
*
* @since 1.4.4
*/
int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike);
/**
* Set the partition type of the MBR partition which represents the ISO
* filesystem or at least protects it.
* This is without effect if no such partition emerges by other settings or
* if the partition type is prescribed mandatorily like 0xee for GPT protective
* MBR or 0x96 for CHRP.
* @param opts
* The option set to be manipulated.
* @param part_type
* 0x00 to 0xff as desired partition type.
* Any other value (e.g. -1) enables the default types of the various
* occasions.
* @since 1.4.8
*/
int iso_write_opts_set_iso_mbr_part_type(IsoWriteOpts *opts, int part_type);
/**
* Inquire the start address of the file data blocks after having used
* IsoWriteOpts with iso_image_create_burn_source().
@ -3118,7 +3258,7 @@ void *iso_image_get_attached_data(IsoImage *image);
* effect if both, the truncate mode value from "isofs.nt" and the current
* truncate mode of the IsoImage are 1, and the length is between 64 and 255.
*
* @param image
* @param img
* The image which shall be manipulated.
* @param mode
* 0= Do not truncate but throw error ISO_RR_NAME_TOO_LONG if a file name
@ -3142,7 +3282,7 @@ int iso_image_set_truncate_mode(IsoImage *img, int mode, int length);
/**
* Inquire the current setting of iso_image_set_truncate_mode().
*
* @param image
* @param img
* The image which shall be inquired.
* @param mode
* Returns the mode value.
@ -3371,16 +3511,16 @@ const char *iso_image_get_app_use(IsoImage *image);
*
* @param image
* The image to be inquired.
* @param vol_creation_time
* @param creation_time
* Returns a pointer to the Volume Creation time:
* When "the information in the volume was created."
* @param vol_modification_time
* @param modification_time
* Returns a pointer to Volume Modification time:
* When "the information in the volume was last modified."
* @param vol_expiration_time
* @param expiration_time
* Returns a pointer to Volume Expiration time:
* When "the information in the volume may be regarded as obsolete."
* @param vol_effective_time
* @param effective_time
* Returns a pointer to Volume Expiration time:
* When "the information in the volume may be used."
* @return
@ -3401,14 +3541,22 @@ int iso_image_get_pvd_times(IsoImage *image,
* The image to make bootable. If it was already bootable this function
* returns an error and the image remains unmodified.
* @param image_path
* The absolute path of a IsoFile to be used as default boot image.
* The absolute path of a IsoFile to be used as default boot image or
* --interval:appended_partition_$number[_start_$start_size_$size]:...
* if type is ELTORITO_NO_EMUL. $number gives the partition number.
* If _start_$start_size_$size is present, then it overrides the 2 KiB
* start block of the partition and the partition size counted in
* blocks of 512 bytes.
* @param type
* The boot media type. This can be one of 3 types:
* - Floppy emulation: Boot image file must be exactly
* 1200 kB, 1440 kB or 2880 kB.
* - Hard disc emulation: The image must begin with a master
* - ELTORITO_FLOPPY_EMUL.
* Floppy emulation: Boot image file must be exactly
* 1200 KiB, 1440 KiB or 2880 KiB.
* - ELTORITO_HARD_DISC_EMUL.
* Hard disc emulation: The image must begin with a master
* boot record with a single image.
* - No emulation. You should specify load segment and load size
* - ELTORITO_NO_EMUL.
* No emulation. You should specify load segment and load size
* of image.
* @param catalog_path
* The absolute path in the image tree where the catalog will be stored.
@ -3443,9 +3591,11 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
* The image to which the boot image shall be added.
* returns an error and the image remains unmodified.
* @param image_path
* The absolute path of a IsoFile to be used as default boot image.
* The absolute path of a IsoFile to be used as boot image or
* --interval:appended_partition_$number[_start_$start_size_$size]:...
* if type is ELTORITO_NO_EMUL. See iso_image_set_boot_image.
* @param type
* The boot media type. See iso_image_set_boot_image
* The boot media type. See iso_image_set_boot_image.
* @param flag
* Bitfield for control purposes. Unused yet. Submit 0.
* @param boot
@ -3488,6 +3638,7 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
* @param imgnode
* When not NULL, it will be filled with the image tree node. No extra ref
* is added, you can use iso_node_ref() to get one if you need it.
* The returned value is NULL if the boot image source is no IsoFile.
* @param catnode
* When not NULL, it will be filled with the catnode tree node. No extra
* ref is added, you can use iso_node_ref() to get one if you need it.
@ -3545,6 +3696,10 @@ int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
* @param bootnodes
* Returns NULL or an allocated array of pointers to the IsoFile nodes
* which bear the content of the boot images in boots.
* An array entry is NULL if the boot image source is no IsoFile.
>>> Need getter for partition index
* @param flag
* Bitfield for control purposes. Unused yet. Submit 0.
* @return
@ -3715,6 +3870,26 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors);
*/
int el_torito_get_load_size(ElToritoBootImage *bootimg);
/**
* State that the load size shall be the size of the boot image automatically.
* This overrides el_torito_set_load_size().
* @param bootimg
* The image to to manipulate
* @param mode
* 0= use value of el_torito_set_load_size()
* 1= determine value from boot image
*/
void el_torito_set_full_load(ElToritoBootImage *bootimg, int mode);
/**
* Inquire the setting of el_torito_set_full_load().
* @param bootimg
* The image to inquire
* @return
* The mode set with el_torito_set_full_load().
*/
int el_torito_get_full_load(ElToritoBootImage *bootimg);
/**
* Marks the specified boot image as not bootable
*
@ -3796,7 +3971,7 @@ int el_torito_set_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20]);
*
* @param bootimg
* The image to inquire
* @param id_string
* @param crit
* Returns 20 bytes of type and data
* @return
* 1 = ok , <0 = error
@ -4166,7 +4341,7 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
#define ISO_SYSAREA_REPORT_DOC_ALPHA \
"If a DEC Alpha SRM boot sector is present:", \
" DEC Alpha ldr size : decimal", \
" tells the number of 512-byte blocks in DEC Alpha Secondary Bootstrap" \
" tells the number of 512-byte blocks in DEC Alpha Secondary Bootstrap", \
" Loader file.", \
" DEC Alpha ldr adr : decimal", \
" tells the start of the loader file in units of 512-byte blocks.", \
@ -4183,7 +4358,7 @@ int iso_image_get_system_area(IsoImage *img, char data[32768],
* Else it will consist of lines as described in ISO_SYSAREA_REPORT_DOC above.
*
* File paths and other long texts are reported as "(too long to show here)"
* if their length plus preceeding text plus trailing 0-byte exceeds the
* if their length plus preceding text plus trailing 0-byte exceeds the
* line length limit of ISO_MAX_SYSAREA_LINE_LENGTH bytes.
* Texts which may contain whitespace or unprintable characters will start
* at fixed positions and extend to the end of the line.
@ -4339,7 +4514,7 @@ uint32_t iso_crc32_gpt(unsigned char *data, int count, int flag);
* the first added file gets into effect with this system area type.
* The data files which shall serve as MIPS boot files have to be brought into
* the image by the normal means.
* @param img
* @param image
* The image to be manipulated.
* @param path
* Absolute path of the boot file in the ISO 9660 Rock Ridge tree.
@ -4354,7 +4529,7 @@ int iso_image_add_mips_boot_file(IsoImage *image, char *path, int flag);
/**
* Obtain the number of added MIPS Big Endian boot files and pointers to
* their paths in the ISO 9660 Rock Ridge tree.
* @param img
* @param image
* The image to be inquired.
* @param paths
* An array of pointers to be set to the registered boot file paths.
@ -4370,7 +4545,7 @@ int iso_image_get_mips_boot_files(IsoImage *image, char *paths[15], int flag);
/**
* Clear the list of MIPS Big Endian boot file paths.
* @param img
* @param image
* The image to be manipulated.
* @param flag
* Bitfield for control purposes, unused yet, submit 0
@ -4498,7 +4673,7 @@ int iso_image_set_alpha_boot(IsoImage *img, char *boot_loader_path, int flag);
*
* @param img
* The image to be inquired.
* @param cmdline
* @param boot_loader_path
* Will return the path. NULL if none is currently submitted.
* @return
* 1 is success , <0 means error
@ -5165,7 +5340,7 @@ int iso_dir_iter_take(IsoDirIter *iter);
* The node removed will be the one returned by the previous iteration.
*
* It is not allowed to call this function twice without calling
* iso_dir_iter_next inbetween.
* iso_dir_iter_next between the calls.
*
* @return
* 1 on succes, < 0 error
@ -5184,8 +5359,9 @@ int iso_dir_iter_remove(IsoDirIter *iter);
*
* @param node
* The node to be removed.
* @param iter
* If not NULL, then the node will be removed by iso_dir_iter_remove(iter)
* @param boss_iter
* If not NULL, then the node will be removed by
* iso_dir_iter_remove(boss_iter)
* else it will be removed by iso_node_remove(node).
* @return
* 1 is success, <0 indicates error
@ -5389,10 +5565,10 @@ int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond,
const char *iso_symlink_get_dest(const IsoSymlink *link);
/**
* Set the destination of a link.
* Set the destination of a symbolic
*
* @param opts
* The option set to be manipulated
* @param link
* The link node to be manipulated
* @param dest
* New destination for the link. It must be a non-empty string, otherwise
* this function doesn't modify previous destination.
@ -5413,7 +5589,7 @@ int iso_symlink_set_dest(IsoSymlink *link, const char *dest);
* or regular files, this function has no effect.
* @param w
* The weight as a integer number, the greater this value is, the
* closer from the begining of image the file will be written.
* closer from the beginning of image the file will be written.
* Default value at IsoNode creation is 0.
*
* @since 0.6.2
@ -5646,7 +5822,7 @@ int iso_tree_add_new_file(IsoDir *parent, const char *name, IsoStream *stream,
*
* @param buf
* The dynamically allocated memory buffer with the stream content.
* @parm size
* @param size
* The number of bytes which may be read from buf.
* @param stream
* Will return a reference to the newly created stream.
@ -6167,7 +6343,7 @@ int iso_tree_clone(IsoNode *node,
* Add the contents of a dir to a given directory of the iso tree.
*
* There are several options to control what files are added or how they are
* managed. Take a look at iso_tree_set_* functions to see diferent options
* managed. Take a look at iso_tree_set_* functions to see different options
* for recursive directory addition.
*
* TODO comment Builder and Filesystem related issues when exposing both
@ -6185,6 +6361,28 @@ int iso_tree_clone(IsoNode *node,
*/
int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir);
/**
* Inquire whether some local filesystem xattr namespace could not be explored
* during node building. This may happen due to lack of adminstrator privileges
* e.g. on FreeBSD namespace "system".
* It may well be that the processed local files have no attributes which
* would require special privileges. But already their existence was neither
* denied nor confirmed.
*
* @param image
* The image to inquire.
* @param flag
* Bitfield for control purposes:
* bit0 = reset internal value to 0
* @return
* 1 = Exploration was prevented
* 0 = No such prevention occured
*
* @since 1.5.0
*/
int iso_image_was_blind_attrs(IsoImage *image, int flag);
/**
* Locate a node by its absolute path in the image.
* The IsoImage context defines a maximum permissible name length and a mode
@ -6360,7 +6558,7 @@ int iso_set_msgs_severities(char *queue_severity, char *print_severity,
* will discard the whole queue.
*
* @param minimum_severity
* Threshhold
* Threshold
* @param error_code
* Will become a unique error code as listed at the end of this header
* @param imgid
@ -6761,6 +6959,9 @@ int iso_file_source_readlink(IsoFileSource *src, char *buf, size_t bufsiz);
* not be able to produce it again.
* bit1= No need to get ACL (but no guarantee of exclusion)
* bit2= No need to get xattr (but no guarantee of exclusion)
* bit3= if not bit2: import all xattr namespaces from
* local filesystem, not only "user."
* @since 1.5.0
* @return 1 means success (*aa_string == NULL is possible)
* <0 means failure and must b a valid libisofs error code
* (e.g. ISO_FILE_ERROR if no better one can be found).
@ -6810,7 +7011,7 @@ void iso_filesystem_unref(IsoFilesystem *fs);
* @param fs
* Will be filled with a pointer to the filesystem that can be used
* to access image contents.
* @param
* @return
* 1 on success, < 0 on error
*
* @since 0.6.2
@ -7188,7 +7389,7 @@ mode_t iso_node_get_perms_wo_acl(const IsoNode *node);
* @param names
* Will return an array of pointers to 0-terminated names
* @param value_lengths
* Will return an arry with the lenghts of values
* Will return an array with the lengths of values
* @param values
* Will return an array of pointers to strings of 8-bit bytes
* @param flag
@ -7214,7 +7415,7 @@ int iso_node_get_attrs(IsoNode *node, size_t *num_attrs,
* @param name
* The xattr name that shall be looked up.
* @param value_length
* Will return the lenght of value
* Will return the length of value
* @param value
* Will return a string of 8-bit bytes. free() it when no longer needed.
* @param flag
@ -7397,7 +7598,7 @@ int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag);
* @param names
* Will return an array of pointers to 0-terminated names
* @param value_lengths
* Will return an arry with the lenghts of values
* Will return an array with the lengths of values
* @param values
* Will return an array of pointers to 8-bit values
* @param flag
@ -7410,6 +7611,9 @@ int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag);
* bit15= free memory
* @return
* 1 ok
* 2 ok, but it is possible that attributes exist in non-user namespaces
* which could not be explored due to lack of permission.
* @since 1.5.0
* < 0 failure
*
* @since 0.6.14
@ -7433,6 +7637,11 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
* Array of byte lengths for each attribute payload
* @param values
* Array of pointers to the attribute payload bytes
* @param errnos
* Array of integers to return error numbers if encountered at the attempt
* to process the name-value pair at the given array index number:
* 0 = no error , -1 = unknown error
* >0 = errno as of local system calls to set xattr and ACLs
* @param flag
* Bitfield for control purposes
* bit0= do not attach ACLs from an eventual attribute with empty name
@ -7440,12 +7649,24 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
* I.e. those with a name which does not begin by "user."
* bit5= in case of symbolic link: manipulate link target
* bit6= @since 1.1.6
tolerate inappropriate presence or absence of
* tolerate inappropriate presence or absence of
* directory "default" ACL
* bit7= @since 1.5.0
* avoid setting a name value pair if it already exists and
* has the desired value.
* @return
* 1 = ok
* < 0 = error
*
* @since 1.5.0
*/
int iso_local_set_attrs_errno(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values,
int *errnos, int flag);
/**
* Older version of iso_local_set_attrs_errno() without the errnos array.
* All other parameters and the return value have the same meaning.
*
* @since 0.6.14
*/
int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
@ -8097,7 +8318,7 @@ enum IsoHfsplusBlessings {
* Issue a blessing to a particular IsoNode. If the blessing is already issued
* to some file, then it gets revoked from that one.
*
* @param image
* @param img
* The image to manipulate.
* @param blessing
* The kind of blessing to be issued.
@ -8131,7 +8352,7 @@ int iso_image_hfsplus_bless(IsoImage *img, enum IsoHfsplusBlessings blessing,
*
* Several usage restrictions apply. See parameter blessed_nodes.
*
* @param image
* @param img
* The image to inquire.
* @param blessed_nodes
* Will return a pointer to an internal node array of image.
@ -8326,8 +8547,8 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
/** File not supported in ECMA-119 tree and thus ignored (WARNING,MEDIUM, -139) */
#define ISO_FILE_IGNORED 0xD020FF75
/* A file is bigger than supported by used standard (WARNING,MEDIUM, -140) */
#define ISO_FILE_TOO_BIG 0xD020FF74
/* A file is bigger than supported by used standard (FAILURE,HIGH, -140) */
#define ISO_FILE_TOO_BIG 0xE830FF74
/* File read error during image creation (MISHAP,HIGH, -141) */
#define ISO_FILE_CANT_WRITE 0xE430FF73
@ -8715,6 +8936,29 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
/** Unrecognized file type of IsoFileSrc object (SORRY, HIGH, -415) */
#define ISO_BAD_FSRC_FILETYPE 0xE030FE61
/** Cannot derive GPT GUID from undefined pseudo-UUID volume timestamp
(FAILURE, HIGH, -416) */
#define ISO_GPT_NO_VOL_UUID 0xE830FE60
/** Unrecognized GPT disk GUID setup mode
(FAILURE, HIGH, -417) */
#define ISO_BAD_GPT_GUID_MODE 0xE830FE5F
/** Unable to obtain root directory (FATAL,HIGH, -418) */
#define ISO_NO_ROOT_DIR 0xF030FE5E
/** Zero sized, oversized, or mislocated SUSP CE area found
(FAILURE, HIGH, -419) */
#define ISO_SUSP_WRONG_CE_SIZE 0xE830FE5D
/** Multi-session would overwrite imported_iso interval
(FAILURE, HIGH, -420) */
#define ISO_MULTI_OVER_IMPORTED 0xE830FE5C
/** El-Torito EFI image is hidden (NOTE,HIGH, -421) */
#define ISO_ELTO_EFI_HIDDEN 0xB030FE5B
/* Internal developer note:
Place new error codes directly above this comment.
Newly introduced errors must get a message entry in
@ -8724,16 +8968,16 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
/* ! PLACE NEW ERROR CODES ABOVE. NOT AFTER THIS LINE ! */
/** Read error occured with IsoDataSource (SORRY,HIGH, -513) */
/** Read error occurred with IsoDataSource (SORRY,HIGH, -513) */
#define ISO_DATA_SOURCE_SORRY 0xE030FCFF
/** Read error occured with IsoDataSource (MISHAP,HIGH, -513) */
/** Read error occurred with IsoDataSource (MISHAP,HIGH, -513) */
#define ISO_DATA_SOURCE_MISHAP 0xE430FCFF
/** Read error occured with IsoDataSource (FAILURE,HIGH, -513) */
/** Read error occurred with IsoDataSource (FAILURE,HIGH, -513) */
#define ISO_DATA_SOURCE_FAILURE 0xE830FCFF
/** Read error occured with IsoDataSource (FATAL,HIGH, -513) */
/** Read error occurred with IsoDataSource (FATAL,HIGH, -513) */
#define ISO_DATA_SOURCE_FATAL 0xF030FCFF
@ -8911,4 +9155,8 @@ struct burn_source {
#define Libisofs_with_rrip_rR yes
*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LIBISO_LIBISOFS_H_*/

View File

@ -5,6 +5,7 @@ aaip_xinfo_func;
el_torito_get_bootable;
el_torito_get_boot_media_type;
el_torito_get_boot_platform_id;
el_torito_get_full_load;
el_torito_get_id_string;
el_torito_get_isolinux_options;
el_torito_get_load_seg;
@ -13,6 +14,7 @@ el_torito_get_selection_crit;
el_torito_patch_isolinux_image;
el_torito_seems_boot_info_table;
el_torito_set_boot_platform_id;
el_torito_set_full_load;
el_torito_set_id_string;
el_torito_set_isolinux_options;
el_torito_set_load_seg;
@ -68,6 +70,7 @@ iso_filesystem_ref;
iso_filesystem_unref;
iso_finish;
iso_fs_global_id;
iso_generate_gpt_guid;
iso_get_local_charset;
iso_get_messenger;
iso_gzip_get_refcounts;
@ -81,6 +84,7 @@ iso_image_add_new_special;
iso_image_add_new_symlink;
iso_image_attach_data;
iso_image_create_burn_source;
iso_image_dir_get_node;
iso_image_filesystem_new;
iso_image_fs_get_abstract_file_id;
iso_image_fs_get_application_id;
@ -103,8 +107,8 @@ iso_image_get_bootcat;
iso_image_get_boot_image;
iso_image_get_copyright_file_id;
iso_image_get_data_preparer_id;
iso_image_dir_get_node;
iso_image_get_hppa_palo;
iso_image_get_ignore_aclea;
iso_image_get_mips_boot_files;
iso_image_get_msg_id;
iso_image_get_publisher_id;
@ -149,6 +153,7 @@ iso_image_set_volume_id;
iso_image_tree_clone;
iso_image_unref;
iso_image_update_sizes;
iso_image_was_blind_attrs;
iso_init;
iso_init_with_flag;
iso_interval_reader_destroy;
@ -162,6 +167,7 @@ iso_local_get_attrs;
iso_local_get_perms_wo_acl;
iso_local_set_acl_text;
iso_local_set_attrs;
iso_local_set_attrs_errno;
iso_md5_clone;
iso_md5_compute;
iso_md5_end;
@ -308,6 +314,7 @@ iso_write_opts_set_allow_longer_paths;
iso_write_opts_set_allow_lowercase;
iso_write_opts_set_always_gmt;
iso_write_opts_set_appendable;
iso_write_opts_set_appended_as_apm;
iso_write_opts_set_appended_as_gpt;
iso_write_opts_set_default_dir_mode;
iso_write_opts_set_default_file_mode;
@ -319,12 +326,14 @@ iso_write_opts_set_disc_label;
iso_write_opts_set_efi_bootp;
iso_write_opts_set_fat;
iso_write_opts_set_fifo_size;
iso_write_opts_set_gpt_guid;
iso_write_opts_set_hardlinks;
iso_write_opts_set_hfsp_block_size;
iso_write_opts_set_hfsp_serial_number;
iso_write_opts_set_hfsplus;
iso_write_opts_set_iso1999;
iso_write_opts_set_iso_level;
iso_write_opts_set_iso_mbr_part_type;
iso_write_opts_set_joliet;
iso_write_opts_set_joliet_long_names;
iso_write_opts_set_joliet_longer_paths;
@ -337,6 +346,7 @@ iso_write_opts_set_omit_version_numbers;
iso_write_opts_set_output_charset;
iso_write_opts_set_overwrite_buf;
iso_write_opts_set_part_offset;
iso_write_opts_set_part_like_isohybrid;
iso_write_opts_set_partition_img;
iso_write_opts_set_prep_img;
iso_write_opts_set_pvd_times;

View File

@ -37,6 +37,8 @@
#include "ecma119.h"
#include "eltorito.h"
#include "system_area.h"
#include "image.h"
#include "messages.h"
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
@ -60,7 +62,7 @@ license from above stem licenses, typically from LGPL.
In case its generosity is needed, here is the 2-clause BSD license:
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
and 2008-2014 Thomas Schmitt
and 2008-2015 Thomas Schmitt
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
@ -156,7 +158,6 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
/* For generating a weak random number */
struct timeval tv;
struct timezone tz;
if (bin_lba < 0 || bin_lba >= (1 << 29))
return (0); /* 1 TB limit of signed 32 bit addressing of 512 byte blocks */
@ -211,7 +212,7 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
from. An environment variable ?
125: Whatever, i use some 32-bit random value with no crypto strength.
*/
gettimeofday(&tv, &tz);
gettimeofday(&tv, NULL);
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
/*
@ -400,12 +401,15 @@ int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
/* Find out whether GPT and APM are desired
flag bit0 = register APM and GPT requests in Ecma119Image
bit1 = do not asses and register APM
bit2 = do not register overall GPT partition
*/
int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
int *apm_count, int flag)
{
int i, ilx_opts, j, ret, num_img;
uint32_t block_count;
uint64_t start_block;
uint8_t gpt_name[72];
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static uint8_t basic_data_uuid[16] = {
@ -428,11 +432,13 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
num_img = 0;
for (i = 0; i < num_img; i++) {
ilx_opts = t->catalog->bootimages[i]->isolinux_options;
if (((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) {
if ((((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) &&
!(t->boot_appended_idx[i] >= 0 && t->opts->appended_as_gpt)) {
if (*gpt_count < 128)
gpt_idx[*gpt_count]= i;
gpt_idx[*gpt_count] = i;
(*gpt_count)++;
if ((flag & 1) && t->bootsrc[i] != NULL) {
if ((flag & 1) &&
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
/* Register GPT entry */
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count);
@ -441,27 +447,44 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
uuid = hfs_uuid;
else
uuid = basic_data_uuid;
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
if (t->boot_appended_idx[i] >= 0) {
block_count = t->appended_part_size[
t->boot_appended_idx[i]];
start_block = ((uint64_t) t->appended_part_start[
t->boot_appended_idx[i]]) * 4;
} else {
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
start_block = ((uint64_t) t->bootsrc[i]->sections[0].block)
* 4;
}
ret = iso_quick_gpt_entry(
t->gpt_req, &(t->gpt_req_count),
((uint64_t) t->bootsrc[i]->sections[0].block) * 4,
((uint64_t) block_count) * 4,
start_block, ((uint64_t) block_count) * 4,
uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name);
if (ret < 0)
return ret;
}
}
if (ilx_opts & 256) {
if ((ilx_opts & 256) && !(flag & 2)) {
(*apm_count)++;
if ((flag & 1) && t->bootsrc[i] != NULL) {
if ((flag & 1) &&
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
/* Register APM entry */
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
if (t->boot_appended_idx[i] >= 0) {
block_count = t->appended_part_size[
t->boot_appended_idx[i]];
start_block = t->appended_part_start[
t->boot_appended_idx[i]];
} else {
block_count = 0;
for (j = 0; j < t->bootsrc[i]->nsections; j++)
block_count += t->bootsrc[i]->sections[j].size / 2048;
start_block = t->bootsrc[i]->sections[0].block;
}
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->bootsrc[i]->sections[0].block,
(uint32_t) start_block,
block_count, "EFI", "Apple_HFS");
if (ret < 0)
return ret;
@ -471,7 +494,12 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
}
}
}
if ((flag & 1) && *gpt_count > 0) {
if (*gpt_count > 0 && !(flag & 4)) {
(*gpt_count)++;
if (*gpt_count < 128)
gpt_idx[*gpt_count] = -1;
}
if ((flag & 1) && *gpt_count > 0 && !(flag & 4)) {
/* Register overall GPT partition */
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "ISOHybrid");
@ -536,19 +564,28 @@ static int insert_apm_head(uint8_t *buf, int apm_count)
static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
int gpt_idx[128], int *gpt_cursor)
{
int ilx_opts;
int ilx_opts, skip = 0;
off_t hd_blocks;
static uint8_t dummy_chs[3] = {
0xfe, 0xff, 0xff,
};
if (gpt_idx[*gpt_cursor] < 0)
skip = 1;
else if (t->bootsrc[gpt_idx[*gpt_cursor]] == NULL)
skip = 1;
if (skip) {
(*gpt_cursor)++;
return 2;
}
wpt[0] = 0;
memcpy(wpt + 1, dummy_chs, 3);
ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options;
if (((ilx_opts >> 2) & 63) == 2)
wpt[4] = 0x00; /* HFS gets marked as "Empty" */
else
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16/" */
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16)" */
memcpy(wpt + 5, dummy_chs, 3);
@ -567,8 +604,28 @@ static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
}
/* For generating a weak random number */
static uint32_t iso_make_mbr_id(Ecma119Image *t, int flag)
{
uint32_t id;
struct timeval tv;
if(t->opts->vol_uuid[0]) {
id = iso_crc32_gpt((unsigned char *) t->opts->vol_uuid, 16, 0);
} else if(t->opts->vol_modification_time > 0) {
id = iso_crc32_gpt((unsigned char *) &(t->opts->vol_modification_time),
sizeof(time_t), 0);
} else {
gettimeofday(&tv, NULL);
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
}
return id;
}
/*
* @param flag bit0= make own random MBR Id from current time
* >>> or from overridden modification time
* bit1= create protective MBR as of UEFI/GPT specs
*/
int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
@ -580,10 +637,14 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
char *wpt;
uint32_t boot_lba;
int head_count, sector_count, ret;
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor;
/* For generating a weak random number */
struct timeval tv;
struct timezone tz;
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor, i;
if (t->bootsrc[0] == NULL)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem.");
for (i = 0; i < 128; i++)
gpt_idx[i] = -1;
if (flag & 2) {
part_number = 1;
@ -625,8 +686,7 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
(here some 32-bit random value with no crypto strength)
*/
if (flag & 1) {
gettimeofday(&tv, &tz);
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
id = iso_make_mbr_id(t, 0);
lsb_to_buf(&wpt, id, 32, 0);
} else {
wpt+= 4;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2015 Thomas Schmitt
* Copyright (c) 2009 - 2016 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -157,7 +157,7 @@ int iso_init_with_flag(int flag)
#ifdef Libisofs_with_libjtE
/* Ugly compile time check for header version compatibility.
If everthing matches, then it produces no C code. In case of mismatch,
If everything matches, then it produces no C code. In case of mismatch,
intentionally faulty C code will be inserted.
*/
/* The indendation is an advise of man gcc to help old compilers ignoring */
@ -380,7 +380,7 @@ const char *iso_error_to_msg(int errcode)
case ISO_DATA_SOURCE_MISHAP:
case ISO_DATA_SOURCE_FAILURE:
case ISO_DATA_SOURCE_FATAL:
return "Read error occured with IsoDataSource";
return "Read error occurred with IsoDataSource";
case ISO_AAIP_IGNORED:
return "AAIP info with ACL or xattr in ISO image will be ignored";
case ISO_AAIP_BAD_ACL:
@ -543,6 +543,18 @@ const char *iso_error_to_msg(int errcode)
return "A general note message was issued";
case ISO_BAD_FSRC_FILETYPE:
return "Unrecognized file type of IsoFileSrc object";
case ISO_GPT_NO_VOL_UUID:
return "Cannot derive GPT GUID from undefined pseudo-UUID volume timestamp";
case ISO_BAD_GPT_GUID_MODE:
return "Unrecognized GPT disk GUID setup mode";
case ISO_NO_ROOT_DIR:
return "Unable to obtain root directory";
case ISO_SUSP_WRONG_CE_SIZE:
return "Zero sized, oversized, or mislocated SUSP CE area found";
case ISO_MULTI_OVER_IMPORTED:
return "Multi-session would overwrite imported_iso interval";
case ISO_ELTO_EFI_HIDDEN:
return "El-Torito EFI image is hidden";
default:
return "Unknown error";
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2015 Thomas Schmitt
* Copyright (c) 2009 - 2016 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -1114,7 +1114,7 @@ int iso_symlink_set_dest(IsoSymlink *link, const char *dest)
* or regular files, this function has no effect.
* @param w
* The weight as a integer number, the greater this value is, the
* closer from the begining of image the file will be written.
* closer from the beginning of image the file will be written.
*/
void iso_node_set_sort_weight(IsoNode *node, int w)
{
@ -1365,7 +1365,11 @@ int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos,
/* old file is newer */
return ISO_NODE_NAME_NOT_UNIQUE;
}
/* fall down */
if ((node->mode & S_IFMT) != ((*pos)->mode & S_IFMT)) {
/* different file types */
return ISO_NODE_NAME_NOT_UNIQUE;
}
break;
case ISO_REPLACE_IF_SAME_TYPE:
if ((node->mode & S_IFMT) != ((*pos)->mode & S_IFMT)) {
/* different file types */
@ -1818,12 +1822,13 @@ int attr_enlarge_list(char ***names, size_t **value_lengths, char ***values,
/* Merge attribute list of node and given new attribute list into
attribute list returned by m_* parameters.
The m_* paramters have finally to be freed by a call with bit15 set.
The m_* parameters have finally to be freed by a call with bit15 set.
@param flag Bitfield for control purposes
bit0= delete all old names which begin by "user."
(but not if bit2 is set)
bit2= delete the given names rather than overwrite
their content
bit3= with bit0: delete all old non-"isofs." names
bit4= do not overwrite value of empty name
bit5= do not overwrite isofs attributes
bit15= release memory and return 1
@ -1849,9 +1854,11 @@ int iso_node_merge_xattr(IsoNode *node, size_t num_attrs, char **names,
return ret;
if ((flag & 1) && (!(flag & 4))) {
/* Delete unmatched user space pairs */
/* Delete unmatched settable pairs */
for (j = 0; j < *m_num_attrs; j++) {
if (strncmp((*m_names)[j], "user.", 5) != 0)
if (strncmp((*m_names)[j], "isofs.", 6) == 0)
continue;
if (strncmp((*m_names)[j], "user.", 5) != 0 && !(flag & 8))
continue;
for (i = 0; i < num_attrs; i++) {
if (names[i] == NULL || (*m_names)[j] == NULL)
@ -1980,7 +1987,7 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
node, num_attrs, names, value_lengths, values,
&m_num, &m_names, &m_value_lengths, &m_values,
(flag & 4) | (!(flag & 2)) | ((!(flag & 1)) << 4) |
((flag & 16) << 1));
((flag & 16) << 1) | (flag & 8));
if (ret < 0)
goto ex;
num_attrs = m_num;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2016 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -487,7 +487,7 @@ int iso_node_cmp_flag(IsoNode *n1, IsoNode *n2, int flag);
/**
* Set the checksum index (typically comming from IsoFileSrc.checksum_index)
* Set the checksum index (typically coming from IsoFileSrc.checksum_index)
* of a regular file node. The index is encoded as xattr "isofs.cx" with
* four bytes of value.
*/

View File

@ -254,7 +254,7 @@ typedef struct susp_iterator SuspIterator;
SuspIterator *
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
uint8_t len_skp, int msgid);
uint32_t fs_blocks, uint8_t len_skp, int msgid);
/**
* Get the next SUSP System User Entry using given iterator.
@ -266,7 +266,8 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
* @return
* 1 on success, 0 if no more entries, < 0 error
*/
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue);
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
int flag);
/**
* Free a given susp iterator.

View File

@ -35,6 +35,9 @@ struct susp_iterator
IsoDataSource *src;
int msgid;
/* Number of blocks in the ISO 9660 filesystem */
uint32_t fs_blocks;
/* block and offset for next continuation area */
uint32_t ce_block;
uint32_t ce_off;
@ -47,7 +50,7 @@ struct susp_iterator
SuspIterator*
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
uint8_t len_skp, int msgid)
uint32_t fs_blocks, uint8_t len_skp, int msgid)
{
int pad = (record->len_fi[0] + 1) % 2;
struct susp_iterator *iter = malloc(sizeof(struct susp_iterator));
@ -60,6 +63,7 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
iter->size = record->len_dr[0] - record->len_fi[0] - 33 - pad;
iter->src = src;
iter->msgid = msgid;
iter->fs_blocks = fs_blocks;
iter->ce_len = 0;
iter->buffer = NULL;
@ -67,12 +71,30 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
return iter;
}
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
/* More than 1 MiB in a single file's CE area is suspicious */
#define ISO_SUSP_MAX_CE_BYTES (1024 * 1024)
/* @param flag bit0 = First call on root:
Not yet clear whether this is SUSP at all
*/
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
int flag)
{
struct susp_sys_user_entry *entry;
entry = (struct susp_sys_user_entry*)(iter->base + iter->pos);
if (flag & 1) {
/* Yet unclear whether it is SUSP at all */
if (iter->size < 7)
return 0;
if (!SUSP_SIG(entry, 'S', 'P'))
return 0;
if (entry->len_sue[0] < 7)
return 0;
/* Looks like SUSP enough to pass the further processing here. */
}
if ( (iter->pos + 4 > iter->size) || (SUSP_SIG(entry, 'S', 'T'))) {
/*
@ -81,22 +103,31 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
* (IEEE 1281, SUSP. section 4)
*/
if (iter->ce_len) {
uint32_t block, nblocks;
uint32_t block, nblocks, skipped_blocks, skipped_bytes;
/* A CE has found, there is another continuation area */
nblocks = DIV_UP(iter->ce_off + iter->ce_len, BLOCK_SIZE);
/* A CE was found, there is another continuation area */
skipped_blocks = iter->ce_off / BLOCK_SIZE;
skipped_bytes = skipped_blocks * BLOCK_SIZE;
nblocks = DIV_UP(iter->ce_off - skipped_bytes + iter->ce_len,
BLOCK_SIZE);
if (nblocks <= 0 || iter->ce_len > ISO_SUSP_MAX_CE_BYTES)
return ISO_SUSP_WRONG_CE_SIZE;
if (((uint64_t) iter->ce_block) + skipped_blocks + nblocks >
(uint64_t) iter->fs_blocks)
return ISO_SUSP_WRONG_CE_SIZE;
iter->buffer = realloc(iter->buffer, nblocks * BLOCK_SIZE);
/* read all blocks needed to cache the full CE */
/* Read blocks needed to cache the given CE area range */
for (block = 0; block < nblocks; ++block) {
int ret;
ret = iter->src->read_block(iter->src, iter->ce_block + block,
iter->buffer + block * BLOCK_SIZE);
ret = iter->src->read_block(iter->src,
iter->ce_block + skipped_blocks + block,
iter->buffer + block * BLOCK_SIZE);
if (ret < 0) {
return ret;
}
}
iter->base = iter->buffer + iter->ce_off;
iter->base = iter->buffer + (iter->ce_off - skipped_bytes);
iter->pos = 0;
iter->size = iter->ce_len;
iter->ce_len = 0;
@ -134,10 +165,10 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
}
/* we don't want to return CE entry to the user */
return susp_iter_next(iter, sue);
return susp_iter_next(iter, sue, 0);
} else if (SUSP_SIG(entry, 'P', 'D')) {
/* skip padding */
return susp_iter_next(iter, sue);
return susp_iter_next(iter, sue, 0);
}
*sue = entry;
@ -374,12 +405,18 @@ int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont)
if (*cont == 1) {
/* new component */
size_t size = strlen(*dest);
int has_slash;
*dest = realloc(*dest, strlen(*dest) + len + 2);
if (*dest == NULL) {
return ISO_OUT_OF_MEM;
}
/* it is a new compoenent, add the '/' */
if ((*dest)[size-1] != '/') {
has_slash = 0;
if (size > 0)
if ((*dest)[size - 1] == '/')
has_slash = 1;
if (!has_slash) {
(*dest)[size] = '/';
(*dest)[size+1] = '\0';
}
@ -462,24 +499,27 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
if (*is_done) {
/* To coexist with Apple ISO :
Gracefully react on eventually trailing Apple AA
Gracefully react on possibly trailing Apple AA
*/
if (sue->version[0] != 1 || sue->len_sue[0] == 7)
return ISO_SUCCESS;
return ISO_WRONG_RR;
}
/* Eventually create or grow storage */
if (*aa_size == 0 || *aa_string == NULL) {
/* Gracefully react on eventually leading Apple AA
/* Gracefully react on possibly leading Apple AA
*/
if (sue->version[0] != 1 || sue->len_sue[0] < 9) {
if (sue->version[0] != 1 || sue->len_sue[0] < 9)
return ISO_SUCCESS;
}
}
/* A valid AAIP AA entry has 5 header bytes and at least 1 component byte
*/
if (sue->len_sue[0] < 6)
return ISO_WRONG_RR;
/* Possibly create or grow storage */
if (*aa_size == 0 || *aa_string == NULL) {
*aa_size = *aa_len + sue->len_sue[0];
*aa_string = calloc(*aa_size, 1);
*aa_len = 0;
@ -535,7 +575,12 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
if (sue->version[0] != 1)
return ISO_WRONG_RR;
/* Eventually create or grow storage */
/* A valid AL entry has 5 header bytes and at least 1 component byte
*/
if (sue->len_sue[0] < 6)
return ISO_WRONG_RR;
/* Possibly create or grow storage */
if (*aa_size == 0 || *aa_string == NULL) {
*aa_size = *aa_len + sue->len_sue[0];
*aa_string = calloc(*aa_size, 1);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2016 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -41,7 +41,7 @@ void iso_stream_get_file_name(IsoStream *stream, char *name);
* take an extra ref.
*
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
* Possible errors:
*
*/
@ -52,7 +52,7 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream);
* The stream will add a ref. to the IsoFileSource.
*
* @return
* 1 sucess, < 0 error
* 1 success, < 0 error
*/
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
IsoStream **stream);

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2010 - 2015 Thomas Schmitt
* Copyright (c) 2010 - 2018 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -108,11 +108,14 @@ void iso_compute_cyl_head_sec(uint64_t img_blocks, int hpc, int sph,
}
/* @param flag bit0= The path contains instructions for the interval reader
@return ISO_SUCCESS = ok, partition will be written
ISO_SUCCESS + 1 = interval which shall be kept in place
else : error code
*/
static int compute_partition_size(Ecma119Image *t, char *disk_path,
uint32_t *size, int flag)
{
int ret;
int ret, keep;
off_t num;
struct stat stbuf;
struct iso_interval_reader *ivr;
@ -124,8 +127,11 @@ static int compute_partition_size(Ecma119Image *t, char *disk_path,
if (ret < 0)
return ret;
*size = (byte_count + BLOCK_SIZE - 1) / BLOCK_SIZE;
keep = iso_interval_reader_keep(t, ivr, 0);
iso_interval_reader_destroy(&ivr, 0);
return ISO_SUCCESS;
if (keep < 0)
return keep;
return ISO_SUCCESS + (keep > 0);
}
*size = 0;
@ -148,6 +154,7 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
{
int ret, i, sa_type, cyl_align, cyl_size = 0;
uint32_t pos, size, add_pos = 0;
off_t start_byte, byte_count;
sa_type = (t->system_area_options >> 2) & 0x3f;
cyl_align = (t->system_area_options >> 8) & 0x3;
@ -158,7 +165,17 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
else
cyl_size /= 4;
}
#ifdef Libisofs_appended_partitions_inlinE
pos = t->curblock;
#else
pos = (t->vol_space_size + t->opts->ms_block);
#endif
for (i = 0; i < ISO_MAX_PARTITIONS; i++) {
if (t->opts->appended_partitions[i] == NULL)
continue;
@ -168,6 +185,20 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
t->opts->appended_part_flags[i]);
if (ret < 0)
return ret;
if (ret == ISO_SUCCESS + 1) {
/* Interval from imported_iso in add-on session */
t->appended_part_prepad[i] = 0;
ret = iso_interval_reader_start_size(t,
t->opts->appended_partitions[i],
&start_byte, &byte_count, 0);
if (ret < 0)
return ret;
t->appended_part_start[i] = start_byte / 2048;
t->appended_part_size[i] = size;
t->opts->iso_mbr_part_type = 0;
continue;
}
add_pos = 0;
if (sa_type == 3 && (pos % ISO_SUN_CYL_SIZE)) {
add_pos = ISO_SUN_CYL_SIZE - (pos % ISO_SUN_CYL_SIZE);
@ -184,7 +215,7 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
}
t->appended_part_size[i] = size;
pos += add_pos + size;
t->total_size += (add_pos + size) * 2048;
t->total_size += (((off_t) add_pos) + size) * 2048;
if (flag & 1)
t->curblock = pos;
}
@ -192,6 +223,19 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag)
}
static int mbr_part_slot_is_unused(uint8_t *slot)
{
int i;
for (i = 0; i < 16; i++)
if (slot[i] != 0)
break;
if (i >= 16)
return 1;
return 0;
}
/* @param flag
bit1= partition_offset and partition_size are counted in
blocks of 512 rather than 2048
@ -287,7 +331,7 @@ int make_grub_msdos_label(uint32_t img_blocks, int sph, int hpc,
buf[510] = 0x55;
buf[511] = 0xAA;
}
if (!(flag & 2)) {
if ((!(flag & 2)) && part_type != 0xee && part_type != 0xef) {
/* 3) Put 0x80 (for bootable partition), */
*(wpt++) = 0x80;
} else {
@ -993,6 +1037,24 @@ int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
}
static int iso_find_gpt_entry(struct iso_gpt_partition_request **req_array,
int gpt_req_count,
uint64_t start_block, uint64_t block_count,
int *index, int flag)
{
struct iso_gpt_partition_request *entry;
for (*index = 0; *index < gpt_req_count; (*index)++) {
entry = req_array[*index];
if (entry->start_block == start_block &&
entry->block_count == block_count)
return 1;
}
*index = -1;
return 0;
}
/* Convenience frontend for iso_register_gpt_entry().
name has to be already encoded as UTF-16LE.
*/
@ -1187,6 +1249,9 @@ static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
qsort(t->apm_req, t->apm_req_count,
sizeof(struct iso_apm_partition_request *), cmp_partition_request);
if (t->opts->part_like_isohybrid)
return 1; /* No filling, only sorting */
/* t->apm_req_count will grow during the loop */
up_to = t->apm_req_count + 1;
for (i = 1; i < up_to; i++) {
@ -1455,8 +1520,12 @@ static void iso_write_gpt_entry(Ecma119Image *t, uint8_t *buf,
for (i = 0; i < 16; i++)
if (part_uuid[i])
break;
if (i == 16)
iso_random_uuid(t, part_uuid);
if (i == 16) {
if (!t->gpt_disk_guid_set)
iso_gpt_uuid(t, t->gpt_disk_guid);
t->gpt_disk_guid_set = 1;
iso_gpt_uuid(t, part_uuid);
}
memcpy(wpt, part_uuid, 16);
wpt += 16;
iso_lsb_to_buf(&wpt, start_lba & 0xffffffff, 4, 0);
@ -1517,9 +1586,8 @@ int iso_write_gpt_header_block(Ecma119Image *t, uint32_t img_blocks,
(uint32_t) ((back_lba - max_entries / 4 - 1) >> 32), 4, 1);
/* Disk GUID */
/* >>> Make adjustable */
if (!t->gpt_disk_guid_set)
iso_random_uuid(t, t->gpt_disk_guid);
iso_gpt_uuid(t, t->gpt_disk_guid);
t->gpt_disk_guid_set = 1;
memcpy(wpt, t->gpt_disk_guid, 16);
wpt += 16;
@ -1567,6 +1635,69 @@ void iso_ascii_utf_16le(uint8_t gap_name[72])
}
static int intvl_overlap(uint64_t start1, uint64_t end1,
uint64_t start2, uint64_t end2, int second)
{
if (start1 >= start2 && start1 <= end2)
return 1;
if (end1 >= start2 && end1 <= end2)
return 1;
if (!second)
return intvl_overlap(start2, end2, start1, end1, 1);
return 0;
}
/* Check APM HFS+ partitions whether they would fit in gaps.
If so, add them as GPT partitions, too.
*/
static int iso_copy_apmhfs_to_gpt(Ecma119Image *t, int flag)
{
int a, i, counter = 0, ret;
uint64_t bfac = 4;
static uint8_t hfs_plus_uuid[16] = {
0x00, 0x53, 0x46, 0x48, 0x00, 0x00, 0xaa, 0x11,
0xaa, 0x11, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac
};
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint8_t gpt_name[72];
static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1;
if ((t->apm_req_flags & 4) && t->opts->apm_block_size / 512 > 0)
bfac = t->opts->apm_block_size / 512;
for (a = 0; a < t->apm_req_count; a++) {
if (strcmp((char *) t->apm_req[a]->type, "Apple_HFS") != 0)
continue;
for (i = 0; i < t->gpt_req_count; i++)
if (intvl_overlap(t->apm_req[a]->start_block * bfac,
(t->apm_req[a]->start_block +
t->apm_req[a]->block_count - 1) * bfac,
t->gpt_req[i]->start_block,
t->gpt_req[i]->start_block +
t->gpt_req[i]->block_count - 1, 0))
break;
if (i >= t->gpt_req_count) {
memset(gpt_name, 0, 72);
counter++;
if (counter > 1)
sprintf((char *) gpt_name, "HFSPLUS_%d", counter);
else
sprintf((char *) gpt_name, "HFSPLUS");
iso_ascii_utf_16le(gpt_name);
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
t->apm_req[a]->start_block * bfac,
t->apm_req[a]->block_count * bfac,
hfs_plus_uuid, zero_uuid,
gpt_flags, gpt_name);
if (ret < 0)
return ret;
}
}
return 1;
}
static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
{
static uint8_t basic_data_uuid[16] = {
@ -1586,6 +1717,10 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
return 2;
backup_end_lba = ((uint64_t) t->gpt_backup_end - t->gpt_backup_size) * 4;
ret = iso_copy_apmhfs_to_gpt(t, 0);
if (ret <= 0)
return ret;
/* Sort and fill gaps */
qsort(t->gpt_req, t->gpt_req_count,
sizeof(struct iso_gpt_partition_request *), cmp_partition_request);
@ -1593,6 +1728,10 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
up_to = t->gpt_req_count + 1;
goal = 0;
part_end = 0;
if (t->opts->part_like_isohybrid)
up_to = 0; /* No gap filling */
for (i = 0; i < up_to; i++) {
if (i < up_to - 1) {
goal = t->gpt_req[i]->start_block;
@ -1671,12 +1810,40 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
}
/* Add a dummy MBR partition of type 0 with boot flag */
static void iso_dummy_mbr_partition(uint8_t *buf, int mode)
{
int i;
/* bootable , start 0/0/1, type 0x00, end 0/0/1,
start LBA 0, block count 1 */
static uint8_t dummy_entry[16] = {
0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };
for (i = 0; i < 4; i++) {
if (mbr_part_slot_is_unused(buf + 446 + 16 * i)) {
memcpy(buf + 446 + 16 * i, dummy_entry, 16);
return;
}
}
/* Abundance of 0xee and 0xef partitions. No other one free. */
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] != 0xef) {
buf[446 + 16 * i] |= 0x80;
return;
}
}
i = 3;
buf[446 + 16 * i] |= 0x80;
}
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
{
int ret, int_img_blocks, sa_type, i, will_append = 0, do_isohybrid = 0;
int first_partition = 1, last_partition = 4, apm_flag, part_type = 0;
int gpt_count = 0, gpt_idx[128], apm_count = 0, no_boot_mbr = 0;
int offset_flag = 0;
int offset_flag = 0, risk_of_ee = 0;
uint32_t img_blocks, gpt_blocks, mbrp1_blocks, pml_blocks;
uint64_t blk;
uint8_t *wpt;
@ -1699,7 +1866,12 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
break;
}
#ifdef Libisofs_appended_partitions_inlinE
img_blocks = t->vol_space_size;
#else
img_blocks = t->curblock;
#endif
if (t->system_area_data != NULL) {
/* Write more or less opaque boot image */
memcpy(buf, t->system_area_data, 16 * BLOCK_SIZE);
@ -1709,6 +1881,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* Check for isolinux image with magic number of 3.72 and produce
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
*/
if (t->bootsrc[0] == NULL)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem.");
if (img_blocks < 0x80000000) {
int_img_blocks= img_blocks;
} else {
@ -1767,8 +1942,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
"Cannot set up MBR partition table");
return ret;
}
if (t->mbr_req_count > 0 && sa_type != 0)
return ISO_NON_MBR_SYS_AREA;
if (t->mbr_req_count > 0) {
if (sa_type != 0)
return ISO_NON_MBR_SYS_AREA;
risk_of_ee = 1;
}
if (t->gpt_backup_outside)
gpt_blocks = t->total_size / BLOCK_SIZE + t->opts->ms_block;
@ -1784,11 +1962,14 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (t->mbr_req_count == 0){
/* Write GRUB protective msdos label, i.e. a simple partition
table */
if (t->gpt_req_count > 0) {
if (t->gpt_req_count > 0 && ! t->opts->part_like_isohybrid) {
part_type = 0xee;
pml_blocks = gpt_blocks;
} else {
part_type = 0xcd;
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
pml_blocks = img_blocks;
}
ret = make_grub_msdos_label(pml_blocks, t->partition_secs_per_head,
@ -1796,6 +1977,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
(uint8_t) part_type, buf, 0);
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
risk_of_ee = 1;
} else if (t->gpt_req_count > 0) {
/* >>> ??? change first partition type to 0xee */;
}
} else if (do_isohybrid) {
/* Patch externally provided system area as isohybrid MBR */
@ -1808,11 +1994,16 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (gpt_count > 0 || apm_count > 0)
part_type = 0x00;
else
else {
part_type = 0x17;
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
}
if (t->opts->appended_as_gpt && t->have_appended_partitions) {
part_type = 0xee;
risk_of_ee = 1;
img_blocks = gpt_blocks;
no_boot_mbr = 2;
}
@ -1850,14 +2041,23 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
} else if ((t->opts->partition_offset > 0 || will_append) &&
sa_type == 0 && t->mbr_req_count == 0) {
/* Write a simple partition table. */
part_type = 0xcd;
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
t->partition_heads_per_cyl,
(uint8_t) 0xcd, buf, 2);
(uint8_t) part_type, buf, 2);
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
risk_of_ee = 1;
if (t->opts->appended_as_gpt && t->have_appended_partitions) {
/* >>> ??? Do this in any case of t->gpt_req_count > ? */;
/* Re-write partion entry 1 : protective MBR for GPT */
part_type = 0xee;
risk_of_ee = 1;
ret = write_mbr_partition_entry(1, part_type,
(uint64_t) 1, ((uint64_t) gpt_blocks) * 4 - 1,
t->partition_secs_per_head, t->partition_heads_per_cyl,
@ -1867,7 +2067,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
} else if (t->opts->partition_offset == 0) {
/* Re-write partion entry 1 : start at 0, type Linux */
blk = ((uint64_t) img_blocks) * 4 - t->post_iso_part_pad / 512;
ret = write_mbr_partition_entry(1, 0x83, (uint64_t) 0, blk,
part_type = 0x83;
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
ret = write_mbr_partition_entry(1, part_type, (uint64_t) 0, blk,
t->partition_secs_per_head, t->partition_heads_per_cyl,
buf, 2);
if (ret < 0)
@ -1880,8 +2084,18 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* Adjust partition table to partition offset.
With t->mbr_req_count > 0 this has already been done,
*/
img_blocks = t->curblock; /* value might be altered */
if (part_type == 0xee) {
#ifndef Libisofs_appended_partitions_inlinE
img_blocks = t->curblock; /* value might have been altered */
#else
/* A change of t->curblock does not matter in this case */
#endif
if (part_type == 0xee && t->gpt_req_count > 0) {
mbrp1_blocks = t->total_size / BLOCK_SIZE + t->opts->ms_block;
offset_flag |= 2 | 1; /* protective MBR, no other partitions */
} else {
@ -1926,6 +2140,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (sa_type == 0 && (t->system_area_options & 0x4000) && !do_isohybrid) {
/* Patch MBR for GRUB2 */
if (t->bootsrc[0] == NULL)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Cannot refer by GRUB2 MBR to data outside of ISO 9660 filesystem.");
blk = t->bootsrc[0]->sections[0].block * 4 +
Libisofs_grub2_mbr_patch_offsT;
wpt = buf + Libisofs_grub2_mbr_patch_poS;
@ -1933,6 +2150,65 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
wpt[i] = blk >> (i * 8);
}
/* Prevent partition type 0xee if no GPT emerged */
/* >>> ??? check for GPT magic number at byte 512 ff. ? */;
if (sa_type == 0 && ((t->system_area_options & 3) || risk_of_ee) &&
(t->opts->part_like_isohybrid || t->gpt_req_count == 0) &&
t->opts->iso_mbr_part_type != 0xee) {
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] == 0xee) {
iso_msgs_submit(0,
"Prevented partition type 0xEE in MBR without GPT",
0, "WARNING", 0);
part_type = 0xcd;
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
buf[446 + 16 * i + 4] = (uint8_t) part_type;
}
}
}
if (sa_type == 0 && (
(t->system_area_options & 3) ||
(t->system_area_options & (1 << 14)) ||
(((t->system_area_options >> 10) & 15) != 1 &&
(t->system_area_options & (1 << 15)))
)) {
/* This is an MBR which shall have a bootable/active flag
protective-msdos-label, isohybrid, grub2-mbr, mbr-force-bootable
*/
for (i = 0; i < 4; i++)
if (buf[446 + 16 * i] & 0x80)
break;
if (i >= 4) { /* no bootable/active flag set yet */
for (i = 0; i < 4; i++) {
if ((!mbr_part_slot_is_unused(buf + 446 + 16 * i)) &&
buf[446 + 16 * i + 4] != 0xee &&
buf[446 + 16 * i + 4] != 0xef) {
buf[446 + 16 * i] |= 0x80;
break;
}
}
if (i >= 4) { /* still no bootable/active flag set */
if (t->system_area_options & (1 << 15)) /* Force it */
iso_dummy_mbr_partition(buf, 0);
}
}
}
if ((((t->system_area_options >> 2) & 0x3f) == 0 &&
(t->system_area_options & 3) == 1) ||
t->opts->partition_offset > 0) {
/* Protective MBR || partition offset
ISO will not be a partition or add-on session.
It can span the whole image.
*/
t->pvd_size_is_total_size = 1;
}
return ISO_SUCCESS;
}
@ -1972,6 +2248,10 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
off_t imgsize, cylsize = 0, frac;
char *msg = NULL;
#ifdef Libisofs_part_align_writeR
int fap, lap, app_part_count;
#endif
LIBISO_ALLOC_MEM(msg, char, 160);
sa_type = (t->system_area_options >> 2) & 0x3f;
if (sa_type != 0)
@ -1985,7 +2265,22 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
goto ex;
}
#ifdef Libisofs_part_align_writeR
/* If partitions get appended then t->opts->tail_blocks and
t->gpt_backup_size come after the alignment padding.
*/
app_part_count = iso_count_appended_partitions(t, &fap, &lap);
img_blocks = t->curblock;
if (app_part_count == 0)
img_blocks += t->opts->tail_blocks + t->gpt_backup_size;
#else
img_blocks = t->curblock + t->opts->tail_blocks + t->gpt_backup_size;
#endif
imgsize = ((off_t) img_blocks) * (off_t) 2048;
if ((!(t->opts->appended_as_gpt && t->have_appended_partitions))
&& ((t->system_area_options & 3) || always_align)
@ -2064,7 +2359,17 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
t->post_iso_part_pad);
iso_msgs_submit(0, msg, 0, "WARNING", 0);
}
#ifdef Libisofs_part_align_writeR
t->part_align_blocks = (frac + 2047) / 2048;
#else
t->opts->tail_blocks += (frac + 2047) / 2048;
#endif /* ! Libisofs_part_align_writeR */
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(msg);
@ -2173,72 +2478,73 @@ uint32_t iso_crc32_gpt(unsigned char *data, int count, int flag)
return result ^ 0xffffffff;
}
void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16])
void iso_mark_guid_version_4(uint8_t *u)
{
/* Mark as UUID version 4. RFC 4122 says u[6], but UEFI prescribes
bytes 6 and 7 to be swapped.
*/
u[7] = (u[7] & 0x0f) | 0x40;
/* Variant is "1 0 x" as described in RFC 4122.
*/
u[8] = (u[8] & 0x3f) | 0x80;
return;
}
void iso_generate_gpt_guid(uint8_t guid[16])
{
#ifdef Libisofs_with_uuid_generatE
uuid_t u;
uuid_generate(u);
swap_uuid((void *) u);
memcpy(guid, u, 16);
#else
uint8_t u[16];
/* produced by uuid_generate() and byte-swapped to isohybrid.c habits */
uint8_t *u;
/* produced by uuid_generate() and byte-swapped to UEFI specs */
static uint8_t uuid_template[16] = {
0xee, 0x29, 0x9d, 0xfc, 0x65, 0xcc, 0x7c, 0x40,
0x92, 0x61, 0x5b, 0xcd, 0x6f, 0xed, 0x08, 0x34
};
static uint8_t uuid_urandom[16];
uint32_t rnd, salt;
struct timeval tv;
struct timezone tz;
pid_t pid;
static int counter = 0, use_urandom = 0;
int i, ret, fd;
#endif
#ifdef Libisofs_with_uuid_generatE
u = guid;
uuid_generate(u);
swap_uuid((void *) u);
memcpy(uuid, u, 16);
#else
/* First try /dev/urandom.
(Weakening the result by 8 bit saves a lot of pool entropy.)
/* First try /dev/urandom
*/
if ((counter & 0xff) == 0) {
fd = open("/dev/urandom", O_RDONLY | O_BINARY);
if (fd == -1)
goto fallback;
ret = read(fd, uuid_urandom, 16);
if (ret != 16) {
close(fd);
goto fallback;
}
/* Mark as UUID version 4 */
uuid_urandom[7] = (uuid_urandom[7] & 0x0f) | 0x40;
uuid_urandom[8] = (uuid_urandom[8] & 0x3f) | 0x80;
close(fd);
use_urandom = 1;
}
if (!use_urandom)
fd = open("/dev/urandom", O_RDONLY | O_BINARY);
if (fd == -1)
goto fallback;
memcpy(uuid, uuid_urandom, 16);
uuid[9] ^= counter & 0xff;
counter++;
ret = read(fd, u, 16);
if (ret != 16) {
close(fd);
goto fallback;
}
close(fd);
iso_mark_guid_version_4(u);
return;
fallback:;
pid = getpid();
salt = iso_crc32_gpt((unsigned char *) t, sizeof(Ecma119Image), 0) ^ pid;
salt = iso_crc32_gpt((unsigned char *) &guid, sizeof(uint8_t *), 0) ^ pid;
/* This relies on the uniqueness of the template and the rareness of
bootable ISO image production via libisofs. Estimated 53 bits of
bootable ISO image production via libisofs. Estimated 48 bits of
entropy should influence the production of a single day.
So first collisions are to be expected with about 100 million images
So first collisions are to be expected with about 16 million images
per day.
*/
memcpy(u, uuid_template, 16);
gettimeofday(&tv, &tz);
gettimeofday(&tv, NULL);
for (i = 0; i < 4; i++)
u[i] = (salt >> (8 * i)) & 0xff;
for (i = 0; i < 2; i++)
@ -2246,19 +2552,36 @@ fallback:;
u[6] = ((salt >> 8) ^ (pid >> 16)) & 0xff;
rnd = ((0xffffff & tv.tv_sec) << 8) |
(((tv.tv_usec >> 16) ^ (salt & 0xf0)) & 0xff);
u[9] ^= counter & 0xff;
for (i = 0; i < 4; i++)
u[10 + i] ^= (rnd >> (8 * i)) & 0xff;
u[14] ^= (tv.tv_usec >> 8) & 0xff;
u[15] ^= tv.tv_usec & 0xff;
counter++;
memcpy(uuid, u, 16);
iso_mark_guid_version_4(u);
return;
#endif /* ! Libisofs_with_uuid_generatE */
}
void iso_gpt_uuid(Ecma119Image *t, uint8_t uuid[16])
{
if (t->gpt_uuid_counter == 0)
iso_generate_gpt_guid(t->gpt_uuid_base);
memcpy(uuid, t->gpt_uuid_base, 16);
/* Previous implementation changed only byte 9. So i expand it by applying
the counter in little-endian style.
*/
uuid[9] ^= t->gpt_uuid_counter & 0xff;
uuid[10] ^= (t->gpt_uuid_counter >> 8) & 0xff;
uuid[11] ^= (t->gpt_uuid_counter >> 16) & 0xff;
uuid[12] ^= (t->gpt_uuid_counter >> 24) & 0xff;
t->gpt_uuid_counter++;
return;
}
int assess_appended_gpt(Ecma119Image *t, int flag)
{
static uint8_t basic_data_uuid[16] = {
@ -2270,7 +2593,7 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
};
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int i, ret;
int i, ret, do_apm = 0, do_gpt = 0, index, already_in_gpt = 0;
uint8_t gpt_name[72], *type_uuid;
#ifndef Libisofs_appended_partitions_inlinE
@ -2278,31 +2601,51 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
return 2;
#endif
/* Represent in GPT only if other GPT partitions are already registered
or if appended partitions are explicitely desired for GPT-only.
*/
if (t->gpt_req_count == 0 &&
!(t->have_appended_partitions && t->opts->appended_as_gpt))
return 2;
if ((t->apm_req_count > 0 && t->opts->part_like_isohybrid) ||
(t->have_appended_partitions && t->opts->appended_as_apm))
do_apm = 1;
if (t->gpt_req_count > 0 ||
(t->have_appended_partitions && t->opts->appended_as_gpt))
do_gpt = 1;
if (do_apm == 0 && do_gpt == 0)
return 2;
/* Represent appended partitions */
for (i = 0; i <= 3; i++) {
if (t->opts->appended_partitions[i] == NULL)
continue;
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "Appended%d", i + 1);
iso_ascii_utf_16le(gpt_name);
if (t->opts->appended_part_types[i] == 0xef)
type_uuid = efi_sys_uuid;
else
type_uuid = basic_data_uuid;
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
if (do_apm) {
memset(gpt_name, 0, 32);
sprintf((char *) gpt_name, "Appended%d", i + 1);
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
t->appended_part_start[i] * t->hfsp_iso_block_fac,
t->appended_part_size[i] * t->hfsp_iso_block_fac,
(char *) gpt_name, "Data");
if (ret < 0)
return ret;
}
if (do_gpt)
already_in_gpt = iso_find_gpt_entry(t->gpt_req, t->gpt_req_count,
((uint64_t) t->appended_part_start[i]) * 4,
((uint64_t) t->appended_part_size[i]) * 4,
&index, 0);
if (do_gpt && !already_in_gpt) {
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "Appended%d", i + 1);
iso_ascii_utf_16le(gpt_name);
if (t->opts->appended_part_types[i] == 0xef)
type_uuid = efi_sys_uuid;
else
type_uuid = basic_data_uuid;
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
((uint64_t) t->appended_part_start[i]) * 4,
((uint64_t) t->appended_part_size[i]) * 4,
type_uuid, zero_uuid,
(uint64_t) 0, gpt_name);
if (ret < 0)
return ret;
if (ret < 0)
return ret;
}
}
return ISO_SUCCESS;
}
@ -2341,6 +2684,23 @@ static int precompute_gpt(Ecma119Image *t)
return ret;
}
/* With part_like_isohybrid:
If no GPT is registered yet, and MBR, but neither CHRP nor ISOLINUX
isohybrid is desired, then try to apply the isohybrid GPT and APM flags
nevertheless. Avoid an overall ISO image GPT partition.
*/
if (t->opts->part_like_isohybrid && t->gpt_req_count <= 0 &&
((t->system_area_options >> 2) & 0x3f) == 0 &&
((t->system_area_options >> 10) & 0xf) != 1 &&
(!(t->system_area_options & 2))) {
ret = assess_isohybrid_gpt_apm(t, &gpt_count, gpt_idx, &apm_count,
1 | ((t->apm_req_count > 0) << 1) | 4);
if (ret <= 0)
return ret;
t->apm_req_flags |= 2; /* Do not fill APM gaps,
do not adjust final APM partition size */
}
/* Rectify APM requests early in order to learn the size of GPT.
iso_write_apm() relies on this being already done here.
@ -2579,10 +2939,12 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
{
Ecma119Image *t;
IsoFileSrc *src;
int ret, will_have_gpt = 0, with_chrp = 0, i;
int ret, will_have_gpt = 0, with_chrp = 0, i, part_type, keep;
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1;
uint8_t gpt_name[72];
uint64_t part_start;
off_t start_byte, byte_count;
/* <<< ??? Move to system_area.h and publish as macro ? */
static uint8_t efi_sys_uuid[16] = {
@ -2596,11 +2958,11 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
with_chrp = ((t->system_area_options & 0x3cff) == 0x0400);
if (t->opts->efi_boot_partition != NULL ||
(t->opts->hfsplus && !with_chrp) ||
t->gpt_req_count > 0)
t->gpt_req_count > 0) /* Might not catch all cases with GPT */
will_have_gpt = 1;
if (t->opts->efi_boot_partition != NULL) {
keep = 0;
if (t->efi_boot_part_filesrc != NULL) {
/* A file in the emerging ISO image shall store its content
as prepended partition.
@ -2612,23 +2974,35 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
src->sections[i].block = t->curblock + t->efi_boot_part_size;
t->efi_boot_part_size += (src->sections[i].size + 2047) / 2048;
}
part_start = t->curblock * 4;
} else {
ret = compute_partition_size(t, t->opts->efi_boot_partition,
&(t->efi_boot_part_size),
t->opts->efi_boot_part_flag & 1);
if (ret < 0)
return ret;
part_start = t->curblock * 4;
if (ret == ISO_SUCCESS + 1) {
/* Interval from imported_iso in add-on session will be kept */
ret = iso_interval_reader_start_size(t,
t->opts->efi_boot_partition,
&start_byte, &byte_count, 0);
if (ret < 0)
return ret;
part_start = start_byte / 512;
keep = 1;
}
}
memset(gpt_name, 0, 72);
strcpy((char *) gpt_name, "EFI boot partition");
iso_ascii_utf_16le(gpt_name);
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
((uint64_t) t->curblock) * 4,
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count), part_start,
((uint64_t) t->efi_boot_part_size) * 4,
efi_sys_uuid, zero_uuid, gpt_flags, gpt_name);
if (ret < 0)
return ret;
t->curblock += t->efi_boot_part_size;
if (!keep)
t->curblock += t->efi_boot_part_size;
}
if (with_chrp) {
@ -2643,36 +3017,59 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
return ISO_SUCCESS;
}
part_start = t->curblock * 4;
keep = 0;
if (t->opts->prep_partition != NULL) {
ret = compute_partition_size(t, t->opts->prep_partition,
&(t->prep_part_size),
t->opts->prep_part_flag & 1);
if (ret < 0)
return ret;
if (ret == ISO_SUCCESS + 1) {
/* Interval from imported_iso in add-on session will be kept */
ret = iso_interval_reader_start_size(t,
t->opts->prep_partition,
&start_byte, &byte_count, 0);
if (ret < 0)
return ret;
part_start = start_byte / 512;
keep = 1;
}
}
if (t->prep_part_size > 0 || t->opts->fat || will_have_gpt) {
/* Protecting MBR entry for ISO start or whole ISO */
part_type = 0xcd;
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
if (will_have_gpt)
part_type = 0xee;
ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
will_have_gpt ? (uint64_t) 1 :
((uint64_t) t->opts->partition_offset) * 4,
(uint64_t) 0,
will_have_gpt ? 0xee : 0xcd, 0, 0);
(uint64_t) 0, part_type, 0, 0);
if (ret < 0)
return ret;
}
if (t->prep_part_size > 0) {
ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
((uint64_t) t->curblock) * 4,
ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count), part_start,
((uint64_t) t->prep_part_size) * 4,
0x41, 0, 0);
if (ret < 0)
return ret;
t->curblock += t->prep_part_size;
if (!keep) {
t->curblock += t->prep_part_size;
part_start = t->curblock * 4;
} else {
part_start += t->prep_part_size * 4;
}
} else {
part_start = t->curblock * 4;
}
if (t->prep_part_size > 0 || t->opts->fat) {
/* FAT partition or protecting MBR entry for ISO end */
ret = iso_quick_mbr_entry(t->mbr_req, &(t->mbr_req_count),
((uint64_t) t->curblock) * 4, (uint64_t) 0,
part_start, (uint64_t) 0,
t->opts->fat ? 0x0c : 0xcd, 0, 0);
if (ret < 0)
return ret;
@ -2795,7 +3192,7 @@ static int partappend_writer_write_data(IsoImageWriter *writer)
target->opts->appended_partitions[i],
target->appended_part_prepad[i],
target->appended_part_size[i],
target->appended_part_flags[i] & 1);
target->opts->appended_part_flags[i] & 1);
if (res < 0)
return res;
target->curblock += target->appended_part_size[i];

View File

@ -182,10 +182,15 @@ int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
run on other machines with the same process number at the same time.
*/
/* Produces a weakly random variation of a hardcoded real random uuid
/* Produces a GPT disk or partition GUID.
Pseudo-random by iso_generate_gpt_guid() if t->gpt_uuid_counter is 0.
Else derived reproducibly by counter number from t->gpt_uuid_base.
*/
void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]);
void iso_gpt_uuid(Ecma119Image *t, uint8_t uuid[16]);
/* Mark a given byte string as UUID version 4, RFC 4122.
*/
void iso_mark_guid_version_4(uint8_t *u);
/* The parameter struct for production of a single GPT entry.
See also the partial GPT description in doc/boot_sectors.txt.
@ -312,9 +317,13 @@ void iso_ascii_utf_16le(uint8_t gap_name[72]);
#define Libisofs_grub2_sparc_patch_size_poS 0x230
/* >>> It is unclear whether there is a use case for appended partitions
inside the ISO filesystem range.
# define Libisofs_appended_partitions_inlinE yes
/* Put appended partitions into the writer range
*/
#define Libisofs_appended_partitions_inlinE yes
#ifdef Libisofs_appended_partitions_inlinE
/* For padding after appended partitions (and also after backup GPT)
*/
#define Libisofs_part_align_writeR yes
#endif
#endif /* SYSTEM_AREA_H_ */

View File

@ -1823,7 +1823,7 @@ time_t iso_datetime_read_17(const uint8_t *buf)
tm.tm_mon -= 1;
tm.tm_isdst = 0;
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
return timegm(&tm) - ((int8_t)buf[16]) * 60 * 15;
}
/**

View File

@ -29,13 +29,13 @@ struct Iso_Image_Writer
};
/**
* This is the function all Writers shoudl call to write data to image.
* This is the function all Writers should call to write data to image.
* Currently, it is just a wrapper for write(2) Unix system call.
*
* It is implemented in ecma119.c
*
* @return
* 1 on sucess, < 0 error
* 1 on success, < 0 error
*/
int iso_write(Ecma119Image *target, void *buf, size_t count);