Compare commits

...

80 Commits

Author SHA1 Message Date
Thomas Schmitt 78708015af Improved warning messages about symbolic links and special files in ISO 9660:1999 tree 2024-05-19 18:35:40 +02:00
Thomas Schmitt 57fcd4bfbb Fixed assessment of MIPS boot equipment which was broken by commit 405f0f0 2024-05-18 21:29:32 +02:00
Thomas Schmitt 483a68aaf2 Avoided use of uninitialized variables which was introduced by commit d9c548d 2024-05-18 13:42:37 +02:00
Thomas Schmitt 8ffd3b381b Clarified the API description of NULL data in iso_write_opts_set_system_area() 2024-05-12 21:56:15 +02:00
Thomas Schmitt d9c548dbfc Bug fix: File path of imported BIOS boot image was forgotten when it gets overwritten by a file of the same name. Thanks Brian C. Lane. 2024-05-12 13:56:29 +02:00
Thomas Schmitt 8ed27c6255 Enabled up to 8 appended GPT partitions and improved their number mapping 2024-05-10 17:25:07 +02:00
Thomas Schmitt 405f0f04d4 Improved size estimation and property assessment of El Torito hidden boot images 2023-11-20 11:42:41 +01:00
Thomas Schmitt 8a8439768c Clarified in the description of iso_image_set_boot_image() the meaning of pseudo-path parameters "start" and "size" 2023-11-20 09:15:18 +01:00
Thomas Schmitt 9ec998f9fc Updated copyright year in README 2023-06-09 19:57:42 +02:00
Thomas Schmitt 8a4f1f88ae Explicitely included unistd.h in all source file which use ssize_t 2023-06-09 19:54:50 +02:00
Thomas Schmitt 09ec2fa4b7 Bug fix: On non-GNU/Linux systems ssize_t was not defined in rockridge.h . Report and fix proposal by Rui Chen. 2023-06-09 19:48:54 +02:00
Thomas Schmitt 5a867c43ab Version leap to 1.5.7 2023-06-07 19:10:34 +02:00
Thomas Schmitt 170318c42e Updated change log 2023-06-07 13:32:06 +02:00
Thomas Schmitt c2d17b1c4b Version leap to 1.5.6 2023-06-07 13:28:22 +02:00
Thomas Schmitt cdc7f52187 Reduced number of warnings about special files or symlinks in Joliet 2023-04-14 17:47:07 +02:00
Thomas Schmitt bd415402f4 New API call iso_write_opts_set_max_ce_entries() 2023-01-22 16:03:44 +01:00
Thomas Schmitt 7109ba5675 Prevented endless CE loops when reading a very bad ISO fileystem 2023-01-11 12:06:28 +01:00
Thomas Schmitt d35435b5a0 Bug fix: Size of further CE area was calculated wrong if its CE entry ended exactly at a block boundary 2022-12-13 09:53:27 +01:00
Thomas Schmitt acb4bd143c Bug fix: Freshly cloned data files from imported image were not marked as
imported
2022-10-27 17:37:58 +02:00
Thomas Schmitt 71772baab7 Fixed assessment of omit_version_numbers and no_force_dots 2022-10-07 11:14:51 +02:00
Thomas Schmitt 83e5832ed0 New API calls iso_assess_written_features(), iso_read_image_feature_named(), iso_read_image_features_text() 2022-09-20 09:51:39 +02:00
Thomas Schmitt 9b7ccc9727 Improved error messages in case of failing Linux-specific ACL or xattr functions 2022-09-20 09:28:06 +02:00
Thomas Schmitt c6cb7dfa3e Widened the lseek capacity determination to SEEK_SET with wanted size 2022-05-30 18:38:54 +02:00
Thomas Schmitt ad55ec78e4 Avoided automatic MBR partition type 0x00 with iso_write_opts_set_part_like_isohybrid() if partitions do not overlap 2022-05-13 10:52:39 +02:00
Thomas Schmitt 011e2e85e6 Allowed lseekable device files with iso_tree_add_new_cut_out_node(). Proof-of-concept by Ivan Shmakov. 2022-04-26 12:12:15 +02:00
Thomas Schmitt f457a4f8b9 Added missing stream type names to a diagnostic function 2022-04-26 12:06:18 +02:00
Thomas Schmitt 2af17490a0 Bug fix: The lseek methods of IsoFileSource for local filesystem and loaded ISO returned libisofs error codes as positive off_t numbers 2022-04-26 12:03:53 +02:00
Thomas Schmitt da00291519 Let the original isohybrid GPT obey system_area() option bit 17: GPT writable 2022-04-23 09:32:44 +02:00
Thomas Schmitt 1d61b518b5 Bug fix: iso_write_opts_set_part_like_isohybrid() did not cause a MBR partition table if the partitions are data files in the ISO rather than appended 2022-04-23 09:30:34 +02:00
Thomas Schmitt 99251ade08 Avoid to overwrite the loaded MBR partition table just because partition offset is 16 2022-04-23 09:17:08 +02:00
Thomas Schmitt da8e3e66e7 Exempted MBR partitions of type 0xEE from being ignored due to wrong size 2022-04-22 13:39:56 +02:00
Thomas Schmitt 3e61a61a21 Updated URLs, build instructions, and copyright in README file 2021-10-28 19:44:26 +02:00
Thomas Schmitt 80a0691660 Removed unneeded configure.ac macro AC_C_BIGENDIAN 2021-09-02 20:04:16 +02:00
Thomas Schmitt 1c4c04d4e2 New iso_write_opts_set_system_area() option bits 16: GPT "Legacy BIOS bootable" and 17: GPT writable 2021-05-25 21:10:28 +02:00
Thomas Schmitt 75499bcda9 Silenced a warning on 32 bit about value ISO_ZISOFS_V1_LIMIT too large for int 2021-03-12 09:37:07 +01:00
Thomas Schmitt 9e389186f7 Leave prediction of first CE gap to susp_*_to_ce() functions 2021-02-28 17:21:35 +01:00
Thomas Schmitt 7d248c46e1 Ignore mad MBR partitions which extend outside of medium size 2021-02-28 16:16:18 +01:00
Thomas Schmitt 98aea0c18a Heuristic fix for a new problem introduced by commit 058f18d 2021-02-03 13:31:25 +01:00
Thomas Schmitt 058f18d37a Bug fix: Large amounts of AAIP data or many long file names could cause with zisofs an unreadable filesystem after the warning "Calculated and written ECMA-119 tree end differ" 2021-02-01 18:46:34 +01:00
Thomas Schmitt 5add62bda0 Version leap to 1.5.5 2021-01-30 20:44:47 +01:00
Thomas Schmitt 2d1fec2569 Updated change log 2021-01-30 13:13:59 +01:00
Thomas Schmitt 4219bf4950 Version leap to 1.5.4 2021-01-30 13:12:35 +01:00
Thomas Schmitt 2a20e93b13 Small correction to commit 6241141 2020-12-07 20:59:14 +01:00
Thomas Schmitt 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
Thomas Schmitt 8f3ff65c04 Corrected size of GPT protective MBR partition with multi-session emulation 2020-11-26 11:49:58 +01:00
Thomas Schmitt c068a19a8c New API call iso_read_opts_set_joliet_map(), new default joliet_map=stripped 2020-11-22 14:14:49 +01:00
Thomas Schmitt cece6fb371 Bug fix: Appended APM partitions without HFS+ production had start and size 1 2020-11-15 15:23:03 +01:00
Thomas Schmitt 29cc5c8d31 Prevented writing of undesired bytes in make_sun_disk_label() (commit b0230b6) 2020-11-14 09:24:11 +01:00
Thomas Schmitt 92af0c9752 Adjusted fix 7e3b01b after learning that the bug stems from b0230b6 (unreleased) 2020-11-13 21:46:05 +01:00
Thomas Schmitt daaee5e7e6 Fixed access to packed members of struct hfsplus_volheader. Thanks Felipe Franciosi. 2020-11-13 19:24:13 +01:00
Thomas Schmitt 7e3b01b53c Bug fix: Apple Partition Map entries wrote uninitialized data 2020-11-13 19:02:07 +01:00
Thomas Schmitt 1d5566f8bb Changed Public contact from libburn-hackers@pykix.org to bug-xorriso@gnu.org 2020-11-13 18:57:30 +01:00
Thomas Schmitt ac9d55330d Fixed a new bug introduced with previous commit 2020-11-07 10:46:15 +01:00
Thomas Schmitt 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
Thomas Schmitt 5a98a4cda5 Corrected declaration of ziso_add_osiz_filter(). (Lapse in commit b107443) 2020-10-31 14:01:09 +01:00
Thomas Schmitt b7a90c5194 Corrected description of new call iso_zisofs_ctrl_susp_z2() 2020-10-29 09:24:47 +01:00
Thomas Schmitt 8d70c75d4a Added doc/zisofs2_format.txt to EXTRA_DIST 2020-10-29 09:16:58 +01:00
Thomas Schmitt 9605bbe748 New API call iso_zisofs_ctrl_susp_z2() 2020-10-29 09:11:11 +01:00
Thomas Schmitt 46186e5f06 Added Z2 System Use Entry Format to zisofs2 specs 2020-10-29 08:31:31 +01:00
Thomas Schmitt 2ac62f0cac Fixed header size of ZF entries made for zisofs2 files compressed by libisofs 2020-10-29 08:23:15 +01:00
Thomas Schmitt dc61e7d298 New flag bits 8 to 15 in API call iso_node_zf_by_magic() 2020-10-27 12:17:26 +01:00
Thomas Schmitt d5ffecf2f5 Silenced a compiler warning if zlib is not enabled 2020-10-26 19:39:45 +01:00
Thomas Schmitt 80449f0dc9 New API calls iso_stream_zisofs_discard_bpt() and iso_image_zisofs_discard_bpt() 2020-10-25 16:59:32 +01:00
Thomas Schmitt cc2e0e32a3 New iso_zisofs_ctrl parameters bpt_discard_file_blocks , bpt_discard_free_ratio 2020-10-22 13:22:13 +02:00
Thomas Schmitt 239ba69925 Accepting zisofs2 algorithms 2 to 5 for ZF by magic, but not for decompression 2020-10-18 16:46:44 +02:00
Thomas Schmitt 2ca3b292fb New iso_zisofs_ctrl parameter .block_number_target 2020-10-17 14:40:24 +02:00
Thomas Schmitt f291e37ec1 Fixed wrong start block pointer of zisofs2 compression 2020-10-15 14:13:38 +02:00
Thomas Schmitt 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
Thomas Schmitt d297ce3aed Prevented time rollover outside year intervals 1900-2155 and 1-9999 2020-09-21 21:17:20 +02:00
Thomas Schmitt 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
Thomas Schmitt b0230b6ac8 Changed strncpy() to memcpy() in order to please static analyzers 2020-07-07 12:23:20 +02:00
Thomas Schmitt 69e332d17a New error code ISO_HFSPLUS_TOO_MANY_FILES instead of ISO_MANGLE_TOO_MUCH_FILES 2020-06-13 10:17:32 +02:00
Thomas Schmitt 6ca841e002 Reacted on compiler warnings of Debian Sid 2020-06-13 09:56:31 +02:00
Thomas Schmitt c84f6ae689 Removed a germanism from description of iso_image_get_session_md5 2020-06-13 09:55:06 +02:00
Thomas Schmitt ac248877a2 Re-enabled variable LT_RELEASE in configure.ac. Disabling was unintentional. 2019-11-26 11:24:23 +01:00
Thomas Schmitt c1d9639dba Switched to usage of libjte-2.0.0 2019-11-24 13:19:07 +01:00
Thomas Schmitt 773be790e8 Fixed more spelling errors found by fossies.org with codespell 2019-10-30 20:37:24 +01:00
Thomas Schmitt dc3d82cf36 Fixed spelling errors found by fossies.org with codespell 2019-10-28 15:56:58 +01:00
Thomas Schmitt 560c11617e Updated change log 2019-10-27 15:03:35 +01:00
Thomas Schmitt fa43a5a25c Version leap to 1.5.3 2019-10-27 15:02:29 +01:00
52 changed files with 4671 additions and 821 deletions

View File

