Compare commits

...

34 Commits

Author SHA1 Message Date
Thomas Schmitt 405f0f04d4 Improved size estimation and property assessment of El Torito hidden boot images 2023-11-20 11:42:41 +01:00
Thomas Schmitt 8a8439768c Clarified in the description of iso_image_set_boot_image() the meaning of pseudo-path parameters "start" and "size" 2023-11-20 09:15:18 +01:00
Thomas Schmitt 9ec998f9fc Updated copyright year in README 2023-06-09 19:57:42 +02:00
Thomas Schmitt 8a4f1f88ae Explicitely included unistd.h in all source file which use ssize_t 2023-06-09 19:54:50 +02:00
Thomas Schmitt 09ec2fa4b7 Bug fix: On non-GNU/Linux systems ssize_t was not defined in rockridge.h . Report and fix proposal by Rui Chen. 2023-06-09 19:48:54 +02:00
Thomas Schmitt 5a867c43ab Version leap to 1.5.7 2023-06-07 19:10:34 +02:00
Thomas Schmitt 170318c42e Updated change log 2023-06-07 13:32:06 +02:00
Thomas Schmitt c2d17b1c4b Version leap to 1.5.6 2023-06-07 13:28:22 +02:00
Thomas Schmitt cdc7f52187 Reduced number of warnings about special files or symlinks in Joliet 2023-04-14 17:47:07 +02:00
Thomas Schmitt bd415402f4 New API call iso_write_opts_set_max_ce_entries() 2023-01-22 16:03:44 +01:00
Thomas Schmitt 7109ba5675 Prevented endless CE loops when reading a very bad ISO fileystem 2023-01-11 12:06:28 +01:00
Thomas Schmitt d35435b5a0 Bug fix: Size of further CE area was calculated wrong if its CE entry ended exactly at a block boundary 2022-12-13 09:53:27 +01:00
Thomas Schmitt acb4bd143c Bug fix: Freshly cloned data files from imported image were not marked as
imported
2022-10-27 17:37:58 +02:00
Thomas Schmitt 71772baab7 Fixed assessment of omit_version_numbers and no_force_dots 2022-10-07 11:14:51 +02:00
Thomas Schmitt 83e5832ed0 New API calls iso_assess_written_features(), iso_read_image_feature_named(), iso_read_image_features_text() 2022-09-20 09:51:39 +02:00
Thomas Schmitt 9b7ccc9727 Improved error messages in case of failing Linux-specific ACL or xattr functions 2022-09-20 09:28:06 +02:00
Thomas Schmitt c6cb7dfa3e Widened the lseek capacity determination to SEEK_SET with wanted size 2022-05-30 18:38:54 +02:00
Thomas Schmitt ad55ec78e4 Avoided automatic MBR partition type 0x00 with iso_write_opts_set_part_like_isohybrid() if partitions do not overlap 2022-05-13 10:52:39 +02:00
Thomas Schmitt 011e2e85e6 Allowed lseekable device files with iso_tree_add_new_cut_out_node(). Proof-of-concept by Ivan Shmakov. 2022-04-26 12:12:15 +02:00
Thomas Schmitt f457a4f8b9 Added missing stream type names to a diagnostic function 2022-04-26 12:06:18 +02:00
Thomas Schmitt 2af17490a0 Bug fix: The lseek methods of IsoFileSource for local filesystem and loaded ISO returned libisofs error codes as positive off_t numbers 2022-04-26 12:03:53 +02:00
Thomas Schmitt da00291519 Let the original isohybrid GPT obey system_area() option bit 17: GPT writable 2022-04-23 09:32:44 +02:00
Thomas Schmitt 1d61b518b5 Bug fix: iso_write_opts_set_part_like_isohybrid() did not cause a MBR partition table if the partitions are data files in the ISO rather than appended 2022-04-23 09:30:34 +02:00
Thomas Schmitt 99251ade08 Avoid to overwrite the loaded MBR partition table just because partition offset is 16 2022-04-23 09:17:08 +02:00
Thomas Schmitt da8e3e66e7 Exempted MBR partitions of type 0xEE from being ignored due to wrong size 2022-04-22 13:39:56 +02:00
Thomas Schmitt 3e61a61a21 Updated URLs, build instructions, and copyright in README file 2021-10-28 19:44:26 +02:00
Thomas Schmitt 80a0691660 Removed unneeded configure.ac macro AC_C_BIGENDIAN 2021-09-02 20:04:16 +02:00
Thomas Schmitt 1c4c04d4e2 New iso_write_opts_set_system_area() option bits 16: GPT "Legacy BIOS bootable" and 17: GPT writable 2021-05-25 21:10:28 +02:00
Thomas Schmitt 75499bcda9 Silenced a warning on 32 bit about value ISO_ZISOFS_V1_LIMIT too large for int 2021-03-12 09:37:07 +01:00
Thomas Schmitt 9e389186f7 Leave prediction of first CE gap to susp_*_to_ce() functions 2021-02-28 17:21:35 +01:00
Thomas Schmitt 7d248c46e1 Ignore mad MBR partitions which extend outside of medium size 2021-02-28 16:16:18 +01:00
Thomas Schmitt 98aea0c18a Heuristic fix for a new problem introduced by commit 058f18d 2021-02-03 13:31:25 +01:00
Thomas Schmitt 058f18d37a Bug fix: Large amounts of AAIP data or many long file names could cause with zisofs an unreadable filesystem after the warning "Calculated and written ECMA-119 tree end differ" 2021-02-01 18:46:34 +01:00
Thomas Schmitt 5add62bda0 Version leap to 1.5.5 2021-01-30 20:44:47 +01:00
29 changed files with 2370 additions and 364 deletions

