Compare commits

...

127 Commits

Author SHA1 Message Date
2d1fec2569 Updated change log 2021-01-30 13:13:59 +01:00
4219bf4950 Version leap to 1.5.4 2021-01-30 13:12:35 +01:00
2a20e93b13 Small correction to commit 6241141 2020-12-07 20:59:14 +01:00
62411411db New API calls iso_read_image_features_tree_loaded() and iso_read_image_features_rr_loaded() 2020-12-07 18:02:24 +01:00
8f3ff65c04 Corrected size of GPT protective MBR partition with multi-session emulation 2020-11-26 11:49:58 +01:00
c068a19a8c New API call iso_read_opts_set_joliet_map(), new default joliet_map=stripped 2020-11-22 14:14:49 +01:00
cece6fb371 Bug fix: Appended APM partitions without HFS+ production had start and size 1 2020-11-15 15:23:03 +01:00
29cc5c8d31 Prevented writing of undesired bytes in make_sun_disk_label() (commit b0230b6) 2020-11-14 09:24:11 +01:00
92af0c9752 Adjusted fix 7e3b01b after learning that the bug stems from b0230b6 (unreleased) 2020-11-13 21:46:05 +01:00
daaee5e7e6 Fixed access to packed members of struct hfsplus_volheader. Thanks Felipe Franciosi. 2020-11-13 19:24:13 +01:00
7e3b01b53c Bug fix: Apple Partition Map entries wrote uninitialized data 2020-11-13 19:02:07 +01:00
1d5566f8bb Changed Public contact from libburn-hackers@pykix.org to bug-xorriso@gnu.org 2020-11-13 18:57:30 +01:00
ac9d55330d Fixed a new bug introduced with previous commit 2020-11-07 10:46:15 +01:00
b0687643c5 Bug fix: El Torito production failed if no catalog name was given and the boot image path contains no slash 2020-11-07 10:31:52 +01:00
5a98a4cda5 Corrected declaration of ziso_add_osiz_filter(). (Lapse in commit b107443) 2020-10-31 14:01:09 +01:00
b7a90c5194 Corrected description of new call iso_zisofs_ctrl_susp_z2() 2020-10-29 09:24:47 +01:00
8d70c75d4a Added doc/zisofs2_format.txt to EXTRA_DIST 2020-10-29 09:16:58 +01:00
9605bbe748 New API call iso_zisofs_ctrl_susp_z2() 2020-10-29 09:11:11 +01:00
46186e5f06 Added Z2 System Use Entry Format to zisofs2 specs 2020-10-29 08:31:31 +01:00
2ac62f0cac Fixed header size of ZF entries made for zisofs2 files compressed by libisofs 2020-10-29 08:23:15 +01:00
dc61e7d298 New flag bits 8 to 15 in API call iso_node_zf_by_magic() 2020-10-27 12:17:26 +01:00
d5ffecf2f5 Silenced a compiler warning if zlib is not enabled 2020-10-26 19:39:45 +01:00
80449f0dc9 New API calls iso_stream_zisofs_discard_bpt() and iso_image_zisofs_discard_bpt() 2020-10-25 16:59:32 +01:00
cc2e0e32a3 New iso_zisofs_ctrl parameters bpt_discard_file_blocks , bpt_discard_free_ratio 2020-10-22 13:22:13 +02:00
239ba69925 Accepting zisofs2 algorithms 2 to 5 for ZF by magic, but not for decompression 2020-10-18 16:46:44 +02:00
2ca3b292fb New iso_zisofs_ctrl parameter .block_number_target 2020-10-17 14:40:24 +02:00
f291e37ec1 Fixed wrong start block pointer of zisofs2 compression 2020-10-15 14:13:38 +02:00
b107443769 Implemented production and reading of zisofs2 for files larger than 4 GiB - 1. New API call iso_stream_get_zisofs_par(). New struct iso_zisofs_ctrl version 2. 2020-10-14 20:19:11 +02:00
d297ce3aed Prevented time rollover outside year intervals 1900-2155 and 1-9999 2020-09-21 21:17:20 +02:00
f962d0da66 Bug fix: Big-Endian MIPS Volume Header boot file size was rounded up to full 2048. Thanks René Rebe. 2020-07-07 12:31:52 +02:00
b0230b6ac8 Changed strncpy() to memcpy() in order to please static analyzers 2020-07-07 12:23:20 +02:00
69e332d17a New error code ISO_HFSPLUS_TOO_MANY_FILES instead of ISO_MANGLE_TOO_MUCH_FILES 2020-06-13 10:17:32 +02:00
6ca841e002 Reacted on compiler warnings of Debian Sid 2020-06-13 09:56:31 +02:00
c84f6ae689 Removed a germanism from description of iso_image_get_session_md5 2020-06-13 09:55:06 +02:00
ac248877a2 Re-enabled variable LT_RELEASE in configure.ac. Disabling was unintentional. 2019-11-26 11:24:23 +01:00
c1d9639dba Switched to usage of libjte-2.0.0 2019-11-24 13:19:07 +01:00
773be790e8 Fixed more spelling errors found by fossies.org with codespell 2019-10-30 20:37:24 +01:00
dc3d82cf36 Fixed spelling errors found by fossies.org with codespell 2019-10-28 15:56:58 +01:00
560c11617e Updated change log 2019-10-27 15:03:35 +01:00
fa43a5a25c Version leap to 1.5.3 2019-10-27 15:02:29 +01:00
4d8a467e1a Updated changelog. 2019-10-26 15:46:31 +02:00
65c4dce69a Version leap to 1.5.2 2019-10-26 15:44:16 +02:00
fe98b35afb Made sure that iso_image_get_bootcat() cannot return non-zero size with NULL content 2019-08-13 10:13:18 +02:00
130b46cf71 New flag bit2 of iso_node_set_acl_text() to be verbous about failures 2019-07-24 16:11:50 +02:00
eb7dc408e0 Added Alpha to table of content of boot sectors description 2019-07-24 16:06:21 +02:00
a5e209265d Putting doc/boot_sectors.txt into release tarball 2019-04-22 10:30:02 +02:00
458ab43ecd New API call iso_nowtime() 2019-04-18 10:56:01 +02:00
4b21386e82 Bug fix: SIGSEGV happened if options bit 14 of iso_write_opts_set_system_area() is set and no El Torito boot image is defined 2019-04-18 10:49:40 +02:00
c62d9d7b1b Replaced inclusion of version numbers from autotools by those from libisofs.h 2019-04-07 17:31:38 +02:00
3aab1cafc5 Disabled autotools macro AM_MAINTAINER_MODE on advise of Ross Burton 2019-04-07 10:41:49 +02:00
8fbc2fcdfd Made libisofs ready for building out-of-source. Thanks Ross Burton. 2019-04-05 18:04:46 +02:00
aed8bda955 New API calls iso_write_opts_set_part_type_guid(), iso_write_opts_set_iso_type_guid() 2019-02-18 12:47:09 +01:00
e1097dbb5d Changed interface of helper function iso_tell_max_part_range() 2019-01-15 19:07:01 +01:00
a1e75003b5 Bug fix: Appending partitions 5 to 8 caused damaged ISO filesystems if not for SUN disk label 2019-01-15 16:26:56 +01:00
4064a7e0ee Bug fix: Multi-session emulation spoiled GPT production "GPT partitions ... overlap". Regression towards 1.4.8 2019-01-10 20:15:44 +01:00
96261585f1 Bug fix: Appended GPT partitions were not covered by the protective MBR partition 2019-01-10 09:21:43 +01:00
01415ae208 New report line with iso_image_report_el_torito() "El Torito hdsiz/512:" 2018-11-05 14:06:09 +01:00
241b9ea832 Corrected and updated copyright statements 2018-10-06 20:40:08 +02:00
6a6343c146 Updated copyright dates in COPYING and README 2018-09-24 10:13:12 +02:00
a63b16f7da Updated change log 2018-09-16 15:01:42 +02:00
31c4c26567 Version leap to 1.5.1 2018-09-16 15:00:17 +02:00
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
56 changed files with 4263 additions and 797 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-2018
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,77 @@
libisofs-1.5.4.tar.gz Sat Jan 30 2021
===============================================================================
* Bug fix: Big-Endian MIPS Volume Header boot file size was rounded up to
full 2048. Thanks René Rebe.
* Bug fix: El Torito production failed if no catalog path is given and the
first boot image path contains no slash
* Bug fix: zisofs production was wrong on big-endian machines
* Bug fix: Apple Partition Map entries wrote uninitialized data
* Bug fix: Appended APM partitions without HFS+ production had start and size 1
* Switched to usage of libjte-2.0.0
* Implemented production and reading of zisofs2 for files larger than 4 GiB - 1.
* New struct iso_zisofs_ctrl version 2
* New API call iso_stream_get_zisofs_par()
* New API call iso_stream_zisofs_discard_bpt()
* New API call iso_image_zisofs_discard_bpt()
* New flag bits 8 to 15 in API call iso_node_zf_by_magic()
* New API call iso_zisofs_ctrl_susp_z2()
* New API call iso_read_opts_set_joliet_map(), new default joliet_map=stripped
* New API calls iso_read_image_features_tree_loaded() and
iso_read_image_features_rr_loaded()
libisofs-1.5.2.tar.gz Sat Oct 26 2019
===============================================================================
* New API calls iso_write_opts_set_part_type_guid(),
iso_write_opts_set_iso_type_guid()
* New API call iso_nowtime()
* New flag bit2 of iso_node_set_acl_text() to be verbous about failures
* Made libisofs ready for building out-of-source. Thanks Ross Burton.
* Bug fix: Appended GPT partitions were not covered by the protective MBR
partition
* Bug fix: Multi-session emulation spoiled GPT production.
"GPT partitions ... overlap". Regression towards 1.4.8
* Bug fix: Appending partitions 5 to 8 caused damaged ISO filesystems if not
for SUN disk label
* Bug fix: SIGSEGV happened if options bit 14 of
iso_write_opts_set_system_area() is set and no El Torito boot image
is defined
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
===============================================================================

View File

@ -1,4 +1,8 @@
# Copyright (c) 2007 Vreixo Formoso
# Copyright (c) 2009 - 2019 Thomas Schmitt
# Provided under the terms of the GNU General Public License version 2 or later.
# ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4
# was: pkgconfigdir=$(libdir)/pkgconfig
pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
@ -8,6 +12,9 @@ libincludedir=$(includedir)/libisofs
lib_LTLIBRARIES = libisofs/libisofs.la
ACLOCAL_AMFLAGS = -I ./
# Enable this if the source includes generated files like version.h
# AM_CPPFLAGS = -I $(top_builddir)/libisofs
## ========================================================================= ##
# Build libraries
@ -113,8 +120,8 @@ noinst_PROGRAMS = \
# ts A90807
# Consolidated demo code for having less linker mesages with a make run.
demo_demo_CPPFLAGS = -Ilibisofs
# Consolidated demo code for having less linker messages with a make run.
demo_demo_CPPFLAGS = -I $(top_srcdir)/libisofs
demo_demo_LDADD = $(libisofs_libisofs_la_OBJECTS) $(libisofs_libisofs_la_LIBADD)
demo_demo_SOURCES = demo/demo.c
@ -278,7 +285,9 @@ EXTRA_DIST = \
doc/susp_aaip_2_0.txt \
doc/susp_aaip_isofs_names.txt \
doc/zisofs_format.txt \
doc/zisofs2_format.txt \
doc/checksums.txt \
doc/boot_sectors.txt \
libisofs/libisofs.ver \
libisofs/aaip-os-dummy.c \
libisofs/aaip-os-linux.c \

7
README
View File

@ -2,9 +2,10 @@
libisofs
------------------------------------------------------------------------------
Released under GPL (see COPYING file for details).
Released under GNU General Public License version 2 or later.
See COPYING file for details.
Copyright (C) 2008 - 2016 Vreixo Formoso,
Copyright (C) 2008 - 2018 Vreixo Formoso,
Mario Danic,
Vladimir Serbinenko,
Thomas Schmitt
@ -208,5 +209,5 @@ We are firmly committed to allow GPLv2+ now and with future releases.
Signed: Mario Danic, Thomas Schmitt
Agreement joined later by: Vreixo Formoso
Public contact: <libburn-hackers@pykix.org>
Public contact: <bug-xorriso@gnu.org>

View File

