Compare commits
184 Commits
release-1.
...
master
Author | SHA1 | Date |
---|---|---|
Thomas Schmitt | 78708015af | |
Thomas Schmitt | 57fcd4bfbb | |
Thomas Schmitt | 483a68aaf2 | |
Thomas Schmitt | 8ffd3b381b | |
Thomas Schmitt | d9c548dbfc | |
Thomas Schmitt | 8ed27c6255 | |
Thomas Schmitt | 405f0f04d4 | |
Thomas Schmitt | 8a8439768c | |
Thomas Schmitt | 9ec998f9fc | |
Thomas Schmitt | 8a4f1f88ae | |
Thomas Schmitt | 09ec2fa4b7 | |
Thomas Schmitt | 5a867c43ab | |
Thomas Schmitt | 170318c42e | |
Thomas Schmitt | c2d17b1c4b | |
Thomas Schmitt | cdc7f52187 | |
Thomas Schmitt | bd415402f4 | |
Thomas Schmitt | 7109ba5675 | |
Thomas Schmitt | d35435b5a0 | |
Thomas Schmitt | acb4bd143c | |
Thomas Schmitt | 71772baab7 | |
Thomas Schmitt | 83e5832ed0 | |
Thomas Schmitt | 9b7ccc9727 | |
Thomas Schmitt | c6cb7dfa3e | |
Thomas Schmitt | ad55ec78e4 | |
Thomas Schmitt | 011e2e85e6 | |
Thomas Schmitt | f457a4f8b9 | |
Thomas Schmitt | 2af17490a0 | |
Thomas Schmitt | da00291519 | |
Thomas Schmitt | 1d61b518b5 | |
Thomas Schmitt | 99251ade08 | |
Thomas Schmitt | da8e3e66e7 | |
Thomas Schmitt | 3e61a61a21 | |
Thomas Schmitt | 80a0691660 | |
Thomas Schmitt | 1c4c04d4e2 | |
Thomas Schmitt | 75499bcda9 | |
Thomas Schmitt | 9e389186f7 | |
Thomas Schmitt | 7d248c46e1 | |
Thomas Schmitt | 98aea0c18a | |
Thomas Schmitt | 058f18d37a | |
Thomas Schmitt | 5add62bda0 | |
Thomas Schmitt | 2d1fec2569 | |
Thomas Schmitt | 4219bf4950 | |
Thomas Schmitt | 2a20e93b13 | |
Thomas Schmitt | 62411411db | |
Thomas Schmitt | 8f3ff65c04 | |
Thomas Schmitt | c068a19a8c | |
Thomas Schmitt | cece6fb371 | |
Thomas Schmitt | 29cc5c8d31 | |
Thomas Schmitt | 92af0c9752 | |
Thomas Schmitt | daaee5e7e6 | |
Thomas Schmitt | 7e3b01b53c | |
Thomas Schmitt | 1d5566f8bb | |
Thomas Schmitt | ac9d55330d | |
Thomas Schmitt | b0687643c5 | |
Thomas Schmitt | 5a98a4cda5 | |
Thomas Schmitt | b7a90c5194 | |
Thomas Schmitt | 8d70c75d4a | |
Thomas Schmitt | 9605bbe748 | |
Thomas Schmitt | 46186e5f06 | |
Thomas Schmitt | 2ac62f0cac | |
Thomas Schmitt | dc61e7d298 | |
Thomas Schmitt | d5ffecf2f5 | |
Thomas Schmitt | 80449f0dc9 | |
Thomas Schmitt | cc2e0e32a3 | |
Thomas Schmitt | 239ba69925 | |
Thomas Schmitt | 2ca3b292fb | |
Thomas Schmitt | f291e37ec1 | |
Thomas Schmitt | b107443769 | |
Thomas Schmitt | d297ce3aed | |
Thomas Schmitt | f962d0da66 | |
Thomas Schmitt | b0230b6ac8 | |
Thomas Schmitt | 69e332d17a | |
Thomas Schmitt | 6ca841e002 | |
Thomas Schmitt | c84f6ae689 | |
Thomas Schmitt | ac248877a2 | |
Thomas Schmitt | c1d9639dba | |
Thomas Schmitt | 773be790e8 | |
Thomas Schmitt | dc3d82cf36 | |
Thomas Schmitt | 560c11617e | |
Thomas Schmitt | fa43a5a25c | |
Thomas Schmitt | 4d8a467e1a | |
Thomas Schmitt | 65c4dce69a | |
Thomas Schmitt | fe98b35afb | |
Thomas Schmitt | 130b46cf71 | |
Thomas Schmitt | eb7dc408e0 | |
Thomas Schmitt | a5e209265d | |
Thomas Schmitt | 458ab43ecd | |
Thomas Schmitt | 4b21386e82 | |
Thomas Schmitt | c62d9d7b1b | |
Thomas Schmitt | 3aab1cafc5 | |
Thomas Schmitt | 8fbc2fcdfd | |
Thomas Schmitt | aed8bda955 | |
Thomas Schmitt | e1097dbb5d | |
Thomas Schmitt | a1e75003b5 | |
Thomas Schmitt | 4064a7e0ee | |
Thomas Schmitt | 96261585f1 | |
Thomas Schmitt | 01415ae208 | |
Thomas Schmitt | 241b9ea832 | |
Thomas Schmitt | 6a6343c146 | |
Thomas Schmitt | a63b16f7da | |
Thomas Schmitt | 31c4c26567 | |
Thomas Schmitt | 6b31667ee4 | |
Thomas Schmitt | 066c6f685d | |
Thomas Schmitt | e317a8d93e | |
Thomas Schmitt | d3c17d0555 | |
Thomas Schmitt | 69c8c543a9 | |
Thomas Schmitt | f39d4eefee | |
Thomas Schmitt | 848e039e6d | |
Thomas Schmitt | c5a9cc56e3 | |
Thomas Schmitt | 310612174b | |
Thomas Schmitt | ad843f1723 | |
Thomas Schmitt | 615dc7e997 | |
Thomas Schmitt | a936409a82 | |
Thomas Schmitt | 580b154773 | |
Thomas Schmitt | 1da3b17233 | |
Thomas Schmitt | 633b4d5f72 | |
Thomas Schmitt | 4b031b58ea | |
Thomas Schmitt | 7d45c88cff | |
Thomas Schmitt | 79baab3fc9 | |
Thomas Schmitt | 53b2d6dcd7 | |
Thomas Schmitt | 874dc16d92 | |
Thomas Schmitt | 34e35865fe | |
Thomas Schmitt | ce831f111c | |
Thomas Schmitt | 48ee49a7e0 | |
Thomas Schmitt | bdfd4c4a37 | |
Thomas Schmitt | dfc6de9f79 | |
Thomas Schmitt | 7234425502 | |
Thomas Schmitt | 4e5a54c2f9 | |
Thomas Schmitt | 028f9275d3 | |
Thomas Schmitt | cace41ec16 | |
Thomas Schmitt | e599a575dc | |
Thomas Schmitt | 78b0a7b111 | |
Thomas Schmitt | a7152f5794 | |
Thomas Schmitt | 2a64d89e6e | |
Thomas Schmitt | 31088d9acc | |
Thomas Schmitt | 91490d5f34 | |
Thomas Schmitt | 661b68ce8c | |
Thomas Schmitt | 16bde11076 | |
Thomas Schmitt | 36c8800ff3 | |
Thomas Schmitt | 860a91dd2f | |
Thomas Schmitt | 280108d2d5 | |
Thomas Schmitt | 1e40ed3fab | |
Thomas Schmitt | e19a338a09 | |
Thomas Schmitt | c6e4035918 | |
Thomas Schmitt | 18ab6019bc | |
Thomas Schmitt | 6282bbc0bc | |
Thomas Schmitt | d7737e3ed5 | |
Thomas Schmitt | fb8697081b | |
Thomas Schmitt | 0e7300b1a8 | |
Thomas Schmitt | 94e4bfb42b | |
Thomas Schmitt | 86f6ffc9c9 | |
Thomas Schmitt | 5600f3d726 | |
Thomas Schmitt | e66b9bfe0c | |
Thomas Schmitt | 094b3f7546 | |
Thomas Schmitt | 5c1c5cd964 | |
Thomas Schmitt | 215280448f | |
Thomas Schmitt | 3043b5f660 | |
Thomas Schmitt | afb10aac3b | |
Thomas Schmitt | 76181d0aa3 | |
Thomas Schmitt | 8ec75eea6a | |
Thomas Schmitt | 01020ef544 | |
Thomas Schmitt | 2961bdef9f | |
Thomas Schmitt | ed209e0b6e | |
Thomas Schmitt | dc6cd946ba | |
Thomas Schmitt | c51efce8d1 | |
Thomas Schmitt | 8bf32d8d14 | |
Thomas Schmitt | 561e2a6aaa | |
Thomas Schmitt | e7dd325ff6 | |
Thomas Schmitt | 0447496710 | |
Thomas Schmitt | 496b8051c5 | |
Thomas Schmitt | 63c074b0aa | |
Thomas Schmitt | 2be47f9af8 | |
Thomas Schmitt | bf5678c6d4 | |
Thomas Schmitt | 9d64318502 | |
Thomas Schmitt | 866f647fad | |
Thomas Schmitt | 2f134dcdcb | |
Thomas Schmitt | b14ee71d51 | |
Thomas Schmitt | c5c9d4e7bf | |
Thomas Schmitt | 6321ed4d97 | |
Thomas Schmitt | 188e36178b | |
Thomas Schmitt | cbfa9afcf1 | |
Thomas Schmitt | cb519b3692 | |
Thomas Schmitt | 8407d9e936 | |
Thomas Schmitt | d482eb4c96 |
|
@ -1,7 +1,9 @@
|
|||
Vreixo Formoso <metalpain2002@yahoo.es>,
|
||||
Mario Danic <mario.danic@gmail.com>,
|
||||
Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (C) 2007-2015 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||
Copyright (C) 2007-2018
|
||||
Vreixo Formoso, Mario Danic, Vladimir Serbinenko, Thomas Schmitt
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
|
114
ChangeLog
114
ChangeLog
|
@ -1,3 +1,117 @@
|
|||
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()
|
||||
* New API call iso_nowtime()
|
||||
* New flag bit2 of iso_node_set_acl_text() to be verbous about failures
|
||||
* Made libisofs ready for building out-of-source. Thanks Ross Burton.
|
||||
* Bug fix: Appended GPT partitions were not covered by the protective MBR
|
||||
partition
|
||||
* Bug fix: Multi-session emulation spoiled GPT production.
|
||||
"GPT partitions ... overlap". Regression towards 1.4.8
|
||||
* Bug fix: Appending partitions 5 to 8 caused damaged ISO filesystems if not
|
||||
for SUN disk label
|
||||
* Bug fix: SIGSEGV happened if options bit 14 of
|
||||
iso_write_opts_set_system_area() is set and no El Torito boot image
|
||||
is defined
|
||||
|
||||
libisofs-1.5.0.tar.gz Sat Sep 15 2018
|
||||
===============================================================================
|
||||
* New API call iso_image_get_ignore_aclea(),
|
||||
new iso_image_set_ignore_aclea() and iso_file_source_get_aa_string()
|
||||
flag bit3 to import all xattr namespaces
|
||||
* New API calls iso_image_was_blind_attrs(), iso_local_set_attrs_errno().
|
||||
* New flag bit7 with iso_local_set_attrs() to avoid unnecessary write attempts.
|
||||
* New return value 2 of IsoFileSource.get_aa_string() and iso_local_get_attrs().
|
||||
* Now putting user defined padding after appended partitions.
|
||||
* Bug fix: Add-on sessions with partition offset claimed too many blocks as
|
||||
size. Regression of version 1.4.8.
|
||||
* Bug fix: Long Joliet names without dot were mangled with one character too
|
||||
many. Long Joliet names with leading dot were mangled one char
|
||||
too short.
|
||||
* Bug fix: Reading beyond array end for HFS+ production caused SIGSEGV with
|
||||
FreeBSD 11 CLANG -O2. Thanks ASX of GhostBSD.
|
||||
|
||||
libisofs-1.4.8.tar.gz Tue Sep 12 2017
|
||||
===============================================================================
|
||||
* Bug fix: iso_read_opts_set_no_rockridge() did not prevent reading of root
|
||||
SUSP.
|
||||
* Bug fix: Non-SUSP data in System Use Area prevented image loading if
|
||||
Rock Ridge was enabled. Thanks to Jonathan Dowland.
|
||||
* Bug fix: Protective MBR for GPT could emerge with boot flag set.
|
||||
* Bug fix: Appended partitions of size >= 4 GiB led to abort with error message
|
||||
"FATAL : ISO overwrite". Thanks to Sven Haardiek.
|
||||
* Bug fix: Bit 15 of iso_write_opts_set_system_area did not work with generic
|
||||
MBR.
|
||||
* Bug fix: Keeping and patching of loaded boot images failed.
|
||||
Regression by version 1.4.4.
|
||||
* Bug fix: Program crashes by intentionally wrong ISO image input.
|
||||
Found by American Fuzzy Lop and Jakub Wilk.
|
||||
Debian bug reports: 872372, 872475, 872545, 872590, 872761.
|
||||
* New API calls el_torito_set_full_load(), el_torito_get_full_load().
|
||||
* New API call iso_write_opts_set_iso_mbr_part_type().
|
||||
|
||||
|
||||
libisofs-1.4.6.tar.gz Fri Sep 16 2016
|
||||
===============================================================================
|
||||
* Bug fix: SIGSEGV by NULL when a data file was larger than ISO level allows.
|
||||
* Bug fix: Interpretation of 17 digit timestamps was wrong.
|
||||
* New API calls iso_generate_gpt_guid() and iso_write_opts_set_gpt_guid().
|
||||
* Made several pseudo-random ids reproducible by overriding volume modification
|
||||
time.
|
||||
|
||||
libisofs-1.4.4.tar.gz Fri Jul 01 2016
|
||||
===============================================================================
|
||||
|
|
13
Makefile.am
13
Makefile.am
|
@ -1,4 +1,8 @@
|
|||
|
||||
# Copyright (c) 2007 Vreixo Formoso
|
||||
# Copyright (c) 2009 - 2019 Thomas Schmitt
|
||||
# Provided under the terms of the GNU General Public License version 2 or later.
|
||||
|
||||
# ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4
|
||||
# was: pkgconfigdir=$(libdir)/pkgconfig
|
||||
pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
|
||||
|
@ -8,6 +12,9 @@ libincludedir=$(includedir)/libisofs
|
|||
lib_LTLIBRARIES = libisofs/libisofs.la
|
||||
ACLOCAL_AMFLAGS = -I ./
|
||||
|
||||
# Enable this if the source includes generated files like version.h
|
||||
# AM_CPPFLAGS = -I $(top_builddir)/libisofs
|
||||
|
||||
## ========================================================================= ##
|
||||
|
||||
# Build libraries
|
||||
|
@ -113,8 +120,8 @@ noinst_PROGRAMS = \
|
|||
|
||||
|
||||
# ts A90807
|
||||
# Consolidated demo code for having less linker mesages with a make run.
|
||||
demo_demo_CPPFLAGS = -Ilibisofs
|
||||
# Consolidated demo code for having less linker messages with a make run.
|
||||
demo_demo_CPPFLAGS = -I $(top_srcdir)/libisofs
|
||||
demo_demo_LDADD = $(libisofs_libisofs_la_OBJECTS) $(libisofs_libisofs_la_LIBADD)
|
||||
demo_demo_SOURCES = demo/demo.c
|
||||
|
||||
|
@ -278,7 +285,9 @@ EXTRA_DIST = \
|
|||
doc/susp_aaip_2_0.txt \
|
||||
doc/susp_aaip_isofs_names.txt \
|
||||
doc/zisofs_format.txt \
|
||||
doc/zisofs2_format.txt \
|
||||
doc/checksums.txt \
|
||||
doc/boot_sectors.txt \
|
||||
libisofs/libisofs.ver \
|
||||
libisofs/aaip-os-dummy.c \
|
||||
libisofs/aaip-os-linux.c \
|
||||
|
|
24
README
24
README
|
@ -2,9 +2,10 @@
|
|||
libisofs
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Released under GPL (see COPYING file for details).
|
||||
Released under GNU General Public License version 2 or later.
|
||||
See COPYING file for details.
|
||||
|
||||
Copyright (C) 2008 - 2015 Vreixo Formoso,
|
||||
Copyright (C) 2008 - 2023 Vreixo Formoso,
|
||||
Mario Danic,
|
||||
Vladimir Serbinenko,
|
||||
Thomas Schmitt
|
||||
|
@ -14,25 +15,24 @@ libisofs is part of the libburnia project (libburnia-project.org)
|
|||
|
||||
Download, Build and Installation
|
||||
|
||||
libisofs code is mantained 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
|
||||
|
@ -208,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>
|
||||
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
|
||||
dnl Copyright (c) 2009 - 2019 Thomas Schmitt
|
||||
dnl Provided under the terms of the GNU General Public License version 2 or later.
|
||||
|
||||
|
||||
AC_DEFUN([LIBBURNIA_SET_FLAGS],
|
||||
[
|
||||
case $target_os in
|
||||
|
@ -144,12 +149,12 @@ dnl It tests whether -Wl,--version-script=... works with the compiler
|
|||
AC_DEFUN([LIBISOFS_ASSERT_VERS_LIBS],
|
||||
[
|
||||
libburnia_save_LDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,--version-script=libisofs/libisofs.ver"
|
||||
LDFLAGS="$LDFLAGS -Wl,--version-script=$srcdir/libisofs/libisofs.ver"
|
||||
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
|
||||
[vers_libs_test="yes"], [vers_libs_test="no"])
|
||||
if test x$vers_libs_test = xyes
|
||||
then
|
||||
LIBLDFLAGS="-Wl,--version-script=libisofs/libisofs.ver"
|
||||
LIBLDFLAGS="-Wl,--version-script=$srcdir/libisofs/libisofs.ver"
|
||||
fi
|
||||
LDFLAGS="$libburnia_save_LDFLAGS"
|
||||
AC_SUBST(LIBLDFLAGS)
|
||||
|
|
83
configure.ac
83
configure.ac
|
@ -1,4 +1,4 @@
|
|||
AC_INIT([libisofs], [1.4.4], [http://libburnia-project.org])
|
||||
AC_INIT([libisofs], [1.5.7], [http://libburnia-project.org])
|
||||
AC_PREREQ([2.50])
|
||||
dnl AC_CONFIG_HEADER([config.h])
|
||||
|
||||
|
@ -40,8 +40,8 @@ dnl
|
|||
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||
dnl
|
||||
LIBISOFS_MAJOR_VERSION=1
|
||||
LIBISOFS_MINOR_VERSION=4
|
||||
LIBISOFS_MICRO_VERSION=4
|
||||
LIBISOFS_MINOR_VERSION=5
|
||||
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
|
||||
# 2016.07.01 development jump has not yet happened
|
||||
# SONAME = 86 - 80 = 6 . Library name = libisofs.6.80.0
|
||||
LT_CURRENT=86
|
||||
LT_AGE=80
|
||||
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`
|
||||
|
||||
|
@ -67,12 +67,12 @@ AC_SUBST(LT_CURRENT_MINUS_AGE)
|
|||
AC_PREFIX_DEFAULT([/usr/local])
|
||||
test "$prefix" = "NONE" && prefix=$ac_default_prefix
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
dnl ts B90405 : Disabled on advise of Ross Burton
|
||||
dnl AM_MAINTAINER_MODE
|
||||
|
||||
AM_PROG_CC_C_O
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
dnl Large file support
|
||||
AC_SYS_LARGEFILE
|
||||
|
@ -92,7 +92,7 @@ LIBBURNIA_ASSERT_ICONV
|
|||
|
||||
AC_PROG_LIBTOOL
|
||||
AC_SUBST(LIBTOOL_DEPS)
|
||||
dnl LIBTOOL="$LIBTOOL --silent"
|
||||
# LIBTOOL="$LIBTOOL --silent"
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
|
@ -202,19 +202,68 @@ fi
|
|||
AC_SUBST(LIBACL_DEF)
|
||||
|
||||
|
||||
dnl ts A90123 - B51212
|
||||
dnl ts A90123 - B80508
|
||||
AC_ARG_ENABLE(xattr,
|
||||
[ --enable-xattr Enable use of extended file attributes by libisofs, default=yes],
|
||||
, enable_xattr=yes)
|
||||
AC_ARG_ENABLE(xattr_h_pref_attr,
|
||||
[ --enable-xattr-h-pref-attr Prefer include file attr/xattr.h over sys/xattr.h, default=no],
|
||||
, enable_xattr_h_pref_attr=no)
|
||||
|
||||
XATTR_DEF=
|
||||
XATTR_ADDON_DEF=
|
||||
if test x"$LIBBURNIA_SUPP_FATTR" = xxattr
|
||||
then
|
||||
if test "x$enable_xattr" = xyes; then
|
||||
dnl Check whether there is the header for Linux xattr.
|
||||
dnl If not, erase this macro which would enable use of listxattr and others
|
||||
XATTR_DEF="-DLibisofs_with_aaip_xattR"
|
||||
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
|
||||
XATTR_DEF= ), XATTR_DEF= )
|
||||
|
||||
XATTR_A_DEF=
|
||||
XATTR_S_DEF=
|
||||
if test x"$enable_xattr_h_pref_attr" = xyes
|
||||
then
|
||||
echo "prefering include file attr/xattr.h over sys/attr.h"
|
||||
XATTR_A_DEF=1
|
||||
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
|
||||
XATTR_A_DEF= ), XATTR_A_DEF= )
|
||||
if test x"$XATTR_A_DEF" = x1
|
||||
then
|
||||
XATTR_DEF="-DLibisofs_with_aaip_xattR"
|
||||
else
|
||||
XATTR_S_DEF=1
|
||||
AC_CHECK_HEADER(sys/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
|
||||
XATTR_S_DEF= ), XATTR_S_DEF= )
|
||||
if test x"$XATTR_S_DEF" = x1
|
||||
then
|
||||
XATTR_DEF="-DLibisofs_with_aaip_xattR"
|
||||
XATTR_ADDON_DEF="-DLibisofs_with_sys_xattR"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
XATTR_S_DEF=1
|
||||
AC_CHECK_HEADER(sys/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
|
||||
XATTR_S_DEF= ), XATTR_S_DEF= )
|
||||
if test x"$XATTR_S_DEF" = x1
|
||||
then
|
||||
XATTR_DEF="-DLibisofs_with_aaip_xattR"
|
||||
XATTR_ADDON_DEF="-DLibisofs_with_sys_xattR"
|
||||
else
|
||||
XATTR_A_DEF=1
|
||||
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
|
||||
XATTR_A_DEF= ), XATTR_A_DEF= )
|
||||
if test x"$XATTR_A_DEF" = x1
|
||||
then
|
||||
XATTR_DEF="-DLibisofs_with_aaip_xattR"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if test x"$XATTR_S_DEF" = x1
|
||||
then
|
||||
echo "decided to include file sys/attr.h"
|
||||
elif test x"$XATTR_A_DEF" = x1
|
||||
then
|
||||
echo "decided to include file attr/xattr.h"
|
||||
fi
|
||||
fi
|
||||
elif test x"$LIBBURNIA_SUPP_FATTR" = xextattr
|
||||
then
|
||||
|
@ -233,6 +282,8 @@ then
|
|||
else
|
||||
echo "disabled local processing of extended file attributes"
|
||||
fi
|
||||
XATTR_DEF="$XATTR_DEF $XATTR_ADDON_DEF"
|
||||
|
||||
AC_SUBST(XATTR_DEF)
|
||||
|
||||
|
||||
|
@ -255,11 +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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2007 - 2015 Vreixo Formoso, Thomas Schmitt
|
||||
* Copyright (c) 2007 - 2016 Vreixo Formoso, Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
|
@ -375,7 +375,7 @@ int gesture_iso(int argc, char **argv)
|
|||
|
||||
result = iso_write_opts_new(&opts, 0);
|
||||
if (result < 0) {
|
||||
printf ("Cant create write opts, error %d\n", result);
|
||||
printf ("Cannot create write opts, error %d\n", result);
|
||||
goto ex;
|
||||
}
|
||||
iso_write_opts_set_iso_level(opts, level);
|
||||
|
@ -385,7 +385,7 @@ int gesture_iso(int argc, char **argv)
|
|||
|
||||
result = iso_image_create_burn_source(image, opts, &burn_src);
|
||||
if (result < 0) {
|
||||
printf ("Cant create image, error %d\n", result);
|
||||
printf ("Cannot create image, error %d\n", result);
|
||||
goto ex;
|
||||
}
|
||||
|
||||
|
@ -904,7 +904,7 @@ int gesture_iso_ms(int argc, char **argv)
|
|||
|
||||
result = iso_image_create_burn_source(image, opts, &burn_src);
|
||||
if (result < 0) {
|
||||
printf ("Cant create image, error %d\n", result);
|
||||
printf ("Cannot create image, error %d\n", result);
|
||||
goto ex;
|
||||
}
|
||||
iso_write_opts_free(opts);
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
Collection of Boot Sector Formats for ISO 9660 Images
|
||||
|
||||
|
||||
by Thomas Schmitt - mailto:scdbackup@gmx.net
|
||||
Libburnia project - mailto:libburn-hackers@pykix.org
|
||||
by Thomas Schmitt - scdbackup@gmx.net
|
||||
Libburnia project - bug-xorriso@gnu.org
|
||||
pkg-libburnia-devel@lists.alioth.debian.org
|
||||
|
||||
This information is collected from various sources. Some is backed by
|
||||
specifications, some is just rumor which happens to work (maybe not even that).
|
||||
|
@ -37,6 +38,8 @@ Common Hardware Reference Platform (CHRP), for IBM PowerPC
|
|||
HP-PA via PALO header version 4
|
||||
HP-PA via PALO header version 5
|
||||
|
||||
DEC Alpha SRM boot sector, for Alpha architecture
|
||||
|
||||
Combinations of boot mechanisms:
|
||||
- SYSLINUX isohybrid MBR
|
||||
- SYSLINUX isohybrid for MBR, UEFI and x86-Mac
|
||||
|
@ -120,7 +123,7 @@ Optional:
|
|||
| | Entries
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
An architecture is refered by a Platform Id number.
|
||||
An architecture is referred by a Platform Id number.
|
||||
Defined by El Torito are:
|
||||
0 = "80x86" which is used for standard PCs with Intel x86 or compatible CPU
|
||||
1 = "PowerPC" (possibly for IBM machines with PowerPC CPU)
|
||||
|
@ -301,28 +304,44 @@ Byte Range | Value | Meaning
|
|||
|
||||
Sources:
|
||||
http://en.wikipedia.org/wiki/Master_boot_record
|
||||
https://en.wikipedia.org/wiki/INT_13H
|
||||
Mailing list conversations with H. Peter Anvin and Vladimir Serbinenko.
|
||||
Mail conversations with Natalia Portillo.
|
||||
|
||||
|
||||
The candidates for MBR booting will normally use El Torito rather than MBR
|
||||
if the ISO image is presented on CD, DVD, or BD media.
|
||||
The eventual MBR comes into effect if the image is on a media that is
|
||||
interpreted by the BIOS as some kind of hard disk. Usually real hard disks,
|
||||
floppy disks, USB sticks, memory cards.
|
||||
The MBR comes into effect if the image is on a media that is interpreted by
|
||||
the BIOS as some kind of hard disk. Usually real hard disks, floppy disks,
|
||||
USB sticks, memory cards.
|
||||
|
||||
An important part of an MBR is the DOS style partition table. It describes up
|
||||
to four primary partitions. There are two formats used for block address:
|
||||
Cylinder/Head/Sector (C/H/S) and Logical Block Address (LBA). Both are based
|
||||
on units of 512 bytes. So MBR_LBA = ISO_LBA * 4.
|
||||
|
||||
Contemporary x86 BIOS normally supports LBA addressing directly.
|
||||
If INT 0x13 AH 0x41 returns with CX bit0 set, then INT 0x13 AH 0x42 may be used
|
||||
for reading. (Sometimes even if the bit is not set to indicate the capability.)
|
||||
|
||||
For C/H/S, the sector address is broken up into whole cylinders, remaining
|
||||
heads, and remaining sectors + 1. The nomenclature seems to stem from antique
|
||||
drum storage.
|
||||
There are two parameters, sectors_per_head and heads_per_cylinder which are not
|
||||
stored in the MBR. So it is more or less arbitray how to convert a LBA into
|
||||
a C/H/S address and vice versa. For maximum range of C/H/S addresses one
|
||||
may use sectors_per_head = 63 , heads_per_cylinder = 255.
|
||||
stored in the MBR. So at ISO production time it is more or less arbitrary how
|
||||
to convert a LBA into a C/H/S address and vice versa.
|
||||
At boot time the x86 BIOS decides about the two parameters. The boot loader may
|
||||
inquire these values by INT 0x13 AH 0x08 and use them to convert LBA to C/H/S
|
||||
for the read operation INT 0x13 AH 0x02. So the C/H/S values in an ISO's
|
||||
partition table are quite fictional and of few impact on boot loaders.
|
||||
|
||||
More important seems to align partition ends to a consistent cylinder size,
|
||||
because some partition editors deduce their idea of disk geometry from there
|
||||
and raise protest if they deem it inconsistent.
|
||||
For maximum range of C/H/S addresses one may use sectors_per_head = 63 ,
|
||||
heads_per_cylinder = 255. But that is not divisible by 4 and imposes alignment
|
||||
problems with ISO 9660 filesystems. So (32,64) for images up to 1 GiB
|
||||
or (63,252) for larger images are better.
|
||||
|
||||
Words are composed little-endian style.
|
||||
|
||||
|
@ -331,8 +350,9 @@ Byte Range | Value | Meaning
|
|||
0 - 439 | = opaque = | Code Area filled with bytes for some boot system,
|
||||
| | typically machine code.
|
||||
| |
|
||||
440 - 443 | disk_sgntr | Disc signature, an individual disk id of obscure
|
||||
| | usability.
|
||||
440 - 443 | disk_sgntr | Disc signature: An individual disk id. Some software
|
||||
| | might use it to recognize the same storage medium
|
||||
| | at different device addresses.
|
||||
| | (The Code Area might extend up to this field.)
|
||||
| |
|
||||
444 - 445 | 0 | "usually nulls"
|
||||
|
@ -340,8 +360,11 @@ Byte Range | Value | Meaning
|
|||
| |
|
||||
446 - 461 | ========== | Partition Table Entry for partition 1
|
||||
| |
|
||||
446 - 446 | status | Governs bootability:
|
||||
| | 0x80 = bootable/active , 0x00 non-bootable/inactive
|
||||
446 - 446 | status | For some generic MBRs this marks the one partition
|
||||
| | from which the MBR should load and run more code.
|
||||
| | 0x80 = bootflag/active , 0x00 = noboot/inactive
|
||||
| | Some BIOSes ignore MBRs with no bootflag in any of
|
||||
| | their partition table entries.
|
||||
| |
|
||||
447 - 449 | ========== | C/H/S address of partition start
|
||||
447 - 447 | start_head | Heads part of start address.
|
||||
|
@ -359,7 +382,7 @@ Byte Range | Value | Meaning
|
|||
| | Bits 6 to 7 : Bits 8 to 9 of cylinders part.
|
||||
453 - 453 | end_cyl | Lower 8 bits of cylinders part of end address
|
||||
| |
|
||||
454 - 457 | start_lba | LBA of first absolute sector in partiton.
|
||||
454 - 457 | start_lba | LBA of first absolute sector in partition.
|
||||
| | Block size is 512. Counting starts at 0.
|
||||
| |
|
||||
458 - 461 | num_blocks | Number of sectors in partition.
|
||||
|
@ -404,6 +427,8 @@ Sources:
|
|||
http://www.informit.com/articles/article.aspx?p=376123&seqNum=3
|
||||
syslinux-4.05/utils/isohybrid.c
|
||||
Mail conversations with Vladimir Serbinenko.
|
||||
Mail conversations with Natalia Portillo of DiskImageChef,
|
||||
who quoted "Inside Macintosh" Volumes IV and V.
|
||||
|
||||
|
||||
APM has an adjustable block size. Because the ISO images shall always work
|
||||
|
@ -412,11 +437,19 @@ additional GPT, only block size 2048 is considered here.
|
|||
The role of APM in the boot process is to guide the firmware to a
|
||||
HFS+ filesystem.
|
||||
|
||||
Block0 of an APM begins at byte 0 of the medium. Thus it collides with MBR and
|
||||
other boot sector formats. By lucky coincidence it is possible to compose
|
||||
a mock-up of a Block0 which is acceptable to firmware which expects APM,
|
||||
and is also harmless x86 machine code with no negative side effects.
|
||||
So it is possible to combine APM with an especially prepared MBR.
|
||||
Block0 (aka Driver Descriptor Map) of an APM begins at byte 0 of the medium.
|
||||
Thus it collides with MBR and other boot sector formats. By lucky coincidence
|
||||
it is possible to compose a mock-up of a Block0 which is acceptable to firmware
|
||||
which expects APM, and is also harmless x86 machine code with no negative
|
||||
side effects. So it is possible to combine APM with an especially prepared MBR.
|
||||
|
||||
Block0 is optional. But in the context of bootable hybrid ISOs it is not only
|
||||
needed to announce block size 2048, but also it is much better suited for
|
||||
staging as harmless x86 machine code than is an APM partition entry.
|
||||
|
||||
Usually there is no Device Partition Map block (signature "TS"), although it
|
||||
is demanded by the book "Inside Macintosh". It would sit where GPT has its
|
||||
header block. So DPM is not described here.
|
||||
|
||||
The layout of a Block0 of an APM is:
|
||||
|
||||
|
@ -427,13 +460,17 @@ Byte Range | Value | Meaning (all numbers are stored big endian)
|
|||
4 - 7 | block_count| Number of blocks covered by APM
|
||||
| | Often some x86-harmless dummy. E.g. 0x9090 = 37008
|
||||
| | or 0xeb02ffff = 3,942,842,367
|
||||
8 - 9 | dev_type | obscure: "device type"
|
||||
10 - 11 | dev_id | obscure: "device id"
|
||||
12 - 15 | drv_data | obscure: "driver data"
|
||||
16 - 17 | drv_count | obscure: "driver descriptor count"
|
||||
18 - 81 | drv_map | obscure: "driver descriptor table"
|
||||
| | with 8 entries of 16 bytes each
|
||||
82 - 511 | reserved |
|
||||
8 - 9 | dev_type | Device type: The id of the Mac driver which is in
|
||||
| | charge of the storage device.
|
||||
10 - 11 | dev_id | Device id: Address in an i/o bus system.
|
||||
12 - 15 | drv_data | Driver data: Not used.
|
||||
16 - 17 | drv_count | Driver count: Count of entries in drv_map.
|
||||
18 - 505 | drv_map | Driver descriptor table:
|
||||
| | Up to 61 entries of 8 bytes each.
|
||||
| | They contain the 32 bit 512-byte LBA of the driver's
|
||||
| | storage location, its 16 bit size in 512-byte blocks,
|
||||
| | and value 0x0001.
|
||||
506 - 511 | reserved |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
The SYSLINUX program isohybrid.c overwrites the first 32 bytes of this
|
||||
|
@ -463,9 +500,12 @@ Byte Range | Value | Meaning (all numbers are stored big endian)
|
|||
84 - 87 | lb_count | Logical block count (same as block_count)
|
||||
88 - 91 | flags | Status flags
|
||||
| | bit0= entry is valid
|
||||
| | bit1= entry is allocated
|
||||
| | bit1= partition is allocated
|
||||
| | bit2= partition is in use
|
||||
| | bit3= partition contains valid boot information
|
||||
| | bit4= partition is readable
|
||||
| | bit5= partition is writable
|
||||
| | bit7= boot code is position independent
|
||||
| | bit30= automatic mount (legacy Mac)
|
||||
92 - 95 | boot_block | Logical start block number of boot code = 0
|
||||
96 - 99 | boot_bytes | Number of bytes in boot code = 0
|
||||
|
@ -649,6 +689,7 @@ Sources:
|
|||
There are traces in the web which relate this to specs by
|
||||
MIPS Computer Systems, Inc. , 1985
|
||||
Silicon Graphics Computer Systems, Inc. , 2000
|
||||
Mail conversations with Natalia Portillo.
|
||||
|
||||
|
||||
The first 512 bytes of the media constitute the Volume Header.
|
||||
|
@ -659,7 +700,11 @@ Byte Range | Value | Meaning
|
|||
0 - 3 | 0x0be5a941 | Magic number
|
||||
4 - 5 | 0 | Root partition number
|
||||
6 - 7 | 0 | Swap partition number
|
||||
8 - 23 | 0 | Name of file to boot (unclear what this means)
|
||||
8 - 23 | 0 | One of the boot_name items from the Volume Directory
|
||||
| | may be put here to choose for booting the entry with
|
||||
| | that name.
|
||||
| | (Obviously it may be empty if only one non-zero entry
|
||||
| | exists in the Volume Directory.)
|
||||
| |
|
||||
24 - 71 | ========== | Device Parameters
|
||||
| |
|
||||
|
@ -694,7 +739,7 @@ Byte Range | Value | Meaning
|
|||
72 - 311 | ========== | Volume Directory with 15 entries of 16 bytes each
|
||||
| |
|
||||
72 - 87 | ========== | Volume Directory Entry 1
|
||||
72 - 79 | boot_name | Boot file basename, eventually padded by 0 to lenght 8
|
||||
72 - 79 | boot_name | Boot file basename, eventually padded by 0 to length 8
|
||||
80 - 83 | boot_block | ISO 9660 LBA of boot file * 4, i.e. in blocks of 512
|
||||
84 - 87 | boot_bytes | File length in bytes
|
||||
| |
|
||||
|
@ -1265,7 +1310,7 @@ intentionally non-essential:
|
|||
90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90
|
||||
They may be overwritten by other bytes which must not produce errors or
|
||||
undesirable side effects when executed as x86 machine code.
|
||||
The following 32 bytes from block 0 of an Apple Partiton Map (APM) are such
|
||||
The following 32 bytes from block 0 of an Apple Partition Map (APM) are such
|
||||
harmless code. They stem from Fedora-LiveCD.iso by Matthew Garrett:
|
||||
45 52 08 00 00 00 90 90 00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
|
|
|
@ -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=
|
||||
|
@ -189,7 +189,7 @@ With tag type 2:
|
|||
|
||||
Keep the original MD5 context of the data blocks and clone one for obtaining
|
||||
the MD5 bytes.
|
||||
If the MD5s match, then compute the checksum block and all folowing ones into
|
||||
If the MD5s match, then compute the checksum block and all following ones into
|
||||
the kept MD5 context and go on with reading and computing for the tree checksum
|
||||
tag. This will be found at block address next_tag, verified and parsed by:
|
||||
iso_util_decode_md5_tag(block, &tag_type, &pos,
|
||||
|
@ -211,7 +211,7 @@ next_tag. Go on by looking for tag type 2 and follow above prescription.
|
|||
|
||||
Checking the Data Part of the Session
|
||||
|
||||
In order to check the trustworthyness of a whole session, continue reading
|
||||
In order to check the trustworthiness of a whole session, continue reading
|
||||
and checksumming after the tree was verified.
|
||||
|
||||
Read and checksum the blocks. When reaching block address next_tag (from the
|
||||
|
@ -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
|
||||
|
|
|
@ -394,12 +394,6 @@ MAX_INITIALIZER_LINES = 30
|
|||
|
||||
SHOW_USED_FILES = YES
|
||||
|
||||
# If the sources in your project are distributed over multiple directories
|
||||
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
|
||||
# in the documentation. The default is NO.
|
||||
|
||||
SHOW_DIRECTORIES = NO
|
||||
|
||||
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
|
||||
# doxygen should invoke to get the current version for each file (typically from the
|
||||
# version control system). Doxygen will invoke the program by executing (via
|
||||
|
@ -527,7 +521,7 @@ EXCLUDE_SYMBOLS =
|
|||
# directories that contain example code fragments that are included (see
|
||||
# the \include command).
|
||||
|
||||
EXAMPLE_PATH = test
|
||||
EXAMPLE_PATH = demo/demo.c
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
|
@ -698,12 +692,6 @@ HTML_FOOTER =
|
|||
|
||||
HTML_STYLESHEET =
|
||||
|
||||
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
|
||||
# files or namespaces will be aligned in HTML using tables. If set to
|
||||
# NO a bullet list will be used.
|
||||
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
|
||||
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
|
||||
# will be generated that can be used as input for tools like the
|
||||
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
|
||||
|
@ -938,18 +926,6 @@ GENERATE_XML = NO
|
|||
|
||||
XML_OUTPUT = xml
|
||||
|
||||
# The XML_SCHEMA tag can be used to specify an XML schema,
|
||||
# which can be used by a validating XML parser to check the
|
||||
# syntax of the XML files.
|
||||
|
||||
XML_SCHEMA =
|
||||
|
||||
# The XML_DTD tag can be used to specify an XML DTD,
|
||||
# which can be used by a validating XML parser to check the
|
||||
# syntax of the XML files.
|
||||
|
||||
XML_DTD =
|
||||
|
||||
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
|
||||
# dump the program listings (including syntax highlighting
|
||||
# and cross-referencing information) to the XML output. Note that
|
||||
|
|
|
@ -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.
|
||||
|
@ -235,7 +235,7 @@ An eventually needed qualifier is stored in one or more Qualifier Records.
|
|||
[b] "BP 2 - Qualifier Record Head" shall be present only if QUALIFIER is set
|
||||
to 1. It shall give the number of Qualifier Bytes and eventually
|
||||
indicate that the qualifier continues in a Qualifier Record which comes
|
||||
imediately after this record.
|
||||
immediately after this record.
|
||||
0 to 127 Q_LENGTH, the qualifier is complete by this record
|
||||
128 to 255 Q_LENGTH+128, the qualifier is continued by next record
|
||||
So a Qualifier Record can contain at most 127 Qualifier Bytes.
|
||||
|
@ -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:
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Directory of Namespace "isofs."
|
||||
|
||||
by Thomas Schmitt - mailto:scdbackup@gmx.net
|
||||
Libburnia project - mailto:libburn-hackers@pykix.org
|
||||
Libburnia project - mailto:bug-xorriso@gnu.org
|
||||
|
||||
|
||||
The following names are defined for AAIP namespace "isofs." as mentioned in
|
||||
|
@ -224,13 +224,13 @@ Registered:
|
|||
-------------------------------------------------------------------------------
|
||||
|
||||
This text is under
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2009 - 2015 Thomas Schmitt <scdbackup@gmx.net>
|
||||
It shall only be modified in sync with libisofs and other software which
|
||||
makes use of AAIP. Please mail change requests to mailing list
|
||||
<libburn-hackers@pykix.org> or to the copyright holder in private.
|
||||
<bug-xorriso@gnu.org> or to the copyright holder in private.
|
||||
Only if you cannot reach the copyright holder for at least one month it is
|
||||
permissible to modify this text under the same license as the affected
|
||||
copy of libisofs.
|
||||
copy of libisofs. Currently: GNU General Public License version 2 or later.
|
||||
If you do so, you commit yourself to taking reasonable effort to stay in
|
||||
sync with the other interested users of this text.
|
||||
|
||||
|
|
|
@ -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".
|
||||
|
|
@ -11,7 +11,12 @@
|
|||
|
||||
To be included by aaip_0_2.c
|
||||
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
|
||||
This file is part of the libisofs project; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
or later as published by the Free Software Foundation.
|
||||
See COPYING file for details.
|
||||
|
||||
*/
|
||||
|
||||
|
@ -99,10 +104,14 @@ int aaip_set_acl_text(char *path, char *text, int flag)
|
|||
-7 support of ACL not enabled at compile time
|
||||
*/
|
||||
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag)
|
||||
size_t *value_lengths, char **values, int *errnos,
|
||||
int flag)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for(i= 0; i < num_attrs; i++)
|
||||
errnos[i]= 0;
|
||||
|
||||
for(i= 0; i < num_attrs; i++) {
|
||||
if(names[i] == NULL || values[i] == NULL)
|
||||
continue;
|
||||
|
|
|
@ -5,9 +5,14 @@
|
|||
Arbitrary Attribute Interchange Protocol , system adapter for getting and
|
||||
setting of ACLs and xattr.
|
||||
|
||||
To be included by aaip_0_2.c for FreeBSD and NetBSD
|
||||
To be included by aaip_0_2.c for FreeBSD, NetBSD, and OpenBSD
|
||||
|
||||
Copyright (c) 2009 - 2014 Thomas Schmitt, libburnia project, GPLv2+
|
||||
Copyright (c) 2009 - 2016 Thomas Schmitt
|
||||
|
||||
This file is part of the libisofs project; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
or later as published by the Free Software Foundation.
|
||||
See COPYING file for details.
|
||||
|
||||
*/
|
||||
|
||||
|
@ -228,6 +233,10 @@ static int aaip_extattr_make_list(char *path, int attrnamespace,
|
|||
*list_size = 0;
|
||||
return(2);
|
||||
}
|
||||
if(errno == EPERM && attrnamespace == EXTATTR_NAMESPACE_SYSTEM) {
|
||||
*list_size = 0;
|
||||
return(3);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
if(*list_size == 0)
|
||||
|
@ -312,6 +321,54 @@ static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
|
|||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int get_single_attr(char *path, char *name, size_t *value_length,
|
||||
char **value_bytes, int flag)
|
||||
{
|
||||
char *namept;
|
||||
int attrnamespace;
|
||||
ssize_t value_ret;
|
||||
|
||||
*value_bytes= NULL;
|
||||
*value_length= 0;
|
||||
if(strncmp(name, "user.", 5) == 0) {
|
||||
attrnamespace= EXTATTR_NAMESPACE_USER;
|
||||
namept= name + 5;
|
||||
} else {
|
||||
if(!(flag & 8))
|
||||
return(0);
|
||||
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
|
||||
namept= name + 7;
|
||||
}
|
||||
/* Predict length of value */
|
||||
if(flag & 32) /* follow link */
|
||||
value_ret= extattr_get_file(path, attrnamespace, namept, NULL, (size_t) 0);
|
||||
else
|
||||
value_ret= extattr_get_link(path, attrnamespace, namept, NULL, (size_t) 0);
|
||||
if(value_ret == -1)
|
||||
return(0);
|
||||
|
||||
*value_bytes= calloc(value_ret + 1, 1);
|
||||
if(*value_bytes == NULL)
|
||||
return(-1);
|
||||
|
||||
/* Obtain value */
|
||||
if(flag & 32) /* follow link */
|
||||
value_ret= extattr_get_file(path, attrnamespace, namept,
|
||||
*value_bytes, (size_t) value_ret);
|
||||
else
|
||||
value_ret= extattr_get_link(path, attrnamespace, namept,
|
||||
*value_bytes, (size_t) value_ret);
|
||||
if(value_ret == -1) {
|
||||
free(*value_bytes);
|
||||
*value_bytes= NULL;
|
||||
*value_length= 0;
|
||||
return(0);
|
||||
}
|
||||
*value_length= value_ret;
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_freebsd_extattR */
|
||||
|
||||
|
||||
|
@ -320,7 +377,7 @@ static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
|
|||
@param path Path to the file
|
||||
@param num_attrs Will return the number of name-value pairs
|
||||
@param names Will return an array of pointers to 0-terminated names
|
||||
@param value_lengths Will return an arry with the lenghts of values
|
||||
@param value_lengths Will return an array with the lengths of values
|
||||
@param values Will return an array of pointers to 8-bit values
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= obtain ACL (access and eventually default)
|
||||
|
@ -332,7 +389,8 @@ static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
|
|||
bit4= do not return trivial ACL that matches st_mode
|
||||
bit5= in case of symbolic link: inquire link target
|
||||
bit15= free memory of names, value_lengths, values
|
||||
@return >0 ok
|
||||
@return 1 ok
|
||||
2 ok, no permission to inspect non-user namespaces
|
||||
<=0 error
|
||||
-1= out of memory
|
||||
-2= program error with prediction of result size
|
||||
|
@ -350,12 +408,12 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||
size_t a_acl_len= 0;
|
||||
#endif
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
char *list= NULL, *user_list= NULL, *sys_list= NULL, *namept;
|
||||
ssize_t value_ret, retry= 0, list_size= 0, user_list_size= 0;
|
||||
char *list= NULL, *user_list= NULL, *sys_list= NULL;
|
||||
ssize_t value_ret, list_size= 0, user_list_size= 0;
|
||||
ssize_t sys_list_size= 0;
|
||||
int attrnamespace;
|
||||
int acl_names= 0;
|
||||
#endif
|
||||
int no_perm_for_system= 0;
|
||||
|
||||
if(flag & (1 << 15)) { /* Free memory */
|
||||
{ret= 1; goto ex;}
|
||||
|
@ -391,6 +449,8 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||
&sys_list, &sys_list_size, flag & 32);
|
||||
if(ret <= 0)
|
||||
{ret= -1; goto ex;}
|
||||
if(ret == 3)
|
||||
no_perm_for_system= 1;
|
||||
}
|
||||
|
||||
/* Check for NUL in names, convert into a linuxish list of namespace.name */
|
||||
|
@ -445,45 +505,10 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||
}
|
||||
|
||||
for(i= 0; (size_t) i < *num_attrs; i++) {
|
||||
if(strncmp((*names)[i], "user.", 5) == 0) {
|
||||
attrnamespace= EXTATTR_NAMESPACE_USER;
|
||||
namept= (*names)[i] + 5;
|
||||
} else {
|
||||
if(!(flag & 8))
|
||||
continue;
|
||||
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
|
||||
namept= (*names)[i] + 7;
|
||||
}
|
||||
/* Predict length of value */
|
||||
if(flag & 32) /* follow link */
|
||||
value_ret= extattr_get_file(path, attrnamespace, namept,
|
||||
NULL, (size_t) 0);
|
||||
else
|
||||
value_ret= extattr_get_link(path, attrnamespace, namept,
|
||||
NULL, (size_t) 0);
|
||||
if(value_ret == -1)
|
||||
continue;
|
||||
|
||||
(*values)[i]= calloc(value_ret + 1, 1);
|
||||
if((*values)[i] == NULL)
|
||||
value_ret= get_single_attr(path, (*names)[i], *value_lengths + i,
|
||||
*values + i, flag & (8 | 32));
|
||||
if(value_ret <= 0)
|
||||
{ret= -1; goto ex;}
|
||||
|
||||
/* Obtain value */
|
||||
if(flag & 32) /* follow link */
|
||||
value_ret= extattr_get_file(path, attrnamespace, namept,
|
||||
(*values)[i], (size_t) value_ret);
|
||||
else
|
||||
value_ret= extattr_get_link(path, attrnamespace, namept,
|
||||
(*values)[i], (size_t) value_ret);
|
||||
if(value_ret == -1) { /* there could be a race condition */
|
||||
|
||||
if(retry++ > 5)
|
||||
{ret= -1; goto ex;}
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
(*value_lengths)[i]= value_ret;
|
||||
retry= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -494,8 +519,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||
if(flag & 1) { /* Obtain ACL */
|
||||
/* access-ACL */
|
||||
aaip_get_acl_text(path, &a_acl_text, flag & (16 | 32));
|
||||
if(a_acl_text == NULL)
|
||||
{ret= 1; goto ex;} /* empty ACL / only st_mode info was found in ACL */
|
||||
if(a_acl_text == NULL) {
|
||||
/* empty ACL / only st_mode info was found in ACL */
|
||||
ret= 1 + no_perm_for_system;
|
||||
goto ex;
|
||||
}
|
||||
ret= aaip_encode_acl(a_acl_text, (mode_t) 0, &a_acl_len, &a_acl, flag & 2);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
|
@ -514,7 +542,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||
|
||||
#endif /* Libisofs_with_aaip_acL */
|
||||
|
||||
ret= 1;
|
||||
ret= 1 + no_perm_for_system;
|
||||
ex:;
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
if(a_acl != NULL)
|
||||
|
@ -563,7 +591,7 @@ ex:;
|
|||
@param path Path to the file
|
||||
@param num_attrs Will return the number of name-value pairs
|
||||
@param names Will return an array of pointers to 0-terminated names
|
||||
@param value_lengths Will return an arry with the lenghts of values
|
||||
@param value_lengths Will return an array with the lengths of values
|
||||
@param values Will return an array of pointers to 8-bit values
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= obtain ACL (access and eventually default)
|
||||
|
@ -773,6 +801,15 @@ static int aaip_extattr_delete_names(char *path, int attrnamespace,
|
|||
#endif /* Libisofs_with_freebsd_extattR */
|
||||
|
||||
|
||||
static void register_errno(int *errnos, int i, int in_errno)
|
||||
{
|
||||
if(in_errno > 0)
|
||||
errnos[i]= in_errno;
|
||||
else
|
||||
errnos[i]= -1;
|
||||
}
|
||||
|
||||
|
||||
/* Bring the given attributes and/or ACLs into effect with the given file.
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= decode and set ACLs
|
||||
|
@ -784,6 +821,8 @@ static int aaip_extattr_delete_names(char *path, int attrnamespace,
|
|||
bit5= in case of symbolic link: manipulate link target
|
||||
bit6= tolerate inappropriate presence or absence of
|
||||
directory default ACL
|
||||
bit7= void setting a name value pair if it already
|
||||
exists and has the desired value.
|
||||
@return 1 success
|
||||
-1 error memory allocation
|
||||
-2 error with decoding of ACL
|
||||
|
@ -796,17 +835,23 @@ static int aaip_extattr_delete_names(char *path, int attrnamespace,
|
|||
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag)
|
||||
size_t *value_lengths, char **values,
|
||||
int *errnos, int flag)
|
||||
{
|
||||
int ret, has_default_acl= 0;
|
||||
int ret, has_default_acl= 0, end_ret= 1;
|
||||
size_t i, consumed, acl_text_fill, acl_idx= 0;
|
||||
char *acl_text= NULL;
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
char *user_list= NULL, *sys_list= NULL, *namept;
|
||||
ssize_t user_list_size= 0, sys_list_size= 0;
|
||||
char *user_list= NULL, *sys_list= NULL, *namept, *old_value;
|
||||
ssize_t user_list_size= 0, sys_list_size= 0, value_ret;
|
||||
int attrnamespace;
|
||||
size_t old_value_l;
|
||||
int skip;
|
||||
#endif
|
||||
|
||||
for(i= 0; i < num_attrs; i++)
|
||||
errnos[i]= 0;
|
||||
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
|
||||
if(flag & 2) { /* Delete all file attributes */
|
||||
|
@ -855,16 +900,35 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
|
||||
namept= names[i] + 7;
|
||||
} else {
|
||||
{ret= -8; goto ex;}
|
||||
register_errno(errnos, i, (int) EFAULT);
|
||||
end_ret= -8;
|
||||
continue;
|
||||
}
|
||||
skip= 0;
|
||||
if(flag & 128) {
|
||||
value_ret= get_single_attr(path, names[i], &old_value_l,
|
||||
&old_value, flag & (8 | 32));
|
||||
if(value_ret > 0 && old_value_l == value_lengths[i]) {
|
||||
if(memcmp(old_value, values[i], value_lengths[i]) == 0)
|
||||
skip= 1;
|
||||
}
|
||||
if(old_value != NULL)
|
||||
free(old_value);
|
||||
}
|
||||
if(!skip) {
|
||||
if(flag & 32)
|
||||
ret= extattr_set_file(path, attrnamespace, namept,
|
||||
values[i], value_lengths[i]);
|
||||
else
|
||||
ret= extattr_set_link(path, attrnamespace, namept,
|
||||
values[i], value_lengths[i]);
|
||||
if(ret == -1) {
|
||||
register_errno(errnos, i, errno);
|
||||
if(end_ret != 1)
|
||||
end_ret= -4;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(flag & 32)
|
||||
ret= extattr_set_file(path, attrnamespace, namept,
|
||||
values[i], value_lengths[i]);
|
||||
else
|
||||
ret= extattr_set_link(path, attrnamespace, namept,
|
||||
values[i], value_lengths[i]);
|
||||
if(ret == -1)
|
||||
{ret= -4; goto ex;}
|
||||
|
||||
#else
|
||||
|
||||
|
@ -879,8 +943,12 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||
}
|
||||
|
||||
/* Decode ACLs */
|
||||
/* It is important that this happens after restoring xattr which might be
|
||||
representations of ACL, too. If isofs ACL are enabled, then they shall
|
||||
override the xattr ones.
|
||||
*/
|
||||
if(acl_idx == 0)
|
||||
{ret= 1; goto ex;}
|
||||
{ret= end_ret; goto ex;}
|
||||
i= acl_idx - 1;
|
||||
|
||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||
|
@ -902,6 +970,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
ret= aaip_set_acl_text(path, acl_text, flag & (32 | 64));
|
||||
if(ret == -1)
|
||||
register_errno(errnos, i, errno);
|
||||
if(ret <= 0)
|
||||
{ret= -3; goto ex;}
|
||||
#else
|
||||
|
@ -911,7 +981,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||
if(has_default_acl && !(flag & 64))
|
||||
{ret= -3; goto ex;}
|
||||
|
||||
ret= 1;
|
||||
ret= end_ret;
|
||||
ex:;
|
||||
if(acl_text != NULL)
|
||||
free(acl_text);
|
||||
|
|
|
@ -7,7 +7,12 @@
|
|||
|
||||
To be included by aaip_0_2.c for Linux
|
||||
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||
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
|
||||
or later as published by the Free Software Foundation.
|
||||
See COPYING file for details.
|
||||
|
||||
*/
|
||||
|
||||
|
@ -30,8 +35,12 @@
|
|||
#endif
|
||||
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
#ifdef Libisofs_with_sys_xattR
|
||||
#include <sys/xattr.h>
|
||||
#else
|
||||
#include <attr/xattr.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* ------------------------------ Inquiry --------------------------------- */
|
||||
|
@ -68,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.
|
||||
|
@ -159,12 +206,50 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
|||
}
|
||||
|
||||
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
|
||||
static int get_single_attr(char *path, char *name, size_t *value_length,
|
||||
char **value_bytes, int flag)
|
||||
{
|
||||
ssize_t value_ret;
|
||||
|
||||
*value_bytes= NULL;
|
||||
*value_length= 0;
|
||||
if(flag & 32)
|
||||
value_ret= getxattr(path, name, NULL, 0);
|
||||
else
|
||||
value_ret= lgetxattr(path, name, NULL, 0);
|
||||
if(value_ret == -1) {
|
||||
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);
|
||||
if(flag & 32)
|
||||
value_ret= getxattr(path, name, *value_bytes, value_ret);
|
||||
else
|
||||
value_ret= lgetxattr(path, name, *value_bytes, value_ret);
|
||||
if(value_ret == -1) {
|
||||
aaip_local_error((flag & 32) ? "getxattr" : "lgetxattr", path, errno, 0);
|
||||
free(*value_bytes);
|
||||
*value_bytes= NULL;
|
||||
*value_length= 0;
|
||||
return(0);
|
||||
}
|
||||
*value_length= value_ret;
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_aaip_xattR */
|
||||
|
||||
|
||||
/* Obtain the Extended Attributes and/or the ACLs of the given file in a form
|
||||
that is ready for aaip_encode().
|
||||
@param path Path to the file
|
||||
@param num_attrs Will return the number of name-value pairs
|
||||
@param names Will return an array of pointers to 0-terminated names
|
||||
@param value_lengths Will return an arry with the lenghts of values
|
||||
@param value_lengths Will return an array with the lengths of values
|
||||
@param values Will return an array of pointers to 8-bit values
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= obtain ACL (access and eventually default)
|
||||
|
@ -176,7 +261,9 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
|||
bit4= do not return trivial ACL that matches st_mode
|
||||
bit5= in case of symbolic link: inquire link target
|
||||
bit15= free memory of names, value_lengths, values
|
||||
@return >0 ok
|
||||
@return 1 ok
|
||||
(reserved for FreeBSD: 2 ok, no permission to inspect
|
||||
non-user namespaces.)
|
||||
<=0 error
|
||||
-1= out of memory
|
||||
-2= program error with prediction of result size
|
||||
|
@ -195,7 +282,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||
#endif
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
char *list= NULL;
|
||||
ssize_t value_ret, retry= 0, list_size= 0;
|
||||
ssize_t value_ret, list_size= 0;
|
||||
#define Libisofs_aaip_get_attr_activE yes
|
||||
#endif
|
||||
#ifdef Libisofs_aaip_get_attr_activE
|
||||
|
@ -229,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);
|
||||
|
@ -242,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++;
|
||||
|
@ -288,27 +381,10 @@ ex:;
|
|||
if(!(flag & 8))
|
||||
if(strncmp((*names)[i], "user.", 5))
|
||||
continue;
|
||||
if(flag & 32)
|
||||
value_ret= getxattr(path, (*names)[i], NULL, 0);
|
||||
else
|
||||
value_ret= lgetxattr(path, (*names)[i], NULL, 0);
|
||||
if(value_ret == -1)
|
||||
continue;
|
||||
(*values)[i]= calloc(value_ret + 1, 1);
|
||||
if((*values)[i] == NULL)
|
||||
value_ret= get_single_attr(path, (*names)[i], *value_lengths + i,
|
||||
*values + i, flag & 32);
|
||||
if(value_ret <= 0)
|
||||
{ret= -1; goto ex;}
|
||||
if(flag & 32)
|
||||
value_ret= getxattr(path, (*names)[i], (*values)[i], value_ret);
|
||||
else
|
||||
value_ret= lgetxattr(path, (*names)[i], (*values)[i], value_ret);
|
||||
if(value_ret == -1) { /* there could be a race condition */
|
||||
if(retry++ > 5)
|
||||
{ret= -1; goto ex;}
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
(*value_lengths)[i]= value_ret;
|
||||
retry= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,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)
|
||||
|
@ -434,6 +513,15 @@ ex:
|
|||
}
|
||||
|
||||
|
||||
static void register_errno(int *errnos, int i)
|
||||
{
|
||||
if(errno > 0)
|
||||
errnos[i]= errno;
|
||||
else
|
||||
errnos[i]= -1;
|
||||
}
|
||||
|
||||
|
||||
/* Bring the given attributes and/or ACLs into effect with the given file.
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= decode and set ACLs
|
||||
|
@ -443,8 +531,10 @@ ex:
|
|||
I.e. those with a name which does not begin
|
||||
by "user."
|
||||
bit5= in case of symbolic link: manipulate link target
|
||||
bit6= tolerate inappropriate presence or absense of
|
||||
bit6= tolerate inappropriate presence or absence of
|
||||
directory default ACL
|
||||
bit7= avoid setting a name value pair if it already
|
||||
exists and has the desired value.
|
||||
@return 1 success
|
||||
-1 error memory allocation
|
||||
-2 error with decoding of ACL
|
||||
|
@ -457,20 +547,25 @@ ex:
|
|||
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag)
|
||||
size_t *value_lengths, char **values,
|
||||
int *errnos, int flag)
|
||||
{
|
||||
int ret;
|
||||
int ret, end_ret= 1;
|
||||
size_t i, consumed, acl_text_fill, acl_idx= 0;
|
||||
char *acl_text= NULL;
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
char *list= NULL;
|
||||
ssize_t list_size= 0;
|
||||
char *list= NULL, *old_value;
|
||||
ssize_t list_size= 0, value_ret;
|
||||
size_t old_value_l;
|
||||
int skip;
|
||||
#endif
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
size_t h_consumed;
|
||||
int has_default_acl= 0;
|
||||
#endif
|
||||
|
||||
for(i= 0; i < num_attrs; i++)
|
||||
errnos[i]= 0;
|
||||
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
|
||||
|
@ -488,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))
|
||||
|
@ -498,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;
|
||||
}
|
||||
|
@ -525,12 +626,30 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
|
||||
if(flag & 32)
|
||||
ret= setxattr(path, names[i], values[i], value_lengths[i], 0);
|
||||
else
|
||||
ret= lsetxattr(path, names[i], values[i], value_lengths[i], 0);
|
||||
if(ret == -1)
|
||||
{ret= -4; goto ex;}
|
||||
skip= 0;
|
||||
if(flag & 128) {
|
||||
value_ret= get_single_attr(path, names[i], &old_value_l,
|
||||
&old_value, flag & 32);
|
||||
if(value_ret > 0 && old_value_l == value_lengths[i]) {
|
||||
if(memcmp(old_value, values[i], value_lengths[i]) == 0)
|
||||
skip= 1;
|
||||
}
|
||||
if(old_value != NULL)
|
||||
free(old_value);
|
||||
}
|
||||
if(!skip) {
|
||||
if(flag & 32)
|
||||
ret= setxattr(path, names[i], values[i], value_lengths[i], 0);
|
||||
else
|
||||
ret= lsetxattr(path, names[i], values[i], value_lengths[i], 0);
|
||||
if(ret == -1) {
|
||||
aaip_local_error((flag & 32) ? "setxattr" : "lsetxattr", path, errno,
|
||||
1);
|
||||
register_errno(errnos, i);
|
||||
end_ret= -4;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
@ -540,9 +659,13 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||
|
||||
}
|
||||
|
||||
/* Decode ACLs */
|
||||
/* Decode ACLs */
|
||||
/* It is important that this happens after restoring xattr which might be
|
||||
representations of ACL, too. If isofs ACL are enabled, then they shall
|
||||
override the xattr ones.
|
||||
*/
|
||||
if(acl_idx == 0)
|
||||
{ret= 1; goto ex;}
|
||||
{ret= end_ret; goto ex;}
|
||||
i= acl_idx - 1;
|
||||
/* "access" ACL */
|
||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||
|
@ -566,6 +689,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||
has_default_acl= (ret == 2);
|
||||
|
||||
ret= aaip_set_acl_text(path, acl_text, flag & 32);
|
||||
if(ret == -1)
|
||||
register_errno(errnos, i);
|
||||
if(ret <= 0)
|
||||
{ret= -3; goto ex;}
|
||||
/* "default" ACL */
|
||||
|
@ -590,6 +715,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
|
||||
if(ret == -1)
|
||||
register_errno(errnos, i);
|
||||
if(ret <= 0)
|
||||
{ret= -3; goto ex;}
|
||||
} else {
|
||||
|
@ -601,7 +728,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||
|
||||
}
|
||||
}
|
||||
ret= 1;
|
||||
ret= end_ret;
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -7,7 +7,12 @@
|
|||
See libisofs/aaip_0_2.h
|
||||
http://libburnia-project.org/wiki/AAIP
|
||||
|
||||
Copyright (c) 2009 - 2015 Thomas Schmitt, libburnia project, GPLv2+
|
||||
Copyright (c) 2009 - 2019 Thomas Schmitt
|
||||
|
||||
This file is part of the libisofs project; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
or later as published by the Free Software Foundation.
|
||||
See COPYING file for details.
|
||||
|
||||
*/
|
||||
|
||||
|
@ -27,6 +32,7 @@
|
|||
|
||||
#include "libisofs.h"
|
||||
#include "util.h"
|
||||
#include "messages.h"
|
||||
|
||||
/*
|
||||
#define Aaip_encode_debuG 1
|
||||
|
@ -275,6 +281,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
bit2= this is a default ACL, prepend SWITCH_MARK
|
||||
bit3= check for completeness of list and eventually
|
||||
fill up with entries deduced from st_mode
|
||||
bit4= be verbose about failure causes
|
||||
@return >0 means ok
|
||||
<=0 means error
|
||||
-1= out of memory
|
||||
|
@ -290,7 +297,7 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
|||
*result= NULL;
|
||||
*result_len= 0;
|
||||
bytes= aaip_encode_acl_text(acl_text, st_mode,
|
||||
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8)));
|
||||
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8 | 16)));
|
||||
if(bytes < -2)
|
||||
return(bytes);
|
||||
if(bytes < 0)
|
||||
|
@ -305,7 +312,7 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
|||
(*result)[bytes]= 0;
|
||||
*result_len= bytes;
|
||||
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
|
||||
(flag & (2 | 4 | 8)));
|
||||
(flag & (2 | 4 | 8 | 16)));
|
||||
if(bytes < -2)
|
||||
return(bytes);
|
||||
if(bytes < 0)
|
||||
|
@ -357,10 +364,11 @@ static int aaip_make_aaip_perms(int r, int w, int x)
|
|||
bit2= this is a default ACL, prepend SWITCH_MARK 1
|
||||
bit3= check for completeness of list and eventually
|
||||
fill up with entries deduced from st_mode
|
||||
bit4= be verbose about failure causes
|
||||
@return >=0 number of bytes produced resp. counted
|
||||
<0 means error
|
||||
-1: result size overflow
|
||||
-2: conversion errror with user name or group name
|
||||
-2: conversion error with user name or group name
|
||||
ISO_AAIP_ACL_MULT_OBJ: multiple entries of user::, group::, other::
|
||||
*/
|
||||
static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
|
@ -383,7 +391,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
/* set SWITCH_MARK to indicate a default ACL */;
|
||||
if(!(flag & 1)) {
|
||||
if((size_t) count >= result_size)
|
||||
{ret= -1; goto ex;}
|
||||
goto result_size_overflow;
|
||||
result[count]= (Aaip_SWITCH_MARK << 4) | Aaip_EXEC;
|
||||
}
|
||||
count++;
|
||||
|
@ -412,6 +420,9 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
/* >>> Duplicate u:: entry. */;
|
||||
/* >>> ??? If it matches the previous one: ignore */
|
||||
|
||||
if(flag & 16)
|
||||
iso_msg_submit(-1, ISO_AAIP_ACL_MULT_OBJ, 0,
|
||||
"Duplicate u:: entry detected in ACL text");
|
||||
ret = ISO_AAIP_ACL_MULT_OBJ;
|
||||
goto ex;
|
||||
}
|
||||
|
@ -429,6 +440,9 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
num= aaip_numeric_id(name, 0);
|
||||
if(num <= 0) {
|
||||
/* ACL_USER is not part of AAIP 2.0 */
|
||||
if(flag & 16)
|
||||
iso_msg_submit(-1, ISO_AAIP_BAD_ACL_TEXT, 0,
|
||||
"Unknown user name found in ACL text: '%s'", name);
|
||||
{ret= -2; goto ex;}
|
||||
}
|
||||
uid= huid= num;
|
||||
|
@ -458,6 +472,9 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
/* >>> Duplicate g:: entry. */;
|
||||
/* >>> ??? If it matches the previous one: ignore */
|
||||
|
||||
if(flag & 16)
|
||||
iso_msg_submit(-1, ISO_AAIP_ACL_MULT_OBJ, 0,
|
||||
"Duplicate g:: entry detected in ACL text");
|
||||
ret = ISO_AAIP_ACL_MULT_OBJ;
|
||||
goto ex;
|
||||
}
|
||||
|
@ -475,6 +492,9 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
num= aaip_numeric_id(name, 0);
|
||||
if(num <= 0) {
|
||||
/* ACL_GROUP is not part of AAIP 2.0 */
|
||||
if(flag & 16)
|
||||
iso_msg_submit(-1, ISO_AAIP_BAD_ACL_TEXT, 0,
|
||||
"Unknown group name found in ACL text: '%s'", name);
|
||||
{ret= -2; goto ex;}
|
||||
}
|
||||
gid= hgid= num;
|
||||
|
@ -503,6 +523,9 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
/* >>> Duplicate o:: entry. */;
|
||||
/* >>> ??? If it matches the previous one: ignore */
|
||||
|
||||
if(flag & 16)
|
||||
iso_msg_submit(-1, ISO_AAIP_ACL_MULT_OBJ, 0,
|
||||
"Duplicate o:: entry detected in ACL text");
|
||||
ret = ISO_AAIP_ACL_MULT_OBJ;
|
||||
goto ex;
|
||||
}
|
||||
|
@ -519,7 +542,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
|
||||
if(!(flag & 1)) {
|
||||
if((size_t) count >= result_size)
|
||||
{ret= -1; goto ex;}
|
||||
goto result_size_overflow;
|
||||
result[count]= perms | ((!!qualifier) << 3) | (type << 4);
|
||||
}
|
||||
count++;
|
||||
|
@ -528,7 +551,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
num_recs= (qualifier_len / 127) + !!(qualifier_len % 127);
|
||||
if(!(flag & 1)) {
|
||||
if((size_t) (count + 1) > result_size)
|
||||
{ret= -1; goto ex;}
|
||||
goto result_size_overflow;
|
||||
for(i= 0; i < num_recs; i++) {
|
||||
if(i < num_recs - 1)
|
||||
result[count++]= 255;
|
||||
|
@ -538,7 +561,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
result[count - 1]= 127;
|
||||
}
|
||||
if((size_t) (count + (result[count - 1] & 127)) > result_size)
|
||||
{ret= -1; goto ex;}
|
||||
goto result_size_overflow;
|
||||
memcpy(result + count, name + i * 127, result[count - 1] & 127);
|
||||
count+= result[count - 1] & 127;
|
||||
}
|
||||
|
@ -553,7 +576,7 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
count+= needed;
|
||||
else {
|
||||
if((size_t) (count + needed) > result_size)
|
||||
{ret= -1; goto ex;}
|
||||
goto result_size_overflow;
|
||||
}
|
||||
}
|
||||
if ((flag & 8) && needed > 0 && !(flag & 1)) {
|
||||
|
@ -582,6 +605,13 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||
ex:;
|
||||
LIBISO_FREE_MEM(name);
|
||||
return(ret);
|
||||
|
||||
result_size_overflow:;
|
||||
if(flag & 16)
|
||||
iso_msg_submit(-1, ISO_ASSERT_FAILURE, 0,
|
||||
"Program error: Text to ACL conversion result size overflow");
|
||||
ret= -1;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
|
||||
|
@ -593,13 +623,14 @@ int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode,
|
|||
unsigned char *a_acl= NULL, *d_acl= NULL, *acl= NULL;
|
||||
|
||||
if(a_acl_text != NULL) {
|
||||
ret= aaip_encode_acl(a_acl_text, st_mode, &a_acl_len, &a_acl, flag & 11);
|
||||
ret= aaip_encode_acl(a_acl_text, st_mode, &a_acl_len, &a_acl,
|
||||
flag & (1 | 2 | 8 | 16));
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
if(d_acl_text != NULL) {
|
||||
ret= aaip_encode_acl(d_acl_text, (mode_t) 0, &d_acl_len, &d_acl,
|
||||
(flag & 3) | 4);
|
||||
(flag & (1 | 2 | 16)) | 4);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
|
@ -648,7 +679,7 @@ ex:;
|
|||
mission bits.
|
||||
|
||||
*/
|
||||
/* Analyze occurence of ACL tag types in long text form. If not disabled by
|
||||
/* Analyze occurrence of ACL tag types in long text form. If not disabled by
|
||||
parameter flag remove the entries of type "user::" , "group::" , "other::" ,
|
||||
or "other:" from an ACL in long text form if they match the bits in st_mode
|
||||
as described by man 2 stat and man 5 acl.
|
||||
|
@ -1929,7 +1960,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
|
|||
@param handle The decoding context created by aaip_decode_attrs()
|
||||
@param num_attrs Will return the number of name-value pairs
|
||||
@param names Will return an array of pointers to 0-terminated names
|
||||
@param value_lengths Will return an arry with the lenghts of values
|
||||
@param value_lengths Will return an array with the lengths of values
|
||||
@param values Will return an array of pointers to 8-bit values
|
||||
@param flag Bitfield for control purposes
|
||||
bit15= free memory of names, value_lengths, values
|
||||
|
@ -2188,6 +2219,11 @@ ex:;
|
|||
/* ----------------------- Adapter for operating systems ----------------- */
|
||||
|
||||
|
||||
#ifdef Libisofs_use_os_dummY
|
||||
|
||||
#include "aaip-os-dummy.c"
|
||||
|
||||
#else
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#include "aaip-os-freebsd.c"
|
||||
|
@ -2213,6 +2249,11 @@ ex:;
|
|||
|
||||
#include "aaip-os-freebsd.c"
|
||||
|
||||
#else
|
||||
#ifdef __OpenBSD__
|
||||
|
||||
#include "aaip-os-freebsd.c"
|
||||
|
||||
#else
|
||||
#ifdef __linux
|
||||
|
||||
|
@ -2230,7 +2271,9 @@ ex:;
|
|||
#include "aaip-os-dummy.c"
|
||||
|
||||
#endif /* ! __linux */
|
||||
#endif /* ! __OpenBSD__ */
|
||||
#endif /* ! __NetBSD__ */
|
||||
#endif /* ! __FreeBSD_kernel__ */
|
||||
#endif /* ! __FreeBSD__ */
|
||||
#endif /* ! Libisofs_use_os_dummY */
|
||||
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
|
||||
test/aaip_0_2.h - Public declarations
|
||||
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||
Copyright (c) 2009 - 2016 Thomas Schmitt
|
||||
|
||||
This file is part of the libisofs project; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License version 2
|
||||
or later as published by the Free Software Foundation.
|
||||
See COPYING file for details.
|
||||
|
||||
*/
|
||||
|
||||
|
@ -93,7 +98,7 @@ int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode,
|
|||
size_t *result_len, unsigned char **result, int flag);
|
||||
|
||||
|
||||
/* Analyze occurence of ACL tag types in long text form. If not disabled by
|
||||
/* Analyze occurrence of ACL tag types in long text form. If not disabled by
|
||||
parameter flag remove the entries of type "user::" , "group::" , "other::" ,
|
||||
or "other:" from an ACL in long text form if they match the bits in st_mode
|
||||
as described by man 2 stat and man 5 acl.
|
||||
|
@ -194,7 +199,7 @@ int aaip_get_acl_text(char *path, char **text, int flag);
|
|||
@param path Path to the file
|
||||
@param num_attrs Will return the number of name-value pairs
|
||||
@param names Will return an array of pointers to 0-terminated names
|
||||
@param value_lengths Will return an arry with the lenghts of values
|
||||
@param value_lengths Will return an array with the lengths of values
|
||||
@param values Will return an array of pointers to 8-bit values
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= obtain ACLs (access and eventually default) via
|
||||
|
@ -430,7 +435,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
|
|||
@param handle The decoding context created by aaip_decode_attrs()
|
||||
@param num_attrs Will return the number of name-value pairs
|
||||
@param names Will return an array of pointers to 0-terminated names
|
||||
@param value_lengths Will return an arry with the lenghts of values
|
||||
@param value_lengths Will return an array with the lengths of values
|
||||
@param values Will return an array of pointers to 8-bit values
|
||||
@param flag Bitfield for control purposes
|
||||
bit15= free memory of names, value_lengths, values
|
||||
|
@ -507,7 +512,8 @@ int aaip_set_acl_text(char *path, char *text, int flag);
|
|||
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag);
|
||||
size_t *value_lengths, char **values,
|
||||
int *errnos, int flag);
|
||||
|
||||
#endif /* ! Aaip_h_is_includeD */
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -252,8 +252,11 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||
/* Obtain ownership of eventual AAIP string */
|
||||
ret = iso_file_source_get_aa_string(src, &aa_string,
|
||||
1 | (image->builder_ignore_acl << 1) |
|
||||
(image->builder_ignore_ea << 2 ));
|
||||
if (ret == 1 && aa_string != NULL) {
|
||||
(image->builder_ignore_ea << 2) |
|
||||
(image->builder_take_all_ea << 3));
|
||||
if(ret == 2)
|
||||
image->blind_on_local_get_attrs = 1;
|
||||
if (ret > 0 && aa_string != NULL) {
|
||||
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -145,7 +145,7 @@ void ds_free_data(IsoDataSource *src)
|
|||
|
||||
/**
|
||||
* Create a new IsoDataSource from a local file. This is suitable for
|
||||
* accessing regular .iso images, or to acces drives via its block device
|
||||
* accessing regular .iso images, or to access drives via its block device
|
||||
* and standard POSIX I/O calls.
|
||||
*
|
||||
* @param path
|
||||
|
|
|
@ -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,7 @@
|
|||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef Xorriso_standalonE
|
||||
|
||||
|
@ -193,7 +194,7 @@ size_t calc_dirent_len(Ecma119Image *t, Ecma119Node *n)
|
|||
|
||||
/**
|
||||
* Computes the total size of all directory entries of a single dir,
|
||||
* acording to ECMA-119 6.8.1.1
|
||||
* according to ECMA-119 6.8.1.1
|
||||
*
|
||||
* This also take into account the size needed for RR entries and
|
||||
* SUSP continuation areas (SUSP, 5.1).
|
||||
|
@ -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");
|
||||
|
@ -573,10 +595,8 @@ int ecma119_writer_write_vol_desc(IsoImageWriter *writer)
|
|||
vol.vol_desc_version[0] = 1;
|
||||
strncpy_pad((char*)vol.system_id, system_id, 32);
|
||||
strncpy_pad((char*)vol.volume_id, vol_id, 32);
|
||||
if (t->pvd_size_is_total_size) {
|
||||
iso_bb(vol.vol_space_size,
|
||||
t->total_size / 2048 + t->opts->ms_block - t->eff_partition_offset,
|
||||
4);
|
||||
if (t->pvd_size_is_total_size && t->eff_partition_offset <= 0) {
|
||||
iso_bb(vol.vol_space_size, t->total_size / 2048, 4);
|
||||
} else {
|
||||
iso_bb(vol.vol_space_size,
|
||||
t->vol_space_size - t->eff_partition_offset, 4);
|
||||
|
@ -760,7 +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;
|
||||
|
@ -1190,6 +1210,13 @@ int tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||
{
|
||||
int ret;
|
||||
Ecma119Image *target;
|
||||
|
||||
#ifdef Libisofs_part_align_writeR
|
||||
|
||||
target = writer->target;
|
||||
|
||||
#else
|
||||
|
||||
struct iso_zero_writer_data_struct *data;
|
||||
char msg[80];
|
||||
|
||||
|
@ -1204,21 +1231,57 @@ int tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||
iso_msgs_submit(0, msg, 0, "NOTE", 0);
|
||||
data->num_blocks = target->opts->tail_blocks;
|
||||
}
|
||||
|
||||
#endif /* ! Libisofs_part_align_writeR */
|
||||
|
||||
if (target->opts->tail_blocks <= 0)
|
||||
return ISO_SUCCESS;
|
||||
ret = zero_writer_compute_data_blocks(writer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
int part_align_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
int ret;
|
||||
Ecma119Image *target;
|
||||
struct iso_zero_writer_data_struct *data;
|
||||
char msg[80];
|
||||
|
||||
target = writer->target;
|
||||
|
||||
/* Default setting in case no alignment is needed */
|
||||
target->alignment_end_block = target->curblock;
|
||||
|
||||
ret = iso_align_isohybrid(target, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
data = (struct iso_zero_writer_data_struct *) writer->data;
|
||||
if (target->part_align_blocks != 0) {
|
||||
sprintf(msg, "Aligned image size to cylinder size by %d blocks",
|
||||
target->part_align_blocks);
|
||||
iso_msgs_submit(0, msg, 0, "NOTE", 0);
|
||||
data->num_blocks = target->part_align_blocks;
|
||||
}
|
||||
if (target->part_align_blocks <= 0)
|
||||
return ISO_SUCCESS;
|
||||
ret = zero_writer_compute_data_blocks(writer);
|
||||
target->alignment_end_block = target->curblock;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@param flag bit0= use tail_writer_compute_data_blocks rather than
|
||||
zero_writer_compute_data_blocks
|
||||
@param flag bit0-3= compute_data_blocks mode:
|
||||
0= zero_writer_compute_data_blocks
|
||||
1= tail_writer_compute_data_blocks
|
||||
2= part_align_writer_compute_data_blocks
|
||||
*/
|
||||
static
|
||||
int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
|
||||
{
|
||||
IsoImageWriter *writer;
|
||||
struct iso_zero_writer_data_struct *data;
|
||||
int mode;
|
||||
|
||||
writer = malloc(sizeof(IsoImageWriter));
|
||||
if (writer == NULL) {
|
||||
|
@ -1231,8 +1294,11 @@ int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
|
|||
}
|
||||
data->num_blocks = num_blocks;
|
||||
|
||||
if (flag & 1) {
|
||||
mode = (flag & 15);
|
||||
if (mode == 1) {
|
||||
writer->compute_data_blocks = tail_writer_compute_data_blocks;
|
||||
} else if (mode == 2) {
|
||||
writer->compute_data_blocks = part_align_writer_compute_data_blocks;
|
||||
} else {
|
||||
writer->compute_data_blocks = zero_writer_compute_data_blocks;
|
||||
}
|
||||
|
@ -1330,6 +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)
|
||||
|
@ -1352,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);
|
||||
|
@ -1417,9 +1485,10 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
|||
target->partiton_offset from any LBA pointer.
|
||||
*/
|
||||
target->eff_partition_offset = target->opts->partition_offset;
|
||||
target->pvd_size_is_total_size = 0;
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
writer = target->writers[i];
|
||||
/* Not all writers have an entry in the partion volume descriptor set.
|
||||
/* Not all writers have an entry in the partition volume descriptor set.
|
||||
It must be guaranteed that they write exactly one block.
|
||||
*/
|
||||
|
||||
|
@ -1455,7 +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;
|
||||
|
||||
|
@ -1497,9 +1566,6 @@ static int finish_libjte(Ecma119Image *target)
|
|||
}
|
||||
|
||||
|
||||
/* >>> need opportunity to just mark a partition in the older sessions
|
||||
*/
|
||||
|
||||
|
||||
struct iso_interval_zeroizer {
|
||||
int z_type; /* 0= $zero_start"-"$zero_end ,
|
||||
|
@ -2000,6 +2066,50 @@ process_pending:;
|
|||
}
|
||||
|
||||
|
||||
/* Tells whether ivr is a reader from imported_iso in a multi-session
|
||||
add-on situation, and thus to be kept in place.
|
||||
*/
|
||||
int iso_interval_reader_keep(Ecma119Image *target,
|
||||
struct iso_interval_reader *ivr,
|
||||
int flag)
|
||||
{
|
||||
/* Source must be "imported_iso" */
|
||||
if (!(ivr->flags & 1))
|
||||
return 0;
|
||||
|
||||
/* It must not be a new ISO */
|
||||
if (!target->opts->appendable)
|
||||
return 0;
|
||||
|
||||
/* --- From here on return either 1 or <0 --- */
|
||||
|
||||
/* multi-session write offset must be larger than interval end */
|
||||
if (target->opts->ms_block <= ivr->end_byte / BLOCK_SIZE)
|
||||
return ISO_MULTI_OVER_IMPORTED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int iso_interval_reader_start_size(Ecma119Image *t, char *path,
|
||||
off_t *start_byte, off_t *byte_count,
|
||||
int flag)
|
||||
{
|
||||
struct iso_interval_reader *ivr;
|
||||
int keep, ret;
|
||||
|
||||
ret = iso_interval_reader_new(t->image, path, &ivr, byte_count, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*start_byte = ivr->start_byte;
|
||||
keep = iso_interval_reader_keep(t, ivr, 0);
|
||||
if (keep < 0)
|
||||
return(keep);
|
||||
iso_interval_reader_destroy(&ivr, 0);
|
||||
return ISO_SUCCESS + (keep > 0);
|
||||
}
|
||||
|
||||
|
||||
int iso_write_partition_file(Ecma119Image *target, char *path,
|
||||
uint32_t prepad, uint32_t blocks, int flag)
|
||||
{
|
||||
|
@ -2025,6 +2135,14 @@ int iso_write_partition_file(Ecma119Image *target, char *path,
|
|||
&ivr, &byte_count, 0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
ret = iso_interval_reader_keep(target, ivr, 0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
if (ret > 0) {
|
||||
/* From imported_iso and for add-on session. Leave it in place. */
|
||||
ret = ISO_SUCCESS;
|
||||
goto ex;
|
||||
}
|
||||
for (i = 0; i < blocks; i++) {
|
||||
ret = iso_interval_reader_read(ivr, buf, &buf_fill, 0);
|
||||
if (ret < 0)
|
||||
|
@ -2084,7 +2202,7 @@ void *write_function(void *arg)
|
|||
{
|
||||
int res, i;
|
||||
#ifndef Libisofs_appended_partitions_inlinE
|
||||
int first_partition = 1, last_partition = 0, sa_type;
|
||||
int first_partition = 1, last_partition = 0;
|
||||
#endif
|
||||
IsoImageWriter *writer;
|
||||
|
||||
|
@ -2113,14 +2231,7 @@ void *write_function(void *arg)
|
|||
#ifndef Libisofs_appended_partitions_inlinE
|
||||
|
||||
/* Append partition data */
|
||||
sa_type = (target->system_area_options >> 2) & 0x3f;
|
||||
if (sa_type == 0) { /* MBR */
|
||||
first_partition = 1;
|
||||
last_partition = 4;
|
||||
} else if (sa_type == 3) { /* SUN Disk Label */
|
||||
first_partition = 2;
|
||||
last_partition = 8;
|
||||
}
|
||||
iso_count_appended_partitions(target, &first_partition, &last_partition);
|
||||
for (i = first_partition - 1; i <= last_partition - 1; i++) {
|
||||
if (target->opts->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
|
@ -2320,6 +2431,73 @@ ex:;
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Determine the alleged time of image production by predicting the volume
|
||||
creation and modification timestamps and taking the maximum of both.
|
||||
*/
|
||||
static
|
||||
void ecma119_determine_now_time(Ecma119Image *target)
|
||||
{
|
||||
IsoWriteOpts *o;
|
||||
time_t now = 0, t, t0;
|
||||
uint8_t time_text[18];
|
||||
int i;
|
||||
|
||||
iso_nowtime(&t0, 0);
|
||||
o = target->opts;
|
||||
if (o->vol_uuid[0]) {
|
||||
for(i = 0; i < 16; i++)
|
||||
if(o->vol_uuid[i] < '0' || o->vol_uuid[i] > '9')
|
||||
break;
|
||||
else
|
||||
time_text[i] = o->vol_uuid[i];
|
||||
for(; i < 16; i++)
|
||||
time_text[i] = '1';
|
||||
time_text[16] = time_text[17] = 0;
|
||||
t = iso_datetime_read_17(time_text);
|
||||
if (t > now)
|
||||
now = t;
|
||||
} else {
|
||||
if (o->vol_creation_time > 0) {
|
||||
if (o->vol_creation_time > now)
|
||||
now = o->vol_creation_time;
|
||||
} else if (t0 > now) {
|
||||
now = t0;
|
||||
}
|
||||
if (o->vol_modification_time > 0) {
|
||||
if (o->vol_modification_time > now)
|
||||
now = o->vol_modification_time;
|
||||
} else if (t0 > now) {
|
||||
now = t0;
|
||||
}
|
||||
}
|
||||
target->now = now;
|
||||
}
|
||||
|
||||
static
|
||||
int gpt_disk_guid_setup(Ecma119Image *target)
|
||||
{
|
||||
if (target->opts->gpt_disk_guid_mode == 0) {
|
||||
/* Random UUID production delayed until really needed */
|
||||
return ISO_SUCCESS;
|
||||
} else if (target->opts->gpt_disk_guid_mode == 1) {
|
||||
memcpy(target->gpt_uuid_base, target->opts->gpt_disk_guid, 16);
|
||||
} else if (target->opts->gpt_disk_guid_mode == 2) {
|
||||
if (target->opts->vol_uuid[0] == 0)
|
||||
return ISO_GPT_NO_VOL_UUID;
|
||||
/* Move centi-seconds part to byte 9 and 10 */
|
||||
memcpy(target->gpt_uuid_base, target->opts->vol_uuid, 9);
|
||||
memcpy(target->gpt_uuid_base + 9, target->opts->vol_uuid + 14, 2);
|
||||
memcpy(target->gpt_uuid_base + 11, target->opts->vol_uuid + 9, 5);
|
||||
iso_mark_guid_version_4(target->gpt_uuid_base);
|
||||
} else {
|
||||
return ISO_BAD_GPT_GUID_MODE;
|
||||
}
|
||||
memcpy(target->gpt_disk_guid, target->gpt_uuid_base, 16);
|
||||
target->gpt_disk_guid_set = 1;
|
||||
target->gpt_uuid_counter = 1;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
||||
{
|
||||
|
@ -2332,13 +2510,19 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
int system_area_options = 0;
|
||||
char *system_area = NULL;
|
||||
int write_count = 0, write_count_mem;
|
||||
uint32_t vol_space_size_mem;
|
||||
off_t total_size_mem;
|
||||
|
||||
#ifdef Libisofs_appended_partitions_inlinE
|
||||
int fap, lap, app_part_count;
|
||||
#endif
|
||||
|
||||
/* 1. Allocate target and attach a copy of in_opts there */
|
||||
target = calloc(1, sizeof(Ecma119Image));
|
||||
if (target == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
/* This reference will be transfered to the burn_source and released by
|
||||
/* This reference will be transferred to the burn_source and released by
|
||||
bs_free_data.
|
||||
*/
|
||||
target->refcount = 1;
|
||||
|
@ -2375,7 +2559,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
target->dir_mode = opts->replace_dir_mode == 2 ? opts->dir_mode : 0555;
|
||||
target->file_mode = opts->replace_file_mode == 2 ? opts->file_mode : 0444;
|
||||
|
||||
target->now = time(NULL);
|
||||
ecma119_determine_now_time(target);
|
||||
|
||||
target->replace_timestamps = opts->replace_timestamps ? 1 : 0;
|
||||
target->timestamp = opts->replace_timestamps == 2 ?
|
||||
|
@ -2406,6 +2590,16 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
target->boot_intvl_start[i] = 0;
|
||||
target->boot_intvl_size[i] = 0;
|
||||
}
|
||||
/* It is not easy to predict when the node gets created and can be
|
||||
manipulated. So it is better for reproducibility to derive its
|
||||
timestamps from the well controllable now-time.
|
||||
*/
|
||||
if (target->catalog->node != NULL) {
|
||||
iso_node_set_mtime((IsoNode *) target->catalog->node, target->now);
|
||||
iso_node_set_atime((IsoNode *) target->catalog->node, target->now);
|
||||
iso_node_set_ctime((IsoNode *) target->catalog->node, target->now);
|
||||
}
|
||||
|
||||
} else {
|
||||
target->num_bootsrc = 0;
|
||||
target->bootsrc = NULL;
|
||||
|
@ -2516,6 +2710,8 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
|
||||
target->wthread_is_running = 0;
|
||||
|
||||
target->part_align_blocks = 0;
|
||||
target->alignment_end_block = 0;
|
||||
target->post_iso_part_pad = 0;
|
||||
target->prep_part_size = 0;
|
||||
target->efi_boot_part_size = 0;
|
||||
|
@ -2533,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++)
|
||||
|
@ -2545,7 +2742,12 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
target->gpt_req_count = 0;
|
||||
target->gpt_req_flags = 0;
|
||||
target->gpt_backup_outside = 0;
|
||||
memset(target->gpt_uuid_base, 0, 16);
|
||||
target->gpt_uuid_counter = 0;
|
||||
target->gpt_disk_guid_set = 0;
|
||||
ret = gpt_disk_guid_setup(target);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
target->gpt_part_start = 0;
|
||||
target->gpt_backup_end = 0;
|
||||
target->gpt_backup_size = 0;
|
||||
|
@ -2557,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.
|
||||
|
@ -2609,6 +2817,12 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
nwriters+= 2;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_part_align_writeR
|
||||
|
||||
nwriters++; /* part_align_blocks writer */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef Libisofs_appended_partitions_inlinE
|
||||
|
||||
nwriters++; /* Inline Partition Append Writer */
|
||||
|
@ -2735,34 +2949,26 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
goto target_cleanup;
|
||||
#endif /* ! Libisofs_gpt_writer_lasT */
|
||||
|
||||
|
||||
/* >>> Should not the checksum writer come before the zero writer ?
|
||||
*/
|
||||
#define Libisofs_checksums_before_paddinG yes
|
||||
#ifndef Libisofs_checksums_before_paddinG
|
||||
|
||||
/* >>> ??? Why is this important ? */
|
||||
/* IMPORTANT: This must be the last writer before the checksum writer */
|
||||
ret = zero_writer_create(target, opts->tail_blocks, 1);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
|
||||
#endif /* !Libisofs_checksums_before_paddinG */
|
||||
|
||||
if ((opts->md5_file_checksums & 1) || opts->md5_session_checksum) {
|
||||
ret = checksum_writer_create(target);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_checksums_before_paddinG
|
||||
|
||||
#ifdef Libisofs_part_align_writeR
|
||||
|
||||
/* Alignment padding before appended partitions */
|
||||
ret = zero_writer_create(target, 0, 2);
|
||||
|
||||
#else
|
||||
|
||||
ret = zero_writer_create(target, opts->tail_blocks, 1);
|
||||
|
||||
#endif /* ! Libisofs_part_align_writeR */
|
||||
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
|
||||
#endif /* Libisofs_checksums_before_paddinG */
|
||||
|
||||
#ifdef Libisofs_appended_partitions_inlinE
|
||||
|
||||
ret = partappend_writer_create(target);
|
||||
|
@ -2771,9 +2977,18 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
|
||||
#endif /* Libisofs_appended_partitions_inlinE */
|
||||
|
||||
#ifdef Libisofs_part_align_writeR
|
||||
|
||||
ret = zero_writer_create(target, opts->tail_blocks, 0);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
|
||||
#endif /* Libisofs_part_align_writeR */
|
||||
|
||||
#ifdef Libisofs_gpt_writer_lasT
|
||||
/* This writer shall be the last one in the list, because it protects the
|
||||
image on media which are seen as GPT partitioned.
|
||||
/* This writer shall be the last one in the list of writers of valuable
|
||||
data, because it protects the image on media which are seen as GPT
|
||||
partitioned.
|
||||
In any case it has to come after any writer which might request
|
||||
production of APM or GPT partition entries by its compute_data_blocks()
|
||||
method.
|
||||
|
@ -2831,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];
|
||||
|
@ -2857,13 +3072,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
goto target_cleanup;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_appended_partitions_inlinE
|
||||
|
||||
target->vol_space_size = target->curblock - opts->ms_block;
|
||||
target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
ret = iso_patch_eltoritos(target);
|
||||
|
@ -2875,12 +3083,24 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
goto target_cleanup;
|
||||
}
|
||||
|
||||
#ifndef Libisofs_appended_partitions_inlinE
|
||||
|
||||
/*
|
||||
* The volume space size is just the size of the last session, in
|
||||
* case of ms images.
|
||||
*/
|
||||
|
||||
#ifdef Libisofs_appended_partitions_inlinE
|
||||
|
||||
app_part_count = iso_count_appended_partitions(target, &fap, &lap);
|
||||
if (app_part_count == 0)
|
||||
target->vol_space_size = target->curblock - opts->ms_block;
|
||||
else
|
||||
target->vol_space_size = target->alignment_end_block - opts->ms_block;
|
||||
|
||||
target->total_size = (off_t) (target->curblock - opts->ms_block) *
|
||||
BLOCK_SIZE;
|
||||
|
||||
#else /* Libisofs_appended_partitions_inlinE */
|
||||
|
||||
target->vol_space_size = target->curblock - opts->ms_block;
|
||||
target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE;
|
||||
|
||||
|
@ -2917,6 +3137,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
}
|
||||
|
||||
/* check if we need to provide a copy of volume descriptors */
|
||||
vol_space_size_mem = target->vol_space_size;
|
||||
if (opts->overwrite != NULL) {
|
||||
|
||||
/* opts->overwrite must be larger by partion_offset
|
||||
|
@ -2928,12 +3149,15 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
* In the PVM to be written in the 16th sector of the disc, we
|
||||
* need to specify the full size.
|
||||
*/
|
||||
target->vol_space_size = target->curblock;
|
||||
target->vol_space_size += opts->ms_block;
|
||||
|
||||
/* System area and volume descriptors */
|
||||
target->opts_overwrite = (char *) opts->overwrite;
|
||||
total_size_mem = target->total_size;
|
||||
target->total_size += target->opts->ms_block * BLOCK_SIZE;
|
||||
ret = write_head_part1(target, &write_count, 1 | 2);
|
||||
target->opts_overwrite = NULL;
|
||||
target->total_size = total_size_mem;
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
|
||||
|
@ -2995,10 +3219,14 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *in_opts, Ecma119Image **img)
|
|||
"Error reading overwrite volume descriptors");
|
||||
goto target_cleanup;
|
||||
}
|
||||
|
||||
/* Delete the filler partitions of GPT and APM so that write_function()
|
||||
can insert new ones for a possibly different total_size */;
|
||||
iso_delete_gpt_apm_fillers(target, 0);
|
||||
}
|
||||
|
||||
/* This was possibly altered by above overwrite buffer production */
|
||||
target->vol_space_size = target->curblock - opts->ms_block;
|
||||
target->vol_space_size = vol_space_size_mem;
|
||||
|
||||
/*
|
||||
*/
|
||||
|
@ -3067,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;
|
||||
|
||||
|
@ -3162,11 +3410,6 @@ int bs_set_size(struct burn_source *bs, off_t size)
|
|||
{
|
||||
Ecma119Image *target = (Ecma119Image*)bs->data;
|
||||
|
||||
/*
|
||||
* just set the value to be returned by get_size. This is not used at
|
||||
* all by libisofs, it is here just for helping libburn to correctly pad
|
||||
* the image if needed.
|
||||
*/
|
||||
target->total_size = size;
|
||||
return 1;
|
||||
}
|
||||
|
@ -3378,7 +3621,7 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
|||
wopts->vol_modification_time = 0;
|
||||
wopts->vol_expiration_time = 0;
|
||||
wopts->vol_effective_time = 0;
|
||||
wopts->vol_uuid[0] = 0;
|
||||
memset(wopts->vol_uuid, 0, 17);
|
||||
wopts->partition_offset = 0;
|
||||
wopts->partition_secs_per_head = 0;
|
||||
wopts->partition_heads_per_cyl = 0;
|
||||
|
@ -3396,10 +3639,15 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
|||
wopts->appended_partitions[i] = NULL;
|
||||
wopts->appended_part_types[i] = 0;
|
||||
wopts->appended_part_flags[i] = 0;
|
||||
memset(wopts->appended_part_type_guids[i], 0, 16);
|
||||
wopts->appended_part_gpt_flags[i] = 0;
|
||||
}
|
||||
wopts->appended_as_gpt = 0;
|
||||
wopts->appended_as_apm = 0;
|
||||
wopts->part_like_isohybrid = 0;
|
||||
wopts->iso_mbr_part_type = -1;
|
||||
memset(wopts->iso_gpt_type_guid, 0, 16);
|
||||
wopts->iso_gpt_flag= 0;
|
||||
wopts->ascii_disc_label[0] = 0;
|
||||
wopts->will_cancel = 0;
|
||||
wopts->allow_dir_id_ext = 0;
|
||||
|
@ -3409,6 +3657,10 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
|||
wopts->hfsp_serial_number[i] = 0;
|
||||
wopts->apm_block_size = 0;
|
||||
wopts->hfsp_block_size = 0;
|
||||
memset(wopts->gpt_disk_guid, 0, 16);
|
||||
wopts->gpt_disk_guid_mode = 0;
|
||||
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;
|
||||
|
@ -4005,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;
|
||||
}
|
||||
|
||||
|
@ -4115,6 +4367,20 @@ int iso_write_opts_set_partition_img(IsoWriteOpts *opts, int partition_number,
|
|||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_part_type_guid(IsoWriteOpts *opts, int partition_number,
|
||||
uint8_t guid[16], int valid)
|
||||
{
|
||||
if (partition_number < 1 || partition_number > ISO_MAX_PARTITIONS)
|
||||
return ISO_BAD_PARTITION_NO;
|
||||
if (valid)
|
||||
memcpy(opts->appended_part_type_guids[partition_number - 1], guid, 16);
|
||||
if (valid)
|
||||
opts->appended_part_gpt_flags[partition_number - 1]|= 1;
|
||||
else
|
||||
opts->appended_part_gpt_flags[partition_number - 1]&= ~1;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_appended_as_gpt(IsoWriteOpts *opts, int gpt)
|
||||
{
|
||||
opts->appended_as_gpt = !!gpt;
|
||||
|
@ -4133,6 +4399,23 @@ int iso_write_opts_set_part_like_isohybrid(IsoWriteOpts *opts, int alike)
|
|||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_iso_mbr_part_type(IsoWriteOpts *opts, int part_type)
|
||||
{
|
||||
if (part_type < -1 || part_type > 255)
|
||||
part_type = -1;
|
||||
opts->iso_mbr_part_type = part_type;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_iso_type_guid(IsoWriteOpts *opts, uint8_t guid[16],
|
||||
int valid)
|
||||
{
|
||||
if (valid)
|
||||
memcpy(opts->iso_gpt_type_guid, guid, 16);
|
||||
opts->iso_gpt_flag = (opts->iso_gpt_flag & ~1) | !!valid;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_disc_label(IsoWriteOpts *opts, char *label)
|
||||
{
|
||||
strncpy(opts->ascii_disc_label, label, ISO_DISC_LABEL_SIZE - 1);
|
||||
|
@ -4160,6 +4443,27 @@ int iso_write_opts_set_hfsp_block_size(IsoWriteOpts *opts,
|
|||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_gpt_guid(IsoWriteOpts *opts, uint8_t guid[16], int mode)
|
||||
{
|
||||
if (mode < 0 || mode > 2)
|
||||
return ISO_BAD_GPT_GUID_MODE;
|
||||
opts->gpt_disk_guid_mode = mode;
|
||||
if (opts->gpt_disk_guid_mode == 1)
|
||||
memcpy(opts->gpt_disk_guid, guid, 16);
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -4168,7 +4472,7 @@ int iso_write_opts_set_hfsp_block_size(IsoWriteOpts *opts,
|
|||
* 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
|
||||
|
@ -4387,3 +4691,46 @@ ex: /* LIBISO_ALLOC_MEM failed */
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Determines the range of valid partition numbers depending on partition
|
||||
table type.
|
||||
*/
|
||||
void iso_tell_max_part_range(IsoWriteOpts *opts,
|
||||
int *first_partition, int *last_partition,
|
||||
int flag)
|
||||
{
|
||||
int sa_type;
|
||||
|
||||
sa_type = (opts->system_area_options >> 2) & 0x3f;
|
||||
if (sa_type == 3) { /* SUN Disk Label */
|
||||
*first_partition = 2;
|
||||
*last_partition = 8;
|
||||
} else if(sa_type == 0 && opts->appended_as_gpt) {
|
||||
*first_partition = 1;
|
||||
*last_partition = 8;
|
||||
} else {
|
||||
*first_partition = 1;
|
||||
*last_partition = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Obtains start and end number of appended partition range and returns
|
||||
the number of valid entries in the list of appended partitions.
|
||||
*/
|
||||
int iso_count_appended_partitions(Ecma119Image *target,
|
||||
int *first_partition, int *last_partition)
|
||||
{
|
||||
int i, count= 0;
|
||||
|
||||
iso_tell_max_part_range(target->opts, first_partition, last_partition, 0);
|
||||
for (i = *first_partition - 1; i <= *last_partition - 1; i++) {
|
||||
if (target->opts->appended_partitions[i] == NULL)
|
||||
continue;
|
||||
if (target->opts->appended_partitions[i][0] == 0)
|
||||
continue;
|
||||
count++;
|
||||
}
|
||||
return(count);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* 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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -59,7 +59,7 @@
|
|||
#define ISO_DISC_LABEL_SIZE 129
|
||||
|
||||
|
||||
/* The maximum lenght of an specs violating ECMA-119 file identifier.
|
||||
/* The maximum length of an specs violating ECMA-119 file identifier.
|
||||
The theoretical limit is 254 - 34 - 28 (len of SUSP CE entry) = 192
|
||||
Currently the practical limit is 254 - 34 - 96 (non-CE RR entries) - 28 (CE)
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -223,7 +223,7 @@ struct iso_write_opts {
|
|||
/**
|
||||
* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12.
|
||||
* I.e. without announcing it by an ER field and thus without the need
|
||||
* to preceed the RRIP fields by an ES and to preceed the AA field by ES.
|
||||
* to precede the RRIP fields by an ES and to precede the AA field by ES.
|
||||
* This saves bytes and might avoid problems with readers which dislike
|
||||
* ER fields other than the ones for RRIP.
|
||||
* On the other hand, SUSP 1.12 frowns on such unannounced extensions
|
||||
|
@ -287,7 +287,7 @@ struct iso_write_opts {
|
|||
/**
|
||||
* The following options set the default values for files and directory
|
||||
* permissions, gid and uid. All these take one of three values: 0, 1 or 2.
|
||||
* If 0, the corresponding attribute will be kept as setted in the IsoNode.
|
||||
* If 0, the corresponding attribute will be kept as set in the IsoNode.
|
||||
* Unless you have changed it, it corresponds to the value on disc, so it
|
||||
* is suitable for backup purposes. If set to 1, the corresponding attrib.
|
||||
* will be changed by a default suitable value. Finally, if you set it to
|
||||
|
@ -349,7 +349,7 @@ struct iso_write_opts {
|
|||
* or write to an .iso file for future burning or distribution.
|
||||
*
|
||||
* On the other side, an appendable image is not self contained, it refers
|
||||
* to serveral files that are stored outside the image. Its usage is for
|
||||
* to several files that are stored outside the image. Its usage is for
|
||||
* multisession discs, where you add data in a new session, while the
|
||||
* previous session data can still be accessed. In those cases, the old
|
||||
* data is not written again. Instead, the new image refers to it, and thus
|
||||
|
@ -381,7 +381,7 @@ struct iso_write_opts {
|
|||
/**
|
||||
* When not NULL, it should point to a buffer of at least 64KiB, where
|
||||
* libisofs will write the contents that should be written at the beginning
|
||||
* of a overwriteable media, to grow the image. The growing of an image is
|
||||
* of a overwritable media, to grow the image. The growing of an image is
|
||||
* a way, used by first time in growisofs by Andy Polyakov, to allow the
|
||||
* appending of new data to non-multisession media, such as DVD+RW, in the
|
||||
* same way you append a new session to a multisession disc, i.e., without
|
||||
|
@ -393,7 +393,7 @@ struct iso_write_opts {
|
|||
*
|
||||
* You should initialize the buffer either with 0s, or with the contents of
|
||||
* the first blocks of the image you're growing. In most cases, 0 is good
|
||||
* enought.
|
||||
* enough.
|
||||
*/
|
||||
uint8_t *overwrite;
|
||||
|
||||
|
@ -476,12 +476,19 @@ struct iso_write_opts {
|
|||
char *efi_boot_partition;
|
||||
int efi_boot_part_flag;
|
||||
|
||||
/* Eventual disk file paths of prepared images which shall be appended
|
||||
after the ISO image and described by partiton table entries in a MBR
|
||||
/* Disk file paths of prepared images which shall be appended
|
||||
after the ISO image and described by partition table entries in a MBR.
|
||||
NULL means unused.
|
||||
*/
|
||||
char *appended_partitions[ISO_MAX_PARTITIONS];
|
||||
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
|
||||
int appended_part_flags[ISO_MAX_PARTITIONS];
|
||||
uint8_t appended_part_type_guids[ISO_MAX_PARTITIONS][16];
|
||||
|
||||
/* Flags in case that appended partitions show up in GPT:
|
||||
bit0= appended_part_type_guids is valid
|
||||
*/
|
||||
uint8_t appended_part_gpt_flags[ISO_MAX_PARTITIONS];
|
||||
|
||||
/* If 1: With appended partitions: create protective MBR and mark by GPT
|
||||
*/
|
||||
|
@ -496,6 +503,22 @@ struct iso_write_opts {
|
|||
*/
|
||||
int part_like_isohybrid;
|
||||
|
||||
/* The type to use for the mountable ISO partition if there is any and if
|
||||
the type is not mandatorily determined for particular circumstances like
|
||||
compliant GPT, CHRP, or PReP.
|
||||
-1 = use the default value (e.g. 0xcd, 0x83, 0x17)
|
||||
0x00 to 0xff = value to use if possible
|
||||
*/
|
||||
int iso_mbr_part_type;
|
||||
|
||||
/* iso_write_opts_set_iso_type_guid
|
||||
*/
|
||||
uint8_t iso_gpt_type_guid[16];
|
||||
/* bit0= iso_gpt_type_guid is valid
|
||||
*/
|
||||
int iso_gpt_flag;
|
||||
|
||||
|
||||
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
|
||||
*/
|
||||
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
||||
|
@ -513,6 +536,24 @@ struct iso_write_opts {
|
|||
*/
|
||||
int apm_block_size;
|
||||
|
||||
/* User defined GUID for GPT header and base of reproducible partition
|
||||
GUIDs. (Not to be confused with volume "UUID", which is actually a
|
||||
timestamp.)
|
||||
See API call iso_write_opts_set_gpt_guid().
|
||||
*/
|
||||
uint8_t gpt_disk_guid[16];
|
||||
int gpt_disk_guid_mode;
|
||||
|
||||
/* 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;
|
||||
|
@ -784,6 +825,11 @@ struct ecma119_image
|
|||
*/
|
||||
IsoFileSrc *sparc_core_src;
|
||||
|
||||
/* Trailing padding of ISO filesystem partition for cylinder alignment */
|
||||
/* Only in effect with Libisofs_part_align_writeR */
|
||||
uint32_t part_align_blocks;
|
||||
uint32_t alignment_end_block;
|
||||
|
||||
/* Counted in blocks of 2048 */
|
||||
uint32_t appended_part_prepad[ISO_MAX_PARTITIONS];
|
||||
uint32_t appended_part_start[ISO_MAX_PARTITIONS];
|
||||
|
@ -844,6 +890,11 @@ struct ecma119_image
|
|||
/* Whether the eventual backup GPT is not part of the ISO filesystem */
|
||||
int gpt_backup_outside;
|
||||
|
||||
/* The base UUID for the generated GPT UUIDs */
|
||||
uint8_t gpt_uuid_base[16];
|
||||
/* The counter which distinguishes the GPT UUIDs */
|
||||
uint32_t gpt_uuid_counter;
|
||||
|
||||
uint32_t efi_boot_part_size;
|
||||
IsoFileSrc *efi_boot_part_filesrc; /* Just a pointer. Do not free. */
|
||||
|
||||
|
@ -873,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]
|
||||
|
@ -1012,5 +1078,29 @@ int iso_write_partition_file(Ecma119Image *target, char *path,
|
|||
|
||||
void issue_ucs2_warning_summary(size_t failures);
|
||||
|
||||
/* Tells whether ivr is a reader from imported_iso in a multi-session
|
||||
add-on situation, and thus to be kept in place.
|
||||
*/
|
||||
int iso_interval_reader_keep(Ecma119Image *target,
|
||||
struct iso_interval_reader *ivr,
|
||||
int flag);
|
||||
|
||||
/* @return: ISO_SUCCESS = ok, ISO_SUCCESS + 1 = keep , < 0 = error */
|
||||
int iso_interval_reader_start_size(Ecma119Image *t, char *path,
|
||||
off_t *start_byte, off_t *byte_count,
|
||||
int flag);
|
||||
|
||||
/* Obtains start and end number of appended partition range and returns
|
||||
the number of valid entries in the list of appended partitions.
|
||||
*/
|
||||
int iso_count_appended_partitions(Ecma119Image *target,
|
||||
int *first_partition, int *last_partition);
|
||||
|
||||
/* Determines the range of valid partition numbers depending on partition
|
||||
table type.
|
||||
*/
|
||||
void iso_tell_max_part_range(IsoWriteOpts *opts,
|
||||
int *first_partition, int *last_partition,
|
||||
int flag);
|
||||
|
||||
#endif /*LIBISO_ECMA119_H_*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2016 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
|
@ -241,11 +241,11 @@ int create_file_src(Ecma119Image *img, IsoFile *iso, IsoFileSrc **src)
|
|||
size = iso_stream_get_size(iso->stream);
|
||||
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && img->opts->iso_level != 3) {
|
||||
char *ipath = iso_tree_get_node_path(ISO_NODE(iso));
|
||||
ret = iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0,
|
||||
"File \"%s\" can't be added to image because "
|
||||
"is greater than 4GB", ipath);
|
||||
iso_msg_submit(img->image->id, ISO_FILE_TOO_BIG, 0,
|
||||
"File \"%s\" cannot be added to image because "
|
||||
"its size is 4 GiB or larger", ipath);
|
||||
free(ipath);
|
||||
return ret;
|
||||
return ISO_FILE_TOO_BIG;
|
||||
}
|
||||
ret = iso_file_src_create(img, iso, src);
|
||||
if (ret < 0) {
|
||||
|
@ -597,7 +597,7 @@ int cmp_node_name(const void *f1, const void *f2)
|
|||
|
||||
/**
|
||||
* Sorts a the children of each directory in the ECMA-119 tree represented
|
||||
* by \p root, acording to the order specified in ECMA-119, section 9.3.
|
||||
* by \p root, according to the order specified in ECMA-119, section 9.3.
|
||||
*/
|
||||
static
|
||||
void sort_tree(Ecma119Node *root)
|
||||
|
@ -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.
|
||||
|
@ -1270,7 +1270,7 @@ int ecma119_tree_create(Ecma119Image *img)
|
|||
|
||||
if (img->opts->rockridge && !img->opts->allow_deep_paths) {
|
||||
|
||||
/* Relocate deep directories, acording to RRIP, 4.1.5 */
|
||||
/* Relocate deep directories, according to RRIP, 4.1.5 */
|
||||
ret = reorder_tree(img, root, 1, 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2010 - 2015 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
|
||||
|
@ -113,9 +113,24 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors)
|
|||
/* API */
|
||||
int el_torito_get_load_size(ElToritoBootImage *bootimg)
|
||||
{
|
||||
return (int) bootimg->load_size;
|
||||
return (int) bootimg->load_size;
|
||||
}
|
||||
|
||||
/* API */
|
||||
void el_torito_set_full_load(ElToritoBootImage *bootimg, int mode)
|
||||
{
|
||||
if (bootimg->type != 0)
|
||||
return;
|
||||
bootimg->load_size_full= !!mode;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int el_torito_get_full_load(ElToritoBootImage *bootimg)
|
||||
{
|
||||
return bootimg->load_size_full;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Marks the specified boot image as not bootable
|
||||
*/
|
||||
|
@ -290,14 +305,14 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
|||
node->size = 0;
|
||||
node->content = NULL;
|
||||
|
||||
/* atributes from parent */
|
||||
/* attributes from parent */
|
||||
node->node.mode = S_IFREG | (parent->node.mode & 0444);
|
||||
node->node.uid = parent->node.uid;
|
||||
node->node.gid = parent->node.gid;
|
||||
node->node.hidden = parent->node.hidden;
|
||||
|
||||
/* current time */
|
||||
now = time(NULL);
|
||||
iso_nowtime(&now, 0);
|
||||
node->node.atime = now;
|
||||
node->node.ctime = now;
|
||||
node->node.mtime = now;
|
||||
|
@ -513,6 +528,7 @@ int create_image(IsoImage *image, const char *image_path,
|
|||
boot->partition_type = partition_type;
|
||||
boot->load_seg = 0;
|
||||
boot->load_size = load_sectors;
|
||||
boot->load_size_full = 0;
|
||||
boot->platform_id = 0; /* 80x86 */
|
||||
memset(boot->id_string, 0, sizeof(boot->id_string));
|
||||
memset(boot->selection_crit, 0, sizeof(boot->selection_crit));
|
||||
|
@ -550,12 +566,10 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||
|
||||
/* get both the dir and the name */
|
||||
catname = strrchr(catdir, '/');
|
||||
if (catname == NULL) {
|
||||
free(catdir);
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
if (catname == NULL)
|
||||
catname = catdir;
|
||||
if (catname == catdir) {
|
||||
/* we are apending catalog to root node */
|
||||
/* we are appending catalog to root node */
|
||||
parent = image->root;
|
||||
} else {
|
||||
IsoNode *p;
|
||||
|
@ -574,7 +588,8 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||
}
|
||||
parent = (IsoDir*)p;
|
||||
}
|
||||
catname++;
|
||||
if (catname[0] == '/' || catname[0] == 0)
|
||||
catname++;
|
||||
ret = iso_tree_add_boot_node(parent, catname, &cat_node);
|
||||
free(catdir);
|
||||
if (ret < 0) {
|
||||
|
@ -695,13 +710,14 @@ int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
|
|||
return 0;
|
||||
*catnode = bootcat;
|
||||
*lba = bootcat->lba;
|
||||
*size = bootcat->size;
|
||||
if (bootcat->size > 0 && bootcat->content != NULL) {
|
||||
*content = calloc(1, bootcat->size);
|
||||
if (*content == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy(*content, bootcat->content, bootcat->size);
|
||||
}
|
||||
if (*content != NULL)
|
||||
*size = bootcat->size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -829,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)
|
||||
|
@ -887,6 +905,32 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
|
|||
sizeof(e->id_string));
|
||||
}
|
||||
|
||||
static int
|
||||
write_section_load_size(struct el_torito_boot_image *img,
|
||||
struct el_torito_section_entry *se,
|
||||
uint16_t load_size, off_t full_byte_size, int flag)
|
||||
{
|
||||
uint16_t size;
|
||||
off_t blocks;
|
||||
|
||||
size= load_size;
|
||||
if(img->type == 0 && img->load_size_full) {
|
||||
blocks= ((full_byte_size + 2047) / 2048) * 4;
|
||||
if (blocks > 65535) {
|
||||
if (img->platform_id == 0xef)
|
||||
size= 0;
|
||||
else
|
||||
size= 65535;
|
||||
} else if(blocks <= 0) {
|
||||
size= 1;
|
||||
} else {
|
||||
size= blocks;
|
||||
}
|
||||
}
|
||||
iso_lsb(se->sec_count, size, 2);
|
||||
return(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write one section entry.
|
||||
* Usable for the Default Entry
|
||||
|
@ -930,6 +974,8 @@ int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
|||
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||
}
|
||||
|
||||
/* >>> check for non-automatic load size */;
|
||||
|
||||
if (t->boot_intvl_size[idx] > 65535) {
|
||||
if (img->platform_id == 0xef)
|
||||
iso_lsb(se->sec_count, 0, 2);
|
||||
|
@ -946,6 +992,9 @@ int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
|||
iso_lsb(se->block, t->boot_intvl_start[idx], 4);
|
||||
} else if (mode == 2) {
|
||||
app_idx = t->boot_appended_idx[idx];
|
||||
|
||||
/* >>> check for non-automatic load size */;
|
||||
|
||||
if (t->appended_part_size[app_idx] * 4 > 65535) {
|
||||
if (img->platform_id == 0xef)
|
||||
iso_lsb(se->sec_count, 0, 2);
|
||||
|
@ -956,7 +1005,8 @@ int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
|||
}
|
||||
iso_lsb(se->block, t->appended_part_start[app_idx], 4);
|
||||
} else {
|
||||
iso_lsb(se->sec_count, img->load_size, 2);
|
||||
write_section_load_size(img, se, (uint16_t) img->load_size,
|
||||
(off_t) t->bootsrc[idx]->sections[0].size, 0);
|
||||
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4);
|
||||
}
|
||||
|
||||
|
@ -1457,11 +1507,6 @@ int eltorito_writer_create(Ecma119Image *target)
|
|||
target->catalog->bootimages[idx]->appended_start;
|
||||
target->boot_intvl_size[idx] =
|
||||
target->catalog->bootimages[idx]->appended_size;
|
||||
if (((target->system_area_options >> 2) & 0x3f) == 0 &&
|
||||
(target->system_area_options & 3) == 1) {
|
||||
/* ISO will not be a partition. It can span the whole image. */
|
||||
target->pvd_size_is_total_size = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2010 - 2014 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 */
|
||||
|
@ -81,10 +84,18 @@ struct el_torito_boot_image {
|
|||
* bit8= Mention in isohybrid Apple partition map
|
||||
*/
|
||||
unsigned int isolinux_options;
|
||||
unsigned char type; /**< The type of image */
|
||||
|
||||
unsigned char type; /**< The type of image :
|
||||
0=no emulation , 1=fd 1.2 MB , 2=fd 1.4 MB
|
||||
3=fd 3.8 MB , 4=hdd (size in partition table)
|
||||
*/
|
||||
unsigned char partition_type; /**< type of partition for HD-emul images */
|
||||
uint32_t emul_hdd_size; /* 512-bytes LBA after highest partition end from
|
||||
HD-emul partition table
|
||||
*/
|
||||
uint16_t load_seg; /**< Load segment for the initial boot image. */
|
||||
uint16_t load_size; /**< Number of sectors to load. */
|
||||
int load_size_full; /* 1= override load_size by image size */
|
||||
|
||||
/* Byte 1 of Validation Entry or Section Header Entry:
|
||||
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
1564
libisofs/fs_image.c
1564
libisofs/fs_image.c
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2017 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
|
@ -50,7 +50,7 @@ typedef struct
|
|||
/** reference to the parent (if root it points to itself) */
|
||||
IsoFileSource *parent;
|
||||
char *name;
|
||||
unsigned int openned :2; /* 0: not openned, 1: file, 2:dir */
|
||||
unsigned int openned :2; /* 0: not opened, 1: file, 2:dir */
|
||||
union
|
||||
{
|
||||
int fd;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ void lfs_free(IsoFileSource *src)
|
|||
static
|
||||
int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
||||
{
|
||||
int ret;
|
||||
int ret, no_non_user_perm= 0;
|
||||
size_t num_attrs = 0, *value_lengths = NULL, result_len;
|
||||
ssize_t sret;
|
||||
char *path = NULL, **names = NULL, **values = NULL;
|
||||
|
@ -507,7 +507,7 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||
|
||||
*aa_string = NULL;
|
||||
|
||||
if ((flag & 3 ) == 3) {
|
||||
if ((flag & 6 ) == 6) { /* Neither ACL nor xattr shall be read */
|
||||
ret = 1;
|
||||
goto ex;
|
||||
}
|
||||
|
@ -521,7 +521,7 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||
}
|
||||
ret = aaip_get_attr_list(path, &num_attrs, &names,
|
||||
&value_lengths, &values,
|
||||
(!(flag & 2)) | 2 | (flag & 4) | 16);
|
||||
(!(flag & 2)) | 2 | (flag & 4) | (flag & 8) | 16);
|
||||
if (ret <= 0) {
|
||||
if (ret == -2)
|
||||
ret = ISO_AAIP_NO_GET_LOCAL;
|
||||
|
@ -529,6 +529,9 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||
ret = ISO_FILE_ERROR;
|
||||
goto ex;
|
||||
}
|
||||
if(ret == 2)
|
||||
no_non_user_perm= 1;
|
||||
|
||||
if (num_attrs == 0)
|
||||
result = NULL;
|
||||
else {
|
||||
|
@ -540,7 +543,7 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||
}
|
||||
}
|
||||
*aa_string = result;
|
||||
ret = 1;
|
||||
ret = 1 + no_non_user_perm;
|
||||
ex:;
|
||||
if (path != NULL)
|
||||
free(path);
|
||||
|
@ -812,7 +815,7 @@ int iso_local_filesystem_new(IsoFilesystem **fs)
|
|||
}
|
||||
|
||||
/* fill struct */
|
||||
strncpy(lfs->type, "file", 4);
|
||||
memcpy(lfs->type, "file", 4);
|
||||
lfs->refcount = 1;
|
||||
lfs->version = 0;
|
||||
lfs->data = NULL; /* we don't need private data */
|
||||
|
@ -867,17 +870,19 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
|
|||
(flag & (1 | 4 | 8 | 32 | (1 << 15))) | 2 | 16);
|
||||
if (ret <= 0)
|
||||
return ISO_AAIP_NO_GET_LOCAL;
|
||||
return 1;
|
||||
return 1 + (ret == 2);
|
||||
}
|
||||
|
||||
|
||||
int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag)
|
||||
int iso_local_set_attrs_errno(char *disk_path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values,
|
||||
int *errnos, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths,
|
||||
values, (flag & (8 | 32 | 64)) | !(flag & 1));
|
||||
values, errnos,
|
||||
(flag & (8 | 32 | 64 | 128)) | !(flag & 1));
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
@ -895,6 +900,25 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
|
|||
}
|
||||
|
||||
|
||||
int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag)
|
||||
{
|
||||
int ret;
|
||||
int *errnos = NULL;
|
||||
|
||||
if(num_attrs > 0) {
|
||||
errnos= calloc(num_attrs, sizeof(int));
|
||||
if(errnos == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
ret= iso_local_set_attrs_errno(disk_path, num_attrs, names, value_lengths,
|
||||
values, errnos, flag);
|
||||
if(errnos != NULL)
|
||||
free(errnos);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag)
|
||||
{
|
||||
struct stat stbuf;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -28,7 +28,7 @@
|
|||
* Create a new IsoFilesystem to deal with local filesystem.
|
||||
*
|
||||
* @return
|
||||
* 1 sucess, < 0 error
|
||||
* 1 success, < 0 error
|
||||
*/
|
||||
int iso_local_filesystem_new(IsoFilesystem **fs);
|
||||
|
||||
|
@ -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_*/
|
||||
|
|
|
@ -91,7 +91,7 @@ int filesrc_block_and_size(Ecma119Image *t, IsoFileSrc *src,
|
|||
*total_size += src->sections[i].size;
|
||||
if (pos != src->sections[i].block) {
|
||||
iso_msg_submit(t->image->id, ISO_SECT_SCATTERED, 0,
|
||||
"File sections do not form consequtive array of blocks");
|
||||
"File sections do not form consecutive array of blocks");
|
||||
return ISO_SECT_SCATTERED;
|
||||
}
|
||||
/* If .size is not aligned to blocks then there is a byte gap.
|
||||
|
@ -543,11 +543,14 @@ int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||
}
|
||||
|
||||
|
||||
static void set_time (uint32_t *tm, uint32_t t)
|
||||
static inline uint32_t mac_time_offset(uint32_t t)
|
||||
{
|
||||
iso_msb ((uint8_t *) tm, t + 2082844800, 4);
|
||||
uint32_t val;
|
||||
iso_msb ((uint8_t *) &val, t + 2082844800, sizeof(val));
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
int nop_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
{
|
||||
return ISO_SUCCESS;
|
||||
|
@ -615,9 +618,9 @@ write_sb (Ecma119Image *t)
|
|||
/* Cleanly unmounted, software locked. */
|
||||
iso_msb ((uint8_t *) &sb.attributes, (1 << 8) | (1 << 15), 4);
|
||||
iso_msb ((uint8_t *) &sb.last_mounted_version, 0x6c69736f, 4);
|
||||
set_time (&sb.ctime, t->now);
|
||||
set_time (&sb.utime, t->now);
|
||||
set_time (&sb.fsck_time, t->now);
|
||||
sb.ctime = mac_time_offset(t->now);
|
||||
sb.utime = mac_time_offset(t->now);
|
||||
sb.fsck_time = mac_time_offset(t->now);
|
||||
iso_msb ((uint8_t *) &sb.file_count, t->hfsp_nfiles, 4);
|
||||
iso_msb ((uint8_t *) &sb.folder_count, t->hfsp_ndirs - 1, 4);
|
||||
iso_msb ((uint8_t *) &sb.blksize, block_size, 4);
|
||||
|
@ -850,12 +853,11 @@ int hfsplus_writer_write_data(IsoImageWriter *writer)
|
|||
((uint8_t *) &common->type)[1] = t->hfsp_leafs[curnode].type;
|
||||
iso_msb ((uint8_t *) &common->valence, t->hfsp_leafs[curnode].nchildren, 4);
|
||||
iso_msb ((uint8_t *) &common->fileid, t->hfsp_leafs[curnode].cat_id, 4);
|
||||
set_time (&common->ctime, t->hfsp_leafs[curnode].node->ctime);
|
||||
set_time (&common->mtime, t->hfsp_leafs[curnode].node->mtime);
|
||||
common->ctime = mac_time_offset(t->hfsp_leafs[curnode].node->ctime);
|
||||
common->mtime = mac_time_offset(t->hfsp_leafs[curnode].node->mtime);
|
||||
/* FIXME: distinguish attr_mtime and mtime. */
|
||||
set_time (&common->attr_mtime, t->hfsp_leafs[curnode].node->mtime);
|
||||
set_time (&common->atime, t->hfsp_leafs[curnode].node->atime);
|
||||
|
||||
common->attr_mtime = mac_time_offset(t->hfsp_leafs[curnode].node->mtime);
|
||||
common->atime = mac_time_offset(t->hfsp_leafs[curnode].node->atime);
|
||||
iso_msb ((uint8_t *) &common->uid, px_get_uid (t, t->hfsp_leafs[curnode].node), 4);
|
||||
iso_msb ((uint8_t *) &common->gid, px_get_gid (t, t->hfsp_leafs[curnode].node), 4);
|
||||
iso_msb ((uint8_t *) &common->mode, px_get_mode (t, t->hfsp_leafs[curnode].node, (t->hfsp_leafs[curnode].type == HFSPLUS_DIR)), 2);
|
||||
|
@ -1577,6 +1579,14 @@ int mangle_leafs(Ecma119Image *target, int flag)
|
|||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
void iso_setup_hfsplus_block_size(Ecma119Image *target)
|
||||
{
|
||||
if (target->opts->hfsp_block_size == 0)
|
||||
target->opts->hfsp_block_size = HFSPLUS_DEFAULT_BLOCK_SIZE;
|
||||
target->hfsp_cat_node_size = 2 * target->opts->hfsp_block_size;
|
||||
target->hfsp_iso_block_fac = 2048 / target->opts->hfsp_block_size;
|
||||
}
|
||||
|
||||
int hfsplus_writer_create(Ecma119Image *target)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1597,10 +1607,7 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||
make_hfsplus_decompose_pages();
|
||||
make_hfsplus_class_pages();
|
||||
|
||||
if (target->opts->hfsp_block_size == 0)
|
||||
target->opts->hfsp_block_size = HFSPLUS_DEFAULT_BLOCK_SIZE;
|
||||
target->hfsp_cat_node_size = 2 * target->opts->hfsp_block_size;
|
||||
target->hfsp_iso_block_fac = 2048 / target->opts->hfsp_block_size;
|
||||
iso_setup_hfsplus_block_size(target);
|
||||
cat_node_size = target->hfsp_cat_node_size;
|
||||
|
||||
writer->compute_data_blocks = hfsplus_writer_compute_data_blocks;
|
||||
|
@ -1790,9 +1797,9 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||
|
||||
if (target->hfsp_nnodes > (cat_node_size - 0x100) * 8)
|
||||
{
|
||||
iso_msg_submit(target->image->id, ISO_MANGLE_TOO_MUCH_FILES, 0,
|
||||
iso_msg_submit(target->image->id, ISO_HFSPLUS_TOO_MANY_FILES, 0,
|
||||
"HFS+ map nodes aren't implemented");
|
||||
ret = ISO_MANGLE_TOO_MUCH_FILES;
|
||||
ret = ISO_HFSPLUS_TOO_MANY_FILES;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -422,6 +422,10 @@ static uint16_t class_page_data[] = {
|
|||
0x21, 0x230,
|
||||
0x22, 0x230,
|
||||
0x23, 0x230,
|
||||
0x00,
|
||||
|
||||
/* End of list */
|
||||
0x00
|
||||
};
|
||||
|
||||
uint16_t *hfsplus_class_pages[256];
|
||||
|
@ -434,7 +438,7 @@ void make_hfsplus_class_pages()
|
|||
uint16_t *rpt, *page_pt;
|
||||
int page_count = 0;
|
||||
|
||||
memset(class_pages, 0, 19 * 256);
|
||||
memset(class_pages, 0, 19 * 256 * sizeof(uint16_t));
|
||||
for (i = 0; i < 256; i++)
|
||||
hfsplus_class_pages[i] = NULL;
|
||||
|
||||
|
|
108
libisofs/image.c
108
libisofs/image.c
|
@ -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);
|
||||
|
@ -203,6 +215,11 @@ int iso_image_new(const char *name, IsoImage **image)
|
|||
img->hfsplus_blessed[i] = NULL;
|
||||
img->collision_warnings = 0;
|
||||
img->imported_sa_info = NULL;
|
||||
img->blind_on_local_get_attrs = 0;
|
||||
img->do_deeper_tree_inspection = 0;
|
||||
img->tree_loaded = 0;
|
||||
img->rr_loaded = 0;
|
||||
img->tree_compliance = NULL;
|
||||
|
||||
*image = img;
|
||||
return ISO_SUCCESS;
|
||||
|
@ -270,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);
|
||||
}
|
||||
}
|
||||
|
@ -610,6 +629,15 @@ void iso_image_set_ignore_aclea(IsoImage *image, int what)
|
|||
{
|
||||
image->builder_ignore_acl = (what & 1);
|
||||
image->builder_ignore_ea = !!(what & 2);
|
||||
image->builder_take_all_ea = !!(what & 8);
|
||||
}
|
||||
|
||||
|
||||
int iso_image_get_ignore_aclea(IsoImage *image)
|
||||
{
|
||||
return image->builder_ignore_acl |
|
||||
(image->builder_ignore_ea << 1) |
|
||||
(image->builder_take_all_ea << 3);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1128,3 +1156,75 @@ int iso_image_truncate_name(IsoImage *image, const char *name, char **namept,
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_image_was_blind_attrs(IsoImage *image, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (image == NULL)
|
||||
return ISO_NULL_POINTER;
|
||||
ret = image->blind_on_local_get_attrs;
|
||||
if (flag & 1)
|
||||
image->blind_on_local_get_attrs = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @param flag bit0= recursion is active
|
||||
*/
|
||||
static
|
||||
int iso_dir_zisofs_discard_bpt(IsoDir *dir, int flag)
|
||||
{
|
||||
int ret;
|
||||
IsoDirIter *iter = NULL;
|
||||
IsoNode *node;
|
||||
IsoDir *subdir;
|
||||
IsoFile *file;
|
||||
IsoStream *stream;
|
||||
|
||||
ret = iso_dir_get_children(dir, &iter);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
while (iso_dir_iter_next(iter, &node) == 1) {
|
||||
if (iso_node_get_type(node) == LIBISO_DIR) {
|
||||
subdir = (IsoDir *) node;
|
||||
ret = iso_dir_zisofs_discard_bpt(subdir, flag | 1);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
continue;
|
||||
}
|
||||
if (iso_node_get_type(node) != LIBISO_FILE)
|
||||
continue;
|
||||
file = (IsoFile *) node;
|
||||
stream = iso_file_get_stream(file);
|
||||
if (stream == NULL)
|
||||
continue;
|
||||
ret = iso_stream_zisofs_discard_bpt(stream, 0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (iter != NULL)
|
||||
iso_dir_iter_free(iter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_image_zisofs_discard_bpt(IsoImage *image, int flag)
|
||||
{
|
||||
int ret;
|
||||
IsoDir *dir;
|
||||
|
||||
if (image == NULL)
|
||||
return ISO_NULL_POINTER;
|
||||
dir = image->root;
|
||||
if (dir == NULL)
|
||||
return ISO_SUCCESS;
|
||||
ret = iso_dir_zisofs_discard_bpt(dir, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -30,8 +30,8 @@
|
|||
* 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.
|
||||
* (Usefull, for example, in Multiple-Document-Interface GUI apps.
|
||||
* so images are completely independent and can be managed together.
|
||||
* (Useful, for example, in Multiple-Document-Interface GUI apps.
|
||||
* [The stuff we have in init belongs really to image!]
|
||||
*/
|
||||
|
||||
|
@ -145,6 +145,12 @@ struct Iso_Image
|
|||
*/
|
||||
unsigned int builder_ignore_ea : 1;
|
||||
|
||||
/**
|
||||
* If not builder_ignore_ea : import all xattr namespaces from local
|
||||
* filesystem, not only "user.
|
||||
*/
|
||||
unsigned int builder_take_all_ea : 1;
|
||||
|
||||
/**
|
||||
* Files to exclude. Wildcard support is included.
|
||||
*/
|
||||
|
@ -241,6 +247,18 @@ struct Iso_Image
|
|||
/* Contains the assessment of boot aspects of the loaded image */
|
||||
struct iso_imported_sys_area *imported_sa_info;
|
||||
|
||||
/* Whether some local filesystem xattr namespace could not be explored
|
||||
* during node building.
|
||||
*/
|
||||
int blind_on_local_get_attrs;
|
||||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -400,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;
|
||||
|
@ -432,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_*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2011-2014 Thomas Schmitt
|
||||
* Copyright (c) 2011-2018 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
|
@ -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:
|
||||
|
@ -401,6 +423,20 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
|
|||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* From Joliet specs:
|
||||
* "ISO 9660 (Section 7.5.1) states that the sum of the following shall not
|
||||
* exceed 30:
|
||||
* - If there is a file name, the length of the file name.
|
||||
* - If there is a file name extension, the length of the file name extension.
|
||||
* On Joliet compliant media, however, the sum as calculated above shall not
|
||||
* exceed 128 [bytes], to allow for longer file identifiers."
|
||||
*
|
||||
* I.e. the dot does not count.
|
||||
*
|
||||
* (We have an option to lift the limit from 64*2 to 103*2, which is the
|
||||
* maximum to fit into an ISO 9660 directory record.)
|
||||
*/
|
||||
static
|
||||
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
{
|
||||
|
@ -455,7 +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 */
|
||||
|
@ -481,25 +517,26 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||
ext = dot + 1;
|
||||
|
||||
extlen = ucslen(ext);
|
||||
max = maxchar + 1 - extlen - 1 - digits;
|
||||
max = maxchar - extlen - digits;
|
||||
if (max <= 0) {
|
||||
/* this can happen if extension is too long */
|
||||
if (extlen + max > 3) {
|
||||
/*
|
||||
* This can happen if the extension is too long.
|
||||
* Reduce its length, to give name at least one
|
||||
* original character, if it has any.
|
||||
*/
|
||||
max = (dot > full_name);
|
||||
extlen = maxchar - max - digits;
|
||||
if (extlen < 3) {
|
||||
/*
|
||||
* reduce extension len, to give name an extra char
|
||||
* note that max is negative or 0
|
||||
*/
|
||||
extlen = extlen + max - 1;
|
||||
ext[extlen] = 0;
|
||||
max = maxchar + 2 - extlen - 1 - digits;
|
||||
} else {
|
||||
/*
|
||||
* error, we don't support extensions < 3
|
||||
* This can't happen with current limit of digits.
|
||||
* error, we do not reduce extensions to length < 3
|
||||
*
|
||||
* This cannot happen with current limit of digits
|
||||
* because maxchar is at least 64 and digits at most 7.
|
||||
*/
|
||||
ret = ISO_ERROR;
|
||||
goto mangle_cleanup;
|
||||
}
|
||||
ext[extlen] = 0;
|
||||
}
|
||||
/* ok, reduce name by digits */
|
||||
if (name + max < dot) {
|
||||
|
@ -508,10 +545,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||
} else {
|
||||
/* Directory, or file without extension */
|
||||
if (children[i]->type == JOLIET_DIR) {
|
||||
max = maxchar + 1 - digits;
|
||||
max = maxchar - digits;
|
||||
dot = NULL; /* dots have no meaning in dirs */
|
||||
} else {
|
||||
max = maxchar + 1 - digits;
|
||||
max = maxchar - digits;
|
||||
}
|
||||
name = full_name;
|
||||
if ((size_t) max < ucslen(name)) {
|
||||
|
@ -1093,7 +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;
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
|
||||
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
|
||||
Message handling facility of libisofs.
|
||||
Copyright (C) 2006-2008 Thomas Schmitt <scdbackup@gmx.net>,
|
||||
provided under GPL version 2 or later
|
||||
Copyright (C) 2006-2016 Thomas Schmitt <scdbackup@gmx.net>,
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
@ -266,8 +271,9 @@ int libiso_msgs_new(struct libiso_msgs **m, int flag);
|
|||
|
||||
/** Destroy a message handling facility and all its eventual messages.
|
||||
The submitted pointer gets set to NULL.
|
||||
Actually only the last destroy call of all offical references to the object
|
||||
will really dispose it. All others just decrement the reference counter.
|
||||
Actually only the last destroy call of all official references to the
|
||||
object will really dispose it. All others just decrement the reference
|
||||
counter.
|
||||
Call this function only with official reference pointers obtained by
|
||||
libiso_msgs_new() or libiso_msgs_refer(), and only once per such pointer.
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||
|
@ -421,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
|
||||
|
@ -553,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
|
||||
|
@ -608,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
|
@ -5,6 +5,7 @@ aaip_xinfo_func;
|
|||
el_torito_get_bootable;
|
||||
el_torito_get_boot_media_type;
|
||||
el_torito_get_boot_platform_id;
|
||||
el_torito_get_full_load;
|
||||
el_torito_get_id_string;
|
||||
el_torito_get_isolinux_options;
|
||||
el_torito_get_load_seg;
|
||||
|
@ -13,12 +14,14 @@ el_torito_get_selection_crit;
|
|||
el_torito_patch_isolinux_image;
|
||||
el_torito_seems_boot_info_table;
|
||||
el_torito_set_boot_platform_id;
|
||||
el_torito_set_full_load;
|
||||
el_torito_set_id_string;
|
||||
el_torito_set_isolinux_options;
|
||||
el_torito_set_load_seg;
|
||||
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;
|
||||
|
@ -68,6 +71,7 @@ iso_filesystem_ref;
|
|||
iso_filesystem_unref;
|
||||
iso_finish;
|
||||
iso_fs_global_id;
|
||||
iso_generate_gpt_guid;
|
||||
iso_get_local_charset;
|
||||
iso_get_messenger;
|
||||
iso_gzip_get_refcounts;
|
||||
|
@ -81,6 +85,7 @@ iso_image_add_new_special;
|
|||
iso_image_add_new_symlink;
|
||||
iso_image_attach_data;
|
||||
iso_image_create_burn_source;
|
||||
iso_image_dir_get_node;
|
||||
iso_image_filesystem_new;
|
||||
iso_image_fs_get_abstract_file_id;
|
||||
iso_image_fs_get_application_id;
|
||||
|
@ -103,8 +108,8 @@ iso_image_get_bootcat;
|
|||
iso_image_get_boot_image;
|
||||
iso_image_get_copyright_file_id;
|
||||
iso_image_get_data_preparer_id;
|
||||
iso_image_dir_get_node;
|
||||
iso_image_get_hppa_palo;
|
||||
iso_image_get_ignore_aclea;
|
||||
iso_image_get_mips_boot_files;
|
||||
iso_image_get_msg_id;
|
||||
iso_image_get_publisher_id;
|
||||
|
@ -149,6 +154,8 @@ iso_image_set_volume_id;
|
|||
iso_image_tree_clone;
|
||||
iso_image_unref;
|
||||
iso_image_update_sizes;
|
||||
iso_image_was_blind_attrs;
|
||||
iso_image_zisofs_discard_bpt;
|
||||
iso_init;
|
||||
iso_init_with_flag;
|
||||
iso_interval_reader_destroy;
|
||||
|
@ -162,6 +169,7 @@ iso_local_get_attrs;
|
|||
iso_local_get_perms_wo_acl;
|
||||
iso_local_set_acl_text;
|
||||
iso_local_set_attrs;
|
||||
iso_local_set_attrs_errno;
|
||||
iso_md5_clone;
|
||||
iso_md5_compute;
|
||||
iso_md5_end;
|
||||
|
@ -220,13 +228,18 @@ iso_node_unref;
|
|||
iso_node_xinfo_get_cloner;
|
||||
iso_node_xinfo_make_clonable;
|
||||
iso_node_zf_by_magic;
|
||||
iso_nowtime;
|
||||
iso_obtain_msgs;
|
||||
iso_read_image_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;
|
||||
|
@ -237,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;
|
||||
|
@ -259,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;
|
||||
|
@ -320,17 +336,21 @@ iso_write_opts_set_disc_label;
|
|||
iso_write_opts_set_efi_bootp;
|
||||
iso_write_opts_set_fat;
|
||||
iso_write_opts_set_fifo_size;
|
||||
iso_write_opts_set_gpt_guid;
|
||||
iso_write_opts_set_hardlinks;
|
||||
iso_write_opts_set_hfsp_block_size;
|
||||
iso_write_opts_set_hfsp_serial_number;
|
||||
iso_write_opts_set_hfsplus;
|
||||
iso_write_opts_set_iso1999;
|
||||
iso_write_opts_set_iso_level;
|
||||
iso_write_opts_set_iso_mbr_part_type;
|
||||
iso_write_opts_set_iso_type_guid;
|
||||
iso_write_opts_set_joliet;
|
||||
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;
|
||||
|
@ -339,6 +359,7 @@ iso_write_opts_set_output_charset;
|
|||
iso_write_opts_set_overwrite_buf;
|
||||
iso_write_opts_set_part_offset;
|
||||
iso_write_opts_set_part_like_isohybrid;
|
||||
iso_write_opts_set_part_type_guid;
|
||||
iso_write_opts_set_partition_img;
|
||||
iso_write_opts_set_prep_img;
|
||||
iso_write_opts_set_pvd_times;
|
||||
|
@ -356,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;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2008 - 2015 Thomas Schmitt
|
||||
* with special credits to H. Peter Anvin for isohybrid
|
||||
* and to Matthew Garrett for isohybrid with GPT and APM
|
||||
* Copyright (c) 2002 - 2008 H. Peter Anvin
|
||||
* 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
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
|
@ -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;
|
||||
|
@ -604,22 +612,45 @@ static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
|
|||
}
|
||||
|
||||
|
||||
/* For generating a weak random number */
|
||||
static uint32_t iso_make_mbr_id(Ecma119Image *t, int flag)
|
||||
{
|
||||
uint32_t id;
|
||||
struct timeval tv;
|
||||
|
||||
if(t->opts->vol_uuid[0]) {
|
||||
id = iso_crc32_gpt((unsigned char *) t->opts->vol_uuid, 16, 0);
|
||||
} else if(t->opts->vol_modification_time > 0) {
|
||||
id = iso_crc32_gpt((unsigned char *) &(t->opts->vol_modification_time),
|
||||
sizeof(time_t), 0);
|
||||
} else {
|
||||
gettimeofday(&tv, NULL);
|
||||
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @param flag bit0= make own random MBR Id from current time
|
||||
* or from overridden modification time
|
||||
* bit1= create protective MBR as of UEFI/GPT specs
|
||||
* 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;
|
||||
/* For generating a weak random number */
|
||||
struct timeval tv;
|
||||
|
||||
if (t->bootsrc[0] == NULL)
|
||||
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||
|
@ -644,40 +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) {
|
||||
gettimeofday(&tv, NULL);
|
||||
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
||||
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
|
||||
*/
|
||||
|
@ -685,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);
|
||||
|
@ -696,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;
|
||||
}
|
||||
|
@ -711,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);
|
||||
|
@ -725,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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* 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
|
||||
|
@ -157,10 +157,10 @@ int iso_init_with_flag(int flag)
|
|||
#ifdef Libisofs_with_libjtE
|
||||
|
||||
/* Ugly compile time check for header version compatibility.
|
||||
If everthing matches, then it produces no C code. In case of mismatch,
|
||||
If everything matches, then it produces no C code. In case of mismatch,
|
||||
intentionally faulty C code will be inserted.
|
||||
*/
|
||||
/* The indendation is an advise of man gcc to help old compilers ignoring */
|
||||
/* 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:
|
||||
|
@ -543,6 +545,34 @@ const char *iso_error_to_msg(int errcode)
|
|||
return "A general note message was issued";
|
||||
case ISO_BAD_FSRC_FILETYPE:
|
||||
return "Unrecognized file type of IsoFileSrc object";
|
||||
case ISO_GPT_NO_VOL_UUID:
|
||||
return "Cannot derive GPT GUID from undefined pseudo-UUID volume timestamp";
|
||||
case ISO_BAD_GPT_GUID_MODE:
|
||||
return "Unrecognized GPT disk GUID setup mode";
|
||||
case ISO_NO_ROOT_DIR:
|
||||
return "Unable to obtain root directory";
|
||||
case ISO_SUSP_WRONG_CE_SIZE:
|
||||
return "Zero sized, oversized, or mislocated SUSP CE area found";
|
||||
case ISO_MULTI_OVER_IMPORTED:
|
||||
return "Multi-session would overwrite imported_iso interval";
|
||||
case ISO_ELTO_EFI_HIDDEN:
|
||||
return "El-Torito EFI image is hidden";
|
||||
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";
|
||||
}
|
||||
|
|
115
libisofs/node.c
115
libisofs/node.c
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* 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
|
||||
|
@ -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)
|
||||
|
@ -1114,7 +1114,7 @@ int iso_symlink_set_dest(IsoSymlink *link, const char *dest)
|
|||
* or regular files, this function has no effect.
|
||||
* @param w
|
||||
* The weight as a integer number, the greater this value is, the
|
||||
* closer from the begining of image the file will be written.
|
||||
* closer from the beginning of image the file will be written.
|
||||
*/
|
||||
void iso_node_set_sort_weight(IsoNode *node, int w)
|
||||
{
|
||||
|
@ -1365,7 +1365,11 @@ int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos,
|
|||
/* old file is newer */
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
}
|
||||
/* fall down */
|
||||
if ((node->mode & S_IFMT) != ((*pos)->mode & S_IFMT)) {
|
||||
/* different file types */
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
}
|
||||
break;
|
||||
case ISO_REPLACE_IF_SAME_TYPE:
|
||||
if ((node->mode & S_IFMT) != ((*pos)->mode & S_IFMT)) {
|
||||
/* different file types */
|
||||
|
@ -1456,6 +1460,7 @@ void iso_notify_dir_iters(IsoNode *node, int flag)
|
|||
int iso_node_new_root(IsoDir **root)
|
||||
{
|
||||
IsoDir *dir;
|
||||
time_t now;
|
||||
|
||||
dir = calloc(1, sizeof(IsoDir));
|
||||
if (dir == NULL) {
|
||||
|
@ -1463,7 +1468,8 @@ int iso_node_new_root(IsoDir **root)
|
|||
}
|
||||
dir->node.refcount = 1;
|
||||
dir->node.type = LIBISO_DIR;
|
||||
dir->node.atime = dir->node.ctime = dir->node.mtime = time(NULL);
|
||||
iso_nowtime(&now, 0);
|
||||
dir->node.atime = dir->node.ctime = dir->node.mtime = now;
|
||||
dir->node.mode = S_IFDIR | 0555;
|
||||
|
||||
/* set parent to itself, to prevent root to be added to another dir */
|
||||
|
@ -1818,12 +1824,13 @@ int attr_enlarge_list(char ***names, size_t **value_lengths, char ***values,
|
|||
|
||||
/* Merge attribute list of node and given new attribute list into
|
||||
attribute list returned by m_* parameters.
|
||||
The m_* paramters have finally to be freed by a call with bit15 set.
|
||||
The m_* parameters have finally to be freed by a call with bit15 set.
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= delete all old names which begin by "user."
|
||||
(but not if bit2 is set)
|
||||
bit2= delete the given names rather than overwrite
|
||||
their content
|
||||
bit3= with bit0: delete all old non-"isofs." names
|
||||
bit4= do not overwrite value of empty name
|
||||
bit5= do not overwrite isofs attributes
|
||||
bit15= release memory and return 1
|
||||
|
@ -1849,9 +1856,11 @@ int iso_node_merge_xattr(IsoNode *node, size_t num_attrs, char **names,
|
|||
return ret;
|
||||
|
||||
if ((flag & 1) && (!(flag & 4))) {
|
||||
/* Delete unmatched user space pairs */
|
||||
/* Delete unmatched settable pairs */
|
||||
for (j = 0; j < *m_num_attrs; j++) {
|
||||
if (strncmp((*m_names)[j], "user.", 5) != 0)
|
||||
if (strncmp((*m_names)[j], "isofs.", 6) == 0)
|
||||
continue;
|
||||
if (strncmp((*m_names)[j], "user.", 5) != 0 && !(flag & 8))
|
||||
continue;
|
||||
for (i = 0; i < num_attrs; i++) {
|
||||
if (names[i] == NULL || (*m_names)[j] == NULL)
|
||||
|
@ -1980,7 +1989,7 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
|
|||
node, num_attrs, names, value_lengths, values,
|
||||
&m_num, &m_names, &m_value_lengths, &m_values,
|
||||
(flag & 4) | (!(flag & 2)) | ((!(flag & 1)) << 4) |
|
||||
((flag & 16) << 1));
|
||||
((flag & 16) << 1) | (flag & 8));
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
num_attrs = m_num;
|
||||
|
@ -2037,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)
|
||||
|
@ -2252,12 +2308,14 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
|||
goto ex;
|
||||
}
|
||||
ret = aaip_encode_both_acl(a_text, d_text, st_mode,
|
||||
&acl_len, &acl, 2 | 8);
|
||||
&acl_len, &acl,
|
||||
2 | 8 | ((flag & 4) << 2));
|
||||
} else {
|
||||
ret = 1;
|
||||
if (access_text != NULL || default_text != NULL)
|
||||
ret = aaip_encode_both_acl(access_text, default_text, st_mode,
|
||||
&acl_len, &acl, 2 | 8);
|
||||
&acl_len, &acl,
|
||||
2 | 8 | ((flag & 4) << 2));
|
||||
}
|
||||
if (ret == -1)
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
|
@ -2316,7 +2374,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
|||
goto ex;
|
||||
}
|
||||
ret = aaip_encode_both_acl(access_text, default_text,
|
||||
st_mode, &acl_len, &acl, 2 | 8);
|
||||
st_mode, &acl_len, &acl,
|
||||
2 | 8 | ((flag & 4) << 2));
|
||||
if (ret < -3)
|
||||
goto ex;
|
||||
if (ret <= 0) {
|
||||
|
@ -2428,22 +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) {
|
||||
|
@ -2460,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;
|
||||
|
@ -2474,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;
|
||||
|
@ -2491,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;
|
||||
|
||||
|
@ -2512,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);
|
||||
|
@ -2734,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)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 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];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -487,7 +494,7 @@ int iso_node_cmp_flag(IsoNode *n1, IsoNode *n2, int flag);
|
|||
|
||||
|
||||
/**
|
||||
* Set the checksum index (typically comming from IsoFileSrc.checksum_index)
|
||||
* Set the checksum index (typically coming from IsoFileSrc.checksum_index)
|
||||
* of a regular file node. The index is encoded as xattr "isofs.cx" with
|
||||
* four bytes of value.
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
@ -254,7 +257,7 @@ typedef struct susp_iterator SuspIterator;
|
|||
|
||||
SuspIterator *
|
||||
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
|
||||
uint8_t len_skp, int msgid);
|
||||
uint32_t fs_blocks, uint8_t len_skp, int msgid);
|
||||
|
||||
/**
|
||||
* Get the next SUSP System User Entry using given iterator.
|
||||
|
@ -266,7 +269,8 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
|
|||
* @return
|
||||
* 1 on success, 0 if no more entries, < 0 error
|
||||
*/
|
||||
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue);
|
||||
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
|
||||
int flag);
|
||||
|
||||
/**
|
||||
* Free a given susp iterator.
|
||||
|
@ -358,7 +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.
|
||||
|
|
|
@ -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
|
||||
|
@ -35,6 +35,12 @@ struct susp_iterator
|
|||
IsoDataSource *src;
|
||||
int msgid;
|
||||
|
||||
/* 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;
|
||||
|
@ -47,7 +53,7 @@ struct susp_iterator
|
|||
|
||||
SuspIterator*
|
||||
susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
|
||||
uint8_t len_skp, int msgid)
|
||||
uint32_t fs_blocks, uint8_t len_skp, int msgid)
|
||||
{
|
||||
int pad = (record->len_fi[0] + 1) % 2;
|
||||
struct susp_iterator *iter = malloc(sizeof(struct susp_iterator));
|
||||
|
@ -60,19 +66,48 @@ susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record,
|
|||
iter->size = record->len_dr[0] - record->len_fi[0] - 33 - pad;
|
||||
iter->src = src;
|
||||
iter->msgid = msgid;
|
||||
iter->fs_blocks = fs_blocks;
|
||||
|
||||
iter->ce_counter = 0;
|
||||
iter->ce_len = 0;
|
||||
iter->ce_block = 0;
|
||||
iter->ce_off = 0;
|
||||
iter->buffer = NULL;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
|
||||
/* More than 1 MiB in a single file's CE area is suspicious */
|
||||
#define ISO_SUSP_MAX_CE_BYTES (1024 * 1024)
|
||||
|
||||
/* 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
|
||||
*/
|
||||
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue,
|
||||
int flag)
|
||||
{
|
||||
struct susp_sys_user_entry *entry;
|
||||
|
||||
process_entry:;
|
||||
entry = (struct susp_sys_user_entry*)(iter->base + iter->pos);
|
||||
|
||||
if (flag & 1) {
|
||||
/* Yet unclear whether it is SUSP at all */
|
||||
if (iter->size < 7)
|
||||
return 0;
|
||||
if (!SUSP_SIG(entry, 'S', 'P'))
|
||||
return 0;
|
||||
if (entry->len_sue[0] < 7)
|
||||
return 0;
|
||||
/* Looks like SUSP enough to pass the further processing here. */
|
||||
|
||||
/* In case of CE hop do not run this check again */
|
||||
flag &= ~1;
|
||||
}
|
||||
if ( (iter->pos + 4 > iter->size) || (SUSP_SIG(entry, 'S', 'T'))) {
|
||||
|
||||
/*
|
||||
|
@ -81,22 +116,31 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
|
|||
* (IEEE 1281, SUSP. section 4)
|
||||
*/
|
||||
if (iter->ce_len) {
|
||||
uint32_t block, nblocks;
|
||||
uint32_t block, nblocks, skipped_blocks, skipped_bytes;
|
||||
|
||||
/* A CE has found, there is another continuation area */
|
||||
nblocks = DIV_UP(iter->ce_off + iter->ce_len, BLOCK_SIZE);
|
||||
/* A CE was found, there is another continuation area */
|
||||
skipped_blocks = iter->ce_off / BLOCK_SIZE;
|
||||
skipped_bytes = skipped_blocks * BLOCK_SIZE;
|
||||
nblocks = DIV_UP(iter->ce_off - skipped_bytes + iter->ce_len,
|
||||
BLOCK_SIZE);
|
||||
if (nblocks <= 0 || iter->ce_len > ISO_SUSP_MAX_CE_BYTES)
|
||||
return ISO_SUSP_WRONG_CE_SIZE;
|
||||
if (((uint64_t) iter->ce_block) + skipped_blocks + nblocks >
|
||||
(uint64_t) iter->fs_blocks)
|
||||
return ISO_SUSP_WRONG_CE_SIZE;
|
||||
iter->buffer = realloc(iter->buffer, nblocks * BLOCK_SIZE);
|
||||
|
||||
/* read all blocks needed to cache the full CE */
|
||||
/* Read blocks needed to cache the given CE area range */
|
||||
for (block = 0; block < nblocks; ++block) {
|
||||
int ret;
|
||||
ret = iter->src->read_block(iter->src, iter->ce_block + block,
|
||||
iter->buffer + block * BLOCK_SIZE);
|
||||
ret = iter->src->read_block(iter->src,
|
||||
iter->ce_block + skipped_blocks + block,
|
||||
iter->buffer + block * BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
iter->base = iter->buffer + iter->ce_off;
|
||||
iter->base = iter->buffer + (iter->ce_off - skipped_bytes);
|
||||
iter->pos = 0;
|
||||
iter->size = iter->ce_len;
|
||||
iter->ce_len = 0;
|
||||
|
@ -120,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;
|
||||
|
@ -134,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);
|
||||
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);
|
||||
goto process_entry;
|
||||
}
|
||||
|
||||
*sue = entry;
|
||||
|
@ -374,12 +423,18 @@ int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont)
|
|||
if (*cont == 1) {
|
||||
/* new component */
|
||||
size_t size = strlen(*dest);
|
||||
int has_slash;
|
||||
|
||||
*dest = realloc(*dest, strlen(*dest) + len + 2);
|
||||
if (*dest == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
/* it is a new compoenent, add the '/' */
|
||||
if ((*dest)[size-1] != '/') {
|
||||
has_slash = 0;
|
||||
if (size > 0)
|
||||
if ((*dest)[size - 1] == '/')
|
||||
has_slash = 1;
|
||||
if (!has_slash) {
|
||||
(*dest)[size] = '/';
|
||||
(*dest)[size+1] = '\0';
|
||||
}
|
||||
|
@ -462,24 +517,27 @@ int read_aaip_AA(struct susp_sys_user_entry *sue,
|
|||
if (*is_done) {
|
||||
|
||||
/* To coexist with Apple ISO :
|
||||
Gracefully react on eventually trailing Apple AA
|
||||
Gracefully react on possibly trailing Apple AA
|
||||
*/
|
||||
if (sue->version[0] != 1 || sue->len_sue[0] == 7)
|
||||
return ISO_SUCCESS;
|
||||
|
||||
return ISO_WRONG_RR;
|
||||
}
|
||||
|
||||
|
||||
/* Eventually create or grow storage */
|
||||
if (*aa_size == 0 || *aa_string == NULL) {
|
||||
|
||||
/* Gracefully react on eventually leading Apple AA
|
||||
/* Gracefully react on possibly leading Apple AA
|
||||
*/
|
||||
if (sue->version[0] != 1 || sue->len_sue[0] < 9) {
|
||||
if (sue->version[0] != 1 || sue->len_sue[0] < 9)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* A valid AAIP AA entry has 5 header bytes and at least 1 component byte
|
||||
*/
|
||||
if (sue->len_sue[0] < 6)
|
||||
return ISO_WRONG_RR;
|
||||
|
||||
/* Possibly create or grow storage */
|
||||
if (*aa_size == 0 || *aa_string == NULL) {
|
||||
*aa_size = *aa_len + sue->len_sue[0];
|
||||
*aa_string = calloc(*aa_size, 1);
|
||||
*aa_len = 0;
|
||||
|
@ -535,7 +593,12 @@ int read_aaip_AL(struct susp_sys_user_entry *sue,
|
|||
if (sue->version[0] != 1)
|
||||
return ISO_WRONG_RR;
|
||||
|
||||
/* Eventually create or grow storage */
|
||||
/* A valid AL entry has 5 header bytes and at least 1 component byte
|
||||
*/
|
||||
if (sue->len_sue[0] < 6)
|
||||
return ISO_WRONG_RR;
|
||||
|
||||
/* Possibly create or grow storage */
|
||||
if (*aa_size == 0 || *aa_string == NULL) {
|
||||
*aa_size = *aa_len + sue->len_sue[0];
|
||||
*aa_string = calloc(*aa_size, 1);
|
||||
|
@ -572,29 +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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2016 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
|
@ -37,11 +37,11 @@ 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
|
||||
* 1 sucess, < 0 error
|
||||
* 1 success, < 0 error
|
||||
* Possible errors:
|
||||
*
|
||||
*/
|
||||
|
@ -52,7 +52,7 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream);
|
|||
* The stream will add a ref. to the IsoFileSource.
|
||||
*
|
||||
* @return
|
||||
* 1 sucess, < 0 error
|
||||
* 1 success, < 0 error
|
||||
*/
|
||||
int iso_cut_out_stream_new(IsoFileSource *src, off_t offset, off_t size,
|
||||
IsoStream **stream);
|
||||
|
@ -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.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2008 Vreixo Formoso
|
||||
* Copyright (c) 2012 - 2015 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[].
|
||||
|
@ -155,6 +163,18 @@ struct iso_apm_partition_request {
|
|||
*/
|
||||
uint8_t name[32];
|
||||
uint8_t type[32];
|
||||
|
||||
/* Status of the request object itself:
|
||||
bit0= this is an automatically placed filler partition
|
||||
*/
|
||||
uint32_t req_status;
|
||||
|
||||
/* 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[].
|
||||
|
@ -182,10 +202,15 @@ int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
|
|||
run on other machines with the same process number at the same time.
|
||||
*/
|
||||
|
||||
/* Produces a weakly random variation of a hardcoded real random uuid
|
||||
/* Produces a GPT disk or partition GUID.
|
||||
Pseudo-random by iso_generate_gpt_guid() if t->gpt_uuid_counter is 0.
|
||||
Else derived reproducibly by counter number from t->gpt_uuid_base.
|
||||
*/
|
||||
void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]);
|
||||
void iso_gpt_uuid(Ecma119Image *t, uint8_t uuid[16]);
|
||||
|
||||
/* Mark a given byte string as UUID version 4, RFC 4122.
|
||||
*/
|
||||
void iso_mark_guid_version_4(uint8_t *u);
|
||||
|
||||
/* The parameter struct for production of a single GPT entry.
|
||||
See also the partial GPT description in doc/boot_sectors.txt.
|
||||
|
@ -234,6 +259,26 @@ struct iso_gpt_partition_request {
|
|||
/* Only if read from imported image: Table index of partition (first = 1)
|
||||
*/
|
||||
uint32_t idx;
|
||||
|
||||
/* Status of the request object itself:
|
||||
bit0= this is an automatically placed filler partition
|
||||
*/
|
||||
uint32_t req_status;
|
||||
|
||||
/* 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[].
|
||||
|
@ -253,6 +298,11 @@ int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array,
|
|||
uint8_t type_guid[16], uint8_t partition_guid[16],
|
||||
uint64_t flags, uint8_t name[72]);
|
||||
|
||||
/* Deletes the partition requests for gap filling in GPT and APM.
|
||||
Purpose is to get the request list clean again after a multi-session
|
||||
emulation superblock was created and handed to the application.
|
||||
*/
|
||||
void iso_delete_gpt_apm_fillers(Ecma119Image *target, int flag);
|
||||
|
||||
/* Internal helper that will be used by system_area.c and make_isohybrid_mbr.c
|
||||
*/
|
||||
|
@ -312,9 +362,13 @@ void iso_ascii_utf_16le(uint8_t gap_name[72]);
|
|||
#define Libisofs_grub2_sparc_patch_size_poS 0x230
|
||||
|
||||
|
||||
/* >>> It is unclear whether there is a use case for appended partitions
|
||||
inside the ISO filesystem range.
|
||||
# define Libisofs_appended_partitions_inlinE yes
|
||||
/* Put appended partitions into the writer range
|
||||
*/
|
||||
#define Libisofs_appended_partitions_inlinE yes
|
||||
#ifdef Libisofs_appended_partitions_inlinE
|
||||
/* For padding after appended partitions (and also after backup GPT)
|
||||
*/
|
||||
#define Libisofs_part_align_writeR yes
|
||||
#endif
|
||||
|
||||
#endif /* SYSTEM_AREA_H_ */
|
||||
|
|
|
@ -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
|
||||
|
@ -87,7 +88,7 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir)
|
|||
iso_node_set_hidden((IsoNode*)node, parent->node.hidden);
|
||||
|
||||
/* current time */
|
||||
now = time(NULL);
|
||||
iso_nowtime(&now, 0);
|
||||
iso_node_set_atime((IsoNode*)node, now);
|
||||
iso_node_set_ctime((IsoNode*)node, now);
|
||||
iso_node_set_mtime((IsoNode*)node, now);
|
||||
|
@ -127,7 +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
|
||||
|
@ -175,7 +176,7 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
|
|||
iso_node_set_hidden((IsoNode*)node, parent->node.hidden);
|
||||
|
||||
/* current time */
|
||||
now = time(NULL);
|
||||
iso_nowtime(&now, 0);
|
||||
iso_node_set_atime((IsoNode*)node, now);
|
||||
iso_node_set_ctime((IsoNode*)node, now);
|
||||
iso_node_set_mtime((IsoNode*)node, now);
|
||||
|
@ -206,7 +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
|
||||
|
@ -278,7 +279,7 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode,
|
|||
iso_node_set_hidden((IsoNode*)node, parent->node.hidden);
|
||||
|
||||
/* current time */
|
||||
now = time(NULL);
|
||||
iso_nowtime(&now, 0);
|
||||
iso_node_set_atime((IsoNode*)node, now);
|
||||
iso_node_set_ctime((IsoNode*)node, now);
|
||||
iso_node_set_mtime((IsoNode*)node, now);
|
||||
|
@ -319,7 +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
|
||||
|
@ -367,7 +368,7 @@ int iso_tree_add_new_file(IsoDir *parent, const char *name, IsoStream *stream,
|
|||
iso_node_set_hidden((IsoNode*)node, parent->node.hidden);
|
||||
|
||||
/* current time */
|
||||
now = time(NULL);
|
||||
iso_nowtime(&now, 0);
|
||||
iso_node_set_atime((IsoNode*)node, now);
|
||||
iso_node_set_ctime((IsoNode*)node, now);
|
||||
iso_node_set_mtime((IsoNode*)node, now);
|
||||
|
@ -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;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* 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
|
||||
|
@ -18,7 +18,6 @@
|
|||
#include "messages.h"
|
||||
#include "joliet.h"
|
||||
#include "node.h"
|
||||
#include "../version.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
@ -804,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, '?')
|
||||
|
@ -1484,6 +1483,14 @@ void iso_lsb(uint8_t *buf, uint32_t num, int bytes)
|
|||
buf[i] = (num >> (8 * i)) & 0xff;
|
||||
}
|
||||
|
||||
void iso_lsb64(uint8_t *buf, uint64_t num)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; ++i)
|
||||
buf[i] = (num >> (8 * i)) & 0xff;
|
||||
}
|
||||
|
||||
void iso_msb(uint8_t *buf, uint32_t num, int bytes)
|
||||
{
|
||||
int i;
|
||||
|
@ -1598,6 +1605,22 @@ void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
|
|||
gmtime_r(&t, &tm);
|
||||
tzoffset = 0;
|
||||
}
|
||||
|
||||
if (tm.tm_year < 0) {
|
||||
tm.tm_year = 0;
|
||||
tm.tm_mon = 0;
|
||||
tm.tm_mday = 1;
|
||||
tm.tm_hour = 0;
|
||||
tm.tm_min = 0;
|
||||
tm.tm_sec = 0;
|
||||
} else if (tm.tm_year > 255) {
|
||||
tm.tm_year = 255;
|
||||
tm.tm_mon = 11;
|
||||
tm.tm_mday = 31;
|
||||
tm.tm_hour = 23;
|
||||
tm.tm_min = 59;
|
||||
tm.tm_sec = 59;
|
||||
}
|
||||
buf[0] = tm.tm_year;
|
||||
buf[1] = tm.tm_mon + 1;
|
||||
buf[2] = tm.tm_mday;
|
||||
|
@ -1651,12 +1674,18 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
|
|||
tzoffset = 0;
|
||||
}
|
||||
|
||||
sprintf((char*)&buf[0], "%04d", tm.tm_year + 1900);
|
||||
sprintf((char*)&buf[4], "%02d", tm.tm_mon + 1);
|
||||
sprintf((char*)&buf[6], "%02d", tm.tm_mday);
|
||||
sprintf((char*)&buf[8], "%02d", tm.tm_hour);
|
||||
sprintf((char*)&buf[10], "%02d", tm.tm_min);
|
||||
sprintf((char*)&buf[12], "%02d", MIN(59, tm.tm_sec));
|
||||
if (tm.tm_year <= -1900) {
|
||||
strcpy((char *) buf, "00010101000000");
|
||||
} else if (tm.tm_year >= 8100) {
|
||||
strcpy((char *) buf, "99991231235959");
|
||||
} else {
|
||||
sprintf((char*)&buf[0], "%04d", tm.tm_year + 1900);
|
||||
sprintf((char*)&buf[4], "%02d", tm.tm_mon + 1);
|
||||
sprintf((char*)&buf[6], "%02d", tm.tm_mday);
|
||||
sprintf((char*)&buf[8], "%02d", tm.tm_hour);
|
||||
sprintf((char*)&buf[10], "%02d", tm.tm_min);
|
||||
sprintf((char*)&buf[12], "%02d", MIN(59, tm.tm_sec));
|
||||
}
|
||||
memcpy(&buf[14], "00", 2);
|
||||
buf[16] = tzoffset;
|
||||
|
||||
|
@ -1823,7 +1852,7 @@ time_t iso_datetime_read_17(const uint8_t *buf)
|
|||
tm.tm_mon -= 1;
|
||||
tm.tm_isdst = 0;
|
||||
|
||||
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
|
||||
return timegm(&tm) - ((int8_t)buf[16]) * 60 * 15;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1943,7 +1972,7 @@ char *ucs2str(const char *buf, size_t len)
|
|||
|
||||
outbytes = (inbytes+1) * MB_LEN_MAX;
|
||||
|
||||
/* ensure enought space */
|
||||
/* ensure enough space */
|
||||
out = calloc(outbytes, 1);
|
||||
if (out == NULL)
|
||||
return NULL;
|
||||
|
@ -1978,16 +2007,25 @@ ex:;
|
|||
|
||||
void iso_lib_version(int *major, int *minor, int *micro)
|
||||
{
|
||||
|
||||
*major = iso_lib_header_version_major;
|
||||
*minor = iso_lib_header_version_minor;
|
||||
*micro = iso_lib_header_version_micro;
|
||||
|
||||
/* No more: values from version.h generated from version.h.in and
|
||||
macro values defined in configure.ac
|
||||
|
||||
*major = LIBISOFS_MAJOR_VERSION;
|
||||
*minor = LIBISOFS_MINOR_VERSION;
|
||||
*micro = LIBISOFS_MICRO_VERSION;
|
||||
*/
|
||||
}
|
||||
|
||||
int iso_lib_is_compatible(int major, int minor, int micro)
|
||||
{
|
||||
int cmajor, cminor, cmicro;
|
||||
|
||||
/* for now, the rule is that library is compitable if requested
|
||||
/* for now, the rule is that library is compatible if requested
|
||||
* version is lower */
|
||||
iso_lib_version(&cmajor, &cminor, &cmicro);
|
||||
|
||||
|
@ -2324,7 +2362,7 @@ int iso_clone_mgtd_mem(char *in, char **out, size_t size)
|
|||
(Also accepts capital letters.)
|
||||
@param text Input like "42", "223062s", "3m" or "-1g"
|
||||
@param flag Bitfield for control purposes:
|
||||
bit0= return -1 rathern than 0 on failure
|
||||
bit0= return -1 rather than 0 on failure
|
||||
bit1= if scaled then compute the last byte of the last unit
|
||||
@return The derived value
|
||||
*/
|
||||
|
@ -2448,3 +2486,27 @@ int iso_truncate_leaf_name(int mode, int length, char *name, int flag)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* API */
|
||||
/* @param flag bit0= *now contains the time to be set as nowtime override
|
||||
bit1= disable the nowtime override
|
||||
@return 1= *now is not overridden , 2= *now is overridden
|
||||
*/
|
||||
int iso_nowtime(time_t *now, int flag)
|
||||
{
|
||||
static int now_time_overridden = 0;
|
||||
static time_t now_time_override = 0;
|
||||
|
||||
if (flag & 1) {
|
||||
now_time_overridden = 1;
|
||||
now_time_override = *now;
|
||||
}
|
||||
if (flag & 2) {
|
||||
now_time_overridden = 0;
|
||||
}
|
||||
*now = time(NULL);
|
||||
if (!now_time_overridden)
|
||||
return 1;
|
||||
*now = now_time_override;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -29,13 +29,13 @@ struct Iso_Image_Writer
|
|||
};
|
||||
|
||||
/**
|
||||
* This is the function all Writers shoudl call to write data to image.
|
||||
* This is the function all Writers should call to write data to image.
|
||||
* Currently, it is just a wrapper for write(2) Unix system call.
|
||||
*
|
||||
* It is implemented in ecma119.c
|
||||
*
|
||||
* @return
|
||||
* 1 on sucess, < 0 error
|
||||
* 1 on success, < 0 error
|
||||
*/
|
||||
int iso_write(Ecma119Image *target, void *buf, size_t count);
|
||||
|
||||
|
|
Loading…
Reference in New Issue