@ -1,4 +1,57 @@
libisofs-1.5.0.tar.gz Sat Oct 26 2019
git clone git@dev.lovelyhq.com:libburnia/libisofs.git
(to become libisofs-1.5.8 or higher)
===============================================================================
- no novelties yet -
libisofs-1.5.6.pl01.tar.gz Fri Jun 09 2023
===============================================================================
* Bug fix: On non-GNU/Linux systems ssize_t was not defined in rockridge.h .
Report and fix proposal by Rui Chen
libisofs-1.5.6.tar.gz Wed Jun 07 2023
===============================================================================
* Bug fix: iso_write_opts_set_part_like_isohybrid() did not cause a MBR
partition table if the partitions are data files in the ISO
rather than appended
* Bug fix: The lseek methods of IsoFileSource for local filesystem and loaded
ISO returned libisofs error codes as positive off_t numbers
* Bug fix: Freshly cloned data files from imported image were not marked as
imported. Thanks to Ivan Shmakov. (Closes: #1022851)
* Bug fix: Size of further CE area was calculated wrong if its CE entry ended
exactly at a block boundary
* New iso_write_opts_set_system_area() option bits 16:
GPT "Legacy BIOS bootable" and 17: GPT writable
* New API calls iso_assess_written_features(), iso_read_image_feature_named(),
iso_read_image_features_text()
* Allowed lseekable device files with iso_tree_add_new_cut_out_node().
Proof-of-concept by Ivan Shmakov.
* New API call iso_write_opts_set_max_ce_entries()
libisofs-1.5.4.tar.gz Sat Jan 30 2021
===============================================================================
* Bug fix: Large amounts of AAIP data or many long file names could cause with
zisofs an unreadable filesystem after the warning "Calculated and
written ECMA-119 tree end differ"
* 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()

View File

@ -285,6 +285,7 @@ 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 \

21
README
View File

@ -5,7 +5,7 @@
Released under GNU General Public License version 2 or later.
See COPYING file for details.
Copyright (C) 2008 - 2018 Vreixo Formoso,
Copyright (C) 2008 - 2023 Vreixo Formoso,
Mario Danic,
Vladimir Serbinenko,
Thomas Schmitt
@ -15,25 +15,24 @@ libisofs is part of the libburnia project (libburnia-project.org)
Download, Build and Installation
libisofs code is maintained in a Bazaar repository at Launchpad
(https://launchpad.net/libisofs/). You can download it with:
libisofs code is maintained in a git repository at dev.lovelyhq.com
(https://dev.lovelyhq.com/libburnia/libisofs). You can download it with:
$ bzr branch lp:libisofs/for-libisoburn
$ git clone https://dev.lovelyhq.com/libburnia/libisofs.git
Our build system is based on autotools. For preparing the build you will need
autotools of at least version 1.7. If you have download the code from the
autotools of at least version 1.7. If you have downloaded the code from the
repository, first of all you need to execute
./autogen.sh
./bootstrap
on toplevel dir to execute autotools.
in the toplevel directory ./libisofs, in order to execute autotools.
Alternatively you may unpack a release tarball for which you do not need
autotools installed. For the most recent release of libisofs see:
http://libburnia-project.org/wiki/Releases
https://dev.lovelyhq.com/libburnia/web/wiki/Releases
To build libisofs it should be sufficient to go into its toplevel directory
and execute
To build libisofs go into its toplevel directory and execute
./configure --prefix=/usr
make
@ -209,5 +208,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,4 +1,4 @@
AC_INIT([libisofs], [1.5.2], [http://libburnia-project.org])
AC_INIT([libisofs], [1.5.7], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -41,7 +41,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=5
LIBISOFS_MICRO_VERSION=2
LIBISOFS_MICRO_VERSION=7
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
# 2019.10.24 development jump has not yet happened
# SONAME = 94 - 88 = 6 . Library name = libisofs.6.88.0
LT_CURRENT=94
LT_AGE=88
dnl 2023.05.07 development jump has not yet happened
dnl SONAME = 98 - 92 = 6 . Library name = libisofs.6.92.0
LT_CURRENT=98
LT_AGE=92
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -73,7 +73,6 @@ dnl AM_MAINTAINER_MODE
AM_PROG_CC_C_O
AC_C_CONST
AC_C_INLINE
AC_C_BIGENDIAN
dnl Large file support
AC_SYS_LARGEFILE
@ -307,11 +306,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

@ -123,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)
@ -328,7 +328,7 @@ 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 at ISO production time it is more or less arbitray how
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
@ -382,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.
@ -739,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
| |
@ -1310,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:

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

@ -377,7 +377,7 @@ static int get_single_attr(char *path, char *name, size_t *value_length,
@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)
@ -591,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)

View File

@ -7,7 +7,7 @@
To be included by aaip_0_2.c for Linux
Copyright (c) 2009 - 2018 Thomas Schmitt
Copyright (c) 2009 - 2022 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
@ -77,6 +77,44 @@ int aaip_local_attr_support(int flag)
}
/* -------------------------- Error reporting ----------------------------- */
/* Report an error with local ACL or xattr calls.
@param flag bit0-7: mode 0=NO_GET_LOCAL , 1=NO_SET_LOCAL
*/
static
void aaip_local_error(char *function_name, char *path, int err, int flag)
{
int mode, err_code;
mode= (flag & 255);
if(mode == 1)
err_code= ISO_AAIP_NO_SET_LOCAL_S;
else
err_code= ISO_AAIP_NO_GET_LOCAL_S;
if(err > 0) {
if(path[0])
iso_msg_submit(-1, err_code, 0,
"Function %s(\"%s\") failed with errno %d '%s'",
function_name, path, err, strerror(err));
else
iso_msg_submit(-1, err_code, 0, "Function %s() failed with %d '%s'",
function_name, err, strerror(err));
} else {
if(path[0])
iso_msg_submit(-1, err_code, 0,
"Function %s(\"%s\") failed without error code",
function_name, path);
else
iso_msg_submit(-1, err_code, 0,
"Function %s() failed without error code",
function_name);
}
}
/* ------------------------------ Getters --------------------------------- */
/* Obtain the ACL of the given file in long text form.
@ -181,8 +219,10 @@ static int get_single_attr(char *path, char *name, size_t *value_length,
value_ret= getxattr(path, name, NULL, 0);
else
value_ret= lgetxattr(path, name, NULL, 0);
if(value_ret == -1)
if(value_ret == -1) {
aaip_local_error((flag & 32) ? "getxattr" : "lgetxattr", path, errno, 0);
return(0);
}
*value_bytes= calloc(value_ret + 1, 1);
if(*value_bytes == NULL)
return(-1);
@ -191,6 +231,7 @@ static int get_single_attr(char *path, char *name, size_t *value_length,
else
value_ret= lgetxattr(path, name, *value_bytes, value_ret);
if(value_ret == -1) {
aaip_local_error((flag & 32) ? "getxattr" : "lgetxattr", path, errno, 0);
free(*value_bytes);
*value_bytes= NULL;
*value_length= 0;
@ -208,7 +249,7 @@ static int get_single_attr(char *path, char *name, size_t *value_length,
@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)
@ -275,10 +316,13 @@ ex:;
else
list_size= llistxattr(path, list, 0);
if(list_size == -1) {
if(errno == ENOSYS) /* Function not implemented */
if(errno == ENOSYS) { /* Function not implemented */
list_size= 0; /* Handle as if xattr was disabled at compile time */
else
} else {
aaip_local_error((flag & 32) ? "listxattr" : "llistxattr", path, errno,
0);
{ret= -1; goto ex;}
}
}
if(list_size > 0) {
list= calloc(list_size, 1);
@ -288,8 +332,11 @@ ex:;
list_size= listxattr(path, list, list_size);
else
list_size= llistxattr(path, list, list_size);
if(list_size == -1)
if(list_size == -1) {
aaip_local_error((flag & 32) ? "listxattr" : "llistxattr", path, errno,
0);
{ret= -1; goto ex;}
}
}
for(i= 0; i < list_size; i+= strlen(list + i) + 1)
num_names++;
@ -443,11 +490,14 @@ int aaip_set_acl_text(char *path, char *text, int flag)
acl= acl_from_text(text);
if(acl == NULL) {
aaip_local_error("acl_from_text", "", errno, 1);
ret= -1; goto ex;
}
ret= acl_set_file(path, (flag & 1) ? ACL_TYPE_DEFAULT : ACL_TYPE_ACCESS, acl);
if(ret == -1)
if(ret == -1) {
aaip_local_error("acl_set_file", path, errno, 1);
goto ex;
}
ret= 1;
ex:
if(acl != NULL)
@ -533,8 +583,11 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
list_size= listxattr(path, list, list_size);
else
list_size= llistxattr(path, list, list_size);
if(list_size == -1)
if(list_size == -1) {
aaip_local_error((flag & 32) ? "listxattr" : "llistxattr", path, errno,
1);
{ret= -5; goto ex;}
}
for(i= 0; i < (size_t) list_size; i+= strlen(list + i) + 1) {
if(!(flag & 8))
if(strncmp(list + i, "user.", 5))
@ -543,8 +596,11 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
ret= removexattr(path, list + i);
else
ret= lremovexattr(path, list + i);
if(ret == -1)
if(ret == -1) {
aaip_local_error((flag & 32) ? "removexattr" : "lremovexattr", path,
errno, 1);
{ret= -5; goto ex;}
}
}
free(list); list= NULL;
}
@ -587,6 +643,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
else
ret= lsetxattr(path, names[i], values[i], value_lengths[i], 0);
if(ret == -1) {
aaip_local_error((flag & 32) ? "setxattr" : "lsetxattr", path, errno,
1);
register_errno(errnos, i);
end_ret= -4;
continue;

View File

@ -281,7 +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 verbous about failure causes
bit4= be verbose about failure causes
@return >0 means ok
<=0 means error
-1= out of memory
@ -364,11 +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 verbous about failure causes
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,
@ -1960,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

View File

@ -199,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
@ -435,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

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

@ -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.
*

View File

@ -479,7 +479,7 @@ configure.ac
libisofs/libisofs.h
Version leap to 1.5.2.
26 Oct 2019 []
26 Oct 2019 [4d8a467]
ChangeLog
libisofs/changelog.txt
Updated change log
@ -500,5 +500,522 @@ Updated change log
iso_write_opts_set_system_area() is set and no El Torito boot image
is defined
------------------------------------ release - libisofs- -
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 [2d1fec2]
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()
30 Jan 2021 [5add62b]
configure.ac
libisofs/libisofs.h
Version leap to 1.5.5
01 Feb 2021 [058f18d]
libisofs/rockridge.c
Bug fix: Large amounts of AAIP data or many long file names could cause with
zisofs an unreadable filesystem after the warning "Calculated and written
ECMA-119 tree end differ"
03 Feb 2021 [98aea0c]
libisofs/rockridge.c
Heuristic fix for a new problem introduced by commit 058f18d
07 Feb 2021 [release-1.5.4.branch: 408eb3f]
libisofs/rockridge.c
Bug fix: Large amounts of AAIP data or many long file names could cause with
zisofs an unreadable filesystem after the warning "Calculated and written
ECMA-119 tree end differ"
07 Feb 2021 [release-1.5.4.branch: a7a9c29]
ChangeLog
libisofs/changelog.txt
Updated change log
------------------------------------ release - libisofs-1.5.4 - 07 Feb 2021
* Bug fix: Large amounts of AAIP data or many long file names could cause with
zisofs an unreadable filesystem after the warning "Calculated and
written ECMA-119 tree end differ"
28 Feb 2021 [7d248c4]
libisofs/fs_image.c
Ignore mad MBR partitions which extend outside of medium size
28 Feb 2021 [9e38918]
libisofs/rockridge.c
Leave prediction of first CE gap to susp_*_to_ce() functions
12 Mar 2021 [75499bc]
libisofs/filters/zisofs.c
Silenced a warning on 32 bit about value ISO_ZISOFS_V1_LIMIT too large for int
25 May 2021 [1c4c04d]
libisofs/libisofs.h
libisofs/ecma119.c
libisofs/system_area.c
New iso_write_opts_set_system_area() option bits 16: GPT "Legacy BIOS bootable"
and 17: GPT writable
02 Sep 2021 [80a0691]
configure.ac
Removed unneeded configure.ac macro AC_C_BIGENDIAN
28 Oct 2021 [3e61a61]
README
Updated URLs, build instructions, and copyright in README file
22 Apr 2022 [da8e3e6]
libisofs/fs_image.c
Exempted MBR partitions of type 0xEE from being ignored due to wrong size
23 Apr 2022 [99251ad]
libisofs/system_area.c
Avoid to overwrite the loaded MBR partition table just because partition offset is 16
23 Apr 2022 [1d61b51]
libisofs/system_area.c
libisofs/make_isohybrid_mbr.c
Bug fix: iso_write_opts_set_part_like_isohybrid() did not cause a MBR partition
table if the partitions are data files in the ISO rather than appended
23 Apr 2022 [da00291]
libisofs/make_isohybrid_mbr.c
Let the original isohybrid GPT obey system_area() option bit 17: GPT writable
26 Apr 2022 [2af1749]
libisofs/fs_local.c
libisofs/fs_image.c
Bug fix: The lseek methods of IsoFileSource for local filesystem and loaded
ISO returned libisofs error codes as positive off_t numbers
26 Apr 2022 [f457a4f]
libisofs/stream.c
Added missing stream type names to a diagnostic function
26 Apr 2022 [011e2e8]
libisofs/libisofs.h
libisofs/tree.c
libisofs/stream.c
libisofs/fsource.h
libisofs/fsource.c
Allowed lseekable device files with iso_tree_add_new_cut_out_node(). Proof-of-concept by Ivan Shmakov.
13 May 2022 [ad55ec7]
libisofs/system_area.c
libisofs/make_isohybrid_mbr.c
Avoided automatic MBR partition type 0x00 with
iso_write_opts_set_part_like_isohybrid() if partitions do not overlap
30 May 2022 [c6cb7df]
libisofs/tree.c
libisofs/stream.c
libisofs/fsource.h
libisofs/fsource.c
Widened the lseek capacity determination to SEEK_SET with wanted size
20 Sep 2022 [9b7ccc9]
libisofs/libisofs.h
libisofs/aaip-os-linux.c
Improved error messages in case of failing Linux-specific ACL or xattr functions
20 Sep 2022 [83e5832]
libisofs/libisofs.h
libisofs/libisofs.ver
libisofs/image.h
libisofs/image.c
libisofs/fs_image.c
libisofs/tree.c
libisofs/messages.c
libisofs/util.h
libisofs/util.c
New API calls iso_assess_written_features(), iso_read_image_feature_named(),
iso_read_image_features_text()
07 Oct 2022 [71772ba]
libisofs/fs_image.c
Fixed assessment of omit_version_numbers and no_force_dots
27 Oct 2022 [acb4bd1]
libisofs/tree.c
Bug fix: Freshly cloned data files from imported image were not marked as
imported
13 Dec 2022 [d35435b]
libisofs/rockridge.c
Bug fix: Size of further CE area was calculated wrong if its CE entry ended
exactly at a block boundary
11 Jan 2023 [7109ba5]
libisofs/rockridge_read.c
Prevented endless CE loops when reading a very bad ISO fileystem
22 Jan 2023 [bd41540]
libisofs/libisofs.h
libisofs/node.h
libisofs/node.c
libisofs/ecma119.h
libisofs/ecma119.c
libisofs/rockridge.h
libisofs/rockridge.c
libisofs/messages.c
libisofs/libisofs.ver
New API call iso_write_opts_set_max_ce_entries()
14 Apr 2023 [cdc7f52]
libisofs/ecma119.h
libisofs/ecma119.c
libisofs/joliet.c
Reduced number of warnings about special files or symlinks in Joliet
07 Jun 2023 [c2d17b1]
configure.ac
libisofs/libisofs.h
Version leap to 1.5.6
07 Jun 2023 [170318c]
ChangeLog
libisofs/changelog.txt
Updated change log
------------------------------------ release - libisofs-1.5.6 - 07 Jun 2023
* New iso_write_opts_set_system_area() option bits 16:
GPT "Legacy BIOS bootable" and 17: GPT writable
* New API calls iso_assess_written_features(), iso_read_image_feature_named(),
iso_read_image_features_text()
* Allowed lseekable device files with iso_tree_add_new_cut_out_node().
Proof-of-concept by Ivan Shmakov.
* New API call iso_write_opts_set_max_ce_entries()
* Bug fix: iso_write_opts_set_part_like_isohybrid() did not cause a MBR
partition table if the partitions are data files in the ISO
rather than appended
* Bug fix: The lseek methods of IsoFileSource for local filesystem and loaded
ISO returned libisofs error codes as positive off_t numbers
* Bug fix: Freshly cloned data files from imported image were not marked as
imported. Thanks to Ivan Shmakov. (Closes: #1022851)
* Bug fix: Size of further CE area was calculated wrong if its CE entry ended
exactly at a block boundary
07 Jun 2023 [5a867c4]
configure.ac
libisofs/libisofs.h
Version leap to 1.5.7
[master: ][branch 1.5.6.pl01: ]
libisofs/rockridge.h
ChangeLog
libisofs/changelog.txt
Bug fix: On non-GNU/Linux systems ssize_t was not defined in rockridge.h .
Report and fix proposal by Rui Chen
------------------------------- release - libisofs-1.5.6.pl01 - 09 Jun 2023
* Bug fix: On non-GNU/Linux systems ssize_t was not defined in rockridge.h .
Report and fix proposal by Rui Chen
[]
libisofs/ecma119.c
libisofs/fs_image.c
libisofs/rockridge.c
libisofs/stream.c
[]
README
Updated copyright year in README
------------------------------------ release - libisofs-1.5.8 -
------------------------------------------------------------------------
Todo about iso_read_image_feature_named() :
Declared but not yet filled:
{"hfsplus", 0, 0, 0, NULL},
{"fat", 0, 0, 0, NULL},
{"hfsp_serial_number", 0, 1, 0, NULL},
{"hfsp_block_size", 0, 0, 0, NULL},
{"hardlinks", 0, 0, 0, NULL},
{"rr_reloc_dir", 0, 1, 0, NULL},
{"rr_reloc_flags", 0, 0, 0, NULL, 0},
{"allow_7bit_ascii", 0, 0, 0, NULL}, ??? How to recognize this ?
{"scdbackup_tag_name", 0, 1, 0, NULL},
{"scdbackup_tag_time", 0, 1, 0, NULL},
{"always_gmt", 0, 0, 0, NULL},
IsoWriteOpts properties not yet covered by above list:
??? dir_rec_mtime
??? sort_files
??? output_charset
??? appendable
??? ms_block
??? data_start_lba
??? tail_blocks
??? vol_*_time
??? vol_uuid
??? system_area_data
??? system_area_size
??? system_area_options
??? partition_offset
??? partition_secs_per_head , partition_heads_per_cyl
??? Other properties of partitions and boot equipment

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2019 Thomas Schmitt
* Copyright (c) 2009 - 2023 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -41,6 +41,7 @@
#include <locale.h>
#include <langinfo.h>
#include <stdio.h>
#include <unistd.h>
#ifdef Xorriso_standalonE
@ -205,17 +206,24 @@ size_t calc_dirent_len(Ecma119Image *t, Ecma119Node *n)
* taking into account the continuation areas.
*/
static
size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
ssize_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
{
size_t i, len;
ssize_t ret;
size_t ce_len = 0;
/* size of "." and ".." entries */
len = 34 + 34;
if (t->opts->rockridge) {
len += rrip_calc_len(t, dir, 1, 34, &ce_len, *ce);
ret = rrip_calc_len(t, dir, 1, 34, &ce_len, *ce);
if (ret < 0)
return ret;
len += ret;
*ce += ce_len;
len += rrip_calc_len(t, dir, 2, 34, &ce_len, *ce);
ret = rrip_calc_len(t, dir, 2, 34, &ce_len, *ce);
if (ret < 0)
return ret;
len += ret;
*ce += ce_len;
}
@ -228,8 +236,10 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
for (section = 0; section < nsections; ++section) {
size_t dirent_len = calc_dirent_len(t, child);
if (t->opts->rockridge) {
dirent_len += rrip_calc_len(t, child, 0, dirent_len, &ce_len,
*ce);
ret = rrip_calc_len(t, child, 0, dirent_len, &ce_len, *ce);
if (ret < 0)
return ret;
dirent_len += ret;
*ce += ce_len;
}
remaining = BLOCK_SIZE - (len % BLOCK_SIZE);
@ -255,14 +265,18 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
}
static
void calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
int calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
{
size_t i, len;
ssize_t ret;
size_t ce_len = 0;
t->ndirs++;
dir->info.dir->block = t->curblock;
len = calc_dir_size(t, dir, &ce_len);
ret = calc_dir_size(t, dir, &ce_len);
if (ret < 0)
return (int) ret;
len = ret;
t->curblock += DIV_UP(len, BLOCK_SIZE);
if (t->opts->rockridge) {
t->curblock += DIV_UP(ce_len, BLOCK_SIZE);
@ -270,9 +284,12 @@ void calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
for (i = 0; i < dir->info.dir->nchildren; i++) {
Ecma119Node *child = dir->info.dir->children[i];
if (child->type == ECMA119_DIR) {
calc_dir_pos(t, child);
ret = calc_dir_pos(t, child);
if (ret < 0)
return (int) ret;
}
}
return ISO_SUCCESS;
}
/**
@ -305,6 +322,7 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
Ecma119Image *target;
uint32_t path_table_size;
size_t ndirs;
int ret;
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
@ -315,7 +333,9 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
/* compute position of directories */
iso_msg_debug(target->image->id, "Computing position of dir structure");
target->ndirs = 0;
calc_dir_pos(target, target->root);
ret = calc_dir_pos(target, target->root);
if (ret < 0)
return ret;
/* compute length of pathlist */
iso_msg_debug(target->image->id, "Computing length of pathlist");
@ -338,7 +358,9 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
/* Take into respect the second directory tree */
ndirs = target->ndirs;
target->ndirs = 0;
calc_dir_pos(target, target->partition_root);
ret = calc_dir_pos(target, target->partition_root);
if (ret < 0)
return ret;
if (target->ndirs != ndirs) {
iso_msg_submit(target->image->id, ISO_ASSERT_FAILURE, 0,
"Number of directories differs in ECMA-119 partiton_tree");
@ -758,7 +780,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;
@ -1374,6 +1396,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)
@ -1396,7 +1420,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);
@ -1464,7 +1488,7 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
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.
*/
@ -1500,7 +1524,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;
@ -2705,6 +2729,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++)
@ -2734,7 +2759,13 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
target->filesrc_start = 0;
target->filesrc_blocks = 0;
target->curr_ce_entries = 0;
target->joliet_ucs2_failures = 0;
target->joliet_symlinks = 0;
target->joliet_specials = 0;
target->iso1999_symlinks = 0;
target->iso1999_specials = 0;
/* If partitions get appended, then the backup GPT cannot be part of
the ISO filesystem.
@ -3015,7 +3046,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];
@ -3264,6 +3295,26 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
* even modified by the read thread (look inside bs_* functions)
*/
if (target->joliet_symlinks > 0) {
iso_msg_submit(target->image->id, ISO_FILE_IGNORED, 0,
"Number of symbolic links omitted from Joliet tree: %lu",
target->joliet_symlinks);
}
if (target->joliet_specials > 0) {
iso_msg_submit(target->image->id, ISO_FILE_IGNORED, 0,
"Number of special files omitted from Joliet tree: %lu",
target->joliet_specials);
}
if (target->iso1999_symlinks > 0) {
iso_msg_submit(target->image->id, ISO_FILE_IGNORED, 0,
"Number of symbolic links omitted from ISO 9660:1999 tree: %lu",
target->iso1999_symlinks);
}
if (target->iso1999_specials > 0) {
iso_msg_submit(target->image->id, ISO_FILE_IGNORED, 0,
"Number of special files omitted from ISO 9660:1999 tree: %lu",
target->iso1999_specials);
}
*img = target;
return ISO_SUCCESS;
@ -3608,6 +3659,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->hfsp_block_size = 0;
memset(wopts->gpt_disk_guid, 0, 16);
wopts->gpt_disk_guid_mode = 0;
wopts->max_ce_entries = 31; /* Linux hates >= RR_MAX_CE_ENTRIES = 32 */
wopts->max_ce_drop_attr = 2; /* If needed drop non-isofs fattr and ACL */
*opts = wopts;
return ISO_SUCCESS;
@ -4204,7 +4257,7 @@ int iso_write_opts_set_system_area(IsoWriteOpts *opts, char data[32768],
opts->system_area_size = 32768;
}
if (!(flag & 4))
opts->system_area_options = options & 0xffff;
opts->system_area_options = options & 0x3ffff;
return ISO_SUCCESS;
}
@ -4400,6 +4453,17 @@ int iso_write_opts_set_gpt_guid(IsoWriteOpts *opts, uint8_t guid[16], int mode)
return ISO_SUCCESS;
}
int iso_write_opts_set_max_ce_entries(IsoWriteOpts *opts, uint32_t num,
int flag)
{
if (num > 100000)
return ISO_TOO_MANY_CE;
if (num == 0)
num = 1;
opts->max_ce_entries = num;
opts->max_ce_drop_attr = flag & 15;
return ISO_SUCCESS;
}
/*
* @param flag
@ -4408,7 +4472,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
@ -4641,6 +4705,9 @@ void iso_tell_max_part_range(IsoWriteOpts *opts,
if (sa_type == 3) { /* SUN Disk Label */
*first_partition = 2;
*last_partition = 8;
} else if(sa_type == 0 && opts->appended_as_gpt) {
*first_partition = 1;
*last_partition = 8;
} else {
*first_partition = 1;
*last_partition = 4;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2019 Thomas Schmitt
* Copyright (c) 2009 - 2023 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;
@ -477,7 +477,7 @@ struct iso_write_opts {
int efi_boot_part_flag;
/* Disk file paths of prepared images which shall be appended
after the ISO image and described by partiton table entries in a MBR.
after the ISO image and described by partition table entries in a MBR.
NULL means unused.
*/
char *appended_partitions[ISO_MAX_PARTITIONS];
@ -543,6 +543,17 @@ struct iso_write_opts {
*/
uint8_t gpt_disk_guid[16];
int gpt_disk_guid_mode;
/* Maximum number of CE entries per file */
uint32_t max_ce_entries;
/* Whether to try dropping AAIP data on too many CE:
bit0-3 = Mode:
0 = throw ISO_TOO_MANY_CE, without trying to drop anything
1 = drop non-isofs fattr
2 = drop ACL if dropping non-isofs fattr does not suffice
*/
int max_ce_drop_attr;
};
typedef struct ecma119_image Ecma119Image;
@ -913,6 +924,21 @@ struct ecma119_image
uint32_t filesrc_start;
uint32_t filesrc_blocks;
/* Number of CE entries in currently processed node */
uint32_t curr_ce_entries;
/* Count of symbolic links and special files which could not be represented
in Joliet.
*/
unsigned long joliet_symlinks;
unsigned long joliet_specials;
/* Count of symbolic links and special files which could not be represented
in ISO 9660:1999.
*/
unsigned long iso1999_symlinks;
unsigned long iso1999_specials;
};
#define BP(a,b) [(b) - (a) + 1]

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

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 - 2016 Thomas Schmitt
* Copyright (c) 2010 - 2024 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
@ -566,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;
@ -590,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) {
@ -846,6 +845,8 @@ void el_torito_boot_catalog_free(struct el_torito_boot_catalog *cat)
continue;
if ((IsoNode*)image->image != NULL)
iso_node_unref((IsoNode*)image->image);
if (image->image_path != NULL)
free(image->image_path);
free(image);
}
if ((IsoNode*)cat->node != NULL)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2010 - 2018 Thomas Schmitt
* Copyright (c) 2010 - 2024 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
@ -53,6 +53,9 @@ struct el_torito_boot_catalog {
struct el_torito_boot_image {
IsoFile *image;
/* Path of image at the time of ISO image loading (NULL = hidden image) */
char *image_path;
/* Overrides .image if >= 0 : array index of appended partition */
int appended_idx;
uint32_t appended_start; /* In blocks of 2048 bytes */

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;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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;
@ -337,7 +337,7 @@ off_t lfs_lseek(IsoFileSource *src, off_t offset, int flag)
int whence;
if (src == NULL) {
return (off_t)ISO_NULL_POINTER;
return (off_t)((int) ISO_NULL_POINTER);
}
switch (flag) {
case 0:
@ -347,7 +347,7 @@ off_t lfs_lseek(IsoFileSource *src, off_t offset, int flag)
case 2:
whence = SEEK_END; break;
default:
return (off_t)ISO_WRONG_ARG_VALUE;
return (off_t)((int) ISO_WRONG_ARG_VALUE);
}
data = src->data;
@ -360,19 +360,19 @@ off_t lfs_lseek(IsoFileSource *src, off_t offset, int flag)
/* error on read */
switch (errno) {
case ESPIPE:
ret = (off_t)ISO_FILE_ERROR;
ret = (off_t)((int) ISO_FILE_ERROR);
break;
default:
ret = (off_t)ISO_ERROR;
ret = (off_t)((int) ISO_ERROR);
break;
}
}
return ret;
}
case 2: /* directory */
return (off_t)ISO_FILE_IS_DIR;
return (off_t)((int) ISO_FILE_IS_DIR);
default:
return (off_t)ISO_FILE_NOT_OPENED;
return (off_t)((int) ISO_FILE_NOT_OPENED);
}
}
@ -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);
}
@ -815,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 */

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2022 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
@ -133,3 +134,104 @@ int iso_file_source_get_aa_string(IsoFileSource *src,
return src->class->get_aa_string(src, aa_string, flag);
}
/* @flag bit0= Open and close src
bit1= Try iso_file_source_lseek(, 0) (=SEEK_SET) with wanted_size
@return <0 iso_file_source_lseek failed , >= 0 readable capacity
*/
off_t iso_file_source_lseek_capacity(IsoFileSource *src, off_t wanted_size,
int flag)
{
int ret, opened = 0;
off_t end, old, reset;
struct stat info;
ret = iso_file_source_stat(src, &info);
if (ret < 0) {
end = -1;
goto ex;
}
if (S_ISDIR(info.st_mode) || S_ISLNK(info.st_mode) ||
S_ISFIFO(info.st_mode) || S_ISSOCK(info.st_mode)) {
/* open(2) on fifo can block and have side effects.
Active Unix sockets have not been tested but they make as few sense
as directories or symbolic links.
*/
end = -1;
goto ex;
}
if (flag & 1) {
ret = iso_file_source_open(src);
if (ret < 0) {
end = -1;
goto ex;
}
opened = 1;
}
old = iso_file_source_lseek(src, 0, 1);
if (old < 0) {
end = -1;
goto ex;
}
if(flag & 2) {
end = iso_file_source_lseek(src, wanted_size, 0);
} else {
end = iso_file_source_lseek(src, 0, 2);
}
if (end < 0) {
end = -1;
goto ex;
}
reset = iso_file_source_lseek(src, old, 0);
if (reset != old) {
end = -1;
goto ex;
}
ex:;
if (opened) {
iso_file_source_close(src);
}
return end;
}
/* Determine whether src is random-access readable and return its capacity.
@flag bit0= For iso_file_source_lseek_capacity(): Open and close src
bit1= wanted_size is valid
*/
off_t iso_file_source_determine_capacity(IsoFileSource *src, off_t wanted_size,
int flag)
{
int ret;
off_t src_size, src_seek_size= -1;
struct stat info;
ret = iso_file_source_stat(src, &info);
if (ret < 0) {
return (off_t) -1;
}
if (S_ISREG(info.st_mode)) {
return info.st_size;
}
src_size = iso_file_source_lseek_capacity(src, wanted_size, (flag & 1));
if (src_size > 0) {
return src_size;
}
if (!(flag & 2)) {
if (src_size == 0) {
return 0;
}
return -1;
}
src_seek_size= src_size;
src_size = iso_file_source_lseek_capacity(src, wanted_size,
2 | (flag & 1));
if (src_size >= 0) {
return src_size;
} else if (src_seek_size >= 0) {
return src_seek_size;
}
return -1;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2016 Thomas Schmitt
* Copyright (c) 2009 - 2022 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
@ -49,4 +49,14 @@ int iso_ifs_source_clone(IsoFileSource *old_source, IsoFileSource **new_source,
int flag);
off_t iso_file_source_lseek_capacity(IsoFileSource *src, off_t wanted_size,
int flag);
/* Determine whether src is random-access readable and return its capacity.
*/
off_t iso_file_source_determine_capacity(IsoFileSource *src, off_t wanted_size,
int flag);
#endif /*LIBISO_FSOURCE_H_*/

View File

@ -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

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2015 Thomas Schmitt
* Copyright (c) 2009 - 2024 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
@ -17,6 +17,7 @@
#include "node.h"
#include "messages.h"
#include "eltorito.h"
#include "system_area.h"
#include <stdlib.h>
#include <string.h>
@ -43,6 +44,7 @@ int iso_imported_sa_new(struct iso_imported_sys_area **boots, int flag)
b->sparc_disc_label = NULL;
b->sparc_core_node = NULL;
b->sparc_core_node_path = NULL;
b->sparc_entries = NULL;
b->hppa_cmdline = NULL;
@ -71,18 +73,27 @@ int iso_imported_sa_unref(struct iso_imported_sys_area **boots, int flag)
return 2;
if (b->mbr_req != NULL) {
for (i = 0; i < b->mbr_req_count; i++)
for (i = 0; i < b->mbr_req_count; i++) {
if (b->mbr_req[i] != NULL)
LIBISO_FREE_MEM(b->mbr_req[i]->image_path);
LIBISO_FREE_MEM(b->mbr_req[i]);
}
LIBISO_FREE_MEM(b->mbr_req);
}
if (b->apm_req != NULL) {
for (i = 0; i < b->apm_req_count; i++)
for (i = 0; i < b->apm_req_count; i++) {
if (b->apm_req[i] != NULL)
LIBISO_FREE_MEM(b->apm_req[i]->image_path);
LIBISO_FREE_MEM(b->apm_req[i]);
}
LIBISO_FREE_MEM(b->apm_req);
}
if (b->gpt_req != NULL) {
for (i = 0; i < b->gpt_req_count; i++)
for (i = 0; i < b->gpt_req_count; i++) {
if (b->gpt_req[i] != NULL)
LIBISO_FREE_MEM(b->gpt_req[i]->image_path);
LIBISO_FREE_MEM(b->gpt_req[i]);
}
LIBISO_FREE_MEM(b->gpt_req);
}
LIBISO_FREE_MEM(b->gpt_backup_comments);
@ -102,6 +113,7 @@ int iso_imported_sa_unref(struct iso_imported_sys_area **boots, int flag)
LIBISO_FREE_MEM(b->sparc_disc_label);
if (b->sparc_core_node != NULL)
iso_node_unref((IsoNode *) b->sparc_core_node);
LIBISO_FREE_MEM(b->sparc_core_node_path);
LIBISO_FREE_MEM(b->sparc_entries);
LIBISO_FREE_MEM(b->hppa_cmdline);
@ -204,6 +216,10 @@ int iso_image_new(const char *name, IsoImage **image)
img->collision_warnings = 0;
img->imported_sa_info = NULL;
img->blind_on_local_get_attrs = 0;
img->do_deeper_tree_inspection = 0;
img->tree_loaded = 0;
img->rr_loaded = 0;
img->tree_compliance = NULL;
*image = img;
return ISO_SUCCESS;
@ -271,6 +287,8 @@ void iso_image_unref(IsoImage *image)
free(image->system_area_data);
iso_image_free_checksums(image, 0);
iso_imported_sa_unref(&(image->imported_sa_info), 0);
if (image->tree_compliance != NULL)
iso_write_opts_free(image->tree_compliance);
free(image);
}
}
@ -1144,9 +1162,69 @@ 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 - 2017 Thomas Schmitt
* Copyright (c) 2009 - 2024 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!]
*/
@ -252,6 +252,13 @@ struct Iso_Image
*/
int blind_on_local_get_attrs;
/* Deeper tree inspection when reading an IsoImage assesses traces of the
used write options.
*/
int do_deeper_tree_inspection;
int tree_loaded; /* 0=ISO 9660/ECMA-119 1=Joliet 2=ISO 9660:1999 */
int rr_loaded; /* 0=plain ISO 9660/ECMA-119 1=Rock Ridge */
IsoWriteOpts *tree_compliance;
};
@ -411,6 +418,12 @@ struct iso_imported_sys_area {
uint32_t sparc_grub2_core_size;
IsoFile *sparc_core_node;
/* Only for representing the imported ISO:
Path of file which held the partition content.
NULL = no such file
*/
char *sparc_core_node_path;
/* see image.h : struct Iso_Image */
int hppa_hdrversion;
char *hppa_cmdline;
@ -443,5 +456,9 @@ int iso_imported_sa_new(struct iso_imported_sys_area **sa_info, int flag);
int iso_imported_sa_unref(struct iso_imported_sys_area **sa_info, int flag);
void iso_image_assess_ecma119_name(IsoImage *image, struct stat *info,
char *path, char *name);
void iso_image_assess_joliet_name(IsoImage *image, struct stat *info,
char *path, char *name);
#endif /*LIBISO_IMAGE_H_*/

View File

@ -251,14 +251,33 @@ int create_tree(Ecma119Image *t, IsoNode *iso, Iso1999Node **tree, int pathlen)
}
break;
case LIBISO_SYMLINK:
case LIBISO_SPECIAL:
{
t->iso1999_symlinks++;
if (t->iso1999_symlinks == 1) {
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"Can't add %s to ISO 9660:1999 tree. This kind of files "
"can only be added to a Rock Ridget tree. Skipping.",
ipath);
"Cannot add symbolic link %s to ISO 9660:1999 tree. Skipping.",
ipath);
free(ipath);
} else {
if (t->iso1999_symlinks == 2)
iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"More symbolic links were omitted from ISO 9660:1999 tree.");
ret = 0;
}
break;
case LIBISO_SPECIAL:
t->iso1999_specials++;
if (t->iso1999_specials == 1) {
char *ipath = iso_tree_get_node_path(iso);
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"Cannot add special file %s to ISO 9660:1999 tree. Skipping.",
ipath);
free(ipath);
} else {
if (t->iso1999_specials == 2)
iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"More special files were omitted from ISO 9660:1999 tree.");
ret = 0;
}
break;
default:
@ -283,7 +302,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 +377,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 +938,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