@ -1,3 +1,8 @@
dnl Copyright (c) 2009 - 2019 Thomas Schmitt
dnl Provided under the terms of the GNU General Public License version 2 or later.
AC_DEFUN([LIBBURNIA_SET_FLAGS],
[
case $target_os in
@ -144,12 +149,12 @@ dnl It tests whether -Wl,--version-script=... works with the compiler
AC_DEFUN([LIBISOFS_ASSERT_VERS_LIBS],
[
libburnia_save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -Wl,--version-script=libisofs/libisofs.ver"
LDFLAGS="$LDFLAGS -Wl,--version-script=$srcdir/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 = xyes
then
LIBLDFLAGS="-Wl,--version-script=libisofs/libisofs.ver"
LIBLDFLAGS="-Wl,--version-script=$srcdir/libisofs/libisofs.ver"
fi
LDFLAGS="$libburnia_save_LDFLAGS"
AC_SUBST(LIBLDFLAGS)

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.4.6], [http://libburnia-project.org])
AC_INIT([libisofs], [1.5.4], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -40,8 +40,8 @@ dnl
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=6
LIBISOFS_MINOR_VERSION=5
LIBISOFS_MICRO_VERSION=4
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
# 2016.07.01 development jump has not yet happened
# SONAME = 88 - 82 = 6 . Library name = libisofs.6.82.0
LT_CURRENT=88
LT_AGE=82
dnl 2021.01.30 development jump has not yet happened
dnl SONAME = 97 - 91 = 6 . Library name = libisofs.6.91.0
LT_CURRENT=97
LT_AGE=91
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -67,7 +67,8 @@ AC_SUBST(LT_CURRENT_MINUS_AGE)
AC_PREFIX_DEFAULT([/usr/local])
test "$prefix" = "NONE" && prefix=$ac_default_prefix
AM_MAINTAINER_MODE
dnl ts B90405 : Disabled on advise of Ross Burton
dnl AM_MAINTAINER_MODE
AM_PROG_CC_C_O
AC_C_CONST
@ -202,19 +203,68 @@ fi
AC_SUBST(LIBACL_DEF)
dnl ts A90123 - B51212
dnl ts A90123 - B80508
AC_ARG_ENABLE(xattr,
[ --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= )
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
@ -233,6 +283,8 @@ then
else
echo "disabled local processing of extended file attributes"
fi
XATTR_DEF="$XATTR_DEF $XATTR_ADDON_DEF"
AC_SUBST(XATTR_DEF)
@ -255,11 +307,11 @@ AC_SUBST(ZLIB_DEF)
dnl ts B00927
AC_ARG_ENABLE(libjte,
[ --enable-libjte Enable use of libjte by libisofs, default=yes],
[ --enable-libjte Enable use of libjte >= 2.0 by libisofs, default=yes],
, enable_libjte=yes)
if test "x$enable_libjte" = xyes; then
LIBJTE_DEF="-DLibisofs_with_libjtE"
AC_CHECK_HEADER(libjte/libjte.h, AC_CHECK_LIB(jte, libjte_new, , LIBJTE_DEF= ), LIBJTE_DEF= )
AC_CHECK_HEADER(libjte/libjte.h, AC_CHECK_LIB(jte, libjte_set_checksum_algorithm, , LIBJTE_DEF= ), LIBJTE_DEF= )
else
LIBJTE_DEF=
fi

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).
@ -37,6 +38,8 @@ Common Hardware Reference Platform (CHRP), for IBM PowerPC
HP-PA via PALO header version 4
HP-PA via PALO header version 5
DEC Alpha SRM boot sector, for Alpha architecture
Combinations of boot mechanisms:
- SYSLINUX isohybrid MBR
- SYSLINUX isohybrid for MBR, UEFI and x86-Mac
@ -120,7 +123,7 @@ Optional:
| | Entries
---------- | ---------- | ----------------------------------------------------
An architecture is refered by a Platform Id number.
An architecture is referred by a Platform Id number.
Defined by El Torito are:
0 = "80x86" which is used for standard PCs with Intel x86 or compatible CPU
1 = "PowerPC" (possibly for IBM machines with PowerPC CPU)
@ -301,28 +304,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 arbitrary 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 +350,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 +360,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.
@ -359,7 +382,7 @@ Byte Range | Value | Meaning
| | Bits 6 to 7 : Bits 8 to 9 of cylinders part.
453 - 453 | end_cyl | Lower 8 bits of cylinders part of end address
| |
454 - 457 | start_lba | LBA of first absolute sector in partiton.
454 - 457 | start_lba | LBA of first absolute sector in partition.
| | Block size is 512. Counting starts at 0.
| |
458 - 461 | num_blocks | Number of sectors in partition.
@ -404,6 +427,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 +437,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 +460,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 +500,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 +689,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 +700,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
| |
@ -694,7 +739,7 @@ Byte Range | Value | Meaning
72 - 311 | ========== | Volume Directory with 15 entries of 16 bytes each
| |
72 - 87 | ========== | Volume Directory Entry 1
72 - 79 | boot_name | Boot file basename, eventually padded by 0 to lenght 8
72 - 79 | boot_name | Boot file basename, eventually padded by 0 to length 8
80 - 83 | boot_block | ISO 9660 LBA of boot file * 4, i.e. in blocks of 512
84 - 87 | boot_bytes | File length in bytes
| |
@ -1265,7 +1310,7 @@ intentionally non-essential:
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
They may be overwritten by other bytes which must not produce errors or
undesirable side effects when executed as x86 machine code.
The following 32 bytes from block 0 of an Apple Partiton Map (APM) are such
The following 32 bytes from block 0 of an Apple Partition Map (APM) are such
harmless code. They stem from Fedora-LiveCD.iso by Matthew Garrett:
45 52 08 00 00 00 90 90 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

View File

@ -79,7 +79,7 @@ Tag_id distinguishes the following tag types
"libisofs_checksum_tag_v1" Session tag
A relocated superblock may appear at LBA 0 of an image which was produced for
being stored in a disk file or on overwriteable media (e.g. DVD+RW, BD-RE).
being stored in a disk file or on overwritable media (e.g. DVD+RW, BD-RE).
Typically there is a first session recorded with a superblock at LBA 32 and
the next session may follow shortly after its session tag. (Typically at the
next block address which is divisible by 32.) Normally no session starts after
@ -131,10 +131,10 @@ checksums as strings of 32 hex digits.
range_start=
The block address where the session is supposed to start. If this does not
match the session start on media then the volume descriptors of the
image have been relocated. (This can happen with overwriteable media. If
image have been relocated. (This can happen with overwritable media. If
checksumming started at LBA 0 and finds range_start=32, then one has to
restart checksumming at LBA 32. See libburn/doc/cookbook.txt
"ISO 9660 multi-session emulation on overwriteable media" for background
"ISO 9660 multi-session emulation on overwritable media" for background
information.)
range_size=
@ -232,7 +232,7 @@ If the media is sequentially recordable, obtain a table of content and check
the first track of each session as prescribed above in Checking Before Image
Tree Loading and in Checking the Data Part of the Session.
With disk files or overwriteable media, look for a relocated superblock tag
With disk files or overwritable media, look for a relocated superblock tag
but do not hop to address next_tag (given by session_start=). Instead look at
LBA 32 for the first session and check it as prescribed above.
After reaching its end, round up the read address to the next multiple of 32

View File

@ -45,7 +45,7 @@ more data bytes than with SL, though, and any of the 256 possible byte values.
The reader shall be prepared to detect and handle oversized data.
One or more AL entries form the Attribute List of a file object with
an even number of components. Each two consequtive components form a pair of
an even number of components. Each two consecutive components form a pair of
Name and Value.
The empty name indicates that the value is a compact representation of ACLs.
@ -359,7 +359,7 @@ SUSP-1.10 does not specify ES entries at all and allows to have extension
entries without announcing them by an ER entry. So if a second ER entry is
not bearable, then the SUSP-1.10 downgrade of AAIP allows to omit the
AAIP ER and the ES entries. But if there is the AAIP ER then there must be ES
at the appropriate places. Else the format would explicitely violate SUSP-1.12.
at the appropriate places. Else the format would explicitly violate SUSP-1.12.
-------------------------------------------------------------------------------
Model Relations:

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
@ -224,13 +224,13 @@ Registered:
-------------------------------------------------------------------------------
This text is under
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
Copyright (c) 2009 - 2015 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.
copy of libisofs. Currently: GNU General Public License version 2 or later.
If you do so, you commit yourself to taking reasonable effort to stay in
sync with the other interested users of this text.

262
doc/zisofs2_format.txt Normal file
View File

@ -0,0 +1,262 @@
Description of the zisofs2 Format
Revision 2.0-dev
as of zisofs2-tools by
Valentín KIVACHUK BURDÁ and Thomas SCHMITT
1 Oct 2020
The zisofs2 format was invented by Valentín KIVACHUK BURDÁ and
Thomas SCHMITT (as extension of zisofs by H. Peter Anvin). It compresses
data file content, marks it by a header and provides a pointer array for
coarse random access. Within a RRIP enhanced ISO 9660 image the format
is additionally marked by a System Use entry with signature "ZF" or "Z2".
The uncompressed size of a single zisofs2 compressed file is restricted
to 2^64 - 1 bytes. Larger files shall not be compressed.
The format of version 1 of zisofs is supported by this specification.
Using it for files with uncompressed size smaller than 4 GiB is friendly
towards software which does not know about zisofs2.
See section **LEGACY** for a summary of version 1 of zisofs.
Data Types
ISO 9660:7.3.1 - little endian 4-byte words
ISO 9660:7.1.1 - unsigned single bytes
ISO 9660:7.3.3 - 8-bytes value, first in little endian, then big endian.
#uint64 - 8-bytes unsigned value in little endian
Supported compressors
The file header has this layout:
@alg_id @alg_char Description
1 'PZ' (50)(5A) Zlib
2 'XZ' (78)(7A) XZ
3 'L4' (6C)(34) LZ4
4 'ZD' (7A)(64) Zstandard
5 'B2' (62)(32) Bzip2
@alg_id is a 7.1.1 value. @alg_char is 2 ASCII characters stored as 2 bytes
Values of @alg_id = 0 and @alg_char = 'pz'(70)(7A) are reserved and
must not be used. Other compressors are allowed and may be added to this
list in the future
Compressor strategy
The default strategy for a compressor is to compress each input data block
independently. The zisofs2 spec may define in the future other strategies,
which will have a new @alg_id, @alg_char and a description in this section.
File Header
The file header has this layout:
Offset Type Identifier Contents
--------------------------------------------------------------------------
0 (8 bytes) @hdr_magic Magic num (EF 22 55 A1 BC 1B 95 A0)
8 7.1.1 @hdr_version File header version (0)
9 7.1.1 @hdr_size header_size >> 2 (6)
10 7.1.1 @alg_id Algorithm Type (>=1)
11 7.1.1 @hdr_bsize log2(block_size) (15, 16, or 17)
12 #uint64 @size Uncompressed file size
20 (4 bytes) - Padding. Ignored
So its size is 24.
Readers shall be able to handle log2(block_size) values 15, 16 and 17
i.e. block sizes 32 kB, 64 kB, and 128 kB. Writers must not use
other sizes.
Block Pointers
There are ceil(input_size / block_size) input resp. output blocks.
Each input block is of fixed size whereas the output blocks have varying
size (down to 0). For each output block there is an offset pointer giving
its byte address in the overall file content. The next block pointer in the
array tells the start of the next block which begins immediately after the
end of its predecessor. A final pointer (*eob*) gives the first invalid
byte address and thus marks the end of the last block.
So there are ceil(input_size / block_size) + 1 block pointers.
They are stored directly after the file header, i.e. beginning at byte 24,
as an array of values in #uint64 format (8 bytes).
Legacy format (zisofs) may be used, which is described in section *LEGACY*
Data Part
The data part begins immediately after the pointer array (*eob*). In
principle it consists of the variable length output blocks as delivered by
different compression algorithms when fed with the fixed size input blocks.
A special case of input and output block is defined:
Zero-length blocks represent a block full of 0-bytes.
Such input blocks do not get processed by compress2() but shall be mapped
to 0-sized output directly. Vice versa 0-sized blocks have to bypass
uncompress() when being read.
ZF System Use Entry Format
The ZF entry follows the general layout of SUSP resp. RRIP.
Its fields are:
[1] "BP 1 to BP 2 - Signature Word" shall be (5A)(46) ("ZF").
[2] "BP 3 - Length" shall specify as an 8-bit number the length in
bytes of the ZF entry recorded according to ISO 9660:7.1.1.
This length is 16 decimal.
Refer to **LEGACY**
[3] "BP 4 - System Use Entry Version" shall be 2 as in ISO 9660:7.1.1.
Refer to **LEGACY**
[4] "BP 5 to BP 6 - Algorithm" shall be two chars to indicate the
compression algorithm. For example, (50)(5A) ("PZ")
(This is a copy of @alg_char). Refer to **LEGACY**
[5] "BP 7 - Header Size Div 4" shall specify as an 8-bit number the
number of 4-byte words in the header part of the file data recorded
according to ISO 9660:7.1.1.
(This is a copy of @hdr_size).
[6] "BP 8 - Log2 of Block Size" shall specify as an 8-bit number the
binary logarithm of the compression block size recorded according to
ISO 9660:7.1.1.
(This is a copy of header byte 13 (@hdr_bsize), resp. header BP 14.
The value has to be 15, 16 or 17 i.e. 32 kiB, 64 kiB, or 128 kiB.)
[7] "BP 9 to BP 16 - Virtual Uncompressed File Size" shall contain
as a 64-bit unsigned little endian number the uncompressed
file size represented by the given extent. Refer to **LEGACY**
| 'Z' | 'F' | LENGTH | 2 | 'P' | 'Z' | HEADER SIZE DIV 4 |
| LOG2 BLOCK SIZE | UNCOMPRESSED SIZE |
Example (block size 128 kiB, uncompressed file size = 40 TB):
{ 'Z', 'F', 16, 2, 'P', 'Z', 8, 17,
0x00, 0x80, 0xCA, 0x39, 0x61, 0x24, 0x00, 0x00 }
Z2 System Use Entry Format
Linux kernels which are configured by CONFIG_ZISOFS to recognize zisofs
but are not aware of zisofs2 will complain about ZF entries which announce
algorithms other than "pz". The system log will show for each zisofs2
compressed file at first stat(2) or open(2) a line like this:
isofs: Unknown ZF compression algorithm: PZ
To avoid these complaints, it is possible to use
[1] "BP 1 to BP 2 - Signature Word" shall be (5A)(32) ("Z2").
instead of "ZF" with the System Use Entry Format specified above.
Everything else shall be like in ZF format version 2, including the version
number itself:
[3] "BP 4 - System Use Entry Version" shall be 2 as in ISO 9660:7.1.1.
**LEGACY**
zisofs2 supports old readers by respecting the zisofs format. This section
describes which definitions from zisofs2 must change to be compatible
with zisofs.
- General behaviour
The uncompressed size of a single zisofs compressed file is restricted
to 4 GiB - 1. Larger files shall not be compressed.
- Supported algorithms
Only algorithm Zlib with default strategy is supported.
- The file header must follow this structure:
Offset Type Identifier Contents
0 (8 bytes) @hdr_magic Magic number (37 E4 53 96 C9 DB D6 07)
8 7.3.1 @size Uncompressed file size
12 7.1.1 @hdr_size header_size >> 2 (4)
13 7.1.1 @hdr_bsize log2(block_size) (15, 16, or 17)
14 (2 bytes) - Reserved, must be zero
So its size is 16.
- Block pointers
The array must use ISO 9660:7.3.1 (4 bytes) values.
- ZF entry
Its fields are:
[1] "BP 1 to BP 2 - Signature Word" shall be (5A)(46) ("ZF").
[2] "BP 3 - Length" must be 16 decimal.
[3] "BP 4 - System Use Entry Version" must be 1.
[4] "BP 5 to BP 6 - Algorithm" must be (70)(7A) ("pz").
[5] "BP 7 - Header Size Div 4" - same as zisofs2.
[6] "BP 8 - Log2 of Block Size" - same as zisofs2.
[7] "BP 9 to BP 16 - Uncompressed Size" This field shall be recorded
according to ISO 9660:7.3.3.
(This number is the same as @size )
| 'Z' | 'F' | LENGTH | 1 | 'p' | 'z' | HEADER SIZE DIV 4 |
| LOG2 BLOCK SIZE | UNCOMPRESSED SIZE |
Example (block size 32 kiB, uncompressed file size = 1,234,567 bytes):
{ 'Z', 'F', 16, 1, 'p', 'z', 4, 15,
0x87, 0xD6, 0x12, 0x00, 0x00, 0x12, 0xD6, 0x87 }
References:
zisofs2-tools
https://github.com/vk496/zisofs2-tools
zisofs-tools
http://freshmeat.net/projects/zisofs-tools/
zlib:
/usr/include/zlib.h
cdrtools with mkisofs
ftp://ftp.berlios.de/pub/cdrecord/alpha
ECMA-119 aka ISO 9660
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
SUSP 1.12
ftp://ftp.ymi.com/pub/rockridge/susp112.ps
RRIP 1.12
ftp://ftp.ymi.com/pub/rockridge/rrip112.ps
zisofs version 1
libisofs-*/doc/zisofs_format.txt
https://dev.lovelyhq.com/libburnia/libisofs/raw/branch/master/doc/zisofs_format.txt
---------------------------------------------------------------------------
This text is under
Copyright (c) 2009 - 2010, 2020 Thomas SCHMITT <scdbackup@gmx.net>
Copyright (c) 2020 - Valentín KIVACHUK BURDÁ <vk18496@gmail.com>
It shall reflect the effective technical specifications as implemented in
zisofs2-tools and the Linux kernel. So please contact mailing list
<bug-xorriso@gnu.org> or to the copyright holders in private, if you
want to make changes.
Only if you cannot reach the copyright holder for at least one month it is
permissible to modify and distribute this text under the license "GPLv3".

View File

@ -11,7 +11,12 @@
To be included by aaip_0_2.c
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2011 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
or later as published by the Free Software Foundation.
See COPYING file for details.
*/
@ -99,10 +104,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

@ -7,7 +7,12 @@
To be included by aaip_0_2.c for FreeBSD, NetBSD, and OpenBSD
Copyright (c) 2009 - 2016 Thomas Schmitt, libburnia project, GPLv2+
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
or later as published by the Free Software Foundation.
See COPYING file for details.
*/
@ -228,6 +233,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 +321,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 */
@ -320,7 +377,7 @@ static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
@param path Path to the file
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit0= obtain ACL (access and eventually default)
@ -332,7 +389,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
@ -350,12 +408,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;}
@ -391,6 +449,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 */
@ -445,45 +505,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;
}
}
@ -494,8 +519,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;
@ -514,7 +542,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)
@ -563,7 +591,7 @@ ex:;
@param path Path to the file
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit0= obtain ACL (access and eventually default)
@ -773,6 +801,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
@ -784,6 +821,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
@ -796,17 +835,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 */
@ -855,16 +900,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
@ -879,8 +943,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],
@ -902,6 +970,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
@ -911,7 +981,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,12 @@
To be included by aaip_0_2.c for Linux
Copyright (c) 2009 - 2016 Thomas Schmitt, libburnia project, GPLv2+
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
or later as published by the Free Software Foundation.
See COPYING file for details.
*/
@ -30,8 +35,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,12 +168,47 @@ 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
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit0= obtain ACL (access and eventually default)
@ -176,7 +220,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 +241,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 +334,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 +463,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
@ -445,6 +483,8 @@ ex:
bit5= in case of symbolic link: manipulate link target
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 +497,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 +570,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 +601,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 +631,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 +657,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 +670,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,12 @@
See libisofs/aaip_0_2.h
http://libburnia-project.org/wiki/AAIP
Copyright (c) 2009 - 2016 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2019 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
or later as published by the Free Software Foundation.
See COPYING file for details.
*/
@ -27,6 +32,7 @@
#include "libisofs.h"
#include "util.h"
#include "messages.h"
/*
#define Aaip_encode_debuG 1
@ -275,6 +281,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
bit2= this is a default ACL, prepend SWITCH_MARK
bit3= check for completeness of list and eventually
fill up with entries deduced from st_mode
bit4= be verbose about failure causes
@return >0 means ok
<=0 means error
-1= out of memory
@ -290,7 +297,7 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
*result= NULL;
*result_len= 0;
bytes= aaip_encode_acl_text(acl_text, st_mode,
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8)));
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8 | 16)));
if(bytes < -2)
return(bytes);
if(bytes < 0)
@ -305,7 +312,7 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
(*result)[bytes]= 0;
*result_len= bytes;
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
(flag & (2 | 4 | 8)));
(flag & (2 | 4 | 8 | 16)));
if(bytes < -2)
return(bytes);
if(bytes < 0)
@ -357,10 +364,11 @@ static int aaip_make_aaip_perms(int r, int w, int x)
bit2= this is a default ACL, prepend SWITCH_MARK 1
bit3= check for completeness of list and eventually
fill up with entries deduced from st_mode
bit4= be verbose about failure causes
@return >=0 number of bytes produced resp. counted
<0 means error
-1: result size overflow
-2: conversion errror with user name or group name
-2: conversion error with user name or group name
ISO_AAIP_ACL_MULT_OBJ: multiple entries of user::, group::, other::
*/
static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
@ -383,7 +391,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
/* set SWITCH_MARK to indicate a default ACL */;
if(!(flag & 1)) {
if((size_t) count >= result_size)
{ret= -1; goto ex;}
goto result_size_overflow;
result[count]= (Aaip_SWITCH_MARK << 4) | Aaip_EXEC;
}
count++;
@ -412,6 +420,9 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
/* >>> Duplicate u:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
if(flag & 16)
iso_msg_submit(-1, ISO_AAIP_ACL_MULT_OBJ, 0,
"Duplicate u:: entry detected in ACL text");
ret = ISO_AAIP_ACL_MULT_OBJ;
goto ex;
}
@ -429,6 +440,9 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
num= aaip_numeric_id(name, 0);
if(num <= 0) {
/* ACL_USER is not part of AAIP 2.0 */
if(flag & 16)
iso_msg_submit(-1, ISO_AAIP_BAD_ACL_TEXT, 0,
"Unknown user name found in ACL text: '%s'", name);
{ret= -2; goto ex;}
}
uid= huid= num;
@ -458,6 +472,9 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
/* >>> Duplicate g:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
if(flag & 16)
iso_msg_submit(-1, ISO_AAIP_ACL_MULT_OBJ, 0,
"Duplicate g:: entry detected in ACL text");
ret = ISO_AAIP_ACL_MULT_OBJ;
goto ex;
}
@ -475,6 +492,9 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
num= aaip_numeric_id(name, 0);
if(num <= 0) {
/* ACL_GROUP is not part of AAIP 2.0 */
if(flag & 16)
iso_msg_submit(-1, ISO_AAIP_BAD_ACL_TEXT, 0,
"Unknown group name found in ACL text: '%s'", name);
{ret= -2; goto ex;}
}
gid= hgid= num;
@ -503,6 +523,9 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
/* >>> Duplicate o:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
if(flag & 16)
iso_msg_submit(-1, ISO_AAIP_ACL_MULT_OBJ, 0,
"Duplicate o:: entry detected in ACL text");
ret = ISO_AAIP_ACL_MULT_OBJ;
goto ex;
}
@ -519,7 +542,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
if(!(flag & 1)) {
if((size_t) count >= result_size)
{ret= -1; goto ex;}
goto result_size_overflow;
result[count]= perms | ((!!qualifier) << 3) | (type << 4);
}
count++;
@ -528,7 +551,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
num_recs= (qualifier_len / 127) + !!(qualifier_len % 127);
if(!(flag & 1)) {
if((size_t) (count + 1) > result_size)
{ret= -1; goto ex;}
goto result_size_overflow;
for(i= 0; i < num_recs; i++) {
if(i < num_recs - 1)
result[count++]= 255;
@ -538,7 +561,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
result[count - 1]= 127;
}
if((size_t) (count + (result[count - 1] & 127)) > result_size)
{ret= -1; goto ex;}
goto result_size_overflow;
memcpy(result + count, name + i * 127, result[count - 1] & 127);
count+= result[count - 1] & 127;
}
@ -553,7 +576,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
count+= needed;
else {
if((size_t) (count + needed) > result_size)
{ret= -1; goto ex;}
goto result_size_overflow;
}
}
if ((flag & 8) && needed > 0 && !(flag & 1)) {
@ -582,6 +605,13 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
ex:;
LIBISO_FREE_MEM(name);
return(ret);
result_size_overflow:;
if(flag & 16)
iso_msg_submit(-1, ISO_ASSERT_FAILURE, 0,
"Program error: Text to ACL conversion result size overflow");
ret= -1;
goto ex;
}
@ -593,13 +623,14 @@ int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode,
unsigned char *a_acl= NULL, *d_acl= NULL, *acl= NULL;
if(a_acl_text != NULL) {
ret= aaip_encode_acl(a_acl_text, st_mode, &a_acl_len, &a_acl, flag & 11);
ret= aaip_encode_acl(a_acl_text, st_mode, &a_acl_len, &a_acl,
flag & (1 | 2 | 8 | 16));
if(ret <= 0)
goto ex;
}
if(d_acl_text != NULL) {
ret= aaip_encode_acl(d_acl_text, (mode_t) 0, &d_acl_len, &d_acl,
(flag & 3) | 4);
(flag & (1 | 2 | 16)) | 4);
if(ret <= 0)
goto ex;
}
@ -1929,7 +1960,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
@param handle The decoding context created by aaip_decode_attrs()
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit15= free memory of names, value_lengths, values
@ -2188,6 +2219,11 @@ ex:;
/* ----------------------- Adapter for operating systems ----------------- */
#ifdef Libisofs_use_os_dummY
#include "aaip-os-dummy.c"
#else
#ifdef __FreeBSD__
#include "aaip-os-freebsd.c"
@ -2239,4 +2275,5 @@ ex:;
#endif /* ! __NetBSD__ */
#endif /* ! __FreeBSD_kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! Libisofs_use_os_dummY */