View File

@ -1,5 +1,37 @@
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

19
README
View File

@ -5,7 +5,7 @@
Released under GNU General Public License version 2 or later.
See COPYING file for details.
Copyright (C) 2008 - 2018 Vreixo Formoso,
Copyright (C) 2008 - 2023 Vreixo Formoso,
Mario Danic,
Vladimir Serbinenko,
Thomas Schmitt
@ -15,25 +15,24 @@ libisofs is part of the libburnia project (libburnia-project.org)
Download, Build and Installation
libisofs code is maintained in a Bazaar repository at Launchpad
(https://launchpad.net/libisofs/). You can download it with:
libisofs code is maintained in a git repository at dev.lovelyhq.com
(https://dev.lovelyhq.com/libburnia/libisofs). You can download it with:
$ bzr branch lp:libisofs/for-libisoburn
$ git clone https://dev.lovelyhq.com/libburnia/libisofs.git
Our build system is based on autotools. For preparing the build you will need
autotools of at least version 1.7. If you have download the code from the
autotools of at least version 1.7. If you have downloaded the code from the
repository, first of all you need to execute
./autogen.sh
./bootstrap
on toplevel dir to execute autotools.
in the toplevel directory ./libisofs, in order to execute autotools.
Alternatively you may unpack a release tarball for which you do not need
autotools installed. For the most recent release of libisofs see:
http://libburnia-project.org/wiki/Releases
https://dev.lovelyhq.com/libburnia/web/wiki/Releases
To build libisofs it should be sufficient to go into its toplevel directory
and execute
To build libisofs go into its toplevel directory and execute
./configure --prefix=/usr
make

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.5.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])
@ -41,7 +41,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=5
LIBISOFS_MICRO_VERSION=4
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
dnl 2021.01.30 development jump has not yet happened
dnl SONAME = 97 - 91 = 6 . Library name = libisofs.6.91.0
LT_CURRENT=97
LT_AGE=91
dnl 2023.05.07 development jump has not yet happened
dnl SONAME = 98 - 92 = 6 . Library name = libisofs.6.92.0
LT_CURRENT=98
LT_AGE=92
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -73,7 +73,6 @@ dnl AM_MAINTAINER_MODE
AM_PROG_CC_C_O
AC_C_CONST
AC_C_INLINE
AC_C_BIGENDIAN
dnl Large file support
AC_SYS_LARGEFILE

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2019 Thomas Schmitt
* Copyright (c) 2009 - 2023 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -41,6 +41,7 @@
#include <locale.h>
#include <langinfo.h>
#include <stdio.h>
#include <unistd.h>
#ifdef Xorriso_standalonE
@ -205,17 +206,24 @@ size_t calc_dirent_len(Ecma119Image *t, Ecma119Node *n)
* taking into account the continuation areas.
*/
static
size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
ssize_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
{
size_t i, len;
ssize_t ret;
size_t ce_len = 0;
/* size of "." and ".." entries */
len = 34 + 34;
if (t->opts->rockridge) {
len += rrip_calc_len(t, dir, 1, 34, &ce_len, *ce);
ret = rrip_calc_len(t, dir, 1, 34, &ce_len, *ce);
if (ret < 0)
return ret;
len += ret;
*ce += ce_len;
len += rrip_calc_len(t, dir, 2, 34, &ce_len, *ce);
ret = rrip_calc_len(t, dir, 2, 34, &ce_len, *ce);
if (ret < 0)
return ret;
len += ret;
*ce += ce_len;
}
@ -228,8 +236,10 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
for (section = 0; section < nsections; ++section) {
size_t dirent_len = calc_dirent_len(t, child);
if (t->opts->rockridge) {
dirent_len += rrip_calc_len(t, child, 0, dirent_len, &ce_len,
*ce);
ret = rrip_calc_len(t, child, 0, dirent_len, &ce_len, *ce);
if (ret < 0)
return ret;
dirent_len += ret;
*ce += ce_len;
}
remaining = BLOCK_SIZE - (len % BLOCK_SIZE);
@ -255,14 +265,18 @@ size_t calc_dir_size(Ecma119Image *t, Ecma119Node *dir, size_t *ce)
}
static
void calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
int calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
{
size_t i, len;
ssize_t ret;
size_t ce_len = 0;
t->ndirs++;
dir->info.dir->block = t->curblock;
len = calc_dir_size(t, dir, &ce_len);
ret = calc_dir_size(t, dir, &ce_len);
if (ret < 0)
return (int) ret;
len = ret;
t->curblock += DIV_UP(len, BLOCK_SIZE);
if (t->opts->rockridge) {
t->curblock += DIV_UP(ce_len, BLOCK_SIZE);
@ -270,9 +284,12 @@ void calc_dir_pos(Ecma119Image *t, Ecma119Node *dir)
for (i = 0; i < dir->info.dir->nchildren; i++) {
Ecma119Node *child = dir->info.dir->children[i];
if (child->type == ECMA119_DIR) {
calc_dir_pos(t, child);
ret = calc_dir_pos(t, child);
if (ret < 0)
return (int) ret;
}
}
return ISO_SUCCESS;
}
/**
@ -305,6 +322,7 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
Ecma119Image *target;
uint32_t path_table_size;
size_t ndirs;
int ret;
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
@ -315,7 +333,9 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
/* compute position of directories */
iso_msg_debug(target->image->id, "Computing position of dir structure");
target->ndirs = 0;
calc_dir_pos(target, target->root);
ret = calc_dir_pos(target, target->root);
if (ret < 0)
return ret;
/* compute length of pathlist */
iso_msg_debug(target->image->id, "Computing length of pathlist");
@ -338,7 +358,9 @@ int ecma119_writer_compute_data_blocks(IsoImageWriter *writer)
/* Take into respect the second directory tree */
ndirs = target->ndirs;
target->ndirs = 0;
calc_dir_pos(target, target->partition_root);
ret = calc_dir_pos(target, target->partition_root);
if (ret < 0)
return ret;
if (target->ndirs != ndirs) {
iso_msg_submit(target->image->id, ISO_ASSERT_FAILURE, 0,
"Number of directories differs in ECMA-119 partiton_tree");
@ -2737,7 +2759,11 @@ 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;
/* If partitions get appended, then the backup GPT cannot be part of
the ISO filesystem.
@ -3267,6 +3293,16 @@ 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);
}
*img = target;
return ISO_SUCCESS;
@ -3611,6 +3647,8 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->hfsp_block_size = 0;
memset(wopts->gpt_disk_guid, 0, 16);
wopts->gpt_disk_guid_mode = 0;
wopts->max_ce_entries = 31; /* Linux hates >= RR_MAX_CE_ENTRIES = 32 */
wopts->max_ce_drop_attr = 2; /* If needed drop non-isofs fattr and ACL */
*opts = wopts;
return ISO_SUCCESS;
@ -4207,7 +4245,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;
}
@ -4403,6 +4441,17 @@ int iso_write_opts_set_gpt_guid(IsoWriteOpts *opts, uint8_t guid[16], int mode)
return ISO_SUCCESS;
}
int iso_write_opts_set_max_ce_entries(IsoWriteOpts *opts, uint32_t num,
int flag)
{
if (num > 100000)
return ISO_TOO_MANY_CE;
if (num == 0)
num = 1;
opts->max_ce_entries = num;
opts->max_ce_drop_attr = flag & 15;
return ISO_SUCCESS;
}
/*
* @param flag

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2019 Thomas Schmitt
* Copyright (c) 2009 - 2023 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -543,6 +543,17 @@ struct iso_write_opts {
*/
uint8_t gpt_disk_guid[16];
int gpt_disk_guid_mode;
/* Maximum number of CE entries per file */
uint32_t max_ce_entries;
/* Whether to try dropping AAIP data on too many CE:
bit0-3 = Mode:
0 = throw ISO_TOO_MANY_CE, without trying to drop anything
1 = drop non-isofs fattr
2 = drop ACL if dropping non-isofs fattr does not suffice
*/
int max_ce_drop_attr;
};
typedef struct ecma119_image Ecma119Image;
@ -913,6 +924,15 @@ 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;
};
#define BP(a,b) [(b) - (a) + 1]