@ -301,14 +301,36 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
}
break;
case LIBISO_SYMLINK:
case LIBISO_SPECIAL:
{
t->joliet_symlinks++;
if (t->joliet_symlinks == 1) {
char *ipath = iso_tree_get_node_path(iso);
/* This first ret might indicate the need to abort */
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"Cannot add %s to Joliet tree. %s can only be added to a "
"Rock Ridge tree.", ipath, (iso->type == LIBISO_SYMLINK ?
"Symlinks" : "Special files"));
"Cannot add %s to Joliet tree. Symlinks can only be added to a "
"Rock Ridge tree.", ipath);
free(ipath);
} else {
if (t->joliet_symlinks == 2)
iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"More symbolic links were omitted from Joliet tree.");
ret = 0;
}
break;
case LIBISO_SPECIAL:
t->joliet_specials++;
if (t->joliet_specials == 1) {
char *ipath = iso_tree_get_node_path(iso);
/* This first ret might indicate the need to abort */
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"Cannot add %s to Joliet tree. "
"Special files can only be added to a Rock Ridge tree.",
ipath);
free(ipath);
} else {
if (t->joliet_specials == 2)
iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
"More special files were omitted from Joliet tree.");
ret = 0;
}
break;
default:
@ -469,7 +491,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 */
@ -1108,7 +1130,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