View File

@ -9,7 +9,12 @@
test/aaip_0_2.h - Public declarations
Copyright (c) 2009 - 2016 Thomas Schmitt, libburnia project, GPLv2+
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
or later as published by the Free Software Foundation.
See COPYING file for details.
*/
@ -194,7 +199,7 @@ int aaip_get_acl_text(char *path, char **text, int flag);
@param path Path to the file
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit0= obtain ACLs (access and eventually default) via
@ -430,7 +435,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
@param handle The decoding context created by aaip_decode_attrs()
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param value_lengths Will return an array with the lengths of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit15= free memory of names, value_lengths, values
@ -507,7 +512,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

@ -12,7 +12,7 @@
*
* TODO #00010 : optimize ring buffer
* - write/read at the end of buffer requires a second mutex_lock, even if
* there's enought space/data at the beginning
* there's enough space/data at the beginning
* - pre-buffer for writes < BLOCK_SIZE
*
*/
@ -145,7 +145,7 @@ void iso_ring_buffer_free(IsoRingBuffer *buf)
* @param
* Number of bytes to write
* @return
* 1 succes, 0 read finished, < 0 error
* 1 success, 0 read finished, < 0 error
*/
int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
{
@ -165,7 +165,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
/*
* Note. There's only a writer, so we have no race conditions.
* Thus, the while(buf->size == buf->cap) is used here
* only to propertly detect the reader has been cancelled
* only to properly detect the reader has been cancelled
*/
if (buf->rend) {
@ -196,7 +196,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
/**
* Read count bytes from the buffer into dest. It blocks until the desired
* bytes has been read. If the writer finishes before outputting enought
* bytes has been read. If the writer finishes before outputting enough
* bytes, 0 (EOF) is returned, the number of bytes already read remains
* unknown.
*
@ -219,7 +219,7 @@ int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
/*
* Note. There's only a reader, so we have no race conditions.
* Thus, the while(buf->size == 0) is used here just to ensure
* a reader detects the EOF propertly if the writer has been
* a reader detects the EOF properly if the writer has been
* canceled while the reader was waiting
*/

View File

@ -55,13 +55,13 @@ void iso_ring_buffer_free(IsoRingBuffer *buf);
* @param
* Number of bytes to write
* @return
* 1 succes, 0 read finished, < 0 error
* 1 success, 0 read finished, < 0 error
*/
int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count);
/**
* Read count bytes from the buffer into dest. It blocks until the desired
* bytes has been read. If the writer finishes before outputting enought
* bytes has been read. If the writer finishes before outputting enough
* bytes, 0 (EOF) is returned, the number of bytes already read remains
* unknown.
*
@ -94,7 +94,7 @@ int iso_ring_buffer_get_buf_status(IsoRingBuffer *buf, size_t *size,
/**
* Close the buffer (to be called by the writer).
* You have to explicity close the buffer when you don't have more data to
* You have to explicitly close the buffer when you don't have more data to
* write, otherwise reader will be waiting forever.
*
* @param error

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;

View File

@ -34,7 +34,7 @@ struct Iso_Node_Builder
* always be created, even if src is another kind of file.
*
* In that case, if the implementation can't do the conversion, it
* should fail propertly.
* should fail properly.
*
* Note that the src is never unref, so you need to free it.
*

772
libisofs/changelog.txt Normal file
View File

@ -0,0 +1,772 @@
------------------------------------------------------------------------------
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.
16 Sep 2018 [31c4c26]
configure.ac
libisofs/libisofs.h
Version leap to 1.5,1
16 Sep 2018 [a63b16f]
ChangeLog
libisofs/changelog.txt
Updated change log
24 Sep 2018 [6a6343c]
COPYRIGHT
README
Updated copyright dates in COPYING and README
06 Oct 2018 [241b9ea]
README
Makefile.am
acinclude.m4
libisofs/make_isohybrid_mbr.c
libisofs/aaip-os-dummy.c
libisofs/aaip-os-freebsd.c
libisofs/aaip-os-linux.c
libisofs/aaip_0_2.h
libisofs/aaip_0_2.c
doc/susp_aaip_isofs_names.txt
Corrected and updated copyright statements
05 Nov 2018 [01415ae]
libisofs/libisofs.h
libisofs/eltorito.h
libisofs/fs_image.c
New report line with iso_image_report_el_torito() "El Torito hdsiz/512:"
10 Jan 2019 [9626158]
libisofs/system_area.c
Bug fix: Appended GPT partitions were not covered by the protective MBR partition
10 Jan 2019 [4064a7e]
libisofs/ecma119.c
libisofs/system_area.h
libisofs/system_area.c
Bug fix: Multi-session emulation spoiled GPT production "GPT partitions ... overlap". Regression towards 1.4.8
15 Jan 2019 [a1e7500]
libisofs/ecma119.h
libisofs/ecma119.c
libisofs/system_area.c
Bug fix: Appending partitions 5 to 8 caused damaged ISO filesystems if not for SUN disk label
15 Jan 2019 [e1097db]
libisofs/ecma119.h
libisofs/ecma119.c
libisofs/system_area.c
Changed interface of helper function iso_tell_max_part_range()
18 Feb 2019 [aed8bda]
libisofs/libisofs.h
libisofs/ecma119.h
libisofs/ecma119.c
libisofs/system_area.c
libisofs/libisofs.ver
New API calls iso_write_opts_set_part_type_guid(), iso_write_opts_set_iso_type_guid()
05 Apr 2019 [8fbc2fc]
acinclude.m4
Makefile.am
Made libisofs ready for building out-of-source. Thanks Ross Burton.
07 Apr 2019 [3aab1ca]
configure.ac
Disabled autotools macro AM_MAINTAINER_MODE on advise of Ross Burton.
07 Apr 2019 [c62d9d7]
Makefile.am
libisofs/util.c
Replaced inclusion of version numbers from autotools by those from libisofs.h
18 Apr 2019 [4b21386]
libisofs/system_area.c
Bug fix: SIGSEGV happened if options bit 14 of iso_write_opts_set_system_area()
is set and no El Torito boot image is defined
18 Apr 2019 [458ab43]
libisofs/libisofs.h
libisofs/libisofs.ver
libisofs/ecma119.c
libisofs/node.c
libisofs/tree.c
libisofs/eltorito.c
libisofs/util.c
New API call iso_nowtime()
22 Apr 2019 [a5e2092]
Makefile.am
Putting doc/boot_sectors.txt into release tarball
24 Jul 2019 [eb7dc40]
doc/boot_sectors.txt
Added Alpha to table of content of boot sectors description
24 Jul 2019 [130b46c]
libisofs/libisofs.h
libisofs/node.c
libisofs/aaip_0_2.c
New flag bit2 of iso_node_set_acl_text() to be verbous about failures
13 Aug 2019 [fe98b35]
libisofs/eltorito.c
Made sure that iso_image_get_bootcat() cannot return non-zero size with NULL content
26 Oct 2019 [65c4dce]
configure.ac
libisofs/libisofs.h
Version leap to 1.5.2.
26 Oct 2019 [4d8a467]
ChangeLog
libisofs/changelog.txt
Updated change log
------------------------------------ release - libisofs-1.5.2 - 26 Oct 2019
* New API calls iso_write_opts_set_part_type_guid(),
iso_write_opts_set_iso_type_guid()
* New API call iso_nowtime()
* New flag bit2 of iso_node_set_acl_text() to be verbous about failures
* Made libisofs ready for building out-of-source. Thanks Ross Burton.
* Bug fix: Appended GPT partitions were not covered by the protective MBR
partition
* Bug fix: Multi-session emulation spoiled GPT production.
"GPT partitions ... overlap". Regression towards 1.4.8
* Bug fix: Appending partitions 5 to 8 caused damaged ISO filesystems if not
for SUN disk label
* Bug fix: SIGSEGV happened if options bit 14 of
iso_write_opts_set_system_area() is set and no El Torito boot image
is defined
27 Oct 2019 [fa43a5a]
configure.ac
libisofs/libisofs.h
Version leap to 1.5.3
27 Oct 2019 [560c116]
ChangeLog
libisofs/changelog.txt
Updated change log
28 Oct 2019 [dc3d82c]
libisofs/libisofs.h
libisofs/node.h
libisofs/node.c
libisofs/builder.h
libisofs/tree.c
libisofs/find.c
libisofs/image.h
libisofs/fs_local.c
libisofs/fs_image.c
libisofs/ecma119.h
libisofs/ecma119.c
libisofs/joliet.c
libisofs/iso1999.c
libisofs/eltorito.c
libisofs/rockridge.h
libisofs/rockridge.c
libisofs/ecma119_tree.c
libisofs/util_rbtree.c
libisofs/system_area.h
libisofs/system_area.c
libisofs/make_isohybrid_mbr.c
libisofs/buffer.h
libisofs/buffer.c
libisofs/md5.c
libisofs/stream.h
libisofs/util.h
libisofs/util.c
libisofs/libiso_msgs.h
libisofs/messages.c
libisofs/aaip_0_2.h
libisofs/aaip_0_2.c
libisofs/aaip-os-linux.c
libisofs/aaip-os-freebsd.c
doc/susp_aaip_2_0.txt
doc/checksums.txt
doc/boot_sectors.txt
Fixed spelling errors found by fossies.org with codespell
30 Oct 2019 [773be79]
libisofs/libisofs.h
libisofs/system_area.c
libisofs/buffer.c
libisofs/ecma119.h
Fixed more spelling errors found by fossies.org with codespell
24 Nov 2019 [c1d9639]
configure.ac
libisofs/libisofs.h
Switched to usage of libjte-2.0.0
26 Nov 2019 [ac24887]
configure.ac
Re-enabled variable LT_RELEASE in configure.ac. Disabling was unintentional.
13 Jun 2020 [c84f6ae]
libisofs/libisofs.h
Removed a germanism from description of iso_image_get_session_md5
13 Jun 2020 [6ca841e]
libisofs/fs_local.c
libisofs/fs_image.c
Reacted on compiler warnings of Debian Sid
13 Jun 2020 [69e332d]
libisofs/libisofs.h
libisofs/messages.c
libisofs/hfsplus.c
New error code ISO_HFSPLUS_TOO_MANY_FILES instead of ISO_MANGLE_TOO_MUCH_FILES
07 Jul 2020 [gitlab 2384800] [gitea b0230b6]
libisofs/system_area.c
Changed strncpy() to memcpy() in order to please static analyzers
07 Jul 2020 [gitlab 30a2e85] [gitea f962d0d]
libisofs/system_area.c
Bug fix: Big-Endian MIPS Volume Header boot file size was rounded up to full 2048. Thanks René Rebe.
21 Sep 2020 [d297ce3]
libisofs/util.c
Prevented time rollover outside year intervals 1900-2155 and 1-9999
14 Oct 2020 [b107443]
libisofs/libisofs.h
libisofs/libisofs.ver
libisofs/fs_image.c
libisofs/messages.c
libisofs/node.h
libisofs/node.c
libisofs/rockridge.h
libisofs/rockridge.c
libisofs/rockridge_read.c
libisofs/stream.h
libisofs/stream.c
libisofs/util.h
libisofs/util.c
libisofs/filters/zisofs.c
+ doc/zisofs2_format.txt
Implemented production and reading of zisofs2 for files larger than 4 GiB - 1.
New API call iso_stream_get_zisofs_par(). New struct iso_zisofs_ctrl version 2.
15 Oct 2020 [f291e37]
libisofs/filters/zisofs.c
Fixed wrong start block pointer of zisofs2 compression
17 Oct 2020 [2ca3b29]
libisofs/libisofs.h
libisofs/messages.c
libisofs/filters/zisofs.c
New iso_zisofs_ctrl parameter .block_number_target
18 Oct 2020 [239ba69]
libisofs/filters/zisofs.c
libisofs/fs_image.c
Accepting zisofs2 algorithms 2 to 5 for ZF by magic, but not for decompression
22 Oct 2020 [cc2e0e3]
libisofs/libisofs.h
libisofs/filters/zisofs.c
New iso_zisofs_ctrl parameters bpt_discard_file_blocks , bpt_discard_free_ratio
25 Oct 2020 [80449f0]
libisofs/libisofs.h
libisofs/libisofs.ver
libisofs/filters/zisofs.c
libisofs/image.c
New API calls iso_stream_zisofs_discard_bpt() and iso_image_zisofs_discard_bpt()
26 Oct 2020 [d5ffecf]
libisofs/filters/zisofs.c
Silenced a compiler warning if zlib is not enabled
27 Oct 2020 [dc61e7d]
libisofs/libisofs.h
libisofs/node.c
New flag bits 8 to 15 in API call iso_node_zf_by_magic()
29 Oct 2020 [2ac62f0]
libisofs/filters/zisofs.c
Fixed header size of ZF entries made for zisofs2 files compressed by libisofs
29 Oct 2020 [46186e5]
doc/zisofs2_format.txt
Added Z2 System Use Entry Format to zisofs2 specs
29 Oct 2020 [9605bbe]
libisofs/libisofs.h
libisofs/libisofs.ver
libisofs/rockridge.c
libisofs/fs_image.c
libisofs/rockridge_read.c
libisofs/filters/zisofs.c
New API call iso_zisofs_ctrl_susp_z2()
29 Oct 2020 [8d70c75]
Makefile.am
libisofs/rockridge.c
libisofs/rockridge_read.c
Added doc/zisofs2_format.txt to EXTRA_DIST
29 Oct 2020 [b7a90c5]
libisofs/libisofs.h
Corrected description of new call iso_zisofs_ctrl_susp_z2()
31 Oct 2020 [5a98a4c]
libisofs/fs_image.c
Corrected declaration of ziso_add_osiz_filter(). (Lapse in commit b107443)
07 Nov 2020 [b068764]
libisofs/eltorito.c
Bug fix: El Torito production failed if no catalog name was given and the
boot image path contains no slash
07 Nov 2020 [ac9d553]
libisofs/eltorito.c
Fixed a new bug introduced with previous commit
13 Nov 2020 [1d5566f]
README
Changed Public contact from libburn-hackers@pykix.org to bug-xorriso@gnu.org
13 Nov 2020 [7e3b01b]
libisofs/system_area.c
Bug fix: Apple Partition Map entries wrote uninitialized data
13 Nov 2020 [daaee5e]
libisofs/hfsplus.c
Fixed access to packed members of struct hfsplus_volheader.
Thanks Felipe Franciosi.
13 Nov 2020 [92af0c9]
libisofs/system_area.c
Adjusted fix 7e3b01b after learning that the bug stems from b0230b6 (unreleased)
14 Nov 2020 [29cc5c8]
libisofs/system_area.c
Prevented writing of undesired bytes in make_sun_disk_label() (commit b0230b6)
15 Nov 2020 [cece6fb]
libisofs/ecma119.c
libisofs/hfsplus.h
libisofs/hfsplus.c
libisofs/system_area.c
Bug fix: Appended APM partitions without HFS+ production had start and size 1
22 Nov 2020 [c068a19]
libisofs/libisofs.h
libisofs/libisofs.ver
libisofs/fs_image.c
New API call iso_read_opts_set_joliet_map(), new default joliet_map=stripped
26 Nov 2020 [8f3ff65]
libisofs/ecma119.c
libisofs/system_area.h
libisofs/system_area.c
Corrected size of GPT protective MBR partition with multi-session emulation
07 Dec 2020 [6241141]
libisofs/libisofs.h
libisofs/libisofs.ver
libisofs/fs_image.c
New API calls iso_read_image_features_tree_loaded() and
iso_read_image_features_rr_loaded()
07 Dec 2020 [2a20e93]
libisofs/fs_image.c
Small correction to commit 6241141
30 Jan 2021 [4219bf4]
configure.ac
libisofs/libisofs.h
Version leap to 1.5.4.
30 Jan 2021 []
ChangeLog
libisofs/changelog.txt
Updated change log
------------------------------------ release - libisofs-1.5.4 - 30 Jan 2021
* Bug fix: Big-Endian MIPS Volume Header boot file size was rounded up to
full 2048. Thanks René Rebe.
* Bug fix: El Torito production failed if no catalog path is given and the
first boot image path contains no slash
* Bug fix: zisofs production was wrong on big-endian machines
* Bug fix: Appended APM partitions without HFS+ production had start and size 1
* Switched to usage of libjte-2.0.0
* Implemented production and reading of zisofs2 for files larger than 4 GiB - 1.
* New struct iso_zisofs_ctrl version 2
* New API call iso_stream_get_zisofs_par()
* New API call iso_stream_zisofs_discard_bpt()
* New API call iso_image_zisofs_discard_bpt()
* New flag bits 8 to 15 in API call iso_node_zf_by_magic()
* New API call iso_zisofs_ctrl_susp_z2()
* New API call iso_read_opts_set_joliet_map(), new default joliet_map=stripped
* New API calls iso_read_image_features_tree_loaded() and
iso_read_image_features_rr_loaded()
------------------------------------ release - libisofs- -

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2016 Thomas Schmitt
* Copyright (c) 2009 - 2019 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
@ -573,10 +573,8 @@ 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);
if (t->pvd_size_is_total_size) {
iso_bb(vol.vol_space_size,
t->total_size / 2048 + t->opts->ms_block - 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);
@ -760,7 +758,7 @@ static
int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
{
size_t i, len;
uint8_t buf[64]; /* 64 is just a convenient size larger enought */
uint8_t buf[64]; /* 64 is just a convenient size larger enough */
struct ecma119_path_table_record *rec;
void (*write_int)(uint8_t*, uint32_t, int);
Ecma119Node *dir;
@ -1190,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];
@ -1204,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) {
@ -1231,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;
}
@ -1330,6 +1374,8 @@ ex:
/* @param flag bit0= initialize system area by target->opts_overwrite
bit1= fifo is not yet draining. Inquire write_count from fifo.
bit2= target->opts->ms_block is not counted in
target->total_size
*/
static
int write_head_part1(Ecma119Image *target, int *write_count, int flag)
@ -1352,7 +1398,7 @@ int write_head_part1(Ecma119Image *target, int *write_count, int flag)
/* Write System Area (ECMA-119, 6.2.1) */
if ((flag & 1) && target->opts_overwrite != NULL)
memcpy(sa, target->opts_overwrite, 16 * BLOCK_SIZE);
res = iso_write_system_area(target, sa);
res = iso_write_system_area(target, sa, (flag & 4) >> 2);
if (res < 0)
goto write_error;
res = iso_write(target, sa, 16 * BLOCK_SIZE);
@ -1417,9 +1463,10 @@ 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.
/* Not all writers have an entry in the partition volume descriptor set.
It must be guaranteed that they write exactly one block.
*/
@ -1455,7 +1502,7 @@ int write_head_part(Ecma119Image *target, int flag)
int res, write_count = 0;
/* System area and volume descriptors */
res = write_head_part1(target, &write_count, 0);
res = write_head_part1(target, &write_count, 4);
if (res < 0)
return res;
@ -1497,9 +1544,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 ,
@ -2000,6 +2044,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)
{
@ -2025,6 +2113,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)
@ -2084,7 +2180,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;
@ -2113,14 +2209,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;
@ -2331,7 +2420,7 @@ void ecma119_determine_now_time(Ecma119Image *target)
uint8_t time_text[18];
int i;
t0 = time(NULL);
iso_nowtime(&t0, 0);
o = target->opts;
if (o->vol_uuid[0]) {
for(i = 0; i < 16; i++)
@ -2399,6 +2488,12 @@ 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));
@ -2593,6 +2688,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;
@ -2610,6 +2707,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
target->hfsp_cat_node_size = 0;
target->hfsp_iso_block_fac = 0;
target->hfsp_collision_count = 0;
iso_setup_hfsplus_block_size(target);
target->apm_req_count = 0;
target->apm_req_flags = 0;
for (i = 0; i < ISO_APM_ENTRIES_MAX; i++)
@ -2691,6 +2789,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 */
@ -2817,34 +2921,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);
@ -2853,9 +2949,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.
@ -2913,7 +3018,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
* 3.
* Call compute_data_blocks() in each Writer.
* That function computes the size needed by its structures and
* increments image current block propertly.
* increments image current block properly.
*/
for (i = 0; i < (int) target->nwriters; ++i) {
IsoImageWriter *writer = target->writers[i];
@ -2939,13 +3044,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);
@ -2957,12 +3055,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;
@ -2999,6 +3109,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
@ -3010,12 +3121,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;
@ -3077,10 +3191,14 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
"Error reading overwrite volume descriptors");
goto target_cleanup;
}
/* Delete the filler partitions of GPT and APM so that write_function()
can insert new ones for a possibly different total_size */;
iso_delete_gpt_apm_fillers(target, 0);
}
/* 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;
/*
*/
@ -3244,11 +3362,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;
}
@ -3478,10 +3591,15 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->appended_partitions[i] = NULL;
wopts->appended_part_types[i] = 0;
wopts->appended_part_flags[i] = 0;
memset(wopts->appended_part_type_guids[i], 0, 16);
wopts->appended_part_gpt_flags[i] = 0;
}
wopts->appended_as_gpt = 0;
wopts->appended_as_apm = 0;
wopts->part_like_isohybrid = 0;
wopts->iso_mbr_part_type = -1;
memset(wopts->iso_gpt_type_guid, 0, 16);
wopts->iso_gpt_flag= 0;
wopts->ascii_disc_label[0] = 0;
wopts->will_cancel = 0;
wopts->allow_dir_id_ext = 0;
@ -4199,6 +4317,20 @@ int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
return ISO_SUCCESS;
}
int iso_write_opts_set_part_type_guid(IsoWriteOpts *opts, int partition_number,
uint8_t guid[16], int valid)
{
if (partition_number < 1 || partition_number > ISO_MAX_PARTITIONS)
return ISO_BAD_PARTITION_NO;
if (valid)
memcpy(opts->appended_part_type_guids[partition_number - 1], guid, 16);
if (valid)
opts->appended_part_gpt_flags[partition_number - 1]|= 1;
else
opts->appended_part_gpt_flags[partition_number - 1]&= ~1;
return ISO_SUCCESS;
}
int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt)
{
opts->appended_as_gpt = !!gpt;
@ -4217,6 +4349,23 @@ int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int 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_iso_type_guid(IsoWriteOpts *opts, uint8_t guid[16],
int valid)
{
if (valid)
memcpy(opts->iso_gpt_type_guid, guid, 16);
opts->iso_gpt_flag = (opts->iso_gpt_flag & ~1) | !!valid;
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);
@ -4262,7 +4411,7 @@ int iso_write_opts_set_gpt_guid(IsoWriteOpts *opts, uint8_t guid[16], int mode)
* 0= generic (to_charset is valid, no reserved characters,
* no length limits)
* 1= Rock Ridge (to_charset is valid)
* 2= Joliet (to_charset gets overriden by UCS-2 or UTF-16)
* 2= Joliet (to_charset gets overridden by UCS-2 or UTF-16)
* 3= ECMA-119 (dull ISO 9660 character set)
* 4= HFS+ (to_charset gets overridden by UTF-16BE)
* bit8= Treat input text as directory name
@ -4481,3 +4630,43 @@ ex: /* LIBISO_ALLOC_MEM failed */
return NULL;
}
/* Determines the range of valid partition numbers depending on partition
table type.
*/
void iso_tell_max_part_range(IsoWriteOpts *opts,
int *first_partition, int *last_partition,
int flag)
{
int sa_type;
sa_type = (opts->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;
}
}
/* 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 i, count= 0;
iso_tell_max_part_range(target->opts, first_partition, last_partition, 0);
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 - 2019 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
@ -33,7 +33,7 @@
#define MAX_ISO_FILE_SECTION_SIZE 0xffffffff
/*
* When a file need to be splitted in several sections, the maximum size
* When a file need to be split in several sections, the maximum size
* of such sections, but the last one. Set to a multiple of BLOCK_SIZE.
* Default to 4GB - 2048 = 0xFFFFF800
*/
@ -88,7 +88,7 @@
/* How many warnings to issue about writing Joliet names which cannot be
properly represented in UCS-2 and thus had to be defaultet to '_'.
properly represented in UCS-2 and thus had to be defaulted to '_'.
*/
#define ISO_JOLIET_UCS2_WARN_MAX 3
@ -111,7 +111,7 @@ struct iso_write_opts {
unsigned int aaip :1; /* whether to write eventual ACL and EAs */
/* allways write timestamps in GMT */
/* always write timestamps in GMT */
unsigned int always_gmt :1;
/*
@ -183,7 +183,7 @@ struct iso_write_opts {
/**
* Allow all characters to be part of Volume and Volset identifiers on
* the Primary Volume Descriptor. This breaks ISO-9660 contraints, but
* the Primary Volume Descriptor. This breaks ISO-9660 constraints, but
* should work on modern systems.
*/
unsigned int relaxed_vol_atts :1;
@ -287,7 +287,7 @@ struct iso_write_opts {
/**
* The following options set the default values for files and directory
* permissions, gid and uid. All these take one of three values: 0, 1 or 2.
* If 0, the corresponding attribute will be kept as setted in the IsoNode.
* If 0, the corresponding attribute will be kept as set in the IsoNode.
* Unless you have changed it, it corresponds to the value on disc, so it
* is suitable for backup purposes. If set to 1, the corresponding attrib.
* will be changed by a default suitable value. Finally, if you set it to
@ -349,7 +349,7 @@ struct iso_write_opts {
* or write to an .iso file for future burning or distribution.
*
* On the other side, an appendable image is not self contained, it refers
* to serveral files that are stored outside the image. Its usage is for
* to several files that are stored outside the image. Its usage is for
* multisession discs, where you add data in a new session, while the
* previous session data can still be accessed. In those cases, the old
* data is not written again. Instead, the new image refers to it, and thus
@ -381,7 +381,7 @@ struct iso_write_opts {
/**
* When not NULL, it should point to a buffer of at least 64KiB, where
* libisofs will write the contents that should be written at the beginning
* of a overwriteable media, to grow the image. The growing of an image is
* of a overwritable media, to grow the image. The growing of an image is
* a way, used by first time in growisofs by Andy Polyakov, to allow the
* appending of new data to non-multisession media, such as DVD+RW, in the
* same way you append a new session to a multisession disc, i.e., without
@ -393,7 +393,7 @@ struct iso_write_opts {
*
* You should initialize the buffer either with 0s, or with the contents of
* the first blocks of the image you're growing. In most cases, 0 is good
* enought.
* enough.
*/
uint8_t *overwrite;
@ -476,12 +476,19 @@ struct iso_write_opts {
char *efi_boot_partition;
int efi_boot_part_flag;
/* Eventual disk file paths of prepared images which shall be appended
after the ISO image and described by partiton table entries in a MBR
/* Disk file paths of prepared images which shall be appended
after the ISO image and described by partition table entries in a MBR.
NULL means unused.
*/
char *appended_partitions[ISO_MAX_PARTITIONS];
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
int appended_part_flags[ISO_MAX_PARTITIONS];
uint8_t appended_part_type_guids[ISO_MAX_PARTITIONS][16];
/* Flags in case that appended partitions show up in GPT:
bit0= appended_part_type_guids is valid
*/
uint8_t appended_part_gpt_flags[ISO_MAX_PARTITIONS];
/* If 1: With appended partitions: create protective MBR and mark by GPT
*/
@ -496,6 +503,22 @@ struct iso_write_opts {
*/
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;
/* iso_write_opts_set_iso_type_guid
*/
uint8_t iso_gpt_type_guid[16];
/* bit0= iso_gpt_type_guid is valid
*/
int iso_gpt_flag;
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
*/
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
@ -791,6 +814,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];
@ -1024,5 +1052,29 @@ 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);
/* Determines the range of valid partition numbers depending on partition
table type.
*/
void iso_tell_max_part_range(IsoWriteOpts *opts,
int *first_partition, int *last_partition,
int flag);
#endif /*LIBISO_ECMA119_H_*/

View File

@ -682,7 +682,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
}
/*
* A max of 7 characters is good enought, it allows handling up to
* A max of 7 characters is good enough, it allows handling up to
* 9,999,999 files with same name. We can increment this to
* max_name_len, but the int_pow() function must then be modified
* to return a bigger integer.

View File

@ -113,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
*/
@ -297,7 +312,7 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
node->node.hidden = parent->node.hidden;
/* current time */
now = time(NULL);
iso_nowtime(&now, 0);
node->node.atime = now;
node->node.ctime = now;
node->node.mtime = now;
@ -513,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));
@ -550,12 +566,10 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
/* get both the dir and the name */
catname = strrchr(catdir, '/');
if (catname == NULL) {
free(catdir);
return ISO_WRONG_ARG_VALUE;
}
if (catname == NULL)
catname = catdir;
if (catname == catdir) {
/* we are apending catalog to root node */
/* we are appending catalog to root node */
parent = image->root;
} else {
IsoNode *p;
@ -574,7 +588,8 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
}
parent = (IsoDir*)p;
}
catname++;
if (catname[0] == '/' || catname[0] == 0)
catname++;
ret = iso_tree_add_boot_node(parent, catname, &cat_node);
free(catdir);
if (ret < 0) {
@ -695,13 +710,14 @@ int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
return 0;
*catnode = bootcat;
*lba = bootcat->lba;
*size = bootcat->size;
if (bootcat->size > 0 && bootcat->content != NULL) {
*content = calloc(1, bootcat->size);
if (*content == NULL)
return ISO_OUT_OF_MEM;
memcpy(*content, bootcat->content, bootcat->size);
}
if (*content != NULL)
*size = bootcat->size;
return 1;
}
@ -887,6 +903,32 @@ 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
@ -930,6 +972,8 @@ int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
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);
@ -946,6 +990,9 @@ int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
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);
@ -956,7 +1003,8 @@ int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
}
iso_lsb(se->block, t->appended_part_start[app_idx], 4);
} else {
iso_lsb(se->sec_count, img->load_size, 2);
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);
}
@ -1457,11 +1505,6 @@ int eltorito_writer_create(Ecma119Image *target)
target->catalog->bootimages[idx]->appended_start;
target->boot_intvl_size[idx] =
target->catalog->bootimages[idx]->appended_size;
if (((target->system_area_options >> 2) & 0x3f) == 0 &&
(target->system_area_options & 3) == 1) {
/* ISO will not be a partition. It can span the whole image. */
target->pvd_size_is_total_size = 1;
}
continue;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 - 2014 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
@ -81,10 +81,18 @@ struct el_torito_boot_image {
* bit8= Mention in isohybrid Apple partition map
*/
unsigned int isolinux_options;
unsigned char type; /**< The type of image */
unsigned char type; /**< The type of image :
0=no emulation , 1=fd 1.2 MB , 2=fd 1.4 MB
3=fd 3.8 MB , 4=hdd (size in partition table)
*/
unsigned char partition_type; /**< type of partition for HD-emul images */
uint32_t emul_hdd_size; /* 512-bytes LBA after highest partition end from
HD-emul partition table
*/
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 */

File diff suppressed because it is too large Load Diff

View File

@ -65,7 +65,7 @@ int get_next(struct find_iter_data *iter, IsoNode **n)
iter->itersec = NULL;
}
if (ret != 0) {
/* succes or error */
/* success or error */
return ret;
}
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2016 Thomas Schmitt
* Copyright (c) 2009 - 2020 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
@ -103,13 +103,21 @@ struct iso_read_opts
* If neither Rock Ridge nor Joliet is used, the ECMA-119 names are mapped
* according to one of these rules
* 0 = unmapped: show name as recorded in ECMA-119 directory record
* (not suitable for writing them to a new ISO filesystem)
* (not suitable for writing it to a new ISO filesystem)
* 1 = stripped: like unmapped, but strip off trailing ";1" or ".;1"
* 2 = uppercase: like stripped, but {a-z} mapped to {A-Z}
* 3 = lowercase: like stripped, but {A-Z} mapped to {a-z}
*/
unsigned int ecma119_map : 2;
/**
* If Joliet is used, apply one of these mapping rules:
* 0 = unmapped: show name as recorded in Joliet directory record
* (not suitable for writing it to a new ISO filesystem)
* 1 = stripped: strip off trailing ";1" or ".;1"
*/
unsigned int joliet_map : 1;
uid_t uid; /**< Default uid when no RR */
gid_t gid; /**< Default uid when no RR */
mode_t dir_mode; /**< Default mode when no RR (only permissions) */
@ -179,6 +187,16 @@ struct iso_read_image_features
/** It will be set to 1 if El-Torito boot record is present, to 0 if not.*/
unsigned int hasElTorito :1;
/**
* Which tree was loaded:
* 0= ISO 9660 + Rock Ridge , 1= Joliet , 2= ISO 9660:1999
*/
int tree_loaded;
/** Whether Rock Ridge info was used while loading: 0= no, 1= yes */
int rr_loaded;
};
static int ifs_fs_open(IsoImageFilesystem *fs);
@ -212,7 +230,7 @@ typedef struct
unsigned int id;
/**
* Counter of the times the filesystem has been openned still pending of
* Counter of the times the filesystem has been opened still pending of
* close. It is used to keep track of when we need to actually open or
* close the IsoDataSource.
*/
@ -309,6 +327,7 @@ typedef struct
int truncate_mode;
int truncate_length;
unsigned int ecma119_map : 2;
unsigned int joliet_map : 1;
/** Whether AAIP info shall be loaded if it is present.
* 1 = yes , 0 = no
@ -325,6 +344,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.
*/
@ -371,7 +395,7 @@ typedef struct
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 +408,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;
@ -412,9 +437,10 @@ struct image_fs_data
unsigned int opened : 2; /**< 0 not opened, 1 opened file, 2 opened dir */
#ifdef Libisofs_with_zliB
uint8_t zisofs_algo[2];
uint8_t header_size_div4;
uint8_t block_size_log2;
uint32_t uncompressed_size;
uint64_t uncompressed_size;
#endif
/* info for content reading */
@ -592,7 +618,7 @@ int read_dir(ImageFileSourceData *data)
record = (struct ecma119_dir_record *)(buffer + pos);
if (pos == 2048 || record->len_dr[0] == 0) {
/*
* The directory entries are splitted in several blocks
* The directory entries are split in several blocks
* read next block
*/
ret = fsdata->src->read_block(fsdata->src, ++block, buffer);
@ -704,7 +730,7 @@ int ifs_open(IsoFileSource *src)
}
if (S_ISDIR(data->info.st_mode)) {
/* ensure fs is openned */
/* ensure fs is opened */
ret = data->fs->open(data->fs);
if (ret < 0) {
return ret;
@ -713,7 +739,7 @@ int ifs_open(IsoFileSource *src)
/*
* Cache all directory entries.
* This can waste more memory, but improves as disc is read in much more
* sequencially way, thus reducing jump between tracks on disc
* sequentially way, thus reducing jump between tracks on disc
*/
ret = read_dir(data);
data->fs->close(data->fs);
@ -727,7 +753,7 @@ int ifs_open(IsoFileSource *src)
return ret;
} else if (S_ISREG(data->info.st_mode)) {
/* ensure fs is openned */
/* ensure fs is opened */
ret = data->fs->open(data->fs);
if (ret < 0) {
return ret;
@ -739,7 +765,7 @@ int ifs_open(IsoFileSource *src)
data->data.offset = 0;
data->opened = 1;
} else {
/* symlinks and special files inside image can't be openned */
/* symlinks and special files inside image can't be opened */
return ISO_FILE_ERROR;
}
return ISO_SUCCESS;
@ -1102,7 +1128,7 @@ void ifs_free(IsoFileSource *src)
data = src->data;
/* close the file if it is already openned */
/* close the file if it is already opened */
if (data->opened) {
src->class->close(src);
}
@ -1246,9 +1272,9 @@ IsoFileSourceIface ifs_class = {
/* Used from libisofs/stream.c : iso_stream_get_src_zf() */
int iso_ifs_source_get_zf(IsoFileSource *src, int *header_size_div4,
int *block_size_log2, uint32_t *uncompressed_size,
int flag)
int iso_ifs_source_get_zf(IsoFileSource *src, uint8_t zisofs_algo[2],
int *header_size_div4, int *block_size_log2,
uint64_t *uncompressed_size, int flag)
{
#ifdef Libisofs_with_zliB
@ -1258,6 +1284,8 @@ int iso_ifs_source_get_zf(IsoFileSource *src, int *header_size_div4,
if (src->class != &ifs_class)
return 0;
data = src->data;
zisofs_algo[0] = data->zisofs_algo[0];
zisofs_algo[1] = data->zisofs_algo[1];
*header_size_div4 = data->header_size_div4;
*block_size_log2 = data->block_size_log2;
*uncompressed_size = data->uncompressed_size;
@ -1415,6 +1443,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),
@ -1453,7 +1482,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
#ifdef Libisofs_with_zliB
uint8_t zisofs_alg[2], zisofs_hs4 = 0, zisofs_bsl2 = 0;
uint32_t zisofs_usize = 0;
uint64_t zisofs_usize = 0;
#endif
if (fs == NULL || fs->data == NULL || record == NULL || src == NULL) {
@ -1576,16 +1605,18 @@ 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)
if (sue->version[0] != 1 &&
!(SUSP_SIG(sue, 'Z', 'F') || SUSP_SIG(sue, 'Z', '2')))
continue;
if (SUSP_SIG(sue, 'P', 'X')) {
@ -1699,7 +1730,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 +1751,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')) {
@ -1782,17 +1823,30 @@ if (name != NULL && !namecont) {
#ifdef Libisofs_with_zliB
} else if (SUSP_SIG(sue, 'Z', 'F')) {
} else if (SUSP_SIG(sue, 'Z', 'F') || SUSP_SIG(sue, 'Z', '2')) {
ret = read_zisofs_ZF(sue, zisofs_alg, &zisofs_hs4,
&zisofs_bsl2, &zisofs_usize, 0);
if (ret < 0 || zisofs_alg[0] != 'p' || zisofs_alg[1] != 'z') {
if (ret < 0) {
invalid_zf:
/* notify and continue */
ret = iso_rr_msg_submit(fsdata, 13, ISO_WRONG_RR_WARN, ret,
"Invalid ZF entry");
SUSP_SIG(sue, 'Z', 'F') ?
"Invalid ZF entry" :
"Invalid Z2 entry");
zisofs_hs4 = 0;
continue;
}
if (zisofs_alg[0] == 'p' || zisofs_alg[1] == 'z') {
if (sue->version[0] != 1)
goto invalid_zf;
} else if (zisofs_alg[0] == 'P' || zisofs_alg[1] == 'Z') {
if (sue->version[0] != 2)
goto invalid_zf;
} else {
ret = 0;
goto invalid_zf;
}
#endif /* Libisofs_with_zliB */
@ -1925,9 +1979,10 @@ if (name != NULL && !namecont) {
/* remove trailing version number */
len = strlen(name);
ecma119_map = fsdata->ecma119_map;
if (fsdata->iso_root_block == fsdata->svd_root_block)
ecma119_map = 0;
ecma119_map = fsdata->joliet_map;
else
ecma119_map = fsdata->ecma119_map;
if (ecma119_map >= 1 && ecma119_map <= 3 &&
len > 2 && name[len-2] == ';' && name[len-1] == '1') {
if (len > 3 && name[len-3] == '.') {
@ -1979,14 +2034,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;}
@ -2064,6 +2122,8 @@ if (name != NULL && !namecont) {
#ifdef Libisofs_with_zliB
if (zisofs_hs4 > 0) {
ifsdata->zisofs_algo[0] = zisofs_alg[0];
ifsdata->zisofs_algo[1] = zisofs_alg[1];
ifsdata->header_size_div4 = zisofs_hs4;
ifsdata->block_size_log2 = zisofs_bsl2;
ifsdata->uncompressed_size = zisofs_usize;
@ -2087,6 +2147,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;
@ -2308,7 +2373,7 @@ void ifs_fs_free(IsoFilesystem *fs)
data = (_ImageFsData*) fs->data;
/* close data source if already openned */
/* close data source if already opened */
if (data->open_count > 0) {
data->src->close(data->src);
}
@ -2341,7 +2406,7 @@ void ifs_fs_free(IsoFilesystem *fs)
/**
* Read the SUSP system user entries of the "." entry of the root directory,
* indentifying when Rock Ridge extensions are being used.
* identifying when Rock Ridge extensions are being used.
*
* @return
* 1 success, 0 ignored, < 0 error
@ -2392,13 +2457,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 +2508,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 +2655,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 +2710,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 */
@ -2847,6 +2908,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
free(data);
{ret = ISO_OUT_OF_MEM; goto ex;}
}
data->rr = RR_EXT_NO;
/* get our ref to IsoDataSource */
data->src = src;
@ -2891,7 +2953,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
goto fs_cleanup;
}
strncpy(ifs->type, "iso ", 4);
memcpy(ifs->type, "iso ", 4);
ifs->data = data;
ifs->refcount = 1;
ifs->version = 0;
@ -2962,7 +3024,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
}
break;
case 2:
/* suplementary volume descritor */
/* supplementary volume descritor */
{
struct ecma119_sup_vol_desc *sup;
struct ecma119_dir_record *root;
@ -3018,16 +3080,10 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
/* 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) {
data->rr = RR_EXT_NO;
} else {
if (ret < 0)
goto fs_cleanup;
if (!opts->norock)
data->rr = data->rr_version;
}
/* select what tree to read */
if (data->rr) {
@ -3067,6 +3123,7 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
data->truncate_mode = opts->truncate_mode;
data->truncate_length = opts->truncate_length;
data->ecma119_map = opts->ecma119_map;
data->joliet_map = opts->joliet_map;
if (data->input_charset == NULL) {
if (opts->input_charset != NULL) {
@ -3151,9 +3208,9 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
#ifdef Libisofs_with_zliB
/* Intimate friendship with this function in filters/zisofs.c */
int ziso_add_osiz_filter(IsoFile *file, uint8_t header_size_div4,
uint8_t block_size_log2,
uint32_t uncompressed_size, int flag);
int ziso_add_osiz_filter(IsoFile *file, uint8_t zisofs_algo[2],
uint8_t header_size_div4, uint8_t block_size_log2,
uint64_t uncompressed_size, int flag);
#endif /* Libisofs_with_zliB */
@ -3267,7 +3324,8 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
#ifdef Libisofs_with_zliB
if (data->header_size_div4 > 0) {
ret = ziso_add_osiz_filter(file, data->header_size_div4,
ret = ziso_add_osiz_filter(file, data->zisofs_algo,
data->header_size_div4,
data->block_size_log2,
data->uncompressed_size, 0);
if (ret < 0) {
@ -3906,10 +3964,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 +3982,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;
@ -4035,10 +4098,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;
}
@ -4343,10 +4406,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;
}
@ -4920,7 +4983,7 @@ void iso_impsysa_report_blockpath(IsoImage *image,
return;
size = next_above - start_block;
/* Replace in msg "path" by "blks", report number in bytes */
/* Replace in msg "path" by "blks", report number in blocks of 2048 */
cpt = strstr(msg, "path");
if (cpt == NULL)
return;
@ -4975,12 +5038,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",
@ -5325,6 +5389,35 @@ int iso_report_help(char **doc, char ***result, int *line_count, int flag)
return ISO_SUCCESS;
}
static
uint32_t iso_impsysa_hdd_emul_size(IsoImage *image, IsoDataSource *src,
uint32_t lba, int flag)
{
uint32_t max_size = 0, start_lba, num_blocks;
int i, ret;
uint8_t *buffer = NULL;
/* Obtain first block of image */
LIBISO_ALLOC_MEM(buffer, uint8_t, 2048);
ret = src->read_block(src, lba, buffer);
if (ret < 0)
goto ex;
/* Check for magic number of MBR */
if (buffer[510] != 0x55 || buffer[511] != 0xaa)
goto ex;
for (i = 0; i < 4; i++) {
start_lba = iso_read_lsb(buffer + 454 + 16 * i, 4);
num_blocks = iso_read_lsb(buffer + 458 + 16 * i, 4);
if (start_lba + num_blocks > max_size)
max_size = start_lba + num_blocks;
}
ex:;
LIBISO_FREE_MEM(buffer);
return max_size;
}
static
int iso_eltorito_report(IsoImage *image, struct iso_impsysa_result *target,
int flag)
@ -5401,6 +5494,11 @@ int iso_eltorito_report(IsoImage *image, struct iso_impsysa_result *target,
if (lba_mem[i] != 0xffffffff) {
sprintf(msg, "El Torito img path : %3d ", i + 1);
iso_impsysa_report_blockpath(image, target, msg, lba_mem[i], 1);
if (img->type == 4 && img->emul_hdd_size > 0) {
sprintf(msg, "El Torito hdsiz/512: %3d %u",
i + 1, (unsigned int) img->emul_hdd_size);
iso_impsysa_line(target, msg);
}
}
sprintf(msg, "El Torito img opts : %3d ", i + 1);
if (img->seems_boot_info_table)
@ -5738,6 +5836,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);
@ -5853,6 +5955,15 @@ 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];
if (boot_image->type == 4) {
boot_image->emul_hdd_size = iso_impsysa_hdd_emul_size(
image, src,
data->bootblocks[idx], 0);
} else {
boot_image->emul_hdd_size = 0;
}
catalog->bootimages[catalog->num_bootimages] = boot_image;
boot_image = NULL;
@ -5924,10 +6035,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;
@ -5983,6 +6105,13 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
(*features)->hasIso1999 = data->iso1999;
(*features)->hasElTorito = data->eltorito;
(*features)->size = data->nblocks;
(*features)->tree_loaded = 0;
if (data->iso_root_block == data->svd_root_block)
(*features)->tree_loaded = 1;
else if (data->iso_root_block == data->evd_root_block &&
data->iso_root_block != data->pvd_root_block)
(*features)->tree_loaded = 2;
(*features)->rr_loaded = (data->rr != RR_EXT_NO);
}
if (data->md5_load) {
@ -6168,6 +6297,7 @@ int iso_read_opts_new(IsoReadOpts **opts, int profile)
ropts->dir_mode = 0555;
ropts->noaaip = 1;
ropts->ecma119_map = 1;
ropts->joliet_map = 1;
ropts->nomd5 = 1;
ropts->load_system_area = 0;
ropts->keep_import_src = 0;
@ -6272,6 +6402,16 @@ int iso_read_opts_set_ecma119_map(IsoReadOpts *opts, int ecma119_map)
return ISO_SUCCESS;
}
int iso_read_opts_set_joliet_map(IsoReadOpts *opts, int joliet_map)
{
if (opts == NULL)
return ISO_NULL_POINTER;
if (joliet_map < 0 || joliet_map > 1)
return 0;
opts->joliet_map = joliet_map;
return ISO_SUCCESS;
}
int iso_read_opts_set_default_uid(IsoReadOpts *opts, uid_t uid)
{
if (opts == NULL) {
@ -6388,6 +6528,22 @@ int iso_read_image_features_has_eltorito(IsoReadImageFeatures *f)
return f->hasElTorito;
}
/**
* Tells what directory tree was loaded:
* 0= ISO 9660 , 1 = Joliet , 2 = ISO 9660:1999
*/
int iso_read_image_features_tree_loaded(IsoReadImageFeatures *f)
{
return f->tree_loaded;
}
/**
* Tells whether Rock Ridge information was used while loading the tree.
*/
int iso_read_image_features_rr_loaded(IsoReadImageFeatures *f)
{
return f->rr_loaded;
}
/**
* Get the start addresses and the sizes of the data extents of a file 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
@ -50,7 +50,7 @@ typedef struct
/** reference to the parent (if root it points to itself) */
IsoFileSource *parent;
char *name;
unsigned int openned :2; /* 0: not openned, 1: file, 2:dir */
unsigned int openned :2; /* 0: not opened, 1: file, 2:dir */
union
{
int fd;
@ -483,7 +483,7 @@ void lfs_free(IsoFileSource *src)
data = src->data;
/* close the file if it is already openned */
/* close the file if it is already opened */
if (data->openned) {
src->class->close(src);
}
@ -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);
@ -812,7 +815,7 @@ int iso_local_filesystem_new(IsoFilesystem **fs)
}
/* fill struct */
strncpy(lfs->type, "file", 4);
memcpy(lfs->type, "file", 4);
lfs->refcount = 1;
lfs->version = 0;
lfs->data = NULL; /* we don't need private data */
@ -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

@ -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.
@ -543,11 +543,14 @@ int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
}
static void set_time (uint32_t *tm, uint32_t t)
static inline uint32_t mac_time_offset(uint32_t t)
{
iso_msb ((uint8_t *) tm, t + 2082844800, 4);
uint32_t val;
iso_msb ((uint8_t *) &val, t + 2082844800, sizeof(val));
return val;
}
int nop_writer_write_vol_desc(IsoImageWriter *writer)
{
return ISO_SUCCESS;
@ -615,9 +618,9 @@ write_sb (Ecma119Image *t)
/* Cleanly unmounted, software locked. */
iso_msb ((uint8_t *) &sb.attributes, (1 << 8) | (1 << 15), 4);
iso_msb ((uint8_t *) &sb.last_mounted_version, 0x6c69736f, 4);
set_time (&sb.ctime, t->now);
set_time (&sb.utime, t->now);
set_time (&sb.fsck_time, t->now);
sb.ctime = mac_time_offset(t->now);
sb.utime = mac_time_offset(t->now);
sb.fsck_time = mac_time_offset(t->now);
iso_msb ((uint8_t *) &sb.file_count, t->hfsp_nfiles, 4);
iso_msb ((uint8_t *) &sb.folder_count, t->hfsp_ndirs - 1, 4);
iso_msb ((uint8_t *) &sb.blksize, block_size, 4);
@ -850,12 +853,11 @@ int hfsplus_writer_write_data(IsoImageWriter *writer)
((uint8_t *) &common->type)[1] = t->hfsp_leafs[curnode].type;
iso_msb ((uint8_t *) &common->valence, t->hfsp_leafs[curnode].nchildren, 4);
iso_msb ((uint8_t *) &common->fileid, t->hfsp_leafs[curnode].cat_id, 4);
set_time (&common->ctime, t->hfsp_leafs[curnode].node->ctime);
set_time (&common->mtime, t->hfsp_leafs[curnode].node->mtime);
common->ctime = mac_time_offset(t->hfsp_leafs[curnode].node->ctime);
common->mtime = mac_time_offset(t->hfsp_leafs[curnode].node->mtime);
/* FIXME: distinguish attr_mtime and mtime. */
set_time (&common->attr_mtime, t->hfsp_leafs[curnode].node->mtime);
set_time (&common->atime, t->hfsp_leafs[curnode].node->atime);
common->attr_mtime = mac_time_offset(t->hfsp_leafs[curnode].node->mtime);
common->atime = mac_time_offset(t->hfsp_leafs[curnode].node->atime);
iso_msb ((uint8_t *) &common->uid, px_get_uid (t, t->hfsp_leafs[curnode].node), 4);
iso_msb ((uint8_t *) &common->gid, px_get_gid (t, t->hfsp_leafs[curnode].node), 4);
iso_msb ((uint8_t *) &common->mode, px_get_mode (t, t->hfsp_leafs[curnode].node, (t->hfsp_leafs[curnode].type == HFSPLUS_DIR)), 2);
@ -1577,6 +1579,14 @@ int mangle_leafs(Ecma119Image *target, int flag)
return ISO_SUCCESS;
}
void iso_setup_hfsplus_block_size(Ecma119Image *target)
{
if (target->opts->hfsp_block_size == 0)
target->opts->hfsp_block_size = HFSPLUS_DEFAULT_BLOCK_SIZE;
target->hfsp_cat_node_size = 2 * target->opts->hfsp_block_size;
target->hfsp_iso_block_fac = 2048 / target->opts->hfsp_block_size;
}
int hfsplus_writer_create(Ecma119Image *target)
{
int ret;
@ -1597,10 +1607,7 @@ int hfsplus_writer_create(Ecma119Image *target)
make_hfsplus_decompose_pages();
make_hfsplus_class_pages();
if (target->opts->hfsp_block_size == 0)
target->opts->hfsp_block_size = HFSPLUS_DEFAULT_BLOCK_SIZE;
target->hfsp_cat_node_size = 2 * target->opts->hfsp_block_size;
target->hfsp_iso_block_fac = 2048 / target->opts->hfsp_block_size;
iso_setup_hfsplus_block_size(target);
cat_node_size = target->hfsp_cat_node_size;
writer->compute_data_blocks = hfsplus_writer_compute_data_blocks;
@ -1790,9 +1797,9 @@ int hfsplus_writer_create(Ecma119Image *target)
if (target->hfsp_nnodes > (cat_node_size - 0x100) * 8)
{
iso_msg_submit(target->image->id, ISO_MANGLE_TOO_MUCH_FILES, 0,
iso_msg_submit(target->image->id, ISO_HFSPLUS_TOO_MANY_FILES, 0,
"HFS+ map nodes aren't implemented");
ret = ISO_MANGLE_TOO_MUCH_FILES;
ret = ISO_HFSPLUS_TOO_MANY_FILES;
goto ex;
}

View File

@ -197,5 +197,6 @@ extern const uint16_t hfsplus_casefold[];
int iso_get_hfsplus_name(char *input_charset, int imgid, char *name,
uint16_t **result, uint32_t *result_len, uint16_t **cmp_name);
void iso_setup_hfsplus_block_size(Ecma119Image *target);
#endif /* LIBISO_HFSPLUS_H */

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,75 @@ 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;
if (image == NULL)
return ISO_NULL_POINTER;
ret = image->blind_on_local_get_attrs;
if (flag & 1)
image->blind_on_local_get_attrs = 0;
return ret;
}
/*
* @param flag bit0= recursion is active
*/
static
int iso_dir_zisofs_discard_bpt(IsoDir *dir, int flag)
{
int ret;
IsoDirIter *iter = NULL;
IsoNode *node;
IsoDir *subdir;
IsoFile *file;
IsoStream *stream;
ret = iso_dir_get_children(dir, &iter);
if (ret < 0)
return ret;
while (iso_dir_iter_next(iter, &node) == 1) {
if (iso_node_get_type(node) == LIBISO_DIR) {
subdir = (IsoDir *) node;
ret = iso_dir_zisofs_discard_bpt(subdir, flag | 1);
if (ret < 0)
goto ex;
continue;
}
if (iso_node_get_type(node) != LIBISO_FILE)
continue;
file = (IsoFile *) node;
stream = iso_file_get_stream(file);
if (stream == NULL)
continue;
ret = iso_stream_zisofs_discard_bpt(stream, 0);
if (ret < 0)
goto ex;
}
ret = ISO_SUCCESS;
ex:;
if (iter != NULL)
iso_dir_iter_free(iter);
return ret;
}
/* API */
int iso_image_zisofs_discard_bpt(IsoImage *image, int flag)
{
int ret;
IsoDir *dir;
if (image == NULL)
return ISO_NULL_POINTER;
dir = image->root;
if (dir == NULL)
return ISO_SUCCESS;
ret = iso_dir_zisofs_discard_bpt(dir, 0);
return ret;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2016 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
@ -30,7 +30,7 @@
* Image is a context for image manipulation.
* 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.
* so images are completely independent and can be managed together.
* (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

@ -283,7 +283,7 @@ cmp_node(const void *f1, const void *f2)
/**
* TODO #00027 Follow ISO 9660:1999 specs when sorting files
* strcmp do not does exactly what ISO 9660:1999, 9.3, as characters
* < 0x20 " " are allowed, so name len must be taken into accout
* < 0x20 " " are allowed, so name len must be taken into account
*/
return strcmp(f->name, g->name);
}
@ -358,7 +358,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
}
/*
* A max of 7 characters is good enought, it allows handling up to
* A max of 7 characters is good enough, it allows handling up to
* 9,999,999 files with same name.
*/
while (digits < 8) {
@ -919,7 +919,7 @@ int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
int ret= ISO_SUCCESS;
uint8_t *zeros = NULL;
/* 256 is just a convenient size large enought */
/* 256 is just a convenient size large enough */
LIBISO_ALLOC_MEM(buf, uint8_t, 256);
path_table_size = 0;

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)
{
@ -455,7 +469,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
}
/*
* A max of 7 characters is good enought, it allows handling up to
* A max of 7 characters is good enough, it allows handling up to
* 9,999,999 files with same name.
*/
/* Important: joliet_create_mangled_name() relies on digits < 8 */
@ -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)) {
@ -1093,7 +1108,7 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
int ret= ISO_SUCCESS;
uint8_t *zeros = NULL;
/* 256 is just a convenient size large enought */
/* 256 is just a convenient size large enough */
LIBISO_ALLOC_MEM(buf, uint8_t, 256);
LIBISO_ALLOC_MEM(zeros, uint8_t, BLOCK_SIZE);
path_table_size = 0;

View File

@ -2,7 +2,12 @@
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
Message handling facility of libisofs.
Copyright (C) 2006-2016 Thomas Schmitt <scdbackup@gmx.net>,
provided under GPL version 2 or later
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
or later as published by the Free Software Foundation.
See COPYING file for details.
*/
@ -422,7 +427,7 @@ Range "elmom" : 0x00010000 to 0x0001ffff
------------------------------------------------------------------------------
Range "scdbackup" : 0x00020000 to 0x0002ffff
Acessing and defending drives:
Accessing and defending drives:
0x00020001 (SORRY,LOW) = Cannot open busy device
0x00020002 (SORRY,HIGH) = Encountered error when closing drive
@ -554,11 +559,11 @@ Range "vreixo" : 0x00030000 to 0x0003ffff
0x0003ffbc (FAILURE,HIGH) = Image already bootable
0x0003ffbb (FAILURE,HIGH) = Trying to use an invalid file as boot image
0x0003ff80 (FAILURE,HIGH) = Error on file operation
0x0003ff7f (FAILURE,HIGH) = Trying to open an already openned file
0x0003ff7f (FAILURE,HIGH) = Trying to open an already opened file
0x0003ff7e (FAILURE,HIGH) = Access to file is not allowed
0x0003ff7d (FAILURE,HIGH) = Incorrect path to file
0x0003ff7c (FAILURE,HIGH) = The file does not exist in the filesystem
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not openned
0x0003ff7b (FAILURE,HIGH) = Trying to read or close a file not opened
0x0003ff7a (FAILURE,HIGH) = Directory used where no dir is expected
0x0003ff79 (FAILURE,HIGH) = File read error
0x0003ff78 (FAILURE,HIGH) = Not dir used where a dir is expected
@ -609,7 +614,7 @@ X 0x00030203 (HINT,MEDIUM) = Unsupported El-Torito feature
X 0x00030204 (SORRY,HIGH) = Invalid file to be an El-Torito image
X 0x00030205 (WARNING,MEDIUM)= Cannot properly patch isolinux image
X 0x00030206 (WARNING,MEDIUM)= Copying El-Torito from a previous image without
X enought info about it
X enough info about it
X 0x00030301 (NOTE,MEDIUM) = Unsupported file type for Joliet tree

File diff suppressed because it is too large Load Diff

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;
@ -82,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;
@ -104,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;
@ -150,6 +153,8 @@ iso_image_set_volume_id;
iso_image_tree_clone;
iso_image_unref;
iso_image_update_sizes;
iso_image_was_blind_attrs;
iso_image_zisofs_discard_bpt;
iso_init;
iso_init_with_flag;
iso_interval_reader_destroy;
@ -163,6 +168,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;
@ -221,6 +227,7 @@ iso_node_unref;
iso_node_xinfo_get_cloner;
iso_node_xinfo_make_clonable;
iso_node_zf_by_magic;
iso_nowtime;
iso_obtain_msgs;
iso_read_image_features_destroy;
iso_read_image_features_get_size;
@ -228,6 +235,8 @@ iso_read_image_features_has_eltorito;
iso_read_image_features_has_iso1999;
iso_read_image_features_has_joliet;
iso_read_image_features_has_rockridge;
iso_read_image_features_rr_loaded;
iso_read_image_features_tree_loaded;
iso_read_opts_auto_input_charset;
iso_read_opts_free;
iso_read_opts_keep_import_src;
@ -238,6 +247,7 @@ iso_read_opts_set_default_permissions;
iso_read_opts_set_default_uid;
iso_read_opts_set_ecma119_map;
iso_read_opts_set_input_charset;
iso_read_opts_set_joliet_map;
iso_read_opts_set_new_inos;
iso_read_opts_set_no_aaip;
iso_read_opts_set_no_iso1999;
@ -260,12 +270,14 @@ iso_stream_get_id;
iso_stream_get_input_stream;
iso_stream_get_size;
iso_stream_get_source_path;
iso_stream_get_zisofs_par;
iso_stream_is_repeatable;
iso_stream_open;
iso_stream_read;
iso_stream_ref;
iso_stream_unref;
iso_stream_update_size;
iso_stream_zisofs_discard_bpt;
iso_symlink_get_dest;
iso_symlink_set_dest;
iso_text_to_sev;
@ -328,6 +340,8 @@ 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_iso_type_guid;
iso_write_opts_set_joliet;
iso_write_opts_set_joliet_long_names;
iso_write_opts_set_joliet_longer_paths;
@ -341,6 +355,7 @@ 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_part_type_guid;
iso_write_opts_set_partition_img;
iso_write_opts_set_prep_img;
iso_write_opts_set_pvd_times;
@ -358,6 +373,7 @@ iso_write_opts_set_system_area;
iso_write_opts_set_tail_blocks;
iso_write_opts_set_untranslated_name_len;
iso_write_opts_set_will_cancel;
iso_zisofs_ctrl_susp_z2;
iso_zisofs_get_params;
iso_zisofs_get_refcounts;
iso_zisofs_set_params;

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2002 - 2008 H. Peter Anvin
* Copyright (c) 2008 - 2015 Thomas Schmitt
* with special credits to H. Peter Anvin for isohybrid
* and to Matthew Garrett for isohybrid with GPT and APM
* with special credits to Matthew Garrett for isohybrid with GPT and APM
*
* 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
@ -702,7 +702,7 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
for (part = 1 ; part <= 4; part++) {
if ((int) part != part_number) {
/* if this_partition != partition_number: write 16 zero bytes
(this is now overriden by the eventual desire to announce
(this is now overridden by the eventual desire to announce
EFI and HFS boot images.)
*/
memset(wpt, 0, 16);

View File

@ -781,7 +781,7 @@ ex:;
* 1= session tag (End checksumming.)
* 2= superblock tag (System Area and Volume Descriptors)
* 3= tree tag (ECMA-119 and Rock Ridge tree)
* 4= relocated superblock tag (at LBA 0 of overwriteable media)
* 4= relocated superblock tag (at LBA 0 of overwritable media)
* Write to target->opts_overwrite rather than to iso_write().
*/
int iso_md5_write_tag(Ecma119Image *t, int flag)

View File

@ -160,7 +160,7 @@ int iso_init_with_flag(int flag)
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 */
/* The indentation is an advise of man gcc to help old compilers ignoring */
#if iso_libjte_req_major > LIBJTE_VERSION_MAJOR
#define Libisofs_libjte_dot_h_too_olD 1
#endif
@ -402,13 +402,13 @@ const char *iso_error_to_msg(int errcode)
case ISO_ZLIB_NOT_ENABLED:
return "Use of zlib was not enabled at compile time";
case ISO_ZISOFS_TOO_LARGE:
return "Cannot apply zisofs filter to file >= 4 GiB";
return "File too large. Cannot apply zisofs filter.";
case ISO_FILTER_WRONG_INPUT:
return "Filter input differs from previous run";
case ISO_ZLIB_COMPR_ERR:
return "zlib compression/decompression error";
case ISO_ZISOFS_WRONG_INPUT:
return "Input stream is not in zisofs format";
return "Input stream is not in a supported zisofs format";
case ISO_ZISOFS_PARAM_LOCK:
return "Cannot set global zisofs parameters while filters exist";
case ISO_ZLIB_EARLY_EOF:
@ -547,6 +547,22 @@ const char *iso_error_to_msg(int errcode)
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";
case ISO_HFSPLUS_TOO_MANY_FILES:
return "Too many files in HFS+ directory tree";
case ISO_ZISOFS_TOO_MANY_PTR:
return "Too many zisofs block pointers needed overall";
case ISO_ZISOFS_BPT_UNDERRUN:
return "Prevented zisofs block pointer counter underrun";
case ISO_ZISOFS_UNKNOWN_SIZE:
return "Cannot obtain size of zisofs compressed stream";
default:
return "Unknown error";
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2016 Thomas Schmitt
* Copyright (c) 2009 - 2020 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
@ -35,7 +35,7 @@ struct dir_iter_data
IsoNode *pos;
/* Some control flags.
* bit 0 -> 1 if next called, 0 reseted at start or on deletion
* bit 0 -> 1 if next called, 0 reset at start or on deletion
*/
int flag;
};
@ -49,7 +49,7 @@ void iso_node_ref(IsoNode *node)
}
/**
* Decrements the reference couting of the given node.
* Decrements the reference counting of the given node.
* If it reach 0, the node is free, and, if the node is a directory,
* its children will be unref() too.
*/
@ -586,7 +586,7 @@ int iso_node_get_hidden(IsoNode *node)
* if the dir already contains a node with the same name, whether to
* replace or not the old node with this.
* @return
* number of nodes in dir if succes, < 0 otherwise
* number of nodes in dir if success, < 0 otherwise
*/
int iso_dir_add_node(IsoDir *dir, IsoNode *child,
enum iso_replace_mode replace)
@ -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 */
@ -1456,6 +1460,7 @@ void iso_notify_dir_iters(IsoNode *node, int flag)
int iso_node_new_root(IsoDir **root)
{
IsoDir *dir;
time_t now;
dir = calloc(1, sizeof(IsoDir));
if (dir == NULL) {
@ -1463,7 +1468,8 @@ int iso_node_new_root(IsoDir **root)
}
dir->node.refcount = 1;
dir->node.type = LIBISO_DIR;
dir->node.atime = dir->node.ctime = dir->node.mtime = time(NULL);
iso_nowtime(&now, 0);
dir->node.atime = dir->node.ctime = dir->node.mtime = now;
dir->node.mode = S_IFDIR | 0555;
/* set parent to itself, to prevent root to be added to another dir */
@ -1824,6 +1830,7 @@ int attr_enlarge_list(char ***names, size_t **value_lengths, char ***values,
(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 +1856,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 +1989,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;
@ -2252,12 +2261,14 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
goto ex;
}
ret = aaip_encode_both_acl(a_text, d_text, st_mode,
&acl_len, &acl, 2 | 8);
&acl_len, &acl,
2 | 8 | ((flag & 4) << 2));
} else {
ret = 1;
if (access_text != NULL || default_text != NULL)
ret = aaip_encode_both_acl(access_text, default_text, st_mode,
&acl_len, &acl, 2 | 8);
&acl_len, &acl,
2 | 8 | ((flag & 4) << 2));
}
if (ret == -1)
ret = ISO_OUT_OF_MEM;
@ -2316,7 +2327,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
goto ex;
}
ret = aaip_encode_both_acl(access_text, default_text,
st_mode, &acl_len, &acl, 2 | 8);
st_mode, &acl_len, &acl,
2 | 8 | ((flag & 4) << 2));
if (ret < -3)
goto ex;
if (ret <= 0) {
@ -2428,22 +2440,25 @@ int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag)
* bit1= permission to overwrite existing zisofs_zf_info
* bit2= if no zisofs header is found:
* create xinfo with parameters which indicate no zisofs
* bit8-bit15= maximum zisofs version to be recognized (0 means 1)
* @return 1= zf xinfo added, 0= no zisofs data found ,
* 2= found existing zf xinfo and flag bit1 was not set
* <0 means error
*/
int iso_file_zf_by_magic(IsoFile *file, int flag)
{
int ret, stream_type, header_size_div4, block_size_log2;
uint32_t uncompressed_size;
int ret, stream_type, header_size_div4, block_size_log2, version;
uint64_t uncompressed_size;
IsoStream *stream, *input_stream;
struct zisofs_zf_info *zf = NULL;
void *xipt;
uint8_t algo[2];
/* Intimate friendship with this function in filters/zisofs.c */
int ziso_is_zisofs_stream(IsoStream *stream, int *stream_type,
uint8_t zisofs_algo[2],
int *header_size_div4, int *block_size_log2,
uint32_t *uncompressed_size, int flag);
uint64_t *uncompressed_size, int flag);
ret = iso_node_get_xinfo((IsoNode *) file, zisofs_zf_xinfo_func, &xipt);
if (ret == 1) {
@ -2460,13 +2475,18 @@ int iso_file_zf_by_magic(IsoFile *file, int flag)
break;
stream = input_stream;
}
ret = ziso_is_zisofs_stream(stream, &stream_type, &header_size_div4,
version = ((flag >> 8) & 0xff);
algo[0] = algo[1] = 0;
ret = ziso_is_zisofs_stream(stream, &stream_type, algo, &header_size_div4,
&block_size_log2, &uncompressed_size, 3);
if (ret < 0)
return ret;
if (version < 2 && ret > 0 && (algo[0] != 'p' || algo[1] != 'z'))
ret = 0;
if (ret != 1 || stream_type != 2) {
if (flag & 4)
if (!(flag & 4))
return 0;
algo[0] = algo[1] = 0;
header_size_div4 = 0;
block_size_log2 = 0;
uncompressed_size = 0;
@ -2474,6 +2494,8 @@ int iso_file_zf_by_magic(IsoFile *file, int flag)
zf = calloc(1, sizeof(struct zisofs_zf_info));
if (zf == NULL)
return ISO_OUT_OF_MEM;
zf->zisofs_algo[0] = algo[0];
zf->zisofs_algo[1] = algo[1];
zf->uncompressed_size = uncompressed_size;
zf->header_size_div4 = header_size_div4;
zf->block_size_log2 = block_size_log2;
@ -2491,7 +2513,7 @@ int iso_node_zf_by_magic(IsoNode *node, int flag)
IsoDir *dir;
if (node->type == LIBISO_FILE)
return iso_file_zf_by_magic((IsoFile *) node, flag);
return iso_file_zf_by_magic((IsoFile *) node, flag & 0xff06);
if (node->type != LIBISO_DIR || (flag & 8))
return 0;
@ -2512,7 +2534,7 @@ int iso_node_zf_by_magic(IsoNode *node, int flag)
return 0; /* Will not be zisofs format */
}
}
hflag = flag & ~6;
hflag = flag & 0xff06;
if ((flag & 1) && file->from_old_session)
hflag |= 1;
ret = iso_file_zf_by_magic(file, hflag);
@ -2734,7 +2756,7 @@ int iso_node_cmp_flag(IsoNode *n1, IsoNode *n2, int flag)
if (n1->type != n2->type)
return (n1->type < n2->type ? -1 : 1);
/* Imported or explicite ISO image node id has priority */
/* Imported or explicit ISO image node id has priority */
ret1 = (iso_node_get_id(n1, &fs_id1, &dev_id1, &ino_id1, 1) > 0);
ret2 = (iso_node_get_id(n2, &fs_id2, &dev_id2, &ino_id2, 1) > 0);
if (ret1 != ret2)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2016 Thomas Schmitt
* Copyright (c) 2009 - 2020 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
@ -284,7 +284,7 @@ int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link);
* Create a new special file node. As far as libisofs concerns,
* an special file is a block device, a character device, a FIFO (named pipe)
* or a socket. You can choose the specific kind of file you want to add
* by setting mode propertly (see man 2 stat).
* by setting mode properly (see man 2 stat).
*
* Note that special files are only written to image when Rock Ridge
* extensions are enabled. Moreover, a special file is just a directory entry
@ -437,9 +437,10 @@ int zisofs_zf_xinfo_func(void *data, int flag);
* Parameter structure which is to be managed by zisofs_zf_xinfo_func.
*/
struct zisofs_zf_info {
uint32_t uncompressed_size;
uint64_t uncompressed_size;
uint8_t header_size_div4;
uint8_t block_size_log2;
uint8_t zisofs_algo[2];
};
/**

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 - 2020 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
@ -378,7 +378,7 @@ int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
ret = strconv(str, input_charset, output_charset, name);
if (ret < 0) {
/* TODO we should check for possible cancelation */
/* TODO we should check for possible cancellation */
if (!(flag & 1))
iso_msg_submit(imgid, ISO_FILENAME_WRONG_CHARSET, ret,
"Charset conversion error. Cannot convert %s from %s to %s",
@ -573,7 +573,7 @@ int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
}
/*
* In this case we are sure we're writting to CE. Check for
* In this case we are sure we're writing to CE. Check for
* debug purposes
*/
if (ce == 0) {
@ -953,26 +953,42 @@ int pseudo_susp_add_PAD(Ecma119Image *t, struct susp_info *susp)
/**
* see doc/zisofs_format.txt : "ZF System Use Entry Format"
* see doc/zisofs2_format.txt : "ZF System Use Entry Format", "Z2 ..."
*/
static
int zisofs_add_ZF(Ecma119Image *t, struct susp_info *susp, int to_ce,
int header_size_div4, int block_size_log2,
uint32_t uncompressed_size, int flag)
uint8_t algo[2], int header_size_div4, int block_size_log2,
uint64_t uncompressed_size, int flag)
{
unsigned char *ZF = malloc(16);
/* Intimate friendship with this variable in filters/zisofs.c */
extern int iso_zisofs2_enable_susp_z2;
if (ZF == NULL) {
return ISO_OUT_OF_MEM;
}
ZF[0] = 'Z';
ZF[1] = 'F';
ZF[2] = (unsigned char) 16;
ZF[3] = (unsigned char) 1;
ZF[4] = (unsigned char) 'p';
ZF[5] = (unsigned char) 'z';
if (algo[0] == 'p' && algo[1] == 'z') {
ZF[3] = (unsigned char) 1;
} else {
ZF[3] = (unsigned char) 2;
if (iso_zisofs2_enable_susp_z2)
ZF[1] = '2';
}
ZF[4] = (unsigned char) algo[0];
ZF[5] = (unsigned char) algo[1];
ZF[6] = (unsigned char) header_size_div4;
ZF[7] = (unsigned char) block_size_log2;
iso_bb(&ZF[8], uncompressed_size, 4);
if (algo[0] == 'p' && algo[1] == 'z') {
if (uncompressed_size > (uint64_t) 0xffffffff)
return ISO_ZISOFS_TOO_LARGE;
iso_bb(&ZF[8], (uint32_t) uncompressed_size, 4);
} else {
iso_lsb64(&ZF[8], uncompressed_size);
}
if (to_ce) {
return susp_append_ce(t, susp, ZF);
} else {
@ -991,17 +1007,19 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
{
int ret, will_copy = 1, stream_type = 0, do_zf = 0;
int header_size_div4 = 0, block_size_log2 = 0;
uint32_t uncompressed_size = 0;
uint64_t uncompressed_size = 0;
IsoStream *stream = NULL, *input_stream, *last_stream, *first_stream;
IsoStream *first_filter = NULL;
IsoFile *file;
void *xipt;
struct zisofs_zf_info *zf;
uint8_t algo[2];
/* Intimate friendship with this function in filters/zisofs.c */
int ziso_is_zisofs_stream(IsoStream *stream, int *stream_type,
uint8_t zisofs_algo[2],
int *header_size_div4, int *block_size_log2,
uint32_t *uncompressed_size, int flag);
uint64_t *uncompressed_size, int flag);
if (!(flag & 1))
flag |= 2;
@ -1043,7 +1061,8 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
}
/* Determine stream type : 1=ziso , -1=osiz , 0=other */
ret = ziso_is_zisofs_stream(stream, &stream_type, &header_size_div4,
algo[0] = algo[1] = 0;
ret = ziso_is_zisofs_stream(stream, &stream_type, algo, &header_size_div4,
&block_size_log2, &uncompressed_size, 0);
if (ret < 0)
return ret;
@ -1054,7 +1073,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
do_zf = 1;
} else if(first_stream == last_stream || !will_copy) {
/* Try whether the image side stream remembers a ZF field */
ret = iso_stream_get_src_zf(first_stream, &header_size_div4,
ret = iso_stream_get_src_zf(first_stream, algo, &header_size_div4,
&block_size_log2, &uncompressed_size, 0);
if (ret == 1 && header_size_div4 > 0)
do_zf = 1;
@ -1068,6 +1087,8 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
header_size_div4 = zf->header_size_div4;
block_size_log2 = zf->block_size_log2;
uncompressed_size = zf->uncompressed_size;
algo[0] = zf->zisofs_algo[0];
algo[1] = zf->zisofs_algo[1];
if (header_size_div4 > 0)
do_zf = 1;
}
@ -1086,7 +1107,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
return 1;
/* write ZF field */
ret = zisofs_add_ZF(t, info, (*ce_len > 0), header_size_div4,
ret = zisofs_add_ZF(t, info, (*ce_len > 0), algo, header_size_div4,
block_size_log2, uncompressed_size, 0);
if (ret < 0)
return ret;
@ -1249,7 +1270,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
/*
* ok, we need a Continuation Area anyway
* TODO this can be handled better, but for now SL
* will be completelly moved into the CA
* will be completely moved into the CA
*/
if (!(flag & 1)) {
free(dest);
@ -1600,7 +1621,7 @@ void susp_info_free(struct susp_info* susp)
* Pointer to the struct susp_info where the entries will be stored.
* If some entries need to go to a Continuation Area, they will be added
* to the existing ce_susp_fields, and ce_len will be incremented
* propertly. Please ensure ce_block is initialized propertly.
* properly. Please ensure ce_block is initialized properly.
* @return
* 1 success, < 0 error
*/
@ -1837,7 +1858,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
/*
* ok, we need a Continuation Area anyway
* TODO this can be handled better, but for now SL
* will be completelly moved into the CA
* will be completely moved into the CA
*/
/* sua_free, ce_len, nm_type already account for CE */
@ -2201,7 +2222,7 @@ int susp_update_CE_sizes(Ecma119Image *t, struct susp_info *info, int flag)
* fields are not written.
* If info does not contain any SUSP entry this function just return.
* After written, the info susp_fields array will be freed, and the counters
* updated propertly.
* updated properly.
*/
void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
uint8_t *buf)

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 - 2020 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
@ -219,7 +219,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
* Pointer to the struct susp_info where the entries will be stored.
* If some entries need to go to a Continuation Area, they will be added
* to the existing ce_susp_fields, and ce_len will be incremented
* propertly. Please ensure ce_block is initialized propertly.
* properly. Please ensure ce_block is initialized properly.
* @return
* 1 success, < 0 error
*/
@ -231,7 +231,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
* fields are not written.
* If info does not contain any SUSP entry this function just return.
* After written, the info susp_fields array will be freed, and the counters
* updated propertly.
* updated properly.
*/
void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
uint8_t *buf);
@ -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.
@ -358,7 +359,7 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
*/
int read_zisofs_ZF(struct susp_sys_user_entry *zf, uint8_t algorithm[2],
uint8_t *header_size_div4, uint8_t *block_size_log2,
uint32_t *uncompressed_size, int flag);
uint64_t *uncompressed_size, int flag);
/**
* Convert a RR filename to the requested charset.

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);
@ -572,29 +617,36 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
}
/**
* Reads the zisofs parameters from a ZF field (see doc/zisofs_format.txt).
* Reads the zisofs parameters from a ZF field (see doc/zisofs_format.txt
* and doc/zisofs2_format.txt).
*
* @return
* 1 on success, < 0 on error
*/
int read_zisofs_ZF(struct susp_sys_user_entry *zf, uint8_t algorithm[2],
uint8_t *header_size_div4, uint8_t *block_size_log2,
uint32_t *uncompressed_size, int flag)
uint64_t *uncompressed_size, int flag)
{
if (zf == NULL) {
return ISO_NULL_POINTER;
}
if (zf->sig[0] != 'Z' || zf->sig[1] != 'F') {
if ((zf->sig[0] != 'Z' || zf->sig[1] != 'F') &&
(zf->sig[0] != 'Z' || zf->sig[1] != '2'))
return ISO_WRONG_ARG_VALUE;
}
if (zf->len_sue[0] != 16) {
return ISO_WRONG_RR;
}
if (zf->version[0] > 2)
return ISO_WRONG_RR;
algorithm[0] = zf->data.ZF.parameters[0];
algorithm[1] = zf->data.ZF.parameters[1];
*header_size_div4 = zf->data.ZF.parameters[2];
*block_size_log2 = zf->data.ZF.parameters[3];
*uncompressed_size = iso_read_bb(&(zf->data.ZF.parameters[4]), 4, NULL);
if (zf->version[0] == 1)
*uncompressed_size = iso_read_bb(&(zf->data.ZF.parameters[4]), 4,
NULL);
else
*uncompressed_size = iso_read_lsb64(&(zf->data.ZF.parameters[4]));
return ISO_SUCCESS;
}

View File

@ -290,25 +290,25 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream)
}
int iso_stream_get_src_zf(IsoStream *stream, int *header_size_div4,
int *block_size_log2, uint32_t *uncompressed_size,
int flag)
int iso_stream_get_src_zf(IsoStream *stream, uint8_t zisofs_algo[2],
int *header_size_div4, int *block_size_log2,
uint64_t *uncompressed_size, int flag)
{
int ret;
FSrcStreamData *data;
IsoFileSource *src;
/* Intimate friendship with libisofs/fs_image.c */
int iso_ifs_source_get_zf(IsoFileSource *src, int *header_size_div4,
int *block_size_log2, uint32_t *uncompressed_size, int flag);
int iso_ifs_source_get_zf(IsoFileSource *src, uint8_t zisofs_algo[2],
int *header_size_div4, int *block_size_log2,
uint64_t *uncompressed_size, int flag);
if (stream->class != &fsrc_stream_class)
return 0;
data = stream->data;
src = data->src;
ret = iso_ifs_source_get_zf(src, header_size_div4, block_size_log2,
uncompressed_size, 0);
ret = iso_ifs_source_get_zf(src, zisofs_algo, header_size_div4,
block_size_log2, uncompressed_size, 0);
return ret;
}

View File

@ -37,7 +37,7 @@ void iso_stream_get_file_name(IsoStream *stream, char *name);
/**
* Create a stream to read from a IsoFileSource.
* The stream will take the ref. to the IsoFileSource, so after a successfully
* exectution of this function, you musn't unref() the source, unless you
* execution of this function, you must not unref() the source, unless you
* take an extra ref.
*
* @return
@ -65,9 +65,9 @@ int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
* type, though, unless fsrc_stream_class would be used without FSrcStreamData.
* @return 1= returned parameters are valid, 0=no ZF info found , <0 error
*/
int iso_stream_get_src_zf(IsoStream *stream, int *header_size_div4,
int *block_size_log2, uint32_t *uncompressed_size,
int flag);
int iso_stream_get_src_zf(IsoStream *stream, uint8_t zisofs_algo[2],
int *header_size_div4, int *block_size_log2,
uint64_t *uncompressed_size, int flag);
/**
* Set the inode number of a stream that is based on FSrcStreamData, i.e.

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2010 - 2016 Thomas Schmitt
* Copyright (c) 2010 - 2019 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;
@ -147,7 +153,10 @@ static int compute_partition_size(Ecma119Image *t, char *disk_path,
int iso_compute_append_partitions(Ecma119Image *t, int flag)
{
int ret, i, sa_type, cyl_align, cyl_size = 0;
int first_partition, last_partition;
uint32_t pos, size, add_pos = 0;
off_t start_byte, byte_count;
char msg[128];
sa_type = (t->system_area_options >> 2) & 0x3f;
cyl_align = (t->system_area_options >> 8) & 0x3;
@ -158,16 +167,49 @@ 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
iso_tell_max_part_range(t->opts, &first_partition, &last_partition, 0);
for (i = 0; i < ISO_MAX_PARTITIONS; i++) {
if (t->opts->appended_partitions[i] == NULL)
continue;
if (t->opts->appended_partitions[i][0] == 0)
continue;
if (i + 1 > last_partition || i + 1 < first_partition) {
sprintf(msg,
"Partition number %d of appended partition is out of range [%d - %d]",
i + 1, first_partition, last_partition);
iso_msgs_submit(0, msg, 0, "FAILURE", 0);
return ISO_BAD_PARTITION_NO;
}
ret = compute_partition_size(t, t->opts->appended_partitions[i], &size,
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 +226,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 +234,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 +342,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 {
@ -500,9 +555,12 @@ static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
stream = iso_file_get_stream((IsoFile *) node);
file_size = iso_stream_get_size(stream);
/* Shall i really round up to 2048 ? Steve says yes.*/
iso_msb(buf + (72 + 16 * idx) + 12,
((file_size + 2047) / 2048 ) * 2048, 4);
/* genisoimage rounds up to full multiples of 2048.
libisofs did this too until 2020, but the arcload mips boot loader
throws error if the rounded size is stored here.
So now the exact bytecount gets stored.
*/
iso_msb(buf + (72 + 16 * idx) + 12, file_size, 4);
}
@ -731,18 +789,21 @@ static int write_sun_partition_entry(int partition_number,
*/
static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag)
{
int ret, i;
int ret, i, l;
uint64_t blk;
/* Bytes 512 to 32767 may come from image or external file */
memset(buf, 0, 512);
/* 0 - 127 | label | ASCII Label */
if (t->opts->ascii_disc_label[0])
strncpy((char *) buf, t->opts->ascii_disc_label, 128);
else
if (t->opts->ascii_disc_label[0]) {
for (l = 0; l < 128 && t->opts->ascii_disc_label[l] != 0; l++);
if (l > 0)
memcpy((char *) buf, t->opts->ascii_disc_label, l);
} else {
strcpy((char *) buf,
"CD-ROM Disc with Sun sparc boot created by libisofs");
}
/* 128 - 131 | 1 | Layout version */
iso_msb(buf + 128, 1, 4);
@ -977,7 +1038,7 @@ int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
uint32_t start_block, uint32_t block_count,
char *name, char *type)
{
int ret;
int ret, l;
struct iso_apm_partition_request *entry;
entry = calloc(1, sizeof(struct iso_apm_partition_request));
@ -985,8 +1046,13 @@ int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
return ISO_OUT_OF_MEM;
entry->start_block = start_block;
entry->block_count = block_count;
strncpy((char *) entry->name, name, 32);
strncpy((char *) entry->type, type, 32);
for (l = 0; l < 32 && name[l] != 0; l++);
if (l > 0)
memcpy((char *) entry->name, name, l);
for (l = 0; l < 32 && type[l] != 0; l++);
if (l > 0)
memcpy((char *) entry->type, type, l);
entry->req_status = 0;
ret = iso_register_apm_entry(req_array, apm_req_count, entry, 0);
free(entry);
return ret;
@ -1032,6 +1098,7 @@ int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array,
memcpy(entry->partition_guid, partition_guid, 16);
entry->flags = flags;
memcpy(entry->name, name, 72);
entry->req_status = 0;
ret = iso_register_gpt_entry(req_array, gpt_req_count, entry, 0);
free(entry);
return ret;
@ -1243,6 +1310,8 @@ static int fill_apm_gaps(Ecma119Image *t, uint32_t img_blocks)
gap_name, "ISO9660_data");
if (ret < 0)
return ret;
/* Mark as automatically placed filler request */
t->apm_req[t->apm_req_count - 1]->req_status |= 1;
}
}
@ -1334,8 +1403,13 @@ static int iso_write_apm(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf,
/* Adjust last partition to img_size. This size was not known when the
number of APM partitions was determined.
*/
t->apm_req[t->apm_req_count - 1]->block_count =
img_blocks * block_fac - t->apm_req[t->apm_req_count - 1]->start_block;
if (img_blocks * block_fac <
t->apm_req[t->apm_req_count - 1]->start_block)
t->apm_req[t->apm_req_count - 1]->block_count = 0;
else
t->apm_req[t->apm_req_count - 1]->block_count =
img_blocks * block_fac -
t->apm_req[t->apm_req_count - 1]->start_block;
/* If it is still empty, remove it */
if(t->apm_req[t->apm_req_count - 1]->block_count == 0) {
free(t->apm_req[t->apm_req_count - 1]);
@ -1667,6 +1741,7 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
struct iso_gpt_partition_request *req;
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 *type_guid;
static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1;
if (t->gpt_req_count == 0)
@ -1715,19 +1790,25 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
}
} else if (part_end < goal) {
memset(gpt_name, 0, 72);
type_guid = basic_data_uuid;
if (goal == t->vol_space_size * (uint64_t) 4 &&
part_end == t->opts->partition_offset * (uint64_t) 4)
part_end == t->opts->partition_offset * (uint64_t) 4) {
sprintf((char *) gpt_name, "ISO9660");
else
if (t->opts->iso_gpt_flag & 1)
type_guid = t->opts->iso_gpt_type_guid;
} else {
sprintf((char *) gpt_name, "Gap%d", gap_counter);
}
iso_ascii_utf_16le(gpt_name);
gap_counter++;
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
part_end, goal - part_end,
basic_data_uuid, zero_uuid,
type_guid, zero_uuid,
gpt_flags, gpt_name);
if (ret < 0)
return ret;
/* Mark as automatically placed filler request */
t->gpt_req[t->gpt_req_count - 1]->req_status |= 1;
}
}
/* Merge list of gap partitions with list of already sorted entries */
@ -1777,7 +1858,7 @@ static void iso_dummy_mbr_partition(uint8_t *buf, int mode)
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 };
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] == 0x00) {
if (mbr_part_slot_is_unused(buf + 446 + 16 * i)) {
memcpy(buf + 446 + 16 * i, dummy_entry, 16);
return;
}
@ -1794,7 +1875,10 @@ static void iso_dummy_mbr_partition(uint8_t *buf, int mode)
}
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* @param flag
bit0= t->opts->ms_block is not counted in t->total_size
*/
int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag)
{
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;
@ -1812,17 +1896,20 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
memset(buf, 0, 16 * BLOCK_SIZE);
sa_type = (t->system_area_options >> 2) & 0x3f;
if (sa_type == 3) {
first_partition = 2;
last_partition = 8;
}
iso_tell_max_part_range(t->opts, &first_partition, &last_partition, 0);
for (i = first_partition - 1; i <= last_partition - 1; i++)
if (t->opts->appended_partitions[i] != NULL) {
will_append = 1;
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);
@ -1900,7 +1987,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
}
if (t->gpt_backup_outside)
gpt_blocks = t->total_size / BLOCK_SIZE + t->opts->ms_block;
gpt_blocks = t->total_size / BLOCK_SIZE +
(flag & 1) * t->opts->ms_block;
else
gpt_blocks = img_blocks;
ret = iso_write_gpt(t, gpt_blocks, buf);
@ -1918,6 +2006,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
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,
@ -1942,8 +2033,12 @@ 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;
@ -1985,9 +2080,13 @@ 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;
@ -1995,7 +2094,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* >>> ??? Do this in any case of t->gpt_req_count > ? */;
/* Re-write partion entry 1 : protective MBR for GPT */
/* Re-write partition entry 1 : protective MBR for GPT */
part_type = 0xee;
risk_of_ee = 1;
ret = write_mbr_partition_entry(1, part_type,
@ -2005,9 +2104,28 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (ret < 0)
return ret;
} else if (t->opts->partition_offset == 0) {
/* Re-write partion entry 1 : start at 0, type Linux */
/* Re-write partition 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)
return ret;
}
}
/* Check for protective MBR in mbr_req and adjust to GPT size */
if (t->gpt_req_count > 0 && sa_type == 0 && t->mbr_req_count == 1) {
if (t->mbr_req[0]->type_byte == 0xee && buf[450] == 0xee &&
t->mbr_req[0]->desired_slot <= 1) {
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,
buf, 2);
if (ret < 0)
@ -2020,9 +2138,20 @@ 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 */
#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;
mbrp1_blocks = t->total_size / BLOCK_SIZE +
(flag & 1) * t->opts->ms_block;
offset_flag |= 2 | 1; /* protective MBR, no other partitions */
} else {
mbrp1_blocks = img_blocks;
@ -2036,10 +2165,11 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
return ISO_ASSERT_FAILURE;
}
/* This eventually overwrites the non-mbr_req partition table entries
/* This possibly overwrites the non-mbr_req partition table entries
made so far. Overwriting those from t->mbr_req is not allowed.
*/
if (sa_type == 3 || !t->opts->appended_as_gpt) {
if (sa_type == 3 ||
!(t->opts->appended_as_gpt || t->opts->appended_as_apm)) {
for (i = first_partition - 1; i <= last_partition - 1; i++) {
if (t->opts->appended_partitions[i] == NULL)
continue;
@ -2066,6 +2196,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->num_bootsrc <= 0)
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"No boot image found as jump target for GRUB2 MBR.");
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.");
@ -2081,13 +2214,18 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* >>> ??? 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->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);
buf[446 + 16 * i + 4] = 0xcd;
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;
}
}
}
@ -2095,7 +2233,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
if (sa_type == 0 && (
(t->system_area_options & 3) ||
(t->system_area_options & (1 << 14)) ||
(((t->system_area_options >> 2) & 0x3f) == 2 &&
(((t->system_area_options >> 10) & 15) != 1 &&
(t->system_area_options & (1 << 15)))
)) {
/* This is an MBR which shall have a bootable/active flag
@ -2106,7 +2244,7 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
break;
if (i >= 4) { /* no bootable/active flag set yet */
for (i = 0; i < 4; i++) {
if (buf[446 + 16 * i + 4] != 0x00 &&
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;
@ -2120,6 +2258,16 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
}
}
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;
}
@ -2159,6 +2307,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)
@ -2172,7 +2324,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)
@ -2251,7 +2418,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);
@ -2474,9 +2651,14 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
0x28, 0x73, 0x2a, 0xc1, 0x1f, 0xf8, 0xd2, 0x11,
0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b
};
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};
int i, ret, do_apm = 0, do_gpt = 0, index, already_in_gpt;
int i, ret, do_apm = 0, do_gpt = 0, index, already_in_gpt = 0;
uint8_t gpt_name[72], *type_uuid;
char apm_type[33];
#ifndef Libisofs_appended_partitions_inlinE
if (!t->gpt_backup_outside)
@ -2500,10 +2682,16 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
if (do_apm) {
memset(gpt_name, 0, 32);
sprintf((char *) gpt_name, "Appended%d", i + 1);
strcpy(apm_type, "Data");
if (t->opts->appended_part_gpt_flags[i] & 1) {
if (memcmp(t->opts->appended_part_type_guids[i], hfs_plus_uuid,
16) == 0)
strcpy(apm_type, "Apple_HFS");
}
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");
(char *) gpt_name, apm_type);
if (ret < 0)
return ret;
}
@ -2516,7 +2704,9 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
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)
if (t->opts->appended_part_gpt_flags[i] & 1)
type_uuid = t->opts->appended_part_type_guids[i];
else if (t->opts->appended_part_types[i] == 0xef)
type_uuid = efi_sys_uuid;
else
type_uuid = basic_data_uuid;
@ -2584,6 +2774,11 @@ static int precompute_gpt(Ecma119Image *t)
do not adjust final APM partition size */
}
/* Assess impact of appended partitions on GPT */
ret = assess_appended_gpt(t, 0);
if (ret < 0)
return ret;
/* Rectify APM requests early in order to learn the size of GPT.
iso_write_apm() relies on this being already done here.
So perform even if no GPT is required.
@ -2592,9 +2787,6 @@ static int precompute_gpt(Ecma119Image *t)
if (ret < 0)
return ret;
/* Assess impact of appended partitions on GPT */
ret = assess_appended_gpt(t, 0);
#ifdef NIX
/* Disabled */
@ -2821,10 +3013,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] = {
@ -2842,6 +3036,7 @@ static int partprepend_writer_compute_data_blocks(IsoImageWriter *writer)
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.
@ -2853,23 +3048,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) {
@ -2884,36 +3091,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;
@ -3013,20 +3243,15 @@ static int partappend_writer_write_vol_desc(IsoImageWriter *writer)
static int partappend_writer_write_data(IsoImageWriter *writer)
{
Ecma119Image *target;
int res, first_partition = 1, last_partition = 0, sa_type;
int res, first_partition = 1, last_partition = 0;
int i;
target = writer->target;
/* 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_tell_max_part_range(target->opts,
&first_partition, &last_partition, 0);
for (i = first_partition - 1; i <= last_partition - 1; i++) {
if (target->opts->appended_partitions[i] == NULL)
continue;
@ -3036,7 +3261,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];
@ -3075,3 +3300,42 @@ int partappend_writer_create(Ecma119Image *target)
#endif /* Libisofs_appended_partitions_inlinE */
void iso_delete_gpt_apm_fillers(Ecma119Image *target, int flag)
{
int i, widx;
/* Dispose the requests with req_status bit0 */
for (i = 0; i < target->gpt_req_count; i++) {
if (target->gpt_req[i]->req_status & 1) {
free(target->gpt_req[i]);
target->gpt_req[i] = NULL;
}
}
/* Densify the request arrays */
widx = 0;
for (i = 0; i < target->gpt_req_count; i++) {
if (target->gpt_req[i] != NULL) {
target->gpt_req[widx] = target->gpt_req[i];
widx++;
}
}
target->gpt_req_count = widx;
/* And again for APM */
for (i = 0; i < target->apm_req_count; i++) {
if (target->apm_req[i]->req_status & 1) {
free(target->apm_req[i]);
target->apm_req[i] = NULL;
}
}
widx = 0;
for (i = 0; i < target->apm_req_count; i++) {
if (target->apm_req[i] != NULL) {
target->apm_req[widx] = target->apm_req[i];
widx++;
}
}
target->apm_req_count = widx;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2012 - 2015 Thomas Schmitt
* Copyright (c) 2012 - 2019 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
@ -42,10 +42,12 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag);
*
* @param buf
* A buffer with at least 32 K allocated
* @param flag
* bit0= t->opts->ms_block is not counted in t->total_size
* @return
* 1 if success, < 0 on error
*/
int iso_write_system_area(Ecma119Image *t, uint8_t *buf);
int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag);
/**
* Adjust t->tail_blocks to the eventual alignment needs of isohybrid booting.
@ -72,7 +74,7 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag);
in the table.
Requested entries with block_count == 0 get expanded to the start of
the next requested entry resp. to image end, if no entry follows.
start_block of a follwing entry must be at least a high as the sum of
start_block of a following entry must be at least a high as the sum of
start_block and block_count of the previous entry.
Empty requested entries will be represented as 16 bytes of 0.
*/
@ -155,6 +157,11 @@ struct iso_apm_partition_request {
*/
uint8_t name[32];
uint8_t type[32];
/* Status of the request object itself:
bit0= this is an automatically placed filler partition
*/
uint32_t req_status;
};
/* Copies the content of req and registers it in t.apm_req[].
@ -239,6 +246,11 @@ struct iso_gpt_partition_request {
/* Only if read from imported image: Table index of partition (first = 1)
*/
uint32_t idx;
/* Status of the request object itself:
bit0= this is an automatically placed filler partition
*/
uint32_t req_status;
};
/* Copies the content of req and registers it in t.gpt_req[].
@ -258,6 +270,11 @@ int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array,
uint8_t type_guid[16], uint8_t partition_guid[16],
uint64_t flags, uint8_t name[72]);
/* Deletes the partition requests for gap filling in GPT and APM.
Purpose is to get the request list clean again after a multi-session
emulation superblock was created and handed to the application.
*/
void iso_delete_gpt_apm_fillers(Ecma119Image *target, int flag);
/* Internal helper that will be used by system_area.c and make_isohybrid_mbr.c
*/
@ -317,9 +334,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