View File

@ -46,7 +46,9 @@
/* The lowest size of a file which shall not be represented by zisofs v1 */
#define ISO_ZISOFS_V1_LIMIT 4294967296
/* The constant 4294967296 causes protests about int size on 32 bit machines */
#define ISO_ZISOFS_V1_LIMIT ((off_t) (1 << 16) * (off_t) (1 << 16))
/* zisofs2: Test value for small mixed-version ISOs: 1 million
ISO_ZISOFS_V1_LIMIT 1000000

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2016 Thomas Schmitt
* Copyright (c) 2009 - 2022 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -49,4 +49,14 @@ int iso_ifs_source_clone(IsoFileSource *old_source, IsoFileSource **new_source,
int flag);
off_t iso_file_source_lseek_capacity(IsoFileSource *src, off_t wanted_size,
int flag);
/* Determine whether src is random-access readable and return its capacity.
*/
off_t iso_file_source_determine_capacity(IsoFileSource *src, off_t wanted_size,
int flag);
#endif /*LIBISO_FSOURCE_H_*/

View File

@ -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
@ -204,6 +204,10 @@ int iso_image_new(const char *name, IsoImage **image)
img->collision_warnings = 0;
img->imported_sa_info = NULL;
img->blind_on_local_get_attrs = 0;
img->do_deeper_tree_inspection = 0;
img->tree_loaded = 0;
img->rr_loaded = 0;
img->tree_compliance = NULL;
*image = img;
return ISO_SUCCESS;
@ -271,6 +275,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);
}
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2017 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
@ -252,6 +252,13 @@ struct Iso_Image
*/
int blind_on_local_get_attrs;
/* Deeper tree inspection when reading an IsoImage assesses traces of the
used write options.
*/
int do_deeper_tree_inspection;
int tree_loaded; /* 0=ISO 9660/ECMA-119 1=Joliet 2=ISO 9660:1999 */
int rr_loaded; /* 0=plain ISO 9660/ECMA-119 1=Rock Ridge */
IsoWriteOpts *tree_compliance;
};
@ -443,5 +450,9 @@ int iso_imported_sa_new(struct iso_imported_sys_area **sa_info, int flag);
int iso_imported_sa_unref(struct iso_imported_sys_area **sa_info, int flag);
void iso_image_assess_ecma119_name(IsoImage *image, struct stat *info,
char *path, char *name);
void iso_image_assess_joliet_name(IsoImage *image, struct stat *info,
char *path, char *name);
#endif /*LIBISO_IMAGE_H_*/