@ -21,6 +21,7 @@ el_torito_set_load_seg;
el_torito_set_load_size;
el_torito_set_no_bootable;
el_torito_set_selection_crit;
iso_assess_written_features;
iso_conv_name_chars;
iso_crc32_gpt;
iso_data_source_new_from_file;
@ -154,6 +155,7 @@ 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;
@ -228,12 +230,16 @@ iso_node_xinfo_make_clonable;
iso_node_zf_by_magic;
iso_nowtime;
iso_obtain_msgs;
iso_read_image_feature_named;
iso_read_image_features_destroy;
iso_read_image_features_get_size;
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_text;
iso_read_image_features_tree_loaded;
iso_read_opts_auto_input_charset;
iso_read_opts_free;
iso_read_opts_keep_import_src;
@ -244,6 +250,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;
@ -266,12 +273,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;
@ -341,6 +350,7 @@ iso_write_opts_set_joliet_long_names;
iso_write_opts_set_joliet_longer_paths;
iso_write_opts_set_joliet_utf16;
iso_write_opts_set_max_37_char_filenames;
iso_write_opts_set_max_ce_entries;
iso_write_opts_set_ms_block;
iso_write_opts_set_no_force_dots;
iso_write_opts_set_old_empty;
@ -367,6 +377,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,6 +1,6 @@
/*
* Copyright (c) 2002 - 2008 H. Peter Anvin
* Copyright (c) 2008 - 2015 Thomas Schmitt
* Copyright (c) 2008 - 2022 Thomas Schmitt
* 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
@ -420,8 +420,8 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
0x00, 0x53, 0x46, 0x48, 0x00, 0x00, 0xaa, 0x11,
0xaa, 0x11, 0x00, 0x30, 0x65, 0x43, 0xec, 0xac
};
uint8_t *uuid;
static uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1;
uint8_t *uuid, *type_guid;
uint64_t gpt_flags = (((uint64_t) 1) << 60) | 1;
*gpt_count = 0;
*apm_count = 0;
@ -504,12 +504,20 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
memset(gpt_name, 0, 72);
sprintf((char *) gpt_name, "ISOHybrid");
iso_ascii_utf_16le(gpt_name);
if (t->opts->iso_gpt_flag & 1)
type_guid = t->opts->iso_gpt_type_guid;
else
type_guid = basic_data_uuid;
if (t->system_area_options & (1 << 16))
gpt_flags|= 4; /* Legacy BIOS bootable */
if (t->opts->system_area_options & (1 << 17))
gpt_flags &= ~(((uint64_t) 1) << 60); /* Not read-only */
/* Let it be open ended. iso_write_gpt() will truncate it as needed. */
block_count = 0xffffffff;
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
(uint64_t) t->opts->partition_offset * 4,
((uint64_t) block_count) * 4,
basic_data_uuid, zero_uuid, gpt_flags,
type_guid, zero_uuid, gpt_flags,
(uint8_t *) gpt_name);
if (ret < 0)
return ret;
@ -625,18 +633,23 @@ static uint32_t iso_make_mbr_id(Ecma119Image *t, int flag)
/*
* @param flag bit0= make own random MBR Id from current time
* >>> or from overridden modification time
* or from overridden modification time
* bit1= create protective MBR as of UEFI/GPT specs
* bit2= write only partition table
* do not insert APM mockup head
* do not treat bytes before code as isohybrid MBR
* do not create MBR id
* bit3= replace fs_type 0x00 by 0x17 if appropriate
*/
int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
int part_offset, int part_number, int fs_type,
uint8_t *buf, int flag)
{
uint32_t id, part, nominal_part_size;
uint32_t id, part, nominal_part_size, mbr_part_start;
off_t hd_img_blocks, hd_boot_lba;
char *wpt;
char *wpt, *fs_type_wpt = NULL;
uint32_t boot_lba;
int head_count, sector_count, ret;
int head_count, sector_count, ret, part_is_in_img = 0;
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor, i;
if (t->bootsrc[0] == NULL)
@ -662,39 +675,44 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
if (ret < 0)
return ret;
/* The rest of APM has already been written by iso_write_apm().
But the isohybrid APM head differs from the hfsplus_writer APM head.
*/
ret = insert_apm_head(buf, apm_count);
if (ret < 0)
return ret;
/* Padding of image_size to a multiple of sector_count*head_count
happens already at compute time and is implemented by
an appropriate increase of Ecma119Image->tail_blocks.
*/
wpt = (char *) buf + 432;
/* write qword boot_lba # Offset 432
*/
hd_boot_lba = ((off_t) boot_lba) * (off_t) 4;
lsb_to_buf(&wpt, hd_boot_lba & 0xffffffff, 32, 0);
lsb_to_buf(&wpt, hd_boot_lba >> 32, 32, 0);
/* write dword mbr_id # Offset 440
(here some 32-bit random value with no crypto strength)
*/
if (flag & 1) {
id = iso_make_mbr_id(t, 0);
lsb_to_buf(&wpt, id, 32, 0);
if(flag & 4) {
wpt= (char *) buf + 446;
} else {
wpt+= 4;
}
/* write word 0 # Offset 444
*/
lsb_to_buf(&wpt, 0, 16, 0);
/* The rest of APM has already been written by iso_write_apm().
But the isohybrid APM head differs from the hfsplus_writer APM head.
*/
ret = insert_apm_head(buf, apm_count);
if (ret < 0)
return ret;
/* Padding of image_size to a multiple of sector_count*head_count
happens already at compute time and is implemented by
an appropriate increase of Ecma119Image->tail_blocks.
*/
wpt = (char *) buf + 432;
/* write qword boot_lba # Offset 432
*/
hd_boot_lba = ((off_t) boot_lba) * (off_t) 4;
lsb_to_buf(&wpt, hd_boot_lba & 0xffffffff, 32, 0);
lsb_to_buf(&wpt, hd_boot_lba >> 32, 32, 0);
/* write dword mbr_id # Offset 440
(here some 32-bit random value with no crypto strength)
*/
if (flag & 1) {
id = iso_make_mbr_id(t, 0);
lsb_to_buf(&wpt, id, 32, 0);
} else {
wpt+= 4;
}
/* write word 0 # Offset 444
*/
lsb_to_buf(&wpt, 0, 16, 0);
}
/* # Offset 446
*/
@ -702,7 +720,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);
@ -713,6 +731,13 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
if (ret < 0)
return ret;
}
/* Will this hit the part_number partition ? */
mbr_part_start = iso_read_lsb((uint8_t *) (wpt + 8), 4);
if (mbr_part_start > 0 &&
mbr_part_start < hd_img_blocks + part_offset)
part_is_in_img = 1;
wpt+= 16;
continue;
}
@ -728,6 +753,7 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
else
lsb_to_buf(&wpt, 0x80, 8, 0);
lba512chs_to_buf(&wpt, part_offset, head_count, sector_count);
fs_type_wpt = wpt;
lsb_to_buf(&wpt, fs_type, 8, 0);
lba512chs_to_buf(&wpt, hd_img_blocks - 1, head_count, sector_count);
lsb_to_buf(&wpt, part_offset, 32, 0);
@ -742,6 +768,17 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
*/
lsb_to_buf(&wpt, 0xaa55, 16, 0);
/* Check whether automatically determined fs_type 0x00 can become 0x17 */
if ((flag & 8) && fs_type_wpt != NULL && fs_type == 0x00 &&
t->opts->iso_mbr_part_type != fs_type && !part_is_in_img) {
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255) {
lsb_to_buf(&fs_type_wpt, t->opts->iso_mbr_part_type, 8, 0);
} else {
lsb_to_buf(&fs_type_wpt, 0x17, 8, 0);
}
}
return(1);
}

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

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2016 Thomas Schmitt
* Copyright (c) 2009 - 2023 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
@ -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
@ -392,8 +392,10 @@ const char *iso_error_to_msg(int errcode)
case ISO_AAIP_BAD_AASTRING:
return "Error with decoding AAIP info for ACL or xattr";
case ISO_AAIP_NO_GET_LOCAL:
case ISO_AAIP_NO_GET_LOCAL_S:
return "Error with reading ACL or xattr from local file";
case ISO_AAIP_NO_SET_LOCAL:
case ISO_AAIP_NO_SET_LOCAL_S:
return "Error with attaching ACL or xattr to local file";
case ISO_AAIP_NON_USER_NAME:
return "Unallowed attempt to set an xattr with non-userspace name";
@ -402,13 +404,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:
@ -555,6 +557,22 @@ const char *iso_error_to_msg(int errcode)
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";
case ISO_UNDEF_READ_FEATURE:
return "Undefined IsoReadImageFeatures name";
case ISO_TOO_MANY_CE:
return "Too many CE entries for single file";
case ISO_TOO_MANY_CE_FOR_LINUX:
return "Too many CE entries for single file when mounted by Linux";
case ISO_CE_REMOVING_ATTR:
return "Too many CE entries for single file, removing attributes";
default:
return "Unknown error";
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2019 Thomas Schmitt
* Copyright (c) 2009 - 2023 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)
@ -2046,13 +2046,60 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
}
ret = 1;
ex:;
/* Dispose eventual merged list */
/* Dispose merged list if it was created */
iso_node_merge_xattr(node, num_attrs, names, value_lengths, values,
&m_num, &m_names, &m_value_lengths, &m_values, 1 << 15);
/* Dispose ACL if saved */
iso_node_get_acl_text(node, &a_acl, &d_acl, 1 << 15);
return ret;
}
/* @param flag
bit0= delete ACL, too
*/
int iso_node_remove_fattr(IsoNode *node, int flag)
{
int ret;
size_t num_attrs, *value_lengths = NULL, i, w;
char **names = NULL, **values = NULL;
ret = iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,
flag & 1);
if (ret < 0)
goto ex;
/* Delete variables of all namespaces except isofs */
w = 0;
for (i = 0; i < num_attrs; i++) {
if (strncmp(names[i], "isofs.", 6) != 0) {
free(names[i]);
names[i] = NULL;
free(values[i]);
values[i] = NULL;
continue;
}
if (w != i) {
/* move i to w , nullify i */
names[w] = names[i];
names[i] = NULL;
values[w] = values[i];
values[i] = NULL;
value_lengths[w] = value_lengths[i];
}
w++;
}
num_attrs = w;
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
(flag & 1) | 8);
ex:;
if (names != NULL)
iso_node_get_attrs(NULL, &num_attrs, &names, &value_lengths, &values,
1 << 15);
return ret;
}
static
int iso_decode_acl(unsigned char *v_data, size_t v_len, size_t *consumed,
char **text, size_t *text_fill, int flag)
@ -2440,22 +2487,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) {
@ -2472,13 +2522,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;
@ -2486,6 +2541,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;
@ -2503,7 +2560,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;
@ -2524,7 +2581,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);
@ -2746,7 +2803,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 - 2023 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
@ -422,6 +422,12 @@ int iso_aa_get_attrs(unsigned char *aa_string, size_t *num_attrs,
int iso_aa_lookup_attr(unsigned char *aa_string, char *name,
size_t *value_length, char **value, int flag);
/**
* Delete variables of all namespaces except isofs
*
* @param flag bit0= delete ACL, too
*/
int iso_node_remove_fattr(IsoNode *node, int flag);
/**
* Function to identify and manage ZF parameters which do not stem from ZF
@ -437,9 +443,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 - 2023 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
@ -15,6 +15,7 @@
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "rockridge.h"
#include "node.h"
@ -94,7 +95,7 @@ int susp_append_ce(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
/* Insert CE entry (actual CE size later by susp_update_CE_sizes) */
ret = susp_make_CE(t, &CE, (uint32_t) (susp->ce_block +
susp->ce_len / BLOCK_SIZE + 1),
(uint32_t) 0, (uint32_t) 2048);
(uint32_t) 0, (uint32_t) 0);
if (ret < 0)
return ret;
susp->ce_susp_fields[susp->n_ce_susp_fields] = CE;
@ -378,7 +379,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 +574,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) {
@ -618,13 +619,15 @@ int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
/* @param flag bit1= care about crossing block boundaries */
static
int susp_calc_add_to_ce(size_t *ce, size_t base_ce, int add, int flag)
int susp_calc_add_to_ce(Ecma119Image *t, size_t *ce, size_t base_ce, int add,
int flag)
{
if (flag & 2) {
/* Account for inserted CE before size exceeds block size */
if ((*ce + base_ce + add + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE !=
(*ce + base_ce) / BLOCK_SIZE) {
/* Insert CE and padding */
t->curr_ce_entries++;
*ce += ISO_CE_ENTRY_SIZE;
if ((*ce + base_ce) % BLOCK_SIZE)
*ce += BLOCK_SIZE - ((*ce + base_ce) % BLOCK_SIZE);
@ -658,12 +661,12 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
es_extra = 5;
if (*sua_free < num_data + es_extra || *ce_len > 0) {
if (es_extra > 0)
susp_calc_add_to_ce(ce_len, ce_mem, es_extra, flag & 2);
susp_calc_add_to_ce(t, ce_len, ce_mem, es_extra, flag & 2);
done = 0;
for (aapt = *data; !done; aapt += aapt[2]) {
done = !(aapt[4] & 1);
len = aapt[2];
susp_calc_add_to_ce(ce_len, ce_mem, len, flag & 2);
susp_calc_add_to_ce(t, ce_len, ce_mem, len, flag & 2);
count += len;
}
} else {
@ -704,7 +707,7 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
} else {
ret = susp_append(t, susp, cpt);
}
if (ret == -1)
if (ret < 0)
return ret;
}
free(*data);
@ -930,49 +933,44 @@ int susp_add_ES(Ecma119Image *t, struct susp_info *susp, int to_ce, int seqno)
}
/**
* A field beginning by 0 causes rrip_write_ce_fields() to pad up to the
* next block.
*/
static
int pseudo_susp_add_PAD(Ecma119Image *t, struct susp_info *susp)
{
unsigned char *pad;
int ret;
pad = malloc(1);
if (pad == NULL)
return ISO_OUT_OF_MEM;
pad[0] = 0;
ret = susp_append_ce(t, susp, pad);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}
/**
* 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 +989,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 +1043,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 +1055,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 +1069,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;
}
@ -1078,7 +1081,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
/* Account for field size */
if (*sua_free < 16 || *ce_len > 0) {
susp_calc_add_to_ce(ce_len, base_ce, 16, flag & 2);
susp_calc_add_to_ce(t, ce_len, base_ce, 16, flag & 2);
} else {
*sua_free -= 16;
}
@ -1086,7 +1089,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;
@ -1139,6 +1142,7 @@ int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
* <0= error:
* -1= not enough SUA space for 28 bytes of CE entry
* -2= out of memory
* (int) ISO_TOO_MANY_CE
*/
static
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
@ -1150,35 +1154,25 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
size_t num_aapt = 0, sua_free = 0;
int ret;
uint8_t *aapt;
uint32_t curr_ce_entries_mem;
#ifdef Libisofs_ce_calc_debug_extrA
if (n->node->name != NULL)
fprintf(stderr, "libburn_DEBUG: susp_calc_nm_sl_al : %.f %s \n",
fprintf(stderr, "libburn_DEBUG: susp_calc_nm_sl_al : %u %.f %s \n",
(unsigned int) t->curr_ce_entries,
(double) base_ce, n->node->name);
#endif /* Libisofs_ce_calc_debug_extrA */
su_mem = *su_size;
ce_mem = *ce;
curr_ce_entries_mem = t->curr_ce_entries;
if (*ce > 0 && !(flag & 1))
goto unannounced_ca;
if (flag & 2) {
if (flag & 2)
flag |= 1;
if (base_ce % BLOCK_SIZE) {
#ifdef Libisofs_ce_calc_debuG
fprintf(stderr,
"\nlibburn_DEBUG: Accounting for %d bytes CE padding : %s\n\n",
(int) (BLOCK_SIZE - (base_ce % BLOCK_SIZE)), n->node->name);
#endif /* Libisofs_ce_calc_debuG */
*ce += BLOCK_SIZE - (base_ce % BLOCK_SIZE);
}
}
namelen = 0;
name = get_rr_fname(t, n->node->name);
@ -1188,10 +1182,11 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
}
if (flag & 1) {
/* Account for 28 bytes of CE field */
if (*su_size + 28 > space)
return -1;
*su_size += 28;
/* Account for 28 bytes of CE field */
if (*su_size + 28 > space)
return -1;
*su_size += 28;
t->curr_ce_entries++;
}
/* NM entry */
@ -1209,7 +1204,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
of the name will always fit into the directory entry.)
*/;
susp_calc_add_to_ce(ce, base_ce, 5 + namelen, flag & 2);
susp_calc_add_to_ce(t, ce, base_ce, 5 + namelen, flag & 2);
*su_size = space;
}
if (n->type == ECMA119_SYMLINK) {
@ -1249,7 +1244,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);
@ -1280,7 +1275,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
* and another SL entry
*/
/* Will fill up old SL and write it */
susp_calc_add_to_ce(ce, base_ce, 255, flag & 2);
susp_calc_add_to_ce(t, ce, base_ce, 255, flag & 2);
sl_len = 5 + (clen - fit); /* Start new SL */
} else {
/*
@ -1289,15 +1284,16 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
* anything in this SL
*/
/* Will write non-full old SL */
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
susp_calc_add_to_ce(t, ce, base_ce, sl_len,
flag & 2);
/* Will write another full SL */
susp_calc_add_to_ce(ce, base_ce, 255, flag & 2);
susp_calc_add_to_ce(t, ce, base_ce, 255, flag & 2);
sl_len = 5 + (clen - 250) + 2; /* Start new SL */
}
} else {
/* case 2, create a new SL entry */
/* Will write non-full old SL */
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
susp_calc_add_to_ce(t, ce, base_ce, sl_len, flag & 2);
sl_len = 5 + clen; /* Start new SL */
}
} else {
@ -1320,7 +1316,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
/* the whole SL fits into the SUA */
*su_size += sl_len;
} else {
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
susp_calc_add_to_ce(t, ce, base_ce, sl_len, flag & 2);
}
}
@ -1380,6 +1376,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
/* Crossed a block boundary */
*su_size = su_mem;
*ce = ce_mem;
t->curr_ce_entries = curr_ce_entries_mem;
return 0;
}
}
@ -1389,6 +1386,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
unannounced_ca:;
*su_size = su_mem;
*ce = ce_mem;
t->curr_ce_entries = curr_ce_entries_mem;
return 0;
}
@ -1435,6 +1433,21 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
}
static
void iso_msg_too_many_ce(Ecma119Image *t, Ecma119Node *n, int err)
{
if (n->node->name != NULL) {
iso_msg_submit(t->image->id, err, 0,
"Too many CE entries for file with name: %s",
n->node->name);
} else {
iso_msg_submit(t->image->id, err, 0,
"Too many CE entries for a single file",
n->node->name);
}
}
/**
* Compute the length needed for write all RR and SUSP entries for a given
* node.
@ -1451,13 +1464,15 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
* @return
* The size needed for the RR entries in the System Use Area
*/
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
size_t *ce, size_t base_ce)
ssize_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
size_t *ce, size_t base_ce)
{
size_t su_size, space;
int ret;
int ret, retry = 0;
size_t aaip_sua_free= 0, aaip_len= 0;
try_again:
/* Directory record length must be even (ECMA-119, 9.1.13). Maximum is 254.
*/
space = 254 - used_up - (used_up % 2);
@ -1470,6 +1485,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
*ce = 0;
su_size = 0;
t->curr_ce_entries = 0;
/* If AAIP enabled and announced by ER : account for 5 bytes of ES */;
if (t->opts->aaip && !t->opts->aaip_susp_1_10)
@ -1519,9 +1535,18 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
if (ret == 0) /* Retry with CE but no block crossing */
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce, 1);
if (ret == 0) /* Retry with aligned CE and block hopping */
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce, 1 | 2);
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce,
1 | 2);
if (ret == -2)
return ISO_OUT_OF_MEM;
/* -1 should not occur. By tradition it would not cause return */
if (ret < -2) {
if (n->node->name != NULL)
iso_msg_submit(t->image->id, ret, 0,
"SUSP planning failed for file with name: %s",
n->node->name);
return ret;
}
} else {
@ -1537,6 +1562,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
* ER needs a Continuation Area, thus we also need a CE entry
*/
su_size += 7 + 28; /* SP + CE */
t->curr_ce_entries++;
/* ER of RRIP */
if (t->opts->rrip_version_1_10) {
*ce = 237;
@ -1559,6 +1585,40 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
}
}
if (t->curr_ce_entries > t->opts->max_ce_entries) {
/* If permitted by API setting: Remove non-isofs-non-ACL fattr */
retry++;
if (retry == 1) {
if ((t->opts->max_ce_drop_attr & 15) >= 1) {
ret = iso_node_remove_fattr(n->node, 0);
if (ret > 0) {
iso_msg_too_many_ce(t, n, ISO_CE_REMOVING_ATTR);
iso_msg_submit(t->image->id, ISO_CE_REMOVING_ATTR, 0,
"Removed non-isofs attributes");
goto try_again;
}
}
} else if (retry == 2) {
if ((t->opts->max_ce_drop_attr & 15) >= 2) {
ret = iso_node_remove_fattr(n->node, 1);
if (ret > 0) {
iso_msg_submit(t->image->id, ISO_CE_REMOVING_ATTR, 0,
"Removed ACL");
goto try_again;
}
}
}
iso_msg_too_many_ce(t, n, ISO_TOO_MANY_CE);
return (ssize_t) (int) ISO_TOO_MANY_CE;
} else if (t->curr_ce_entries >= 32) {
if (n->node->name != NULL)
iso_msg_submit(t->image->id, ISO_TOO_MANY_CE_FOR_LINUX, 0,
"SUSP planning risky for file with name: %s",
n->node->name);
iso_msg_submit(t->image->id, ISO_TOO_MANY_CE_FOR_LINUX, 0,
"Too many CE entries for single file when mounted by Linux");
}
/*
* The System Use field inside the directory record must be padded if
* it is an odd number (ECMA-119, 9.1.13)
@ -1600,7 +1660,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
*/
@ -1775,6 +1835,9 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
ret = ISO_OUT_OF_MEM;
goto add_susp_cleanup;
}
/* -1 should not occur. By tradition it would not cause return */
if (ret < -2)
goto add_susp_cleanup;
/* NM entry */
if (5 + namelen <= sua_free) {
@ -1837,7 +1900,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 */
@ -1968,26 +2031,6 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
}
if (ce_is_predicted) {
if ((info->ce_len % BLOCK_SIZE) &&
(info->ce_len + ce_len_pd - 1 ) / BLOCK_SIZE !=
info->ce_len / BLOCK_SIZE) {
/* Linux fs/isofs wants byte_offset + ce_len <= BLOCK_SIZE
* Insert padding to shift CE offset to next block start
*/
#ifdef Libisofs_ce_calc_debuG
fprintf(stderr,
"\nlibburn_DEBUG: Inserting %d bytes of CE padding : %s\n\n",
(int) (BLOCK_SIZE - (info->ce_len % BLOCK_SIZE)),
n->node->name);
#endif /* Libisofs_ce_calc_debuG */
ret = pseudo_susp_add_PAD(t, info);
if (ret < 0)
goto add_susp_cleanup;
}
/* Add the CE entry */
ret = susp_add_CE(t, ce_len_pd, info);
if (ret < 0) {
@ -2097,6 +2140,8 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
/* Compute length of AAIP string of root node */
aaip_sua_free= 0;
/* (just to give t->curr_ce_entries a defined state) */
t->curr_ce_entries = 0;
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, ce_mem,
1 | 2);
if (ret < 0)
@ -2175,7 +2220,7 @@ int susp_update_CE_sizes(Ecma119Image *t, struct susp_info *info, int flag)
curr_pos = 0;
for (i = info->current_ce_start; i < info->n_ce_susp_fields; i++) {
if (info->ce_susp_fields[i][0] == 0) {
curr_pos = 0; /* pseudo SUSP PAD */
/* ignore pseudo SUSP PAD */
continue;
}
if (info->ce_susp_fields[i][0] == 'C' &&
@ -2185,11 +2230,20 @@ int susp_update_CE_sizes(Ecma119Image *t, struct susp_info *info, int flag)
size = BLOCK_SIZE;
iso_bb(curr_ce + 20, size, 4);
curr_ce = info->ce_susp_fields[i];
/* Start a new CE Area */
curr_pos = 0;
continue;
}
curr_pos = (curr_pos + info->ce_susp_fields[i][2]) % 2048;
}
if (curr_pos > 0) {
size = curr_pos % BLOCK_SIZE;
size = curr_pos;
if (size > BLOCK_SIZE) {
/* Should never happen */
iso_msg_submit(t->image->id, ISO_WRONG_RR_WARN, 0,
"Encountered and truncated oversized Continuation Area");
size = BLOCK_SIZE;
}
iso_bb(curr_ce + 20, size, 4);
}
return ISO_SUCCESS;
@ -2201,7 +2255,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 - 2023 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -41,6 +41,9 @@
#include "ecma119.h"
/* For ssize_t */
#include <unistd.h>
#define SUSP_SIG(entry, a, b) ((entry->sig[0] == a) && (entry->sig[1] == b))
@ -203,8 +206,8 @@ struct susp_sys_user_entry
* @return
* The size needed for the RR entries in the System Use Area
*/
size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
size_t *ce, size_t base_ce);
ssize_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t space,
size_t *ce, size_t base_ce);
/**
* Fill a struct susp_info with the RR/SUSP entries needed for a given
@ -219,7 +222,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 +234,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);
@ -359,7 +362,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

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2023 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
@ -38,6 +38,9 @@ struct susp_iterator
/* Number of blocks in the ISO 9660 filesystem */
uint32_t fs_blocks;
/* For detecting (nearly) endless loops */
uint32_t ce_counter;
/* block and offset for next continuation area */
uint32_t ce_block;
uint32_t ce_off;
@ -65,7 +68,10 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
iter->msgid = msgid;
iter->fs_blocks = fs_blocks;
iter->ce_counter = 0;
iter->ce_len = 0;
iter->ce_block = 0;
iter->ce_off = 0;
iter->buffer = NULL;
return iter;
@ -74,6 +80,9 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
/* More than 1 MiB in a single file's CE area is suspicious */
#define ISO_SUSP_MAX_CE_BYTES (1024 * 1024)
/* More than 100000 CE entries in a file is suspicious */
#define ISO_SUSP_MAX_CE_HOPS 100000
/* @param flag bit0 = First call on root:
Not yet clear whether this is SUSP at all
@ -83,6 +92,7 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
{
struct susp_sys_user_entry *entry;
process_entry:;
entry = (struct susp_sys_user_entry*)(iter->base + iter->pos);
if (flag & 1) {
@ -94,6 +104,9 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
if (entry->len_sue[0] < 7)
return 0;
/* Looks like SUSP enough to pass the further processing here. */
/* In case of CE hop do not run this check again */
flag &= ~1;
}
if ( (iter->pos + 4 > iter->size) || (SUSP_SIG(entry, 'S', 'T'))) {
@ -151,9 +164,9 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
if (iter->ce_len) {
int ret;
ret = iso_msg_submit(iter->msgid, ISO_UNSUPPORTED_SUSP, 0,
"More than one CE System user entry has found in a single "
"More than one CE System user entry was found in a single "
"System Use field or continuation area. This breaks SUSP "
"standard and it's not supported. Ignoring last CE. Maybe "
"standard and is not supported. Ignoring last CE. Maybe "
"the image is damaged.");
if (ret < 0) {
return ret;
@ -165,10 +178,15 @@ 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, 0);
if (++(iter->ce_counter) > ISO_SUSP_MAX_CE_HOPS) {
iso_msg_submit(iter->msgid, ISO_WRONG_RR, 0,
"Damaged RR/SUSP information: Too many CE hops.");
return ISO_WRONG_RR;
}
goto process_entry;
} else if (SUSP_SIG(entry, 'P', 'D')) {
/* skip padding */
return susp_iter_next(iter, sue, 0);
goto process_entry;
}
*sue = entry;
@ -617,29 +635,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

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2015 Thomas Schmitt
* Copyright (c) 2009 - 2022 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
@ -22,6 +22,7 @@
#include <string.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#ifndef PATH_MAX
@ -290,25 +291,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;
}
@ -330,6 +331,7 @@ int cut_out_open(IsoStream *stream)
{
int ret;
struct stat info;
off_t src_size, pos;
IsoFileSource *src;
struct cut_out_stream *data;
@ -348,20 +350,26 @@ int cut_out_open(IsoStream *stream)
return ret;
}
{
off_t ret;
if (data->offset > info.st_size) {
/* file is smaller than expected */
ret = iso_file_source_lseek(src, info.st_size, 0);
} else {
ret = iso_file_source_lseek(src, data->offset, 0);
}
if (ret < 0) {
return (int) ret;
}
if (S_ISREG(info.st_mode)) {
src_size= info.st_size;
} else {
/* Determine src_size and lseekability of device */
src_size = iso_file_source_determine_capacity(src,
data->offset + data->size, 2);
if (src_size <= 0)
return ISO_WRONG_ARG_VALUE;
}
if (data->offset > src_size) {
/* file is smaller than expected */
pos = iso_file_source_lseek(src, src_size, 0);
} else {
pos = iso_file_source_lseek(src, data->offset, 0);
}
if (pos < 0) {
return (int) pos;
}
data->pos = 0;
if (data->offset + data->size > info.st_size) {
if (data->offset + data->size > src_size) {
return 3; /* file smaller than expected */
} else {
return ISO_SUCCESS;
@ -508,6 +516,7 @@ int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
IsoStream **stream)
{
int r;
off_t src_size;
struct stat info;
IsoStream *str;
struct cut_out_stream *data;
@ -523,10 +532,16 @@ int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
if (r < 0) {
return r;
}
if (!S_ISREG(info.st_mode)) {
return ISO_WRONG_ARG_VALUE;
if (S_ISREG(info.st_mode)) {
src_size = info.st_size;
} else {
/* Open src, do iso_source_lseek(SEEK_END), close src */
src_size = iso_file_source_determine_capacity(src, offset + size, 3);
if (src_size <= 0)
return ISO_WRONG_ARG_VALUE;
}
if (offset > info.st_size) {
if (offset > src_size) {
return ISO_FILE_OFFSET_TOO_BIG;
}
@ -551,7 +566,7 @@ int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
iso_file_source_ref(src);
data->offset = offset;
data->size = MIN(info.st_size - offset, size);
data->size = MIN(src_size - offset, size);
/* get the id numbers */
data->dev_id = (dev_t) 0;
@ -852,12 +867,24 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
strncpy(name, path, PATH_MAX - 1);
name[PATH_MAX - 1] = 0;
free(path);
} else if (!strncmp(type, "boot", 4)) {
strcpy(name, "BOOT CATALOG");
} else if (!strncmp(type, "cout", 4)) {
strcpy(name, "CUT_OUT FILE");
} else if (!strncmp(type, "mem ", 4)) {
strcpy(name, "MEM SOURCE");
} else if (!strncmp(type, "boot", 4)) {
strcpy(name, "BOOT CATALOG");
} else if (!strncmp(type, "extf", 4)) {
strcpy(name, "EXTERNAL FILTER");
} else if (!strncmp(type, "ziso", 4)) {
strcpy(name, "ZISOFS COMPRESSION FILTER");
} else if (!strncmp(type, "osiz", 4)) {
strcpy(name, "ZISOFS DECOMPRESSION FILTER");
} else if (!strncmp(type, "gzip", 4)) {
strcpy(name, "GZIP COMPRESSION FILTER");
} else if (!strncmp(type, "pizg", 4)) {
strcpy(name, "GZIP DECOMPRESSION FILTER");
} else if (!strncmp(type, "user", 4)) {
strcpy(name, "USER SUPPLIED STREAM");
} else {
strcpy(name, "UNKNOWN SOURCE");
}

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 - 2019 Thomas Schmitt
* Copyright (c) 2010 - 2024 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
@ -555,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);
}
@ -786,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);
@ -1032,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));
@ -1040,9 +1046,14 @@ 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;
entry->image_path = NULL;
ret = iso_register_apm_entry(req_array, apm_req_count, entry, 0);
free(entry);
return ret;
@ -1089,6 +1100,7 @@ int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array,
entry->flags = flags;
memcpy(entry->name, name, 72);
entry->req_status = 0;
entry->image_path = NULL;
ret = iso_register_gpt_entry(req_array, gpt_req_count, entry, 0);
free(entry);
return ret;
@ -1118,6 +1130,7 @@ int iso_quick_mbr_entry(struct iso_mbr_partition_request **req_array,
entry->type_byte = type_byte;
entry->status_byte = status_byte;
entry->desired_slot = desired_slot;
entry->image_path = NULL;
ret = iso_register_mbr_entry(req_array, mbr_req_count, entry, 0);
free(entry);
return ret;
@ -1393,8 +1406,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]);
@ -1720,10 +1738,13 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7
};
uint8_t *wpt;
uint32_t p_arr_crc = 0;
uint64_t start_lba, end_lba, goal, part_end, next_end, backup_end_lba;
int ret, i, gap_counter = 0, up_to;
uint64_t eff_gpt_flags;
int ret, i, gap_counter = 0, up_to, slot, j, to_insert;
struct iso_gpt_partition_request *req;
char msg[81];
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;
@ -1776,11 +1797,16 @@ 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;
eff_gpt_flags= gpt_flags;
if (goal == t->vol_space_size * (uint64_t) 4 &&
part_end == t->opts->partition_offset * (uint64_t) 4) {
sprintf((char *) gpt_name, "ISO9660");
if (t->opts->iso_gpt_flag & 1)
type_guid = t->opts->iso_gpt_type_guid;
if (t->system_area_options & (1 << 16))
eff_gpt_flags|= 4; /* Legacy BIOS bootable */
if (t->system_area_options & (1 << 17))
eff_gpt_flags&= ~(((uint64_t) 1) << 60);/* Not read-only */
} else {
sprintf((char *) gpt_name, "Gap%d", gap_counter);
}
@ -1789,7 +1815,7 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
part_end, goal - part_end,
type_guid, zero_uuid,
gpt_flags, gpt_name);
eff_gpt_flags, gpt_name);
if (ret < 0)
return ret;
/* Mark as automatically placed filler request */
@ -1804,6 +1830,8 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
return ISO_BOOT_TOO_MANY_GPT;
/* Write the GPT entries to buf */
wpt= buf + 512 * t->gpt_part_start;
slot= 1;
for (i = 0; i < t->gpt_req_count; i++) {
req = t->gpt_req[i];
start_lba = req->start_block;
@ -1814,11 +1842,38 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
if (end_lba > backup_end_lba)
end_lba = backup_end_lba;
end_lba = end_lba - 1;
iso_write_gpt_entry(t, buf + 512 * t->gpt_part_start + 128 * i,
req->type_guid, req->partition_guid,
if (req->desired_slot > 0) {
to_insert= req->desired_slot - slot;
if (to_insert > 0 &&
slot - 1 + to_insert + t->gpt_req_count - i <=
(int) t->gpt_max_entries) {
/* There is need and room to insert empty partition entries */
for (j = 0; j < to_insert; j++) {
memset(wpt, 0, 128);
wpt+= 128;
slot++;
}
if (!t->wthread_is_running) {
sprintf(msg,
"Inserted %d empty GPT slots before appended partition %d",
to_insert, req->desired_slot);
iso_msgs_submit(0, msg, 0, "DEBUG", 0);
}
} else if (slot != req->desired_slot) {
if (!t->wthread_is_running) {
sprintf(msg,
"Appended GPT partition becomes number %d instead of desired %d",
i + 1, req->desired_slot);
iso_msgs_submit(0, msg, 0, "NOTE", 0);
}
}
}
iso_write_gpt_entry(t, wpt, req->type_guid, req->partition_guid,
start_lba, end_lba, req->flags, req->name);
wpt+= 128;
slot++;
}
for (; i < (int) t->gpt_max_entries; i++)
for (i= slot - 1; i < (int) t->gpt_max_entries; i++)
memset(buf + 512 * t->gpt_part_start + 128 * i, 0, 128);
p_arr_crc = iso_crc32_gpt((unsigned char *) buf + 512 * t->gpt_part_start,
@ -1860,7 +1915,60 @@ static void iso_dummy_mbr_partition(uint8_t *buf, int mode)
}
int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* flag bit0= only accept partition 1 as match for partition_offset
*/
static
int iso_ensure_mbr_part_table(Ecma119Image *t, uint32_t img_blocks,
uint8_t *buf, int flag)
{
int part_type, ret, i, found_part = 0;
uint32_t start_lba, num_blocks;
/* Look for MBR partition which starts at t->opts->partition_offset * 4
and has non-zero length
*/
if (buf[510] == 0x55 && buf[511] == 0xaa &&
t->opts->partition_offset < 0x3fffffff && img_blocks < 0x3fffffff ) {
for (i = 0; i < 4; i++) {
start_lba = iso_read_lsb(buf + 446 + i * 16 + 8, 4);
num_blocks = iso_read_lsb(buf + 446 + i * 16 + 12, 4);
if (t->opts->partition_offset * 4 == start_lba && num_blocks > 0) {
found_part = i + 1;
break;
}
if (flag & 1)
break;
}
}
if (found_part > 0) {
/* Update size fields in found_part */
part_type = buf[446 + (found_part - 1) * 16 + 4];
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(found_part, part_type,
start_lba, img_blocks * 4,
t->partition_secs_per_head,
t->partition_heads_per_cyl, buf, 2);
} 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;
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
t->partition_heads_per_cyl,
(uint8_t) part_type, buf, 2);
}
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
return ISO_SUCCESS;
}
/* @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;
@ -1932,8 +2040,10 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
*/
apm_flag = 0;
if (sa_type == 0 && (t->system_area_options & 3) == 2) {
do_isohybrid = 1;
if (sa_type == 0 && ((t->system_area_options & 3) == 2 ||
t->opts->part_like_isohybrid)) {
if (sa_type == 0 && (t->system_area_options & 3) == 2)
do_isohybrid = 1;
/* >>> Coordinate with partprepend writer */
/* <<< provisory trap */
@ -1969,7 +2079,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);
@ -2003,23 +2114,29 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* >>> ??? change first partition type to 0xee */;
}
} else if (do_isohybrid) {
/* Patch externally provided system area as isohybrid MBR */
if (t->catalog == NULL || t->system_area_data == NULL) {
} else if (do_isohybrid || t->opts->part_like_isohybrid) {
/* Patch externally provided system area as isohybrid MBR
or at least write an MBR partition table as of isohybrid
*/
if ((t->catalog == NULL || t->system_area_data == NULL) &&
do_isohybrid) {
/* isohybrid makes only sense together with ISOLINUX boot image
and externally provided System Area.
*/
return ISO_ISOLINUX_CANT_PATCH;
}
if (gpt_count > 0 || apm_count > 0)
if (gpt_count > 0 || apm_count > 0) {
/* Decision can be revoked in make_isolinux_mbr if !do_isohybrid */
part_type = 0x00;
else {
} else {
part_type = 0x17;
}
/* By tradition, real isohybrid insists in 0x00 if GPT or APM */
if (part_type != 0x00 || !do_isohybrid)
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;
@ -2028,13 +2145,16 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
no_boot_mbr = 2;
}
/* >>> ??? Why is partition_offset 0 here ?
It gets adjusted later by iso_offset_partition_start()
Would it harm to give the real offset here ?
*/;
ret = make_isolinux_mbr(&img_blocks, t, 0, 1, part_type, buf,
1 | no_boot_mbr);
/* ??? Why was partition_offset 0 here ?
It gets adjusted later by iso_offset_partition_start()
Does it harm to give the real offset here ?
Now this is really needed for checking whether partitions
are inside the ISO 9660 partition if !do_isohybrid
*/
ret = make_isolinux_mbr(&img_blocks, t, t->opts->partition_offset * 4,
1, part_type, buf,
1 | no_boot_mbr | ((!do_isohybrid) << 2) |
((!do_isohybrid) << 3));
if (ret != 1)
return ret;
} else if (sa_type == 1) {
@ -2060,14 +2180,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
return ret;
} 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) part_type, buf, 2);
ret= iso_ensure_mbr_part_table(t, img_blocks, buf,
((t->opts->appended_as_gpt && t->have_appended_partitions) ||
t->opts->partition_offset == 0));
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
risk_of_ee = 1;
@ -2075,7 +2190,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,
@ -2085,7 +2200,7 @@ 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;
part_type = 0x83;
if (t->opts->iso_mbr_part_type >= 0 &&
@ -2131,7 +2246,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
#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;
@ -2148,7 +2264,8 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf)
/* 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;
@ -2428,6 +2545,13 @@ int iso_register_apm_entry(struct iso_apm_partition_request **req_array,
return ISO_OUT_OF_MEM;
memcpy(entry, req, sizeof(struct iso_apm_partition_request));
if (req->image_path != NULL) {
entry->image_path = strdup(req->image_path);
if (entry->image_path == NULL) {
LIBISO_FREE_MEM(entry);
return ISO_OUT_OF_MEM;
}
}
req_array[*apm_req_count] = entry;
(*apm_req_count)++;
return ISO_SUCCESS;
@ -2447,6 +2571,13 @@ int iso_register_mbr_entry(struct iso_mbr_partition_request **req_array,
return ISO_OUT_OF_MEM;
memcpy(entry, req, sizeof(struct iso_mbr_partition_request));
if (req->image_path != NULL) {
entry->image_path = strdup(req->image_path);
if (entry->image_path == NULL) {
LIBISO_FREE_MEM(entry);
return ISO_OUT_OF_MEM;
}
}
req_array[*mbr_req_count] = entry;
(*mbr_req_count)++;
return ISO_SUCCESS;
@ -2465,6 +2596,13 @@ int iso_register_gpt_entry(struct iso_gpt_partition_request **req_array,
return ISO_OUT_OF_MEM;
memcpy(entry, req, sizeof(struct iso_gpt_partition_request));
if (req->image_path != NULL) {
entry->image_path = strdup(req->image_path);
if (entry->image_path == NULL) {
LIBISO_FREE_MEM(entry);
return ISO_OUT_OF_MEM;
}
}
req_array[*gpt_req_count] = entry;
(*gpt_req_count)++;
return ISO_SUCCESS;
@ -2630,9 +2768,15 @@ 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 = 0;
int first_partition, last_partition;
uint8_t gpt_name[72], *type_uuid;
char apm_type[33];
#ifndef Libisofs_appended_partitions_inlinE
if (!t->gpt_backup_outside)
@ -2650,16 +2794,23 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
return 2;
/* Represent appended partitions */
for (i = 0; i <= 3; i++) {
iso_tell_max_part_range(t->opts, &first_partition, &last_partition, 0);
for (i = first_partition - 1; i < last_partition; i++) {
if (t->opts->appended_partitions[i] == NULL)
continue;
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;
}
@ -2685,6 +2836,9 @@ int assess_appended_gpt(Ecma119Image *t, int flag)
(uint64_t) 0, gpt_name);
if (ret < 0)
return ret;
t->gpt_req[t->gpt_req_count - 1]->desired_slot = i + 1;
} else if(do_gpt) {
t->gpt_req[index]->desired_slot = i + 1;
}
}
return ISO_SUCCESS;
@ -2742,6 +2896,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.
@ -2750,9 +2909,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 */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2012 - 2019 Thomas Schmitt
* Copyright (c) 2012 - 2024 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.
*/
@ -102,6 +104,12 @@ struct iso_mbr_partition_request {
*/
int desired_slot;
/* Only when representing an imported partition:
Path of file in imported ISO which holds the partition content.
NULL = no such file
*/
char *image_path;
};
/* Copies the content of req and registers it in t.mbr_req[].
@ -160,6 +168,13 @@ struct iso_apm_partition_request {
bit0= this is an automatically placed filler partition
*/
uint32_t req_status;
/* Only when representing an imported partition:
Path of file in imported ISO which holds the partition content.
NULL = no such file
*/
char *image_path;
};
/* Copies the content of req and registers it in t.apm_req[].
@ -249,6 +264,21 @@ struct iso_gpt_partition_request {
bit0= this is an automatically placed filler partition
*/
uint32_t req_status;
/* Desired partition number in emerging GPT: first = 1, no desire = 0
GPT partitions get sorted by start LBA. Gaps of uncovered blocks get
filled. If the resulting sequence positions the partition at a lower
slot than desired, then empty slots get inserted to match the desire.
If the sequence positions the partition at a higher slot, then a mere
note is issued and the partition gets into the higher slot.
*/
int desired_slot;
/* Only when representing an imported partition:
Path of file in imported ISO which holds the partition content.
NULL = no such file
*/
char *image_path;
};
/* Copies the content of req and registers it in t.gpt_req[].

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2011 - 2015 Thomas Schmitt
* Copyright (c) 2011 - 2022 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
@ -24,6 +24,7 @@
#include "messages.h"
#include "tree.h"
#include "util.h"
#include "ecma119.h"
#include <stdlib.h>
#include <string.h>
@ -43,11 +44,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
@ -127,7 +128,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
@ -206,7 +207,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 +230,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
@ -319,7 +320,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
@ -677,6 +678,7 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
IsoNode **node)
{
int result;
off_t src_size;
struct stat info;
IsoFilesystem *fs;
IsoFileSource *src;
@ -715,17 +717,22 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
iso_file_source_unref(src);
return result;
}
if (!S_ISREG(info.st_mode)) {
return ISO_WRONG_ARG_VALUE;
if (S_ISREG(info.st_mode)) {
src_size = info.st_size;
} else {
src_size = iso_file_source_determine_capacity(src, offset + size, 3);
if (src_size <= 0)
return ISO_WRONG_ARG_VALUE;
}
if (offset >= info.st_size) {
if (offset >= src_size) {
return ISO_WRONG_ARG_VALUE;
}
/* force regular file */
result = image->builder->create_file(image->builder, image, src, &new);
/* free the file */
/* Give up the newly acquired surplus reference to src */
iso_file_source_unref(src);
if (result < 0) {
@ -768,7 +775,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++;
@ -1045,6 +1052,17 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
"Error when adding file %s", path);
goto dir_rec_continue;
}
if (image->do_deeper_tree_inspection) {
if (image->tree_loaded == 0 && image->rr_loaded == 0) {
iso_image_assess_ecma119_name(image, &info, path, name);
} else if (image->tree_loaded == 1) {
iso_image_assess_joliet_name(image, &info, path, name);
}
if (info.st_size > MAX_ISO_FILE_SECTION_SIZE &&
image->tree_compliance != NULL)
image->tree_compliance->iso_level = 3;
}
if (check_excludes(image, path)) {
iso_msg_debug(image->id, "Skipping excluded file %s", path);
@ -1276,6 +1294,8 @@ ex:;
}
/* Note: No reference is taken to the found node.
Warning: Do not submit next_above uninitialized.
Submit NULL if next_above is not of interest.
@param flag bit0= recursion
*/
int iso_tree_get_node_of_block(IsoImage *image, IsoDir *dir, uint32_t block,
@ -1435,6 +1455,8 @@ int iso_tree_clone_file(IsoFile *old_file,
if (ret < 0)
goto ex;
new_stream = NULL; /* now owned by new_file */
new_file->from_old_session = old_file->from_old_session;
new_file->explicit_weight = old_file->explicit_weight;
new_file->sort_weight = old_file->sort_weight;
*new_node = (IsoNode *) new_file;
ret = ISO_SUCCESS;

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2019 Thomas Schmitt
* Copyright (c) 2009 - 2022 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
@ -803,18 +803,18 @@ int str2utf16be(const char *icharset, const char *input, uint16_t **output)
return ISO_SUCCESS;
}
static int valid_d_char(char c)
int valid_d_char(char c)
{
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');
}
static int valid_a_char(char c)
int valid_a_char(char c)
{
return (c >= ' ' && c <= '"') || (c >= '%' && c <= '?') ||
(c >= 'A' && c <= 'Z') || (c == '_');
}
static int valid_j_char(uint16_t c)
int valid_j_char(uint16_t c)
{
return cmp_ucsbe(&c, ' ') != -1 && cmp_ucsbe(&c, '*') && cmp_ucsbe(&c, '/')
&& cmp_ucsbe(&c, ':') && cmp_ucsbe(&c, ';') && cmp_ucsbe(&c, '?')
@ -1483,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;
@ -1597,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;
@ -1650,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;
@ -1942,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;
@ -1995,7 +2025,7 @@ 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);
@ -2332,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
*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2022 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
@ -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,19 @@ 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);
/* Check for membership in the d-, a-, or j-character set */
int valid_d_char(char c);
int valid_a_char(char c);
int valid_j_char(uint16_t c);
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 +407,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 +653,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.
*/