@ -43,11 +43,11 @@
* parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE.
* @param dir
* place where to store a pointer to the newly created dir. No extra
* ref is addded, so you will need to call iso_node_ref() if you really
* ref is added, so you will need to call iso_node_ref() if you really
* need it. You can pass NULL in this parameter if you don't need the
* pointer.
* @return
* number of nodes in dir if succes, < 0 otherwise
* number of nodes in dir if success, < 0 otherwise
* Possible errors:
* ISO_NULL_POINTER, if parent or name are NULL
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
@ -87,7 +87,7 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir)
iso_node_set_hidden((IsoNode*)node, parent->node.hidden);
/* current time */
now = time(NULL);
iso_nowtime(&now, 0);
iso_node_set_atime((IsoNode*)node, now);
iso_node_set_ctime((IsoNode*)node, now);
iso_node_set_mtime((IsoNode*)node, now);
@ -127,7 +127,7 @@ int iso_image_add_new_dir(IsoImage *image, IsoDir *parent, const char *name,
* destination of the link
* @param link
* place where to store a pointer to the newly created link. No extra
* ref is addded, so you will need to call iso_node_ref() if you really
* ref is added, so you will need to call iso_node_ref() if you really
* need it. You can pass NULL in this parameter if you don't need the
* pointer
* @return
@ -175,7 +175,7 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
iso_node_set_hidden((IsoNode*)node, parent->node.hidden);
/* current time */
now = time(NULL);
iso_nowtime(&now, 0);
iso_node_set_atime((IsoNode*)node, now);
iso_node_set_ctime((IsoNode*)node, now);
iso_node_set_mtime((IsoNode*)node, now);
@ -206,7 +206,7 @@ int iso_image_add_new_symlink(IsoImage *image, IsoDir *parent,
* Add a new special file to the directory tree. As far as libisofs concerns,
* an special file is a block device, a character device, a FIFO (named pipe)
* or a socket. You can choose the specific kind of file you want to add
* by setting mode propertly (see man 2 stat).
* by setting mode properly (see man 2 stat).
*
* Note that special files are only written to image when Rock Ridge
* extensions are enabled. Moreover, a special file is just a directory entry
@ -229,7 +229,7 @@ int iso_image_add_new_symlink(IsoImage *image, IsoDir *parent,
* device ID, equivalent to the st_rdev field in man 2 stat.
* @param special
* place where to store a pointer to the newly created special file. No
* extra ref is addded, so you will need to call iso_node_ref() if you
* extra ref is added, so you will need to call iso_node_ref() if you
* really need it. You can pass NULL in this parameter if you don't need
* the pointer.
* @return
@ -278,7 +278,7 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode,
iso_node_set_hidden((IsoNode*)node, parent->node.hidden);
/* current time */
now = time(NULL);
iso_nowtime(&now, 0);
iso_node_set_atime((IsoNode*)node, now);
iso_node_set_ctime((IsoNode*)node, now);
iso_node_set_mtime((IsoNode*)node, now);
@ -319,7 +319,7 @@ int iso_image_add_new_special(IsoImage *image, IsoDir *parent,
* IsoStream for the contents of the file
* @param file
* place where to store a pointer to the newly created file. No extra
* ref is addded, so you will need to call iso_node_ref() if you really
* ref is added, so you will need to call iso_node_ref() if you really
* need it. You can pass NULL in this parameter if you don't need the
* pointer
* @return
@ -367,7 +367,7 @@ int iso_tree_add_new_file(IsoDir *parent, const char *name, IsoStream *stream,
iso_node_set_hidden((IsoNode*)node, parent->node.hidden);
/* current time */
now = time(NULL);
iso_nowtime(&now, 0);
iso_node_set_atime((IsoNode*)node, now);
iso_node_set_ctime((IsoNode*)node, now);
iso_node_set_mtime((IsoNode*)node, now);
@ -768,7 +768,7 @@ int check_excludes(IsoImage *image, const char *path)
return 1;
}
} else {
/* relative exclude, it is enought if a part of the path matches */
/* relative exclude, it is enough if a part of the path matches */
char *pos = (char*)path;
while (pos != NULL) {
pos++;

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 - 2019 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
@ -18,7 +18,6 @@
#include "messages.h"
#include "joliet.h"
#include "node.h"
#include "../version.h"
#include <stdlib.h>
#include <wchar.h>
@ -1484,6 +1483,14 @@ void iso_lsb(uint8_t *buf, uint32_t num, int bytes)
buf[i] = (num >> (8 * i)) & 0xff;
}
void iso_lsb64(uint8_t *buf, uint64_t num)
{
int i;
for (i = 0; i < 8; ++i)
buf[i] = (num >> (8 * i)) & 0xff;
}
void iso_msb(uint8_t *buf, uint32_t num, int bytes)
{
int i;
@ -1598,6 +1605,22 @@ void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
gmtime_r(&t, &tm);
tzoffset = 0;
}
if (tm.tm_year < 0) {
tm.tm_year = 0;
tm.tm_mon = 0;
tm.tm_mday = 1;
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
} else if (tm.tm_year > 255) {
tm.tm_year = 255;
tm.tm_mon = 11;
tm.tm_mday = 31;
tm.tm_hour = 23;
tm.tm_min = 59;
tm.tm_sec = 59;
}
buf[0] = tm.tm_year;
buf[1] = tm.tm_mon + 1;
buf[2] = tm.tm_mday;
@ -1651,12 +1674,18 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
tzoffset = 0;
}
sprintf((char*)&buf[0], "%04d", tm.tm_year + 1900);
sprintf((char*)&buf[4], "%02d", tm.tm_mon + 1);
sprintf((char*)&buf[6], "%02d", tm.tm_mday);
sprintf((char*)&buf[8], "%02d", tm.tm_hour);
sprintf((char*)&buf[10], "%02d", tm.tm_min);
sprintf((char*)&buf[12], "%02d", MIN(59, tm.tm_sec));
if (tm.tm_year <= -1900) {
strcpy((char *) buf, "00010101000000");
} else if (tm.tm_year >= 8100) {
strcpy((char *) buf, "99991231235959");
} else {
sprintf((char*)&buf[0], "%04d", tm.tm_year + 1900);
sprintf((char*)&buf[4], "%02d", tm.tm_mon + 1);
sprintf((char*)&buf[6], "%02d", tm.tm_mday);
sprintf((char*)&buf[8], "%02d", tm.tm_hour);
sprintf((char*)&buf[10], "%02d", tm.tm_min);
sprintf((char*)&buf[12], "%02d", MIN(59, tm.tm_sec));
}
memcpy(&buf[14], "00", 2);
buf[16] = tzoffset;
@ -1943,7 +1972,7 @@ char *ucs2str(const char *buf, size_t len)
outbytes = (inbytes+1) * MB_LEN_MAX;
/* ensure enought space */
/* ensure enough space */
out = calloc(outbytes, 1);
if (out == NULL)
return NULL;
@ -1978,16 +2007,25 @@ ex:;
void iso_lib_version(int *major, int *minor, int *micro)
{
*major = iso_lib_header_version_major;
*minor = iso_lib_header_version_minor;
*micro = iso_lib_header_version_micro;
/* No more: values from version.h generated from version.h.in and
macro values defined in configure.ac
*major = LIBISOFS_MAJOR_VERSION;
*minor = LIBISOFS_MINOR_VERSION;
*micro = LIBISOFS_MICRO_VERSION;
*/
}
int iso_lib_is_compatible(int major, int minor, int micro)
{
int cmajor, cminor, cmicro;
/* for now, the rule is that library is compitable if requested
/* for now, the rule is that library is compatible if requested
* version is lower */
iso_lib_version(&cmajor, &cminor, &cmicro);
@ -2324,7 +2362,7 @@ int iso_clone_mgtd_mem(char *in, char **out, size_t size)
(Also accepts capital letters.)
@param text Input like "42", "223062s", "3m" or "-1g"
@param flag Bitfield for control purposes:
bit0= return -1 rathern than 0 on failure
bit0= return -1 rather than 0 on failure
bit1= if scaled then compute the last byte of the last unit
@return The derived value
*/
@ -2448,3 +2486,27 @@ int iso_truncate_leaf_name(int mode, int length, char *name, int flag)
return ret;
}
/* API */
/* @param flag bit0= *now contains the time to be set as nowtime override
bit1= disable the nowtime override
@return 1= *now is not overridden , 2= *now is overridden
*/
int iso_nowtime(time_t *now, int flag)
{
static int now_time_overridden = 0;
static time_t now_time_override = 0;
if (flag & 1) {
now_time_overridden = 1;
now_time_override = *now;
}
if (flag & 2) {
now_time_overridden = 0;
}
*now = time(NULL);
if (!now_time_overridden)
return 1;
*now = now_time_override;
return 2;
}

View File

@ -55,7 +55,7 @@ int iso_init_locale(int flag);
* @param ocharset
* Output charset. Must be supported by iconv
* @param output
* Location where the pointer to the ouput string will be stored
* Location where the pointer to the output string will be stored
* @return
* 1 on success, < 0 on error
*/
@ -80,7 +80,7 @@ int strnconvl(const char *str, const char *icharset, const char *ocharset,
* @param input
* Input string
* @param output
* Location where the pointer to the ouput string will be stored
* Location where the pointer to the output string will be stored
* @return
* 1 on success, < 0 on error
*/
@ -95,7 +95,7 @@ int str2ascii(const char *icharset, const char *input, char **output);
* @param input
* Input string
* @param output
* Location where the pointer to the ouput string will be stored
* Location where the pointer to the output string will be stored
* @return
* 1 on success, < 0 on error
*/
@ -111,7 +111,7 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output);
* @param input
* Input string
* @param output
* Location where the pointer to the ouput string will be stored
* Location where the pointer to the output string will be stored
* @return
* 1 on success, < 0 on error
*/
@ -258,12 +258,13 @@ void iso_handle_split_utf16(uint16_t *utf_word);
/**
* Convert a given input string to d-chars.
* @return
* 1 on succes, < 0 error, 0 if input was null (output is set to null)
* 1 on success, < 0 error, 0 if input was null (output is set to null)
*/
int str2d_char(const char *icharset, const char *input, char **output);
int str2a_char(const char *icharset, const char *input, char **output);
void iso_lsb(uint8_t *buf, uint32_t num, int bytes);
void iso_lsb64(uint8_t *buf, uint64_t num);
void iso_msb(uint8_t *buf, uint32_t num, int bytes);
void iso_bb(uint8_t *buf, uint32_t num, int bytes);
@ -400,7 +401,7 @@ size_t iso_rbtree_get_size(IsoRBTree *tree);
* without counting the final NULL item.
* @return
* A sorted array with the contents of the tree, or NULL if there is not
* enought memory to allocate the array. You should free(3) the array when
* enough memory to allocate the array. You should free(3) the array when
* no more needed. Note that the array is NULL-terminated, and thus it
* has size + 1 length.
*/
@ -646,7 +647,7 @@ int iso_clone_mgtd_mem(char *in, char **out, size_t size);
(Also accepts capital letters.)
@param text Input like "42", "223062s", "3m" or "-1g"
@param flag Bitfield for control purposes:
bit0= return -1 rathern than 0 on failure
bit0= return -1 rather than 0 on failure
bit1= if scaled then compute the last byte of the last unit
@return The derived value
*/

View File

@ -277,7 +277,7 @@ size_t rbtree_to_array_aux(struct iso_rbnode *root, void **array, size_t pos,
* NULL pointer.
* @return
* A sorted array with the contents of the tree, or NULL if there is not
* enought memory to allocate the array. You should free(3) the array when
* enough memory to allocate the array. You should free(3) the array when
* no more needed. Note that the array is NULL-terminated, and thus it
* has size + 1 length.
*/