View File

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

View File

@ -4,7 +4,7 @@
/*
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
* Copyright (c) 2009-2021 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
@ -14,6 +14,8 @@
/* Important: If you add a public API function then add its name to file
libisofs/libisofs.ver
in the node LIBISOFS6_Major.Minor.Micro with the numbers of
the next release version.
*/
#ifdef __cplusplus
@ -94,7 +96,7 @@ extern "C" {
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 5
#define iso_lib_header_version_micro 4
#define iso_lib_header_version_micro 7
/**
* Get version of the libisofs library at runtime.
@ -249,7 +251,7 @@ enum IsoNodeType {
#define ISO_NODE(n) ((IsoNode*)n)
/**
* File section in an old image.
* File section in an imported or emerging image.
*
* @since 0.6.8
*/
@ -374,7 +376,7 @@ enum iso_replace_mode {
};
/**
* Options for image written.
* Options for image writing.
* @see iso_write_opts_new()
* @since 0.6.2
*/
@ -2277,9 +2279,19 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size);
* Is normally combined with options bit0.
* Will not be in effect if options bit1 is set.
* bit15= Only with System area type MBR but not with CHRP
* @since 1.4.4
* Enforce MBR "bootable/active" flag. In worst case by dummy
* partition of type 0x00 which occupies block 0.
* @since 1.4.4
* bit16= "Legacy BIOS bootable" in GPT
* @since 1.5.6
* If this bit is set and a GPT partition for the ISO 9660
* filesystem gets written, then set the GPT partition flags bit 2
* "Legacy BIOS bootable".
* bit17= ISO not read-only
* @since 1.5.6
* Do not set GPT partition flag bit 60 "read-only" for the
* ISO 9660 filesystem partition, if such a partition gets
* written.
* @param flag
* bit0 = invalidate any attached system area data. Same as data == NULL
* (This re-activates eventually loaded image System Area data.
@ -2674,6 +2686,39 @@ int iso_write_opts_set_efi_bootp(IsoWriteOpts *opts, char *image_path,
int iso_write_opts_set_gpt_guid(IsoWriteOpts *opts, uint8_t guid[16],
int mode);
/**
* Set the maximum number of SUSP CE entries and thus continuation areas.
* Each continuation area can hold at most 2048 bytes of SUSP data (Rock Ridge
* or AAIP). The first area can be smaller. There might be some waste at the
* end of each area.
* When the maximum number is exceeded during ISO filesystem production
* then possibly xattr and ACL get removed or error ISO_TOO_MANY_CE gets
* reported and filesystem production is prevented.
*
* Files with 32 or more CE entries do not show up in mounted filesystems on
* Linux. So the default setting is 31 with drop mode 2. If a higher limit is
* chosen and 31 gets surpassed, then a warning message gets reported.
*
* @param opts
* The option set to be manipulated.
* @param num
* The maximum number of CE entries per file.
* Not more than 100000 may be set here.
* 0 gets silently mapped to 1, because the root directory needs one CE.
* @param flag
* bit0-bit3 = Drop mode: What to do with AAIP data on too many CE:
* 0 = throw ISO_TOO_MANY_CE, without dropping anything
* 1 = permanently drop non-isofs fattr from IsoNode and
* retry filesystem production
* 2 = drop ACL if dropping non-isofs fattr does not suffice
* @return
* ISO_SUCCESS or ISO_TOO_MANY_CE
*
* @since 1.5.6
*/
int iso_write_opts_set_max_ce_entries(IsoWriteOpts *opts, uint32_t num,
int flag);
/**
* Generate a pseudo-random GUID suitable for iso_write_opts_set_gpt_guid().
*
@ -3235,7 +3280,40 @@ int iso_image_import(IsoImage *image, IsoDataSource *src, IsoReadOpts *opts,
IsoReadImageFeatures **features);
/**
* Destroy an IsoReadImageFeatures object obtained with iso_image_import.
* Assess features of the importable directory trees of src and an estimation
* of the write options which would cause the recognized features.
* This goes deeper than the feature assessment of iso_image_import(), e.g. by
* inspecting file names.
*
* For the parameters "src", "opts", and "features" see also the description of
* iso_image_import().
*
* @param src
* Data Source from which old image will be read.
* @param opts
* Options for image import. Settings about tree choice will be ignored.
* @param features
* Returns the pointer to a newly allocated and filled IsoReadImageFeatures
* object. NULL is not allowed, other than with iso_image_import().
* If *features is returned as non-NULL, then it should be freed with
* iso_read_image_features_destroy() when no more needed.
* @param write_opts
* Returns the pointer to a newly allocated and filled IsoWriteOpts object.
* If *write_opts is returned as non-NULL, then it should be freed with
* iso_write_opts_free() when no more needed.
*
* @return
* 1 on success, < 0 on error
*
* @since 1.5.6
*/
int iso_assess_written_features(IsoDataSource *src, IsoReadOpts *opts,
IsoReadImageFeatures **features,
IsoWriteOpts **write_opts);
/**
* Destroy an IsoReadImageFeatures object obtained with iso_image_import() or
* iso_assess_written_features().
*
* @since 0.6.2
*/
@ -3293,6 +3371,99 @@ int iso_read_image_features_tree_loaded(IsoReadImageFeatures *f);
*/
int iso_read_image_features_rr_loaded(IsoReadImageFeatures *f);
/**
* Get a named feature as text, num_value, or pt_value depending on its type.
* The set of named features includes the features which can be inquired by
* own iso_read_image_features_*() functions:
* size See iso_read_image_features_get_size()
* rockridge See iso_read_image_features_has_rockridge()
* iso_write_opts_set_rockridge()
* joliet See iso_read_image_features_has_joliet()
* iso_write_opts_set_joliet()
* iso1999 See iso_read_image_features_has_iso1999()
* iso_write_opts_set_iso1999()
* eltorito See iso_read_image_features_has_eltorito()
* tree_loaded See iso_read_image_features_tree_loaded()
* rr_loaded See iso_read_image_features_rr_loaded()
* Other named features are:
* tree_loaded_text Text form of "tree_loaded":
* 0="ISO9660", 1="Joliet", 2="ISO9660:1999"
* aaip 1=AAIP information was seen, 0= no AAIP seen
* Detected traces of potential write option settings:
* iso_level See iso_write_opts_set_iso_level()
* untranslated_name_len See iso_write_opts_set_untranslated_name_len()
* allow_dir_id_ext See iso_write_opts_set_allow_dir_id_ext()
* omit_version_numbers See iso_write_opts_set_omit_version_numbers()
* allow_deep_paths See iso_write_opts_set_allow_deep_paths()
* allow_longer_paths See iso_write_opts_set_allow_longer_paths()
* max_37_char_filenames See iso_write_opts_set_max_37_char_filenames()
* no_force_dots See iso_write_opts_set_no_force_dots()
* allow_lowercase See iso_write_opts_set_allow_lowercase()
* allow_full_ascii See iso_write_opts_set_allow_full_ascii()
* relaxed_vol_atts See iso_write_opts_set_relaxed_vol_atts()
* joliet_longer_paths See iso_write_opts_set_joliet_longer_paths()
* joliet_long_names See iso_write_opts_set_joliet_long_names()
* joliet_utf16 See iso_write_opts_set_joliet_utf16()
* rrip_version_1_10 See iso_write_opts_set_rrip_version_1_10()
* rrip_1_10_px_ino See iso_write_opts_set_rrip_1_10_px_ino()
* aaip_susp_1_10 See iso_write_opts_set_aaip_susp_1_10()
* record_md5_session See iso_write_opts_set_record_md5() param session
* record_md5_files See iso_write_opts_set_record_md5() param files
*
* @param f
* A features object returned by iso_image_import() or
* iso_assess_written_features().
* @param name
* The name of the feature to be inquired.
* @param text
* If text is not NULL, *text returns a textual representation of the
* reply. Dispose *text by free(2) when no longer needed.
* @param type
* Returns which of num_value or pt_value is valid:
* 0= *num_value is valid
* 1= *pt_value is valid
* @param num_value
* Returns the numerical value of the feature if type == 0.
* @param pt_value
* Returns a pointer to a memory area inside the features object if type
* is 1. The area is not necessarily 0-terminated.
* Do _not_ dispose *pt_value and do not use it after f was disposed.
* @param pt_size
* Returns the size of the pt_value memory area if type is 1.
* This counting includes a terminating 0-byte if it is present.
* @return
* 0 = Feature was not yet examined. Reply is not valid.
* 1 = Reply is valid
* ISO_UNDEF_READ_FEATURE = Given name is not known
* <0 = other error
*
* @since 1.5.6
*/
int iso_read_image_feature_named(IsoReadImageFeatures *f, char *name,
char **text, int *type,
int64_t *num_value, void **pt_value,
size_t *pt_size);
/**
* Get all validly assessed named features as one single 0-terminated string
* consisting of single lines for each feature.
*
* @param f
* A features object returned by iso_image_import() or
* iso_assess_written_features().
* @param with_values
* If set to 1: return lines of form name=value\n
* If set to 0: return lines of form name\n
* @param feature_text
* Returns the result string. Dispose by free(2) when no longer needed.
* @return
* 1 = result is valid, <0 indicates error
*
* @since 1.5.6
*/
int iso_read_image_features_text(IsoReadImageFeatures *f, int with_values,
char **feature_text);
/**
* Increments the reference counting of the given image.
*
@ -3652,9 +3823,13 @@ int iso_image_get_pvd_times(IsoImage *image,
* The absolute path of a IsoFile to be used as default boot image or
* --interval:appended_partition_$number[_start_$start_size_$size]:...
* if type is ELTORITO_NO_EMUL. $number gives the partition number.
* If _start_$start_size_$size is present, then it overrides the 2 KiB
* start block of the partition and the partition size counted in
* blocks of 512 bytes.
* If no partitition with the given $number was set by functions like
* iso_write_opts_set_partition_img() and if the optional image_path part
* "_start_$start_size_$size" is present, then $start gets read as 2 KiB
* start block of the interval and $size as number of blocks of 512 bytes.
* If this range of block addresses is below the address set by
* iso_write_opts_set_ms_block(), then that range gets marked as boot
* image. I.e. an old appended partition can be marked as boot image.
* @param type
* The boot media type. This can be one of 3 types:
* - ELTORITO_FLOPPY_EMUL.
@ -6339,8 +6514,9 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
* according to iso_image_set_truncate_mode().
* Its directory path depends on the parent node.
* @param path
* The absolute path of the file in the local filesystem. For now
* only regular files and symlinks to regular files are supported.
* The absolute path of the random-access capable file in the local
* filesystem. Only regular files and device files are supported.
* On Linux, only regular files and block device offer random-access.
* @param offset
* Byte number in the given file from where to start reading data.
* @param size
@ -6358,8 +6534,11 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists
* ISO_OUT_OF_MEM
* ISO_RR_NAME_TOO_LONG
* ISO_WRONG_ARG_VALUE, if path is not suitable for random access
*
* @since 0.6.4
*
* Device files as path: @since 1.5.6
*/
int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
const char *name, const char *path,
@ -8940,9 +9119,13 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
/** Error with reading ACL or xattr from local file (FAILURE, HIGH, -341) */
#define ISO_AAIP_NO_GET_LOCAL 0xE830FEAB
/** Error with reading ACL or xattr from local file (SORRY, HIGH, -341) */
#define ISO_AAIP_NO_GET_LOCAL_S 0xE030FEAB
/** Error with attaching ACL or xattr to local file (FAILURE, HIGH, -342) */
#define ISO_AAIP_NO_SET_LOCAL 0xE830FEAA
/** Error with attaching ACL or xattr to local file (SORRY, HIGH, -342) */
#define ISO_AAIP_NO_SET_LOCAL_S 0xE030FEAA
/** Unallowed attempt to set an xattr with non-userspace name
(FAILURE, HIGH, -343) */
@ -9254,6 +9437,20 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
/** Cannot obtain size of zisofs compressed stream (FAILURE, HIGH, -425) */
#define ISO_ZISOFS_UNKNOWN_SIZE 0xE830FE57
/** Undefined IsoReadImageFeatures name (SORRY, HIGH, -426) */
#define ISO_UNDEF_READ_FEATURE 0xE030FE56
/** Too many CE entries for single file (FAILURE,HIGH, -427) */
#define ISO_TOO_MANY_CE 0xE830FE55
/** Too many CE entries for single file when mounted by Linux
(WARNING,HIGH, -428) */
#define ISO_TOO_MANY_CE_FOR_LINUX 0xD030FE54
/** Too many CE entries for single file, omitting attributes
(WARNING,HIGH, -429) */
#define ISO_CE_REMOVING_ATTR 0xD030FE53
/* Internal developer note:
Place new error codes directly above this comment.

View File

@ -21,6 +21,7 @@ el_torito_set_load_seg;
el_torito_set_load_size;
el_torito_set_no_bootable;
el_torito_set_selection_crit;
iso_assess_written_features;
iso_conv_name_chars;
iso_crc32_gpt;
iso_data_source_new_from_file;
@ -229,6 +230,7 @@ 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;
@ -236,6 +238,7 @@ 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;
@ -347,6 +350,7 @@ iso_write_opts_set_joliet_long_names;
iso_write_opts_set_joliet_longer_paths;
iso_write_opts_set_joliet_utf16;
iso_write_opts_set_max_37_char_filenames;
iso_write_opts_set_max_ce_entries;
iso_write_opts_set_ms_block;
iso_write_opts_set_no_force_dots;
iso_write_opts_set_old_empty;

View File

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

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2016 Thomas Schmitt
* Copyright (c) 2009 - 2023 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -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";
@ -563,6 +565,14 @@ const char *iso_error_to_msg(int errcode)
return "Prevented zisofs block pointer counter underrun";
case ISO_ZISOFS_UNKNOWN_SIZE:
return "Cannot obtain size of zisofs compressed stream";
case ISO_UNDEF_READ_FEATURE:
return "Undefined IsoReadImageFeatures name";
case ISO_TOO_MANY_CE:
return "Too many CE entries for single file";
case ISO_TOO_MANY_CE_FOR_LINUX:
return "Too many CE entries for single file when mounted by Linux";
case ISO_CE_REMOVING_ATTR:
return "Too many CE entries for single file, removing attributes";
default:
return "Unknown error";
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2020 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
@ -2046,13 +2046,60 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
}
ret = 1;
ex:;
/* Dispose eventual merged list */
/* Dispose merged list if it was created */
iso_node_merge_xattr(node, num_attrs, names, value_lengths, values,
&m_num, &m_names, &m_value_lengths, &m_values, 1 << 15);
/* Dispose ACL if saved */
iso_node_get_acl_text(node, &a_acl, &d_acl, 1 << 15);
return ret;
}
/* @param flag
bit0= delete ACL, too
*/
int iso_node_remove_fattr(IsoNode *node, int flag)
{
int ret;
size_t num_attrs, *value_lengths = NULL, i, w;
char **names = NULL, **values = NULL;
ret = iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,
flag & 1);
if (ret < 0)
goto ex;
/* Delete variables of all namespaces except isofs */
w = 0;
for (i = 0; i < num_attrs; i++) {
if (strncmp(names[i], "isofs.", 6) != 0) {
free(names[i]);
names[i] = NULL;
free(values[i]);
values[i] = NULL;
continue;
}
if (w != i) {
/* move i to w , nullify i */
names[w] = names[i];
names[i] = NULL;
values[w] = values[i];
values[i] = NULL;
value_lengths[w] = value_lengths[i];
}
w++;
}
num_attrs = w;
ret = iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
(flag & 1) | 8);
ex:;
if (names != NULL)
iso_node_get_attrs(NULL, &num_attrs, &names, &value_lengths, &values,
1 << 15);
return ret;
}
static
int iso_decode_acl(unsigned char *v_data, size_t v_len, size_t *consumed,
char **text, size_t *text_fill, int flag)

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2020 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
@ -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

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2020 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;
@ -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,27 +933,6 @@ 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 ..."
@ -1099,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;
}
@ -1160,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,
@ -1171,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);
@ -1209,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 */
@ -1230,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) {
@ -1301,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 {
/*
@ -1310,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 {
@ -1341,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);
}
}
@ -1401,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;
}
}
@ -1410,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;
}
@ -1456,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.
@ -1472,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);
@ -1491,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)
@ -1540,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 {
@ -1558,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;
@ -1580,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)
@ -1796,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) {
@ -1989,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) {
@ -2118,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)
@ -2196,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' &&
@ -2206,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;

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2020 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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2010 - 2019 Thomas Schmitt
* Copyright (c) 2010 - 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
@ -1737,6 +1737,7 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
uint32_t p_arr_crc = 0;
uint64_t start_lba, end_lba, goal, part_end, next_end, backup_end_lba;
uint64_t eff_gpt_flags;
int ret, i, gap_counter = 0, up_to;
struct iso_gpt_partition_request *req;
uint8_t gpt_name[72];
@ -1791,11 +1792,16 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
} else if (part_end < goal) {
memset(gpt_name, 0, 72);
type_guid = basic_data_uuid;
eff_gpt_flags= gpt_flags;
if (goal == t->vol_space_size * (uint64_t) 4 &&
part_end == t->opts->partition_offset * (uint64_t) 4) {
sprintf((char *) gpt_name, "ISO9660");
if (t->opts->iso_gpt_flag & 1)
type_guid = t->opts->iso_gpt_type_guid;
if (t->system_area_options & (1 << 16))
eff_gpt_flags|= 4; /* Legacy BIOS bootable */
if (t->system_area_options & (1 << 17))
eff_gpt_flags&= ~(((uint64_t) 1) << 60);/* Not read-only */
} else {
sprintf((char *) gpt_name, "Gap%d", gap_counter);
}
@ -1804,7 +1810,7 @@ static int iso_write_gpt(Ecma119Image *t, uint32_t img_blocks, uint8_t *buf)
ret = iso_quick_gpt_entry(t->gpt_req, &(t->gpt_req_count),
part_end, goal - part_end,
type_guid, zero_uuid,
gpt_flags, gpt_name);
eff_gpt_flags, gpt_name);
if (ret < 0)
return ret;
/* Mark as automatically placed filler request */
@ -1875,6 +1881,56 @@ static void iso_dummy_mbr_partition(uint8_t *buf, int mode)
}
/* flag bit0= only accept partition 1 as match for partition_offset
*/
static
int iso_ensure_mbr_part_table(Ecma119Image *t, uint32_t img_blocks,
uint8_t *buf, int flag)
{
int part_type, ret, i, found_part = 0;
uint32_t start_lba, num_blocks;
/* Look for MBR partition which starts at t->opts->partition_offset * 4
and has non-zero length
*/
if (buf[510] == 0x55 && buf[511] == 0xaa &&
t->opts->partition_offset < 0x3fffffff && img_blocks < 0x3fffffff ) {
for (i = 0; i < 4; i++) {
start_lba = iso_read_lsb(buf + 446 + i * 16 + 8, 4);
num_blocks = iso_read_lsb(buf + 446 + i * 16 + 12, 4);
if (t->opts->partition_offset * 4 == start_lba && num_blocks > 0) {
found_part = i + 1;
break;
}
if (flag & 1)
break;
}
}
if (found_part > 0) {
/* Update size fields in found_part */
part_type = buf[446 + (found_part - 1) * 16 + 4];
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
ret = write_mbr_partition_entry(found_part, part_type,
start_lba, img_blocks * 4,
t->partition_secs_per_head,
t->partition_heads_per_cyl, buf, 2);
} else {
part_type = 0xcd;
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
t->partition_heads_per_cyl,
(uint8_t) part_type, buf, 2);
}
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
return ISO_SUCCESS;
}
/* @param flag
bit0= t->opts->ms_block is not counted in t->total_size
*/
@ -1950,8 +2006,10 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag)
*/
apm_flag = 0;
if (sa_type == 0 && (t->system_area_options & 3) == 2) {
do_isohybrid = 1;
if (sa_type == 0 && ((t->system_area_options & 3) == 2 ||
t->opts->part_like_isohybrid)) {
if (sa_type == 0 && (t->system_area_options & 3) == 2)
do_isohybrid = 1;
/* >>> Coordinate with partprepend writer */
/* <<< provisory trap */
@ -2022,23 +2080,29 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag)
/* >>> ??? change first partition type to 0xee */;
}
} else if (do_isohybrid) {
/* Patch externally provided system area as isohybrid MBR */
if (t->catalog == NULL || t->system_area_data == NULL) {
} else if (do_isohybrid || t->opts->part_like_isohybrid) {
/* Patch externally provided system area as isohybrid MBR
or at least write an MBR partition table as of isohybrid
*/
if ((t->catalog == NULL || t->system_area_data == NULL) &&
do_isohybrid) {
/* isohybrid makes only sense together with ISOLINUX boot image
and externally provided System Area.
*/
return ISO_ISOLINUX_CANT_PATCH;
}
if (gpt_count > 0 || apm_count > 0)
if (gpt_count > 0 || apm_count > 0) {
/* Decision can be revoked in make_isolinux_mbr if !do_isohybrid */
part_type = 0x00;
else {
} else {
part_type = 0x17;
}
/* By tradition, real isohybrid insists in 0x00 if GPT or APM */
if (part_type != 0x00 || !do_isohybrid)
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
}
if (t->opts->appended_as_gpt && t->have_appended_partitions) {
part_type = 0xee;
@ -2047,13 +2111,16 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag)
no_boot_mbr = 2;
}
/* >>> ??? Why is partition_offset 0 here ?
It gets adjusted later by iso_offset_partition_start()
Would it harm to give the real offset here ?
*/;
ret = make_isolinux_mbr(&img_blocks, t, 0, 1, part_type, buf,
1 | no_boot_mbr);
/* ??? Why was partition_offset 0 here ?
It gets adjusted later by iso_offset_partition_start()
Does it harm to give the real offset here ?
Now this is really needed for checking whether partitions
are inside the ISO 9660 partition if !do_isohybrid
*/
ret = make_isolinux_mbr(&img_blocks, t, t->opts->partition_offset * 4,
1, part_type, buf,
1 | no_boot_mbr | ((!do_isohybrid) << 2) |
((!do_isohybrid) << 3));
if (ret != 1)
return ret;
} else if (sa_type == 1) {
@ -2079,14 +2146,9 @@ int iso_write_system_area(Ecma119Image *t, uint8_t *buf, int flag)
return ret;
} else if ((t->opts->partition_offset > 0 || will_append) &&
sa_type == 0 && t->mbr_req_count == 0) {
/* Write a simple partition table. */
part_type = 0xcd;
if (t->opts->iso_mbr_part_type >= 0 &&
t->opts->iso_mbr_part_type <= 255)
part_type= t->opts->iso_mbr_part_type;
ret = make_grub_msdos_label(img_blocks, t->partition_secs_per_head,
t->partition_heads_per_cyl,
(uint8_t) part_type, buf, 2);
ret= iso_ensure_mbr_part_table(t, img_blocks, buf,
((t->opts->appended_as_gpt && t->have_appended_partitions) ||
t->opts->partition_offset == 0));
if (ret != ISO_SUCCESS) /* error should never happen */
return ISO_ASSERT_FAILURE;
risk_of_ee = 1;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2011 - 2015 Thomas Schmitt
* Copyright (c) 2011 - 2022 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -24,6 +24,7 @@
#include "messages.h"
#include "tree.h"
#include "util.h"
#include "ecma119.h"
#include <stdlib.h>
#include <string.h>
@ -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) {
@ -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);
@ -1435,6 +1453,8 @@ int iso_tree_clone_file(IsoFile *old_file,
if (ret < 0)
goto ex;
new_stream = NULL; /* now owned by new_file */
new_file->from_old_session = old_file->from_old_session;
new_file->explicit_weight = old_file->explicit_weight;
new_file->sort_weight = old_file->sort_weight;
*new_node = (IsoNode *) new_file;
ret = ISO_SUCCESS;

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2019 Thomas Schmitt
* Copyright (c) 2009 - 2022 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -803,18 +803,18 @@ int str2utf16be(const char *icharset, const char *input, uint16_t **output)
return ISO_SUCCESS;
}
static int valid_d_char(char c)
int valid_d_char(char c)
{
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');
}
static int valid_a_char(char c)
int valid_a_char(char c)
{
return (c >= ' ' && c <= '"') || (c >= '%' && c <= '?') ||
(c >= 'A' && c <= 'Z') || (c == '_');
}
static int valid_j_char(uint16_t c)
int valid_j_char(uint16_t c)
{
return cmp_ucsbe(&c, ' ') != -1 && cmp_ucsbe(&c, '*') && cmp_ucsbe(&c, '/')
&& cmp_ucsbe(&c, ':') && cmp_ucsbe(&c, ';') && cmp_ucsbe(&c, '?')

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2012 Thomas Schmitt
* Copyright (c) 2009 - 2022 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -263,6 +263,12 @@ void iso_handle_split_utf16(uint16_t *utf_word);
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);