Compare commits
144 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
6c9b81a474 | |||
393cc070f3 | |||
006caa2fd2 | |||
c47167058a | |||
5a3d84cbbb | |||
5f6e64b792 | |||
d4b8cbe474 | |||
a0719328ea | |||
c8776e605e | |||
003aa5832e | |||
a78864252e | |||
e56a782b89 | |||
9e17516e0d | |||
e29cd723dd | |||
b0694b4e25 | |||
850302dde5 | |||
26b4222948 | |||
782bb7854e | |||
9c33eb5f10 | |||
8e55195edc | |||
527b613607 | |||
0819f93f79 | |||
3b0ba17f3d | |||
0611f468c2 | |||
5c6ce72c02 | |||
585a54d020 | |||
7ea6d4ebcb | |||
3e33fa5fa1 | |||
cdc336a02b | |||
288eb75745 | |||
210b5817cb | |||
2fe0bf511b | |||
af23ad0f90 | |||
0fc4421e15 | |||
6ed2404420 | |||
a22c16d5ef | |||
5384342336 | |||
a97c66ebb8 | |||
1c2851b5ba | |||
cbea1335d8 | |||
6da58860ec | |||
c47451d12b | |||
a068a1349a | |||
eae886bcb5 | |||
288e778875 | |||
8e687db01d | |||
273182aa2a | |||
e26d07ee77 | |||
1b5caac764 | |||
42821af4e6 | |||
c17ba1980a | |||
1df1642a61 | |||
c07f42dfd4 | |||
443156e100 | |||
2f517301de | |||
0bce145343 | |||
6d64bc23cf | |||
25295d2bb0 | |||
3370f666f9 | |||
ad279352e3 | |||
dfd74d3d04 | |||
593844b0ed | |||
083795cba2 | |||
3b06d25a37 | |||
9e5158f59e | |||
d93be961e1 | |||
8c1c0775d6 | |||
2f8bd3ac01 | |||
6edc1ac057 | |||
a394f4dfd2 | |||
dd27f579eb | |||
1ac59bec46 | |||
af843e446f | |||
e6e037f87e | |||
ca2643b52b | |||
ed8066580a | |||
97ec68530b | |||
185cbd99bf | |||
0e00aeb638 | |||
03b45c3151 | |||
b82ca42f87 | |||
1a8a216822 | |||
ef528f2f0e | |||
bedfa914d5 | |||
5383ae2faa | |||
d23462657b | |||
b41e36365d | |||
985015cea1 | |||
27d4c79d0e | |||
5b78efb12a | |||
2c2fb7caf2 | |||
d51cefb097 | |||
7637d13e11 | |||
b9b5284f22 | |||
afa65e9f2a | |||
5e1aaca232 | |||
fea649835c | |||
44f475a4ef | |||
60eb7e883c | |||
9b4e0b611a | |||
1be57e34ec | |||
b0e68bbcaa | |||
fa61b94ac8 | |||
3e3c15812b | |||
88555bd059 | |||
ba47d1534c | |||
b7dc0f4057 | |||
0ab9f5f8d2 | |||
1338f29d62 | |||
bc5e2227c8 | |||
654ff82345 | |||
6baeae70e0 | |||
b987972660 | |||
c78526abce | |||
b95e1bb85c | |||
7aa2582129 | |||
3f29d70aba | |||
567d3ddafb | |||
c47f85c639 | |||
40310b4fd7 | |||
f34c274f21 | |||
46e96ee616 | |||
7e60e60e62 | |||
d55ed2d1ca | |||
77c8349c56 | |||
b1c7ed6e29 | |||
e886722d65 | |||
b80b339de3 | |||
efbd05203d | |||
6ca1d76d60 | |||
e1b54056e8 | |||
d5cd610ac7 | |||
91f5ebb376 | |||
ff3b439bda | |||
4672c79181 | |||
83cb07b23c | |||
439a14da1d | |||
d66eef42f6 | |||
337bade549 | |||
eb6503a8ad | |||
1a2e1c767e | |||
858c5479c8 | |||
d36b3d04a8 | |||
da41eb8c6e |
@ -1,7 +1,7 @@
|
||||
Vreixo Formoso <metalpain2002@yahoo.es>,
|
||||
Mario Danic <mario.danic@gmail.com>,
|
||||
Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (C) 2007-2011 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||
Copyright (C) 2007-2014 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
80
ChangeLog
80
ChangeLog
@ -1,9 +1,87 @@
|
||||
libisofs-1.4.0.tar.gz Sun May 17 2014
|
||||
===============================================================================
|
||||
* Bug fix: iso_image_report_system_area() caused SIGSEGV by NULL if no valid
|
||||
ISO 9660 image was loeaded. Thanks to OmegaPhil.
|
||||
* Bug fix: A SIGSEGV could happen when loading a faulty ISO filesystem.
|
||||
Debian bug 774152. Thanks to Jakub Wilk.
|
||||
* Bug fix: Rock Ridge Continuation Area could be produced crossing a block
|
||||
boundary. This is heavily disliked by the Linux kernel and spoils
|
||||
the representation of directories which contain many symbolic links.
|
||||
* Bug fix: If iso_write_opts_set_hardlinks() enabled automatic inode numbers,
|
||||
then they did not get into effect with nodes were zisofs decoder
|
||||
filters got attached during the image load process.
|
||||
* Bug fix: The header indicator of the last El Torito catalog section header
|
||||
was set to 0x90 rather than 0x91 if more than one boot image is in
|
||||
that section.
|
||||
* Bug fix: Only 128 bytes of an emerging GPT header block were zeroized.
|
||||
* Bug fix: iso_image_report_system_area() did not show GPT partitions of
|
||||
size 0.
|
||||
* Bug fix: A zero sized GPT partition was marked after the last appended
|
||||
GPT partition.
|
||||
* Bug fix: GPT production did not yield proper results with appended sessions
|
||||
resp. with TOC emulation enabled.
|
||||
* Increased default weight of El Torito boot catalog to 1 billion.
|
||||
* Improved handling of cylinder alignment if the resulting image size is not
|
||||
divisible by 2048. Old behavior was to not align. New is to pad up by a
|
||||
few blocks of 512 bytes.
|
||||
* New API call iso_write_opts_set_appended_as_gpt()
|
||||
and marking of appended partitions in GPT if GPT emerges for other reasons.
|
||||
* New system area type 6 = DEC Alpha SRM boot sector.
|
||||
New API calls iso_image_set_alpha_boot(), iso_image_get_alpha_boot().
|
||||
Thanks to Helge Deller.
|
||||
* New API object iso_interval_reader. Enabling flag bits for older API calls
|
||||
iso_write_opts_set_prep_img(), iso_write_opts_set_efi_bootp(),
|
||||
and iso_write_opts_set_partition_img().
|
||||
|
||||
|
||||
libisofs-1.3.8.tar.gz Sat Jun 28 2014
|
||||
===============================================================================
|
||||
* Bug fix: Prevent allocation of empty hash tables. Thanks Richard Nolde.
|
||||
* Bug fix: Prevent allocation of empty directory children lists.
|
||||
Thanks Richard Nolde.
|
||||
* Bug fix: The GUIDs of main GPT and backup GPT differed if more than one
|
||||
System Area was written into the ISO image.
|
||||
* New API calls iso_image_report_el_torito() and iso_image_report_system_area()
|
||||
* New API call iso_crc32_gpt()
|
||||
|
||||
libisofs-1.3.6.tar.gz Tue Mar 04 2014
|
||||
===============================================================================
|
||||
* Bug fix: Division by zero if HFS+ was combined with TOC emulation for
|
||||
overwritable media.
|
||||
* New API call iso_write_opts_set_joliet_utf16() and ability to read Joliet
|
||||
names as UTF-16BE
|
||||
* New API call iso_conv_name_chars()
|
||||
|
||||
libisofs-1.3.4.tar.gz Thu Dec 12 2013
|
||||
===============================================================================
|
||||
* Giving sort weight 2 as default to El Torito boot images
|
||||
* Encoding HFS+ names in UTF-16 rather than UCS-2.
|
||||
|
||||
libisofs-1.3.2.tar.gz Wed Aug 07 2013
|
||||
===============================================================================
|
||||
* Bug fix: iso_finish() left an invalid global pointer, which a subsequent
|
||||
call of iso_init() would try to dereference.
|
||||
* The sort weight of data files loaded from ISO image is now 2 exp 28 to 1
|
||||
rather than 2 exp 31 - 1 to - 2 exp 31
|
||||
|
||||
libisofs-1.3.0.tar.gz Fri May 17 2013
|
||||
===============================================================================
|
||||
* Bug fix: GPT header CRC was computed from all 512 bytes rather than from 92.
|
||||
* Bug fix: Unspecified Expiration Time and Effective Time of ISO volume was
|
||||
represented by 0-bytes rather than ASCII '0' digits.
|
||||
* Bug fix: Reserved and unused fields of APM entries were not zeroed.
|
||||
* Bug fix: The protective MBR partition for GPT started at block 0 instead of 1.
|
||||
* New option bits with el_torito_set_isolinux_options() and
|
||||
iso_write_opts_set_system_area() to control GRUB2 patching of
|
||||
boot image and MBR.
|
||||
* New API calls iso_image_set_sparc_core() and iso_image_get_sparc_core().
|
||||
|
||||
libisofs-1.2.8.tar.gz Mon Mar 18 2013
|
||||
===============================================================================
|
||||
* New API call iso_image_get_pvd_times().
|
||||
* Bug fix: Image size prediction altered the pointers to MD5 of data files
|
||||
which stem from a previous session.
|
||||
* Bug fix: Reading damaged Rock Ridge data could cause SIGSEGV by NULL.
|
||||
* New API call iso_image_get_pvd_times().
|
||||
|
||||
libisofs-1.2.6.tar.gz Tue Jan 08 2013
|
||||
===============================================================================
|
||||
|
@ -89,7 +89,7 @@ libinclude_HEADERS = \
|
||||
libisofs/libisofs.h
|
||||
|
||||
install-exec-hook:
|
||||
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicite dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
|
||||
$(LIBBURNIA_LDCONFIG_CMD) "$(DESTDIR)$(libdir)" || echo 'NOTE: Explicit dynamic library configuration failed. If needed, configure manually for:' "$(DESTDIR)$(libdir)"
|
||||
|
||||
## ========================================================================= ##
|
||||
|
||||
|
2
README
2
README
@ -4,7 +4,7 @@
|
||||
|
||||
Released under GPL (see COPYING file for details).
|
||||
|
||||
Copyright (C) 2008 - 2012 Vreixo Formoso,
|
||||
Copyright (C) 2008 - 2013 Vreixo Formoso,
|
||||
Mario Danic,
|
||||
Vladimir Serbinenko,
|
||||
Thomas Schmitt
|
||||
|
14
acinclude.m4
14
acinclude.m4
@ -1,7 +1,7 @@
|
||||
AC_DEFUN([LIBBURNIA_SET_FLAGS],
|
||||
[
|
||||
case $target_os in
|
||||
freebsd*)
|
||||
freebsd* | netbsd*)
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/local/include"
|
||||
;;
|
||||
@ -198,3 +198,15 @@ dnl For debugging only
|
||||
|
||||
])
|
||||
|
||||
dnl LIBBURNIA_TRY_TIMEZONE is by Thomas Schmitt, libburnia project
|
||||
dnl It tests whether the global variable exists and is suitable for
|
||||
dnl integer arithmetics.
|
||||
AC_DEFUN([LIBBURNIA_TRY_TIMEZONE],
|
||||
[
|
||||
echo -n "checking for timezone variable ... "
|
||||
AC_TRY_LINK([ #include <time.h> ], [long int i; i = 1 - timezone; ],
|
||||
[LIBBURNIA_TIMEZONE="timezone"], [LIBBURNIA_TIMEZONE="0"]
|
||||
)
|
||||
echo "$LIBBURNIA_TIMEZONE"
|
||||
])
|
||||
|
||||
|
26
configure.ac
26
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libisofs], [1.2.8], [http://libburnia-project.org])
|
||||
AC_INIT([libisofs], [1.4.0], [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=2
|
||||
LIBISOFS_MICRO_VERSION=8
|
||||
LIBISOFS_MINOR_VERSION=4
|
||||
LIBISOFS_MICRO_VERSION=0
|
||||
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
|
||||
# 2013.03.18 development jump has not yet happened
|
||||
# SONAME = 70 - 64 = 6 . Library name = libisofs.6.64.0
|
||||
LT_CURRENT=70
|
||||
LT_AGE=64
|
||||
# 2015.05.17 development jump has not yet happened
|
||||
# SONAME = 82 - 76 = 6 . Library name = libisofs.6.76.0
|
||||
LT_CURRENT=82
|
||||
LT_AGE=76
|
||||
LT_REVISION=0
|
||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||
|
||||
@ -114,6 +114,16 @@ AC_CHECK_DECL([timegm],
|
||||
,
|
||||
[#include <time.h>])
|
||||
|
||||
dnl Whether timezone is an integer variable
|
||||
AH_TEMPLATE([Libburnia_timezonE], [Either timezone or 0])
|
||||
LIBBURNIA_TRY_TIMEZONE
|
||||
if test x$LIBBURNIA_TIMEZONE = xtimezone
|
||||
then
|
||||
AC_DEFINE([Libburnia_timezonE], [timezone])
|
||||
else
|
||||
AC_DEFINE([Libburnia_timezonE], [0])
|
||||
fi
|
||||
|
||||
dnl Check if non standard eaccess() function is available
|
||||
AC_CHECK_DECL([eaccess],
|
||||
[AC_DEFINE(HAVE_EACCESS, 1, [Define this if eaccess function is available])],
|
||||
@ -140,7 +150,7 @@ if test x$enable_debug != xyes; then
|
||||
CFLAGS="-DNDEBUG $CFLAGS"
|
||||
else
|
||||
if test x$GCC = xyes; then
|
||||
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter $CFLAGS"
|
||||
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter -Wno-char-subscripts $CFLAGS"
|
||||
fi
|
||||
CFLAGS="-DDEBUG $CFLAGS"
|
||||
fi
|
||||
|
10
demo/demo.c
10
demo/demo.c
@ -1,6 +1,6 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 - 2009 Vreixo Formoso, Thomas Schmitt
|
||||
* Copyright (c) 2007 - 2014 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
|
||||
@ -95,7 +95,8 @@ tree_print_dir(IsoDir *dir, int level)
|
||||
sp[i+1] = ' ';
|
||||
}
|
||||
|
||||
sp[level * 2-1] = '-';
|
||||
if (level > 0)
|
||||
sp[level * 2 - 1] = '-';
|
||||
sp[level * 2] = '\0';
|
||||
|
||||
iso_dir_get_children(dir, &iter);
|
||||
@ -445,7 +446,8 @@ iso_read_print_dir(IsoFileSource *dir, int level)
|
||||
sp[i+1] = ' ';
|
||||
}
|
||||
|
||||
sp[level * 2-1] = '-';
|
||||
if (level > 0)
|
||||
sp[level * 2 - 1] = '-';
|
||||
sp[level * 2] = '\0';
|
||||
|
||||
ret = iso_file_source_open(dir);
|
||||
@ -550,7 +552,7 @@ int gesture_iso_cat(int argc, char **argv)
|
||||
IsoReadOpts *opts;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: isocat /path/to/image /path/to/file\n");
|
||||
fprintf(stderr, "Usage: -iso_cat /path/to/image /path/to/file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,8 @@ specifications, some is just rumor which happens to work (maybe not even that).
|
||||
|
||||
EL Torito CD booting, for PC-BIOS x86, PowerPC, (old) Mac, EFI.
|
||||
|
||||
Boot Info Table and GRUB2 Boot Info
|
||||
|
||||
Master Boot Record (MBR), for PC-BIOS x86 from (pseudo-) hard disk
|
||||
|
||||
Apple Partition Map (APM), for more modern Mac
|
||||
@ -26,11 +28,15 @@ MIPS Volume Header, for MIPS Big Endian, e.g. SGI Indigo2.
|
||||
DEC Boot Block, for MIPS Little Endian , e.g. DECstation.
|
||||
|
||||
SUN Disk Label and boot images, for SUN SPARC
|
||||
GRUB2 SUN SPARC Core File Address
|
||||
|
||||
PowerPC Reference Platform (PReP), for IBM PowerPC
|
||||
|
||||
Common Hardware Reference Platform (CHRP), for IBM PowerPC
|
||||
|
||||
HP-PA via PALO header version 4
|
||||
HP-PA via PALO header version 5
|
||||
|
||||
Combinations of boot mechanisms:
|
||||
- SYSLINUX isohybrid MBR
|
||||
- SYSLINUX isohybrid for MBR, UEFI and x86-Mac
|
||||
@ -48,7 +54,7 @@ Sources:
|
||||
El Torito, Bootable CD-ROM Format Specification, Version 1.0, 1995
|
||||
which refers to ECMA-119, the standard for ISO 9660 filesystems.
|
||||
libisofs/eltorito.[ch] by Vreixo Formoso.
|
||||
man mkisofs by Joerg Schilling.
|
||||
http://www.uefi.org/sites/default/files/resources/2_4_Errata_B.pdf
|
||||
|
||||
|
||||
ECMA-119 prescribes that the first 32 kB of an ISO 9660 image are System Area
|
||||
@ -119,7 +125,7 @@ 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)
|
||||
2 = "Mac" (possibly for Apple computers with MC68000 or PowerPC CPU)
|
||||
Further in use by GRUB2 and ISOLINUX is:
|
||||
UEFI 2.4 specifies in 12.3.2.1 "ISO-9660 and El Torito":
|
||||
0xef = EFI, a competitor resp. successor to PC-BIOS, possibly in use with
|
||||
Intel ia64 Itanium and possibly with newer Apple machines.
|
||||
|
||||
@ -237,10 +243,22 @@ Byte Range | Value | Meaning
|
||||
12 - 31 | sel_crit | "Vendor unique selection criteria."
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Boot Info Table and GRUB2 Boot Info
|
||||
|
||||
Sources:
|
||||
man mkisofs by Joerg Schilling
|
||||
Mail conversations with Vladimir Serbinenko.
|
||||
|
||||
|
||||
The boot image file content is mostly opaque to the ISO 9660 image generator.
|
||||
Nevertheless there is a tradition named "Boot Info Table" which prescribes
|
||||
to write information into byte fields of the boot image file content.
|
||||
Recent versions of GRUB2 expect a similar patching which has no name yet.
|
||||
For now let's call it "GRUB2 Boot Info"
|
||||
|
||||
There are no general means known how a producer of ISO 9660 images could
|
||||
detect the need for Boot Info Table production.
|
||||
It rather needs a hint from the user who has to know whether the boot image
|
||||
@ -249,19 +267,31 @@ The Boot Info Table begins at byte 8 of the boot image content.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
8 - 11 | pvd_lba | Block address of the Primary Volume Descriptor
|
||||
8 - 11 | pvd_lba | Block address of the Primary Volume Descriptor.
|
||||
| | This is the session start LBA + 16.
|
||||
| |
|
||||
12 - 15 | file_lba | Block address of the start of the boot image file
|
||||
| | content.
|
||||
| | content. Block size is 2048.
|
||||
| |
|
||||
16 - 19 | file_len | Number of bytes in boot image file content.
|
||||
| |
|
||||
20 - 23 | checksum | Little-endian: The sum of all 32-bit words of the
|
||||
| | file content from byte 64 to file end.
|
||||
20 - 23 | checksum | The sum of all 32-bit words of the file content
|
||||
| | from byte 64 to file end.
|
||||
| |
|
||||
24 - 63 | 0 | Reserved
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
All numbers are stored little-endian.
|
||||
|
||||
GRUB2 Boot Info represents a particular block address inside the boot image.
|
||||
It may well be combined with Boot Info Table. See GRUB2 script grub-mkrescue
|
||||
use of xorrisofs options -boot-info-table and --grub2-boot-info.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
2548 -2555 | grub2_adr | Block address of the start of the boot image file
|
||||
| | content plus 5. Block size is 512.
|
||||
| | 64 bit Little-endian.
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@ -499,6 +529,7 @@ Sources:
|
||||
http://mjg59.fedorapeople.org/Fedora-LiveCD.iso
|
||||
http://en.wikipedia.org/wiki/GUID_Partition_Table
|
||||
http://en.wikipedia.org/wiki/GUID
|
||||
http://www.uefi.org/sites/default/files/resources/2_4_Errata_B.pdf
|
||||
|
||||
|
||||
GPT is the partition map format of EFI, a successor of PC-BIOS.
|
||||
@ -506,8 +537,11 @@ Block size is always 512. GPT consists of a header block at block address 1 and
|
||||
a partition table near the start of the medium. This is called the primary GPT.
|
||||
There is a backup copy of header and table near the end of the medium.
|
||||
|
||||
GPT is particularly designed to co-exist with MBR. If it is present, then the
|
||||
booting firmware may or may not prefer it over the MBR partition table.
|
||||
GPT is particularly designed to co-exist with MBR. Officially only with a
|
||||
Protective MBR which covers the whole medium (except the MBR itself) by
|
||||
a single partition of type 0xee. Inofficially often with filesystem partitions
|
||||
marked in both, GPT and MBR. In the latter case the booting firmware may
|
||||
or may not prefer GPT over the MBR partition table.
|
||||
GPT can co-exist with APM if APM block size is at least 1024. In this case,
|
||||
the primary partition table will begin after the last APM entry block.
|
||||
|
||||
@ -520,7 +554,7 @@ Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
|
||||
16 - 19 | head_crc | CRC-32 of this header while head_crc is 0
|
||||
20 - 23 | reserved | = 0
|
||||
24 - 31 | curr_lba | Location of this header block = 1
|
||||
32 - 39 | back_lba | Location of header backup block. See below.
|
||||
32 - 39 | backup_lba | Location of header backup block. See below.
|
||||
40 - 47 | first_lba | First usable LBA for partitions
|
||||
48 - 55 | last_lba | Last usable LBA for partitions
|
||||
56 - 71 | guid | Disk GUID, Random
|
||||
@ -545,13 +579,12 @@ bit1 becomes bit30, and so on. Further it gets exored with 0xffffffff.
|
||||
|
||||
A GUID consists of a 32-bit integer, two 16-bit integers, and an array of
|
||||
8 bytes. The integers are to be stored big-endian.
|
||||
A globally registered class of GUID are the partition type GUIDs.
|
||||
This example uses two of them
|
||||
A globally registered class of GUID are the partition type GUIDs:
|
||||
Basic data partition: a2 a0 d0 eb , e5 b9 , 33 44 , 87 c0 68 b6 b7 26 99 c7
|
||||
HFS+ partition : 00 53 46 48 , 00 00 , aa 11 , aa 11 00 30 65 43 ec ac
|
||||
EFI System partition: 28 73 2a c1 , 1f f8 , d2 11 , ba 4b 00 a0 c9 3e c9 3b
|
||||
Note that the wikipedia list shows the first 32-bit word and the next two
|
||||
16-bit words in little-endia interpretation.
|
||||
16-bit words in little-endian interpretation.
|
||||
|
||||
The partition table is an array of entries. Each has a size of 128 bytes.
|
||||
A partition table entry looks like:
|
||||
@ -589,7 +622,7 @@ Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
|
||||
| | Is recomputed after the following changes.
|
||||
24 - 31 | curr_lba | Location of this header block.
|
||||
| | Shows own block address.
|
||||
32 - 39 | back_lba | Location of header backup block.
|
||||
32 - 39 | backup_lba | Location of header backup block.
|
||||
| | Points to primary header block = 1
|
||||
72 - 79 | part_start | Partition entries start.
|
||||
| | Points to start of backup partition table.
|
||||
@ -741,8 +774,8 @@ Byte Range | Value | Meaning
|
||||
| | (Elf32_Phdr field p_filesz + 511) / 512;
|
||||
| |
|
||||
28 - 31 | seg_start | Segment file offset. Blocks 512 bytes.
|
||||
| | ISO 9660 LBA of boot file * 4 plus offset
|
||||
| | + offset which stems from ELF header of boot file:
|
||||
| | ISO 9660 LBA of boot file * 4 plus offset which
|
||||
| | stems from ELF header of boot file:
|
||||
| | (Elf32_Phdr field p_offset + 511) / 512;
|
||||
| |
|
||||
32 - 431 | ========== | Boot Map Entries 2 to 51
|
||||
@ -798,7 +831,7 @@ Sources:
|
||||
The Disk Label is written to the first 512 bytes of the image. It can mark
|
||||
8 partitions (slices ) of which the first contains the ISO image. The other
|
||||
7 may contain boot images.
|
||||
Words are composed big-endian style.
|
||||
Words are composed big-endian style. Block size is 512.
|
||||
|
||||
Boot images are provided externally. mkisofs arranges them after the end of
|
||||
the ISO image so that each starts at a cylinder boundary (320 kB).
|
||||
@ -810,7 +843,6 @@ their predecessor in the partition table:
|
||||
If mkisofs is called with -G image -B ... all boot partitions are
|
||||
mapped to the partition that contains the ISO9660 filesystem."
|
||||
|
||||
|
||||
Disk Label components:
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
@ -873,7 +905,7 @@ Byte Range | Value | Meaning
|
||||
| |
|
||||
444 - 447 | start_cyl | Start cylinder
|
||||
| |
|
||||
448 - 451 | num_blocks | Number of blocks in partition
|
||||
448 - 451 | num_blocks | Number of 512-byte blocks in partition
|
||||
| |
|
||||
452 - 507 | ========== | Partition table entries #2 to #8
|
||||
| ... | See above Partition table entry #1
|
||||
@ -884,6 +916,30 @@ Byte Range | Value | Meaning
|
||||
| |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
||||
GRUB2 SUN SPARC Core File Address
|
||||
|
||||
Sources:
|
||||
Mail conversations with Vladimir Serbinenko.
|
||||
|
||||
GRUB2 lets libisofs write after the disk label block the address and size of a
|
||||
data file in the ISO image. E.g. of /boot/grub/sparc64-ieee1275/core.img.
|
||||
This is combined with a SUN Disk Label which exposes only the single partition
|
||||
describing the overall ISO filesystem size.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
------------ | ---------- | --------------------------------------------------
|
||||
512 - 551 | opaque | Code and data provided by GRUB2
|
||||
| |
|
||||
552 - 559 | offset | Start byte number of the file. 64-bit big-endian.
|
||||
| |
|
||||
560 - 563 | size | Number of bytes in the file. 32-bit big-endian.
|
||||
| |
|
||||
564 - 32767 | opaque | Code and data provided by GRUB2
|
||||
| |
|
||||
------------ | ---------- | --------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@ -906,22 +962,191 @@ PReP boots via a MBR partition containing only raw ELF and having type 0x41.
|
||||
|
||||
Sources:
|
||||
Mail conversations with Vladimir Serbinenko.
|
||||
|
||||
http://stuff.mit.edu/afs/sipb/contrib/doc/specs/protocol/chrp/chrp1_7a.pdf
|
||||
https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/W51a7ffcf4dfd_4b40_9d82_446ebc23c550/page/PowerLinux%20Boot%20howto
|
||||
|
||||
CHRP is marked by an MBR partition entry of type 0x96 spanning the whole
|
||||
ISO 9660 image.
|
||||
|
||||
The specs in chrp1_7a.pdf promise that CHRP also recognizes ISO 9660 file
|
||||
systems on unpartitioned disks. (See 11.1.1. Media Layout Format)
|
||||
|
||||
The firmware looks up a file /ppc/bootinfo.txt which in SGML-ish tag
|
||||
<boot-script> contains firmware commands.
|
||||
E.g. to execute the binary /boot/grub/powerpc.elf as first stage of GRUB2:
|
||||
<boot-script>boot &device;:\boot\grub\powerpc.elf</boot-script>
|
||||
|
||||
Vladimir Serbinenko stated:
|
||||
PReP boot may be preferable. At least it can co-exist with other partitions
|
||||
in the ISO image.
|
||||
in the ISO image [without causing overlapping between partitions].
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
>>> ??? HP-PA
|
||||
HP-PA via PALO header version 4
|
||||
for HP PA-RISC
|
||||
|
||||
Sources:
|
||||
cdrkit-1.1.10/genisoimage/boot-hppa.c
|
||||
by Steve McIntyre <steve@einval.com>
|
||||
who states "Heavily inspired by palo"
|
||||
|
||||
This format is expected by PALO versions before 1.92. Their source code defines
|
||||
PALOHDRVERSION as 4. The format also serves as fallback for newer versions,
|
||||
which expect header version 5, if a 0-byte is found at byte position 1024.
|
||||
|
||||
There are five parameters which get encoded into the first 248 bytes of the
|
||||
System Area: cmdline, bootloader, 32-bit kernel, 64-bit kernel, and ramdisk.
|
||||
They are all mandatory.
|
||||
While cmdline is simply a string of at most 127 characters, the other four
|
||||
point to data files inside the ISO image.
|
||||
|
||||
All numbers are recorded big endian.
|
||||
|
||||
Boot sector components:
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 1 | 0x8000 | Magic
|
||||
| |
|
||||
2 - 6 | "PALO" | Zero terminated string
|
||||
| |
|
||||
7 - 7 | 4 | Version
|
||||
| |
|
||||
8 - 11 | kern32_adr | Byte address of the "HPPA 32-bit kernel" file
|
||||
| | genisoimage option -hppa-kernel-32
|
||||
12 - 15 | kern32_len | Byte count of the "HPPA 32-bit kernel" file
|
||||
| |
|
||||
16 - 19 | ramdsk_adr | Byte address of the "HPPA ramdisk" file
|
||||
| | genisoimage option -hppa-ramdisk
|
||||
20 - 23 | ramdsk_len | Byte count of the "HPPA ramdisk" file
|
||||
| |
|
||||
24 - 151 | cmdline | "Command line"
|
||||
| | genisoimage option -hppa-cmdline
|
||||
| |
|
||||
232 - 235 | kern64_adr | Byte address of the "HPPA 64-bit kernel" file
|
||||
| | genisoimage option -hppa-kernel-64
|
||||
236 - 239 | kern64_len | Byte count of the "HPPA 64-bit kernel" file
|
||||
| |
|
||||
240 - 243 | bootld_adr | Byte address of the "HPPA bootloader" file
|
||||
| | genisoimage option -hppa-bootloader
|
||||
244 - 247 | bootld_len | Byte count of the "HPPA bootloader" file
|
||||
| |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
>>> ??? DEC Alpha
|
||||
HP-PA via PALO header version 5
|
||||
for HP PA-RISC
|
||||
|
||||
Sources:
|
||||
Public mail conversations with Helge Deller, beginning with
|
||||
https://lists.debian.org/debian-hppa/2014/01/msg00016.html
|
||||
http://git.kernel.org/cgit/linux/kernel/git/deller/palo.git/tree/lib/
|
||||
(especially struct firstblock in common.h and struct partition in part.h)
|
||||
|
||||
This format is expected by PALO versions 1.92 or higher. They fall back to
|
||||
header version 4 if a 0-byte is found at byte position 1024.
|
||||
Their source code defines PALOHDRVERSION as 5.
|
||||
|
||||
There are five parameters which get encoded into the first 2048 bytes of the
|
||||
System Area: cmdline, bootloader, 32-bit kernel, 64-bit kernel, and ramdisk.
|
||||
They are all mandatory.
|
||||
While cmdline is simply a string of at most 1023 characters, the other four
|
||||
point to data files inside the ISO image.
|
||||
|
||||
Several fields of the firstblock shall be hardcoded to 0, on advise of
|
||||
Helge Deller. Their description is shown in round brackets.
|
||||
|
||||
All numbers are recorded big endian.
|
||||
Except flags, all 4-byte integers are signed.
|
||||
|
||||
Boot sector components:
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 1 | 0x8000 | Magic
|
||||
| |
|
||||
2 - 6 | "PALO" | Zero terminated string
|
||||
| |
|
||||
7 - 7 | 5 | Version
|
||||
| |
|
||||
8 - 11 | kern32_adr | Byte address of the 32-bit kernel file
|
||||
| |
|
||||
12 - 15 | kern32_len | Byte count of the 32-bit kernel file
|
||||
| |
|
||||
16 - 19 | ramdsk_adr | Byte address of the ramdisk file
|
||||
| |
|
||||
20 - 23 | ramdsk_len | Byte count of the ramdisk file
|
||||
| |
|
||||
24 - 141 | 0 | All 0s. Old command line of version 4.
|
||||
| |
|
||||
| |
|
||||
220 - 223 | 0 | (Length of uncompressed 32-bit kernel)
|
||||
| |
|
||||
224 - 227 | 0 | (Length of uncompressed 64-bit kernel)
|
||||
| |
|
||||
228 - 231 | 0 | (flags)
|
||||
| |
|
||||
232 - 235 | kern64_adr | Byte address of the 64-bit kernel file
|
||||
| |
|
||||
236 - 239 | kern64_len | Byte count of the 64-bit kernel file
|
||||
| |
|
||||
240 - 243 | ipl_adr | Byte address of the bootloader file
|
||||
| |
|
||||
244 - 247 | ipl_len | Byte count of the bootloader file
|
||||
| |
|
||||
248 - 251 | 0 | (ipl_entry: offset to first command in bootloader)
|
||||
| |
|
||||
446 - 511 | 0 | (MBR partition table and signature)
|
||||
| |
|
||||
1024 -2047 | cmdline | Zero terminated command line of up to
|
||||
| | 1023 characters
|
||||
| |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
DEC Alpha SRM boot sector
|
||||
for Alpha architecture
|
||||
|
||||
Sources:
|
||||
http://www.tldp.org/HOWTO/text/SRM-HOWTO
|
||||
SRM Firmware Howto - Rich Payne, and David Huggins-Daines
|
||||
cdrkit-1.1.10/genisoimage/boot-alpha.c
|
||||
by Steve McIntyre
|
||||
who states "Heavily inspired by isomarkboot by David Mosberger in 1996"
|
||||
mail conversations with Helge Deller
|
||||
|
||||
The SRM firmware expects a Secondary Bootstrap Loader program, which usually
|
||||
is a data file of the ISO filesystem. This loader is announced by size and
|
||||
block address in the first 512 bytes of the System Area.
|
||||
SRM accepts the boot sector and executes the loader if the checksum matches.
|
||||
|
||||
All numbers are recorded as unsigned 64 bit little endian.
|
||||
|
||||
Boot sector components:
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - ? | boot_string| genisoimage writes
|
||||
| | "Linux/Alpha aboot for ISO filesystem."
|
||||
| | with terminating zero byte.
|
||||
| |
|
||||
? - 479 | 0 | Unused / undefined.
|
||||
| |
|
||||
480 - 487 | length | Size of boot loader file in units of 512 bytes.
|
||||
| |
|
||||
488 - 495 | address | LBA of the boot loader file in units of 512 bytes.
|
||||
| |
|
||||
496 - 503 | flag | "Always 0"
|
||||
| |
|
||||
504 - 511 | checksum | Sum of 64 bit words 0 to 63 (bytes 0 to 503).
|
||||
| |
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
@ -1041,7 +1266,7 @@ intentionally non-essential:
|
||||
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
|
||||
harmless code. They stem from Fedora-LiveCD.iso by Matthew Garret:
|
||||
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
|
||||
They do not depend on any properties of the ISO image or the information
|
||||
@ -1108,7 +1333,7 @@ Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
12 - 15 | head_size | Header size = 0x5c = 92
|
||||
24 - 31 | curr_lba | Location of this header block = 0x1
|
||||
32 - 39 | back_lba | Location of header backup block = 0x144ffe = 1331198
|
||||
32 - 39 | backup_lba | Location of header backup block = 0x144ffe = 1331198
|
||||
| | This is 1 KiB before the end of MBR partition 1
|
||||
| | (but should be 512 bytes).
|
||||
| | (Potential isohybrid.c bug #1:
|
||||
@ -1259,6 +1484,9 @@ Start at block 0xa4 = 164 * 512 = 41 * 2048. The VFAT image file.
|
||||
Last block is 0x0513 = 1299 = 164 + 1135. This end is correct.
|
||||
(Potential isohybrid.c bug #4:
|
||||
Wrong character set and incidential bytes in GPT partition name.)
|
||||
(Potential isohybrid.c bug #5:
|
||||
The EFI System Partition should have type GUID :
|
||||
"C12A7328-F81F-11D2-BA4B-00A0C93EC93B")
|
||||
|
||||
Next entry at byte 0x02100 = 8448:
|
||||
|
||||
@ -1321,12 +1549,21 @@ Sources:
|
||||
Mailing list conversations with Vladimir Serbinenko.
|
||||
|
||||
|
||||
The MBR file that is used with GRUB2 script grub-mkrescue needs only a
|
||||
partition table entry which describes the image size.
|
||||
The MBR file that is used with older versions of GRUB2 script grub-mkrescue
|
||||
needs only a partition table entry which describes the image size.
|
||||
Newer versions get patched by the block address of the content of the first
|
||||
El Torito boot image. See grub-mkrescue use of xorrisofs option --grub2-mbr.
|
||||
|
||||
Byte Range | Value | Meaning
|
||||
---------- | ---------- | ----------------------------------------------------
|
||||
0 - 445 | = opaque = | GRUB2 machine code provided by MBR template
|
||||
0 - 431 | = opaque = | GRUB2 machine code provided by MBR template
|
||||
| |
|
||||
432 - 439 | bootimg_adr| With newer versions of grub-mkrescue:
|
||||
| | Block address of the start of the boot image file
|
||||
| | content plus 4. Block size is 512.
|
||||
| | 64 bit Little-endian.
|
||||
| |
|
||||
440 - 445 | = opaque = | provided by MBR template
|
||||
| |
|
||||
446 - 509 | ========== | Partition table
|
||||
| |
|
||||
|
@ -109,8 +109,6 @@ Each Component Record shall have the following format:
|
||||
[B] "BP 2 - Component Length (LEN_CP)" shall specify as an 8-bit number the
|
||||
number of component bytes in the Component Record. This length shall not
|
||||
include the first two bytes of the Component Record.
|
||||
If any of the bit positions 1-3 is set, the value of this field shall be
|
||||
set to ZERO and no Component Content shall be recorded.
|
||||
This field shall be recorded according to ISO 9660 Format section 7.1.1.
|
||||
|
||||
[C] "BP 3 to 2 + LEN_CP - Component Content" shall contain the component
|
||||
@ -445,7 +443,7 @@ Program mkisofs emits entry XA
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This text is under
|
||||
Copyright (c) 2009 - 2010 Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (c) 2009 - 2013 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.
|
||||
|
@ -128,7 +128,7 @@ Name:
|
||||
|
||||
Purpose:
|
||||
Records the IsoHfsplusBlessings blessing of a IsoNode as defined
|
||||
in libisofs.h. At image load time, this info shall be converted back
|
||||
in libisofs.h. At image load time, this info may be converted back
|
||||
into a relation between IsoImage and IsoNode so that it is available for
|
||||
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
|
||||
|
||||
@ -152,7 +152,7 @@ Name:
|
||||
|
||||
Purpose:
|
||||
Records the iso_hfsplus_xinfo_data information as defined in libisofs.h.
|
||||
At image load time, this info shall be converted back into an xinfo
|
||||
At image load time, this info may be converted back into an xinfo
|
||||
attachment for iso_hfsplus_xinfo_func so that it is available for
|
||||
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
|
||||
|
||||
|
@ -5,9 +5,9 @@
|
||||
Arbitrary Attribute Interchange Protocol , system adapter for getting and
|
||||
setting of ACLs and xattr.
|
||||
|
||||
To be included by aaip_0_2.c
|
||||
To be included by aaip_0_2.c for FreeBSD and NetBSD
|
||||
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||
Copyright (c) 2009 - 2014 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
@ -32,6 +32,8 @@
|
||||
#include <sys/extattr.h>
|
||||
#endif
|
||||
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
/* <<< Use old ACL adapter code that is unable to deal with extattr */
|
||||
/* # define Libisofs_old_freebsd_acl_adapteR */
|
||||
|
||||
@ -70,6 +72,32 @@ int aaip_local_attr_support(int flag)
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
|
||||
static int aaip_extattr_path_supp(char *path, int flag)
|
||||
{
|
||||
|
||||
#ifdef MNT_EXTATTR
|
||||
|
||||
int ret;
|
||||
struct statvfs statvfs_buf;
|
||||
|
||||
ret = statvfs(path, &statvfs_buf);
|
||||
if(ret == -1)
|
||||
return(1);
|
||||
return(!!(statvfs_buf.f_flag & MNT_EXTATTR));
|
||||
|
||||
#else /* MNT_EXTATTR */
|
||||
|
||||
return(1);
|
||||
|
||||
#endif /* ! MNT_EXTATTR */
|
||||
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_freebsd_extattR */
|
||||
|
||||
|
||||
/* ------------------------------ Getters --------------------------------- */
|
||||
|
||||
/* Obtain the ACL of the given file in long text form.
|
||||
@ -195,8 +223,13 @@ static int aaip_extattr_make_list(char *path, int attrnamespace,
|
||||
*list_size= extattr_list_file(path, attrnamespace, NULL, (size_t) 0);
|
||||
else
|
||||
*list_size= extattr_list_link(path, attrnamespace, NULL, (size_t) 0);
|
||||
if(*list_size == -1)
|
||||
if(*list_size == -1) {
|
||||
if(! aaip_extattr_path_supp(path, 0)) {
|
||||
*list_size = 0;
|
||||
return(2);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
if(*list_size == 0)
|
||||
return(2);
|
||||
*list= calloc(*list_size, 1);
|
||||
|
@ -5,7 +5,7 @@
|
||||
Arbitrary Attribute Interchange Protocol , system adapter for getting and
|
||||
setting of ACLs and xattr.
|
||||
|
||||
To be included by aaip_0_2.c
|
||||
To be included by aaip_0_2.c for Linux
|
||||
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
See libisofs/aaip_0_2.h
|
||||
http://libburnia-project.org/wiki/AAIP
|
||||
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||
Copyright (c) 2009 - 2014 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
@ -2065,7 +2065,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
unsigned char *rpt;
|
||||
char perm_text[4], *wpt, *name= NULL;
|
||||
int type, qualifier= 0, perm, ret, cnt, name_size= 1024;
|
||||
size_t w_size, name_fill= 0, i;
|
||||
size_t w_size= 0, name_fill= 0, i;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
struct passwd *pwd;
|
||||
@ -2181,6 +2181,11 @@ ex:;
|
||||
|
||||
#include "aaip-os-freebsd.c"
|
||||
|
||||
#else
|
||||
#ifdef __NetBSD__
|
||||
|
||||
#include "aaip-os-freebsd.c"
|
||||
|
||||
#else
|
||||
#ifdef __linux
|
||||
|
||||
@ -2198,5 +2203,6 @@ ex:;
|
||||
#include "aaip-os-dummy.c"
|
||||
|
||||
#endif /* ! __linux */
|
||||
#endif /* ! __NetBSD__ */
|
||||
#endif /* ! __FreeBSD__ */
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2014 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
|
||||
@ -96,7 +96,7 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
||||
|
||||
static
|
||||
int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
IsoFileSource *src, IsoNode **node)
|
||||
IsoFileSource *src, char *in_name, IsoNode **node)
|
||||
{
|
||||
int ret;
|
||||
struct stat info;
|
||||
@ -122,7 +122,15 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
goto ex;
|
||||
}
|
||||
|
||||
name = iso_file_source_get_name(src);
|
||||
if (in_name == NULL) {
|
||||
name = iso_file_source_get_name(src);
|
||||
} else {
|
||||
name = strdup(in_name);
|
||||
if (name == NULL) {
|
||||
ret = ISO_OUT_OF_MEM; goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
||||
fs = iso_file_source_get_filesystem(src);
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2014 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
|
||||
@ -47,6 +48,7 @@ struct Iso_Node_Builder
|
||||
* Create a new IsoNode from a IsoFileSource. The type of the node to be
|
||||
* created is determined from the type of the file source. Name,
|
||||
* permissions and other attributes are taken from source file.
|
||||
* But name may be overridden by parameter name if it is not NULL.
|
||||
*
|
||||
* Note that the src is never unref, so you need to free it.
|
||||
*
|
||||
@ -54,7 +56,7 @@ struct Iso_Node_Builder
|
||||
* 1 on success, < 0 on error
|
||||
*/
|
||||
int (*create_node)(IsoNodeBuilder *builder, IsoImage *image,
|
||||
IsoFileSource *src, IsoNode **node);
|
||||
IsoFileSource *src, char *name, IsoNode **node);
|
||||
|
||||
/**
|
||||
* Free implementation specific data. Should never be called by user.
|
||||
|
@ -21,6 +21,11 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* O_BINARY is needed for Cygwin but undefined elsewhere */
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Private data for File IsoDataSource
|
||||
*/
|
||||
@ -65,7 +70,7 @@ int ds_open(IsoDataSource *src)
|
||||
return ISO_FILE_ALREADY_OPENED;
|
||||
}
|
||||
|
||||
fd = open(data->path, O_RDONLY);
|
||||
fd = open(data->path, O_RDONLY | O_BINARY);
|
||||
if (fd == -1) {
|
||||
return ISO_FILE_ERROR;
|
||||
}
|
||||
|
1419
libisofs/ecma119.c
1419
libisofs/ecma119.c
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 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
|
||||
@ -87,6 +87,12 @@
|
||||
#define ISO_GPT_ENTRIES_MAX 248
|
||||
|
||||
|
||||
/* How many warnings to issue about writing Joliet names which cannot be
|
||||
properly represented in UCS-2 and thus had to be defaultet to '_'.
|
||||
*/
|
||||
#define ISO_JOLIET_UCS2_WARN_MAX 3
|
||||
|
||||
|
||||
/**
|
||||
* Holds the options for the image generation.
|
||||
*/
|
||||
@ -94,7 +100,7 @@ struct iso_write_opts {
|
||||
|
||||
int will_cancel;
|
||||
|
||||
int level; /**< ISO level to write at. (ECMA-119, 10) */
|
||||
int iso_level; /**< ISO level to write at. (ECMA-119, 10) */
|
||||
|
||||
/** Which extensions to support. */
|
||||
unsigned int rockridge :1;
|
||||
@ -192,6 +198,11 @@ struct iso_write_opts {
|
||||
*/
|
||||
unsigned int joliet_long_names :1;
|
||||
|
||||
/**
|
||||
* Use UTF-16BE rather than its subset UCS-2
|
||||
*/
|
||||
unsigned int joliet_utf16 :1;
|
||||
|
||||
/**
|
||||
* Write Rock Ridge info as of specification RRIP-1.10 rather than
|
||||
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
|
||||
@ -420,6 +431,7 @@ struct iso_write_opts {
|
||||
* See ecma119_image : System Area related information
|
||||
*/
|
||||
char *system_area_data;
|
||||
int system_area_size;
|
||||
int system_area_options;
|
||||
|
||||
/* User settable PVD time stamps */
|
||||
@ -456,17 +468,24 @@ struct iso_write_opts {
|
||||
to HFS+/FAT and IsoFileSrc areas and marked by an MBR partition entry.
|
||||
*/
|
||||
char *prep_partition;
|
||||
int prep_part_flag;
|
||||
|
||||
/* Eventual disk file path of an EFI system partition image which shall
|
||||
be prepended to HFS+/FAT and IsoFileSrc areas and marked by a GPT entry.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
char *appended_partitions[ISO_MAX_PARTITIONS];
|
||||
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
|
||||
int appended_part_flags[ISO_MAX_PARTITIONS];
|
||||
|
||||
/* If 1: With appended partitions: create protective MBR and mark by GPT
|
||||
*/
|
||||
int appended_as_gpt;
|
||||
|
||||
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
|
||||
*/
|
||||
@ -502,70 +521,19 @@ struct ecma119_image
|
||||
IsoImage *image;
|
||||
Ecma119Node *root;
|
||||
|
||||
int will_cancel :1;
|
||||
IsoWriteOpts *opts;
|
||||
|
||||
unsigned int iso_level :2;
|
||||
|
||||
/* extensions */
|
||||
unsigned int rockridge :1;
|
||||
unsigned int joliet :1;
|
||||
/** Whether El Torito data will be produced */
|
||||
unsigned int eltorito :1;
|
||||
unsigned int iso1999 :1;
|
||||
unsigned int hfsplus :1;
|
||||
unsigned int fat :1;
|
||||
|
||||
unsigned int hardlinks:1; /* see iso_write_opts_set_hardlinks() */
|
||||
|
||||
unsigned int aaip :1; /* see iso_write_opts_set_aaip() */
|
||||
|
||||
/* allways write timestamps in GMT */
|
||||
unsigned int always_gmt :1;
|
||||
|
||||
/* relaxed constraints */
|
||||
unsigned int allow_dir_id_ext :1;
|
||||
unsigned int omit_version_numbers :2;
|
||||
unsigned int allow_deep_paths :1;
|
||||
unsigned int allow_longer_paths :1;
|
||||
unsigned int max_37_char_filenames :1;
|
||||
unsigned int no_force_dots :2;
|
||||
unsigned int allow_lowercase :1;
|
||||
unsigned int allow_full_ascii :1;
|
||||
unsigned int allow_7bit_ascii :1;
|
||||
|
||||
unsigned int relaxed_vol_atts : 1;
|
||||
|
||||
/** Allow paths on Joliet tree to be larger than 240 bytes */
|
||||
unsigned int joliet_longer_paths :1;
|
||||
|
||||
/** Allow Joliet names up to 103 characters rather than 64 */
|
||||
unsigned int joliet_long_names :1;
|
||||
|
||||
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
|
||||
unsigned int rrip_version_1_10 :1;
|
||||
|
||||
/** Write field PX with file serial number even with RRIP-1.10 */
|
||||
unsigned int rrip_1_10_px_ino :1;
|
||||
|
||||
/* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12. */
|
||||
unsigned int aaip_susp_1_10 :1;
|
||||
|
||||
/* Store in ECMA-119, Joliet, ISO 9660:1999 timestamp the mtime of source
|
||||
bit0= ECMA-119, bit1= Joliet, bit2= ISO 9660:1999.
|
||||
/* The ECMA-119 directory node where to store Rock Ridge relocated
|
||||
directories. (Path is in IsoWriteOpts.rr_reloc_dir)
|
||||
*/
|
||||
unsigned int dir_rec_mtime :3;
|
||||
|
||||
/* The ECMA-119 directory where to store Rock Ridge relocated directories.
|
||||
*/
|
||||
char *rr_reloc_dir; /* IsoNode name in root directory */
|
||||
int rr_reloc_flags;
|
||||
Ecma119Node *rr_reloc_node; /* Directory node in ecma119_image */
|
||||
|
||||
unsigned int md5_session_checksum :1;
|
||||
unsigned int md5_file_checksums :2;
|
||||
|
||||
/*
|
||||
* Mode replace. If one of these flags is set, the correspodent values are
|
||||
* replaced with values below.
|
||||
* replaced with values below. Both get computed from IsoWriteOpts.
|
||||
*/
|
||||
unsigned int replace_uid :1;
|
||||
unsigned int replace_gid :1;
|
||||
@ -573,30 +541,17 @@ struct ecma119_image
|
||||
unsigned int replace_dir_mode :1;
|
||||
unsigned int replace_timestamps :1;
|
||||
|
||||
/* Mode replacement values. */
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
mode_t file_mode;
|
||||
mode_t dir_mode;
|
||||
time_t timestamp;
|
||||
|
||||
unsigned int old_empty :1;
|
||||
unsigned int untranslated_name_len;
|
||||
|
||||
/**
|
||||
* if sort files or not. Sorting is based of the weight of each file
|
||||
*/
|
||||
int sort_files;
|
||||
|
||||
/* Effective charsets */
|
||||
char *input_charset;
|
||||
char *output_charset;
|
||||
|
||||
/* See iso_write_opts and iso_write_opts_set_hfsp_serial_number().
|
||||
* 00...00 means that it shall be generated by libisofs.
|
||||
*/
|
||||
uint8_t hfsp_serial_number[8];
|
||||
|
||||
unsigned int appendable : 1;
|
||||
uint32_t ms_block; /**< start block for a ms image */
|
||||
time_t now; /**< Time at which writing began. */
|
||||
|
||||
/** Total size of the output. This only includes the current volume. */
|
||||
@ -642,6 +597,7 @@ struct ecma119_image
|
||||
uint32_t joliet_path_table_size;
|
||||
uint32_t joliet_l_path_table_pos;
|
||||
uint32_t joliet_m_path_table_pos;
|
||||
size_t joliet_ucs2_failures;
|
||||
|
||||
/*
|
||||
* HFS+ related information
|
||||
@ -763,14 +719,6 @@ struct ecma119_image
|
||||
Use only underneath ecma119_image_new()
|
||||
and if not NULL*/
|
||||
|
||||
/* ??? Is there a reason why we copy lots of items from IsoWriteOpts
|
||||
rather than taking ownership of the IsoWriteOpts object which
|
||||
is submitted with ecma119_image_new() ?
|
||||
*/
|
||||
|
||||
char scdbackup_tag_parm[100];
|
||||
char *scdbackup_tag_written;
|
||||
|
||||
/* Buffer for communication between burn_source and writer thread */
|
||||
IsoRingBuffer *buffer;
|
||||
|
||||
@ -779,20 +727,7 @@ struct ecma119_image
|
||||
int wthread_is_running;
|
||||
pthread_attr_t th_attr;
|
||||
|
||||
/* User settable PVD time stamps */
|
||||
time_t vol_creation_time;
|
||||
time_t vol_modification_time;
|
||||
time_t vol_expiration_time;
|
||||
time_t vol_effective_time;
|
||||
/* To eventually override vol_creation_time and vol_modification_time
|
||||
* by unconverted string with timezone 0
|
||||
*/
|
||||
char vol_uuid[17];
|
||||
|
||||
/* The number of unclaimed 2K blocks before
|
||||
start of partition 1 as of the MBR in system area. */
|
||||
uint32_t partition_offset;
|
||||
/* Partition table parameter: 1 to 63, 0= disabled/default */
|
||||
/* Effective partition table parameter: 1 to 63, 0= disabled/default */
|
||||
int partition_secs_per_head;
|
||||
/* 1 to 255, 0= disabled/default */
|
||||
int partition_heads_per_cyl;
|
||||
@ -813,26 +748,22 @@ struct ecma119_image
|
||||
uint32_t j_part_l_path_table_pos;
|
||||
uint32_t j_part_m_path_table_pos;
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
struct libjte_env *libjte_handle;
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
uint32_t tail_blocks;
|
||||
|
||||
/* Memorized ELF parameters from MIPS Little Endian boot file */
|
||||
uint32_t mipsel_e_entry;
|
||||
uint32_t mipsel_p_offset;
|
||||
uint32_t mipsel_p_vaddr;
|
||||
uint32_t mipsel_p_filesz;
|
||||
|
||||
char *appended_partitions[ISO_MAX_PARTITIONS];
|
||||
uint8_t appended_part_types[ISO_MAX_PARTITIONS];
|
||||
/* A data file of which the position and size shall be written after
|
||||
a SUN Disk Label.
|
||||
*/
|
||||
IsoFileSrc *sparc_core_src;
|
||||
|
||||
/* Counted in blocks of 2048 */
|
||||
uint32_t appended_part_prepad[ISO_MAX_PARTITIONS];
|
||||
uint32_t appended_part_start[ISO_MAX_PARTITIONS];
|
||||
uint32_t appended_part_size[ISO_MAX_PARTITIONS];
|
||||
|
||||
char ascii_disc_label[ISO_DISC_LABEL_SIZE];
|
||||
int have_appended_partitions;
|
||||
|
||||
/* See IsoImage and libisofs.h */
|
||||
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
||||
@ -841,17 +772,12 @@ struct ecma119_image
|
||||
Only change a block size if it is 0. Set only to 512 or 2048.
|
||||
If it stays 0 then it will become 512 or 2048 in time.
|
||||
*/
|
||||
/* Blocksize of Apple Partition Map
|
||||
May be defined to 512 or 2048 before writer thread starts.
|
||||
*/
|
||||
int apm_block_size;
|
||||
|
||||
/* Allocation block size of HFS+
|
||||
May be defined to 512 or 2048 before hfsplus_writer_create().
|
||||
*/
|
||||
int hfsp_block_size;
|
||||
int hfsp_cat_node_size; /* 2 * apm_block_size */
|
||||
int hfsp_iso_block_fac; /* 2048 / apm_block_size */
|
||||
int hfsp_cat_node_size; /* 2 * hfsp_block_size */
|
||||
int hfsp_iso_block_fac; /* 2048 / hfsp_block_size */
|
||||
|
||||
/* Apple Partition Map description. To be composed during IsoImageWriter
|
||||
method ->compute_data_blocks() by calling iso_register_apm_entry().
|
||||
@ -872,7 +798,12 @@ struct ecma119_image
|
||||
struct iso_mbr_partition_request *mbr_req[ISO_MBR_ENTRIES_MAX];
|
||||
int mbr_req_count;
|
||||
|
||||
char *prep_partition;
|
||||
/* Number of bytes which have to be added after the cylinder aligned end
|
||||
of the overall ISO partition because clinder size is not a multiple
|
||||
of 2048
|
||||
*/
|
||||
int post_iso_part_pad;
|
||||
|
||||
uint32_t prep_part_size;
|
||||
|
||||
/* GPT description. To be composed during IsoImageWriter
|
||||
@ -885,13 +816,17 @@ struct ecma119_image
|
||||
/* bit0= GPT partitions may overlap */
|
||||
int gpt_req_flags;
|
||||
|
||||
char *efi_boot_partition;
|
||||
/* Whether the eventual backup GPT is not part of the ISO filesystem */
|
||||
int gpt_backup_outside;
|
||||
|
||||
uint32_t efi_boot_part_size;
|
||||
IsoFileSrc *efi_boot_part_filesrc; /* Just a pointer. Do not free. */
|
||||
|
||||
/* Messages from gpt_tail_writer_compute_data_blocks() to
|
||||
iso_write_system_area().
|
||||
*/
|
||||
uint8_t gpt_disk_guid[16];
|
||||
int gpt_disk_guid_set;
|
||||
/* Start of GPT entries in System Area, block size 512 */
|
||||
uint32_t gpt_part_start;
|
||||
/* The ISO block number after the backup GPT header , block size 2048 */
|
||||
@ -904,6 +839,7 @@ struct ecma119_image
|
||||
write_data() methods of the writers.
|
||||
*/
|
||||
uint8_t sys_area_as_written[16 * BLOCK_SIZE];
|
||||
int sys_area_already_written;
|
||||
|
||||
/* Size of the filesrc_writer area (data file content).
|
||||
This is available before any IsoImageWriter.compute_data_blocks()
|
||||
@ -1049,4 +985,7 @@ void ecma119_set_voldescr_times(IsoImageWriter *writer,
|
||||
int iso_write_partition_file(Ecma119Image *target, char *path,
|
||||
uint32_t prepad, uint32_t blocks, int flag);
|
||||
|
||||
void issue_ucs2_warning_summary(size_t failures);
|
||||
|
||||
|
||||
#endif /*LIBISO_ECMA119_H_*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2014 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
|
||||
@ -29,52 +29,57 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static
|
||||
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
||||
/* @param flag bit0= Do not issue error messages
|
||||
*/
|
||||
int iso_get_ecma119_name(IsoWriteOpts *opts, char *input_charset, int imgid,
|
||||
char *node_name, enum IsoNodeType node_type,
|
||||
char **name, int flag)
|
||||
{
|
||||
int ret, relaxed, free_ascii_name= 0, force_dots = 0;
|
||||
int ret, relaxed, free_ascii_name = 0, force_dots = 0;
|
||||
char *ascii_name;
|
||||
char *isoname= NULL;
|
||||
char *isoname = NULL;
|
||||
|
||||
if (iso->name == NULL) {
|
||||
if (node_name == NULL) {
|
||||
/* it is not necessarily an error, it can be the root */
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
if (img->untranslated_name_len > 0) {
|
||||
ascii_name = iso->name;
|
||||
if (opts->untranslated_name_len > 0) {
|
||||
ascii_name = node_name;
|
||||
ret = 1;
|
||||
} else {
|
||||
ret = str2ascii(img->input_charset, iso->name, &ascii_name);
|
||||
ret = str2ascii(input_charset, node_name, &ascii_name);
|
||||
free_ascii_name = 1;
|
||||
}
|
||||
if (ret < 0) {
|
||||
iso_msg_submit(img->image->id, ret, 0,
|
||||
"Cannot convert name '%s' to ASCII", iso->name);
|
||||
if (!(flag & 512))
|
||||
iso_msg_submit(imgid, ret, 0,
|
||||
"Cannot convert name '%s' to ASCII", node_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (img->allow_full_ascii) {
|
||||
if (opts->allow_full_ascii) {
|
||||
relaxed = 2;
|
||||
} else {
|
||||
relaxed = (int)img->allow_lowercase;
|
||||
relaxed = (int)opts->allow_lowercase;
|
||||
}
|
||||
if (img->allow_7bit_ascii)
|
||||
if (opts->allow_7bit_ascii)
|
||||
relaxed |= 4;
|
||||
if (iso->type == LIBISO_DIR && !(img->allow_dir_id_ext)) {
|
||||
if (img->untranslated_name_len > 0) {
|
||||
if (strlen(ascii_name) > img->untranslated_name_len) {
|
||||
if (node_type == LIBISO_DIR && !(opts->allow_dir_id_ext)) {
|
||||
if (opts->untranslated_name_len > 0) {
|
||||
if (strlen(ascii_name) > opts->untranslated_name_len) {
|
||||
needs_transl:;
|
||||
iso_msg_submit(img->image->id, ISO_NAME_NEEDS_TRANSL, 0,
|
||||
if (!(flag & 512))
|
||||
iso_msg_submit(imgid, ISO_NAME_NEEDS_TRANSL, 0,
|
||||
"File name too long (%d > %d) for untranslated recording: '%s'",
|
||||
strlen(ascii_name), img->untranslated_name_len,
|
||||
ascii_name);
|
||||
strlen(ascii_name), opts->untranslated_name_len,
|
||||
ascii_name);
|
||||
return ISO_NAME_NEEDS_TRANSL;
|
||||
}
|
||||
isoname = strdup(ascii_name);
|
||||
} else if (img->max_37_char_filenames) {
|
||||
} else if (opts->max_37_char_filenames) {
|
||||
isoname = iso_r_dirid(ascii_name, 37, relaxed);
|
||||
} else if (img->iso_level == 1) {
|
||||
} else if (opts->iso_level == 1) {
|
||||
|
||||
#ifdef Libisofs_old_ecma119_nameS
|
||||
|
||||
@ -99,14 +104,15 @@ needs_transl:;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
force_dots = !((img->no_force_dots & 1) || iso->type == LIBISO_DIR);
|
||||
if (img->untranslated_name_len > 0) {
|
||||
if (strlen(ascii_name) > img->untranslated_name_len)
|
||||
force_dots = !((opts->no_force_dots & 1) ||
|
||||
node_type == LIBISO_DIR);
|
||||
if (opts->untranslated_name_len > 0) {
|
||||
if (strlen(ascii_name) > opts->untranslated_name_len)
|
||||
goto needs_transl;
|
||||
isoname = strdup(ascii_name);
|
||||
} else if (img->max_37_char_filenames) {
|
||||
} else if (opts->max_37_char_filenames) {
|
||||
isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots);
|
||||
} else if (img->iso_level == 1) {
|
||||
} else if (opts->iso_level == 1) {
|
||||
|
||||
#ifdef Libisofs_old_ecma119_nameS
|
||||
|
||||
@ -151,11 +157,21 @@ needs_transl:;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iso_get_ecma119_name(img->opts, img->input_charset, img->image->id,
|
||||
iso->name, iso->type, name, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
|
||||
{
|
||||
if (img->rr_reloc_node == node &&
|
||||
node != img->root && node != img->partition_root &&
|
||||
(img->rr_reloc_flags & 2))
|
||||
(img->opts->rr_reloc_flags & 2))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@ -185,23 +201,26 @@ static
|
||||
int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
|
||||
{
|
||||
int ret;
|
||||
Ecma119Node **children;
|
||||
Ecma119Node **children = NULL;
|
||||
struct ecma119_dir_info *dir_info;
|
||||
|
||||
children = calloc(1, sizeof(void*) * iso->nchildren);
|
||||
if (children == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
if (iso->nchildren > 0) {
|
||||
children = calloc(1, sizeof(void*) * iso->nchildren);
|
||||
if (children == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
dir_info = calloc(1, sizeof(struct ecma119_dir_info));
|
||||
if (dir_info == NULL) {
|
||||
free(children);
|
||||
if (children != NULL)
|
||||
free(children);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
ret = create_ecma119_node(img, (IsoNode*)iso, node);
|
||||
if (ret < 0) {
|
||||
free(children);
|
||||
if (children != NULL)
|
||||
free(children);
|
||||
free(dir_info);
|
||||
return ret;
|
||||
}
|
||||
@ -220,7 +239,7 @@ int create_file_src(Ecma119Image *img, IsoFile *iso, IsoFileSrc **src)
|
||||
off_t size;
|
||||
|
||||
size = iso_stream_get_size(iso->stream);
|
||||
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && img->iso_level != 3) {
|
||||
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 "
|
||||
@ -337,7 +356,8 @@ void ecma119_node_free(Ecma119Node *node)
|
||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||
ecma119_node_free(node->info.dir->children[i]);
|
||||
}
|
||||
free(node->info.dir->children);
|
||||
if (node->info.dir->children != NULL)
|
||||
free(node->info.dir->children);
|
||||
free(node->info.dir);
|
||||
}
|
||||
free(node->iso_name);
|
||||
@ -361,6 +381,7 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
||||
int max_path;
|
||||
char *iso_name= NULL, *ipath = NULL;
|
||||
IsoFileSrc *src = NULL;
|
||||
IsoWriteOpts *opts = image->opts;
|
||||
|
||||
if (image == NULL || iso == NULL || tree == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -385,16 +406,16 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
||||
goto ex;
|
||||
}
|
||||
max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0);
|
||||
if (!image->rockridge) {
|
||||
if (!opts->rockridge) {
|
||||
if ((iso->type == LIBISO_DIR && depth > 8) &&
|
||||
!image->allow_deep_paths) {
|
||||
ipath = iso_tree_get_node_path(iso);
|
||||
!opts->allow_deep_paths) {
|
||||
ipath = iso_tree_get_node_path(iso);
|
||||
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG,
|
||||
0, "File \"%s\" can't be added, "
|
||||
"because directory depth "
|
||||
"is greater than 8.", ipath);
|
||||
goto ex;
|
||||
} else if (max_path > 255 && !image->allow_longer_paths) {
|
||||
} else if (max_path > 255 && !opts->allow_longer_paths) {
|
||||
ipath = iso_tree_get_node_path(iso);
|
||||
ret = iso_msg_submit(image->image->id, ISO_FILE_IMGPATH_WRONG,
|
||||
0, "File \"%s\" can't be added, "
|
||||
@ -418,7 +439,7 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
||||
ret = 0; /* Hidden means non-existing */
|
||||
goto ex;
|
||||
}
|
||||
if (image->rockridge) {
|
||||
if (opts->rockridge) {
|
||||
ret = create_symlink(image, (IsoSymlink*)iso, &node);
|
||||
} else {
|
||||
/* symlinks are only supported when RR is enabled */
|
||||
@ -434,7 +455,7 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
||||
ret = 0; /* Hidden means non-existing */
|
||||
goto ex;
|
||||
}
|
||||
if (image->rockridge) {
|
||||
if (opts->rockridge) {
|
||||
ret = create_special(image, (IsoSpecial*)iso, &node);
|
||||
} else {
|
||||
/* special files are only supported when RR is enabled */
|
||||
@ -472,9 +493,9 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
||||
image->rr_reloc_node = node;
|
||||
} else if (depth == 2) {
|
||||
/* Directories in root may be used as relocation dir */
|
||||
if (image->rr_reloc_dir != NULL)
|
||||
if (image->rr_reloc_dir[0] != 0 &&
|
||||
strcmp(iso->name, image->rr_reloc_dir) == 0)
|
||||
if (opts->rr_reloc_dir != NULL)
|
||||
if (opts->rr_reloc_dir[0] != 0 &&
|
||||
strcmp(iso->name, opts->rr_reloc_dir) == 0)
|
||||
image->rr_reloc_node = node;
|
||||
}
|
||||
}
|
||||
@ -547,6 +568,8 @@ void sort_tree(Ecma119Node *root)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (root->info.dir->children == NULL)
|
||||
return;
|
||||
qsort(root->info.dir->children, root->info.dir->nchildren, sizeof(void*),
|
||||
cmp_node_name);
|
||||
for (i = 0; i < root->info.dir->nchildren; i++) {
|
||||
@ -575,6 +598,9 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
nchildren = dir->info.dir->nchildren;
|
||||
children = dir->info.dir->children;
|
||||
|
||||
if (nchildren <= 0)
|
||||
return ISO_SUCCESS; /* nothing to do */
|
||||
|
||||
/* a hash table will temporary hold the names, for fast searching */
|
||||
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
||||
(compare_function_t)strcmp, &table);
|
||||
@ -606,7 +632,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (img->untranslated_name_len) {
|
||||
if (img->opts->untranslated_name_len) {
|
||||
/* This should not happen because no two IsoNode names should be
|
||||
identical and only unaltered IsoNode names should be seen here.
|
||||
Thus the Ema119Node names should be unique.
|
||||
@ -635,7 +661,8 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
/* compute name and extension */
|
||||
dot = strrchr(full_name, '.');
|
||||
if (dot != NULL &&
|
||||
(children[i]->type != ECMA119_DIR || img->allow_dir_id_ext)) {
|
||||
(children[i]->type != ECMA119_DIR ||
|
||||
img->opts->allow_dir_id_ext)) {
|
||||
|
||||
/*
|
||||
* File (normally not dir) with extension
|
||||
@ -801,11 +828,11 @@ int mangle_tree(Ecma119Image *img, Ecma119Node *dir, int recurse)
|
||||
int max_file, max_dir;
|
||||
Ecma119Node *root;
|
||||
|
||||
if (img->untranslated_name_len > 0) {
|
||||
max_file = max_dir = img->untranslated_name_len;
|
||||
} else if (img->max_37_char_filenames) {
|
||||
if (img->opts->untranslated_name_len > 0) {
|
||||
max_file = max_dir = img->opts->untranslated_name_len;
|
||||
} else if (img->opts->max_37_char_filenames) {
|
||||
max_file = max_dir = 37;
|
||||
} else if (img->iso_level == 1) {
|
||||
} else if (img->opts->iso_level == 1) {
|
||||
max_file = 12; /* 8 + 3 + 1 */
|
||||
max_dir = 8;
|
||||
} else {
|
||||
@ -973,9 +1000,9 @@ int reorder_tree(Ecma119Image *img, Ecma119Node *dir,
|
||||
/* dir is now the relocated Ecma119Node */
|
||||
pathlen = 37 + 1; /* The dir name might get longer by mangling */
|
||||
level = 2;
|
||||
if (img->rr_reloc_dir != NULL) {
|
||||
if (img->opts->rr_reloc_dir != NULL) {
|
||||
pathlen += strlen(img->rr_reloc_node->iso_name) + 1;
|
||||
if(img->rr_reloc_dir[0] != 0)
|
||||
if(img->opts->rr_reloc_dir[0] != 0)
|
||||
level = 3;
|
||||
}
|
||||
}
|
||||
@ -1095,6 +1122,11 @@ int family_set_ino(Ecma119Image *img, Ecma119Node **nodes, size_t family_start,
|
||||
*/
|
||||
if (img_ino == prev_ino)
|
||||
img_ino = 0;
|
||||
|
||||
/* Accept only if it is within the 32 bit range. */
|
||||
if (((uint64_t) img_ino) > 0xffffffff)
|
||||
img_ino = 0;
|
||||
|
||||
}
|
||||
if (img_ino == 0) {
|
||||
img_ino = img_give_ino_number(img->image, 0);
|
||||
@ -1128,7 +1160,7 @@ int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
|
||||
goto ex;
|
||||
|
||||
/* Sort according to id tuples, IsoFileSrc identity, properties, xattr. */
|
||||
if (img->hardlinks)
|
||||
if (img->opts->hardlinks)
|
||||
qsort(nodes, node_count, sizeof(Ecma119Node *), ecma119_node_cmp_hard);
|
||||
else
|
||||
qsort(nodes, node_count, sizeof(Ecma119Node *),
|
||||
@ -1198,7 +1230,7 @@ int ecma119_tree_create(Ecma119Image *img)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (img->rockridge && !img->allow_deep_paths) {
|
||||
if (img->opts->rockridge && !img->opts->allow_deep_paths) {
|
||||
|
||||
/* Relocate deep directories, acording to RRIP, 4.1.5 */
|
||||
ret = reorder_tree(img, root, 1, 0);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* 2012 Thomas Schmitt
|
||||
* 2012 - 2014 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
|
||||
@ -64,9 +64,7 @@ struct ecma119_node
|
||||
|
||||
IsoNode *node; /*< reference to the iso node */
|
||||
|
||||
/* >>> ts A90501 : Shouldn't this be uint32_t
|
||||
as this is what PX will take ? */
|
||||
ino_t ino;
|
||||
uint32_t ino;
|
||||
|
||||
nlink_t nlink;
|
||||
|
||||
@ -103,5 +101,13 @@ Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node);
|
||||
*/
|
||||
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node);
|
||||
|
||||
/**
|
||||
* Determines the ECMA-119 name from node name.
|
||||
* @param flag bit0= Do not issue error messages
|
||||
*/
|
||||
int iso_get_ecma119_name(IsoWriteOpts *opts, char *input_charset, int imgid,
|
||||
char *node_name, enum IsoNodeType node_type,
|
||||
char **name, int flag);
|
||||
|
||||
|
||||
#endif /*LIBISO_ECMA119_TREE_H_*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2010 Thomas Schmitt
|
||||
* Copyright (c) 2010 - 2014 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
|
||||
@ -82,15 +82,16 @@ void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment)
|
||||
{
|
||||
if (bootimg->type != 0)
|
||||
return;
|
||||
bootimg->load_seg = segment;
|
||||
if (segment < 0)
|
||||
bootimg->load_seg = 0x1000 + segment;
|
||||
else
|
||||
bootimg->load_seg = segment;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int el_torito_get_load_seg(ElToritoBootImage *bootimg)
|
||||
{
|
||||
if (bootimg->load_seg < 0)
|
||||
return 0xffff - bootimg->load_seg;
|
||||
return bootimg->load_seg;
|
||||
return (int) bootimg->load_seg;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,15 +103,16 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors)
|
||||
{
|
||||
if (bootimg->type != 0)
|
||||
return;
|
||||
bootimg->load_size = sectors;
|
||||
if (sectors < 0)
|
||||
bootimg->load_size = 0x10000 + sectors;
|
||||
else
|
||||
bootimg->load_size = sectors;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int el_torito_get_load_size(ElToritoBootImage *bootimg)
|
||||
{
|
||||
if (bootimg->load_size < 0)
|
||||
return 0xffff - bootimg->load_size;
|
||||
return bootimg->load_size;
|
||||
return (int) bootimg->load_size;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,7 +162,13 @@ int el_torito_get_selection_crit(ElToritoBootImage *bootimg, uint8_t crit[20])
|
||||
/* API */
|
||||
int el_torito_seems_boot_info_table(ElToritoBootImage *bootimg, int flag)
|
||||
{
|
||||
return bootimg->seems_boot_info_table;
|
||||
switch (flag & 15) {
|
||||
case 0:
|
||||
return bootimg->seems_boot_info_table;
|
||||
case 1:
|
||||
return bootimg->seems_grub2_boot_info;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,14 +205,16 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg)
|
||||
*/
|
||||
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag)
|
||||
{
|
||||
bootimg->isolinux_options = (options & 0x01ff);
|
||||
bootimg->isolinux_options = (options & 0x03ff);
|
||||
bootimg->seems_boot_info_table = !!(options & 1);
|
||||
bootimg->seems_grub2_boot_info = !!(options & (1 << 9));
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int el_torito_get_isolinux_options(ElToritoBootImage *bootimg, int flag)
|
||||
{
|
||||
return bootimg->isolinux_options & 0x01ff;
|
||||
return bootimg->isolinux_options & 0x03ff;
|
||||
}
|
||||
|
||||
/* API */
|
||||
@ -306,7 +316,8 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
||||
static
|
||||
int create_image(IsoImage *image, const char *image_path,
|
||||
enum eltorito_boot_media_type type,
|
||||
struct el_torito_boot_image **bootimg)
|
||||
struct el_torito_boot_image **bootimg,
|
||||
IsoFile **bootnode)
|
||||
{
|
||||
int ret;
|
||||
struct el_torito_boot_image *boot;
|
||||
@ -317,6 +328,7 @@ int create_image(IsoImage *image, const char *image_path,
|
||||
IsoNode *imgfile;
|
||||
IsoStream *stream;
|
||||
|
||||
*bootnode = NULL;
|
||||
ret = iso_tree_path_to_node(image, image_path, &imgfile);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@ -331,6 +343,7 @@ int create_image(IsoImage *image, const char *image_path,
|
||||
if (imgfile->type != LIBISO_FILE) {
|
||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||
}
|
||||
*bootnode = (IsoFile *) imgfile;
|
||||
|
||||
stream = ((IsoFile*)imgfile)->stream;
|
||||
|
||||
@ -431,6 +444,8 @@ int create_image(IsoImage *image, const char *image_path,
|
||||
iso_node_ref(imgfile); /* get our ref */
|
||||
boot->bootable = 1;
|
||||
boot->seems_boot_info_table = 0;
|
||||
boot->seems_grub2_boot_info = 0;
|
||||
boot->seems_isohybrid_capable = 0;
|
||||
boot->isolinux_options = 0;
|
||||
boot->type = boot_media_type;
|
||||
boot->partition_type = partition_type;
|
||||
@ -455,6 +470,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
||||
struct el_torito_boot_catalog *catalog;
|
||||
ElToritoBootImage *boot_image= NULL;
|
||||
IsoBoot *cat_node= NULL;
|
||||
IsoFile *boot_node;
|
||||
|
||||
if (image == NULL || image_path == NULL || catalog_path == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -507,7 +523,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
||||
}
|
||||
|
||||
/* create the boot image */
|
||||
ret = create_image(image, image_path, type, &boot_image);
|
||||
ret = create_image(image, image_path, type, &boot_image, &boot_node);
|
||||
if (ret < 0) {
|
||||
goto boot_image_cleanup;
|
||||
}
|
||||
@ -523,7 +539,9 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
||||
for (i = 1; i < Libisofs_max_boot_imageS; i++)
|
||||
catalog->bootimages[i] = NULL;
|
||||
catalog->node = cat_node;
|
||||
catalog->sort_weight = 1000; /* slightly high */
|
||||
catalog->sort_weight = 1000000000; /* very high */
|
||||
if (!(boot_node->explicit_weight || boot_node->from_old_session))
|
||||
boot_node->sort_weight = 2;
|
||||
iso_node_ref((IsoNode*)cat_node);
|
||||
image->bootcat = catalog;
|
||||
|
||||
@ -694,14 +712,17 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
|
||||
int ret;
|
||||
struct el_torito_boot_catalog *catalog = image->bootcat;
|
||||
ElToritoBootImage *boot_img;
|
||||
IsoFile *boot_node;
|
||||
|
||||
if(catalog == NULL)
|
||||
return ISO_BOOT_NO_CATALOG;
|
||||
if (catalog->num_bootimages >= Libisofs_max_boot_imageS)
|
||||
return ISO_BOOT_IMAGE_OVERFLOW;
|
||||
ret = create_image(image, image_path, type, &boot_img);
|
||||
ret = create_image(image, image_path, type, &boot_img, &boot_node);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (!(boot_node->explicit_weight || boot_node->from_old_session))
|
||||
boot_node->sort_weight = 2;
|
||||
catalog->bootimages[catalog->num_bootimages] = boot_img;
|
||||
catalog->num_bootimages++;
|
||||
if (boot != NULL)
|
||||
@ -793,7 +814,8 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
|
||||
(struct el_torito_section_header *) buf;
|
||||
|
||||
/* 0x90 = more section headers follow , 0x91 = final section */
|
||||
e->header_indicator[0] = 0x90 + (idx == t->catalog->num_bootimages - 1);
|
||||
e->header_indicator[0] =
|
||||
0x90 + (idx == t->catalog->num_bootimages - num_entries);
|
||||
e->platform_id[0] = t->catalog->bootimages[idx]->platform_id;
|
||||
e->num_entries[0] = num_entries & 0xff;
|
||||
e->num_entries[1] = (num_entries >> 8) & 0xff;;
|
||||
@ -936,7 +958,8 @@ int catalog_is_repeatable(IsoStream *stream)
|
||||
/**
|
||||
* fs_id will be the id reserved for El-Torito
|
||||
* dev_id will be 0 for catalog, 1 for boot image (if needed)
|
||||
* we leave ino_id for future use when we support multiple boot images
|
||||
* ino_id 0 is supposed to be unique. At write time it will get assigned
|
||||
* an automatic file serial number in the ISO, if needed.
|
||||
*/
|
||||
static
|
||||
void catalog_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
||||
@ -1096,7 +1119,7 @@ int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch an isolinux boot image.
|
||||
* Patch an El Torito boot image by a boot info table.
|
||||
*
|
||||
* @return
|
||||
* 1 on success, 0 error (but continue), < 0 error
|
||||
@ -1111,12 +1134,33 @@ int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
|
||||
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||
"Isolinux image too small. We won't patch it.");
|
||||
}
|
||||
ret = make_boot_info_table(buf, t->ms_block + (uint32_t) 16,
|
||||
ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16,
|
||||
t->bootsrc[idx]->sections[0].block,
|
||||
(uint32_t) imgsize);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Patch a GRUB2 El Torito boot image.
|
||||
*/
|
||||
static
|
||||
int patch_grub2_boot_image(uint8_t *buf, Ecma119Image *t,
|
||||
size_t imgsize, int idx,
|
||||
size_t pos, int offst)
|
||||
{
|
||||
uint64_t blk;
|
||||
|
||||
if (imgsize < pos + 8)
|
||||
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||
"Isolinux image too small for GRUB2. Will not patch it.");
|
||||
blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst;
|
||||
iso_lsb((buf + pos), blk & 0xffffffff, 4);
|
||||
iso_lsb((buf + pos + 4), blk >> 32, 4);
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Patch the boot images if indicated */
|
||||
int iso_patch_eltoritos(Ecma119Image *t)
|
||||
{
|
||||
@ -1130,7 +1174,7 @@ int iso_patch_eltoritos(Ecma119Image *t)
|
||||
return ISO_SUCCESS;
|
||||
|
||||
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
|
||||
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x01))
|
||||
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
|
||||
continue;
|
||||
original = t->bootsrc[idx]->stream;
|
||||
size = (size_t) iso_stream_get_size(original);
|
||||
@ -1150,13 +1194,27 @@ int iso_patch_eltoritos(Ecma119Image *t)
|
||||
ret = iso_stream_read(original, buf, size);
|
||||
iso_stream_close(original);
|
||||
if (ret != (int) size) {
|
||||
if (ret >= 0)
|
||||
iso_msg_submit(t->image->id, ISO_FILE_READ_ERROR, 0,
|
||||
"Cannot read all bytes from El Torito boot image for boot info table");
|
||||
return (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* ok, patch the read buffer */
|
||||
ret = patch_boot_info_table(buf, t, size, idx);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
if (t->catalog->bootimages[idx]->isolinux_options & 0x200) {
|
||||
/* GRUB2 boot provisions */
|
||||
ret = patch_grub2_boot_image(buf, t, size, idx,
|
||||
Libisofs_grub2_elto_patch_poS,
|
||||
Libisofs_grub2_elto_patch_offsT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
/* Must be done as last patching */
|
||||
if (t->catalog->bootimages[idx]->isolinux_options & 0x01) {
|
||||
/* Boot Info Table */
|
||||
ret = patch_boot_info_table(buf, t, size, idx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* replace the original stream with a memory stream that reads from
|
||||
@ -1255,8 +1313,8 @@ int eltorito_writer_create(Ecma119Image *target)
|
||||
}
|
||||
}
|
||||
|
||||
if (target->efi_boot_partition != NULL)
|
||||
if (strcmp(target->efi_boot_partition, "--efi-boot-image") == 0)
|
||||
if (target->opts->efi_boot_partition != NULL)
|
||||
if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0)
|
||||
outsource_efi = 1;
|
||||
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
|
||||
bootimg = target->catalog->bootimages[idx]->image;
|
||||
@ -1290,8 +1348,8 @@ int eltorito_writer_create(Ecma119Image *target)
|
||||
|
||||
if (outsource_efi) {
|
||||
/* Disable EFI Boot partition and complain */
|
||||
free(target->efi_boot_partition);
|
||||
target->efi_boot_partition = NULL;
|
||||
free(target->opts->efi_boot_partition);
|
||||
target->opts->efi_boot_partition = NULL;
|
||||
iso_msg_submit(target->image->id, ISO_BOOT_NO_EFI_ELTO, 0,
|
||||
"No newly added El Torito EFI boot image found for exposure as GPT partition");
|
||||
return ISO_BOOT_NO_EFI_ELTO;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2010 Thomas Schmitt
|
||||
* Copyright (c) 2010 - 2014 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
|
||||
@ -58,6 +58,11 @@ struct el_torito_boot_image {
|
||||
* Whether the boot image seems to contain a boot_info_table
|
||||
*/
|
||||
unsigned int seems_boot_info_table:1;
|
||||
unsigned int seems_grub2_boot_info:1;
|
||||
/**
|
||||
* Whether the boot image seems to be capable of isohybrid
|
||||
*/
|
||||
unsigned int seems_isohybrid_capable:1;
|
||||
/**
|
||||
* isolinux options
|
||||
* bit 0 -> whether to patch image
|
||||
@ -73,8 +78,8 @@ struct el_torito_boot_image {
|
||||
unsigned int isolinux_options;
|
||||
unsigned char type; /**< The type of image */
|
||||
unsigned char partition_type; /**< type of partition for HD-emul images */
|
||||
short load_seg; /**< Load segment for the initial boot image. */
|
||||
short load_size; /**< Number of sectors to load. */
|
||||
uint16_t load_seg; /**< Load segment for the initial boot image. */
|
||||
uint16_t load_size; /**< Number of sectors to load. */
|
||||
|
||||
/* Byte 1 of Validation Entry or Section Header Entry:
|
||||
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
|
||||
@ -155,4 +160,12 @@ int make_boot_info_table(uint8_t *buf, uint32_t pvd_lba,
|
||||
*/
|
||||
int iso_patch_eltoritos(Ecma119Image *t);
|
||||
|
||||
|
||||
/* Parameters for patch_grub2_boot_image()
|
||||
Might later become variables in struct el_torito_boot_image.
|
||||
*/
|
||||
#define Libisofs_grub2_elto_patch_poS (512 * 5 - 12)
|
||||
#define Libisofs_grub2_elto_patch_offsT 5
|
||||
|
||||
|
||||
#endif /* LIBISO_ELTORITO_H */
|
||||
|
@ -88,8 +88,8 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
||||
}
|
||||
|
||||
/* fill key and other atts */
|
||||
fsrc->no_write = (file->from_old_session && img->appendable);
|
||||
if (file->from_old_session && img->appendable) {
|
||||
fsrc->no_write = (file->from_old_session && img->opts->appendable);
|
||||
if (file->from_old_session && img->opts->appendable) {
|
||||
/*
|
||||
* On multisession discs we keep file sections from old image.
|
||||
*/
|
||||
@ -127,7 +127,8 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
||||
/* insert the filesrc in the tree */
|
||||
ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
|
||||
if (ret <= 0) {
|
||||
if (ret == 0 && (*src)->checksum_index > 0 && !img->will_cancel) {
|
||||
if (ret == 0 && (*src)->checksum_index > 0 &&
|
||||
!img->opts->will_cancel) {
|
||||
/* Duplicate file source was mapped to previously registered source
|
||||
*/
|
||||
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
|
||||
@ -140,8 +141,8 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
||||
}
|
||||
iso_stream_ref(fsrc->stream);
|
||||
|
||||
if ((img->md5_file_checksums & 1) &&
|
||||
file->from_old_session && img->appendable) {
|
||||
if ((img->opts->md5_file_checksums & 1) &&
|
||||
file->from_old_session && img->opts->appendable) {
|
||||
ret = iso_node_get_xinfo((IsoNode *) file, checksum_md5_xinfo_func,
|
||||
&xipt);
|
||||
if (ret <= 0)
|
||||
@ -152,13 +153,14 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
||||
no_md5 = 1;
|
||||
}
|
||||
|
||||
if ((img->md5_file_checksums & 1) && !(no_md5 || img->will_cancel)) {
|
||||
if ((img->opts->md5_file_checksums & 1) &&
|
||||
!(no_md5 || img->opts->will_cancel)) {
|
||||
img->checksum_idx_counter++;
|
||||
if (img->checksum_idx_counter < 0x7fffffff) {
|
||||
fsrc->checksum_index = img->checksum_idx_counter;
|
||||
} else {
|
||||
fsrc->checksum_index= 0;
|
||||
img->checksum_idx_counter= 0x7fffffff; /* keep from rolling over */
|
||||
img->checksum_idx_counter= 0x7ffffffe; /* keep from rolling over */
|
||||
}
|
||||
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
|
||||
if (cret < 0)
|
||||
@ -244,11 +246,11 @@ int filesrc_writer_pre_compute(IsoImageWriter *writer)
|
||||
/* Normally reserve a single zeroed block for all files which have
|
||||
no block address: symbolic links, device files, empty data files.
|
||||
*/
|
||||
if (! t->old_empty)
|
||||
if (! t->opts->old_empty)
|
||||
t->filesrc_blocks++;
|
||||
|
||||
/* on appendable images, ms files shouldn't be included */
|
||||
if (t->appendable) {
|
||||
if (t->opts->appendable) {
|
||||
inc_item = shall_be_written;
|
||||
} else {
|
||||
inc_item = NULL;
|
||||
@ -261,7 +263,7 @@ int filesrc_writer_pre_compute(IsoImageWriter *writer)
|
||||
}
|
||||
|
||||
/* sort files by weight, if needed */
|
||||
if (t->sort_files) {
|
||||
if (t->opts->sort_files) {
|
||||
qsort(filelist, size, sizeof(void*), cmp_by_weight);
|
||||
}
|
||||
|
||||
@ -436,7 +438,7 @@ int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file,
|
||||
file_size = iso_file_src_get_size(file);
|
||||
nblocks = DIV_UP(file_size, BLOCK_SIZE);
|
||||
pre_md5_valid = 0;
|
||||
if (file->checksum_index > 0 && (t->md5_file_checksums & 2)) {
|
||||
if (file->checksum_index > 0 && (t->opts->md5_file_checksums & 2)) {
|
||||
/* Obtain an MD5 of content by a first read pass */
|
||||
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
|
||||
}
|
||||
@ -494,11 +496,11 @@ int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file,
|
||||
/* >>> HFS: need to align to allocation block size */;
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
if (t->libjte_handle != NULL) {
|
||||
res = libjte_begin_data_file(t->libjte_handle, name,
|
||||
if (t->opts->libjte_handle != NULL) {
|
||||
res = libjte_begin_data_file(t->opts->libjte_handle, name,
|
||||
BLOCK_SIZE, file_size);
|
||||
if (res <= 0) {
|
||||
res = iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||
res = iso_libjte_forward_msgs(t->opts->libjte_handle, t->image->id,
|
||||
ISO_LIBJTE_FILE_FAILED, 0);
|
||||
if (res < 0) {
|
||||
filesrc_close(file);
|
||||
@ -593,7 +595,7 @@ int iso_filesrc_write_data(Ecma119Image *t, IsoFileSrc *file,
|
||||
res = iso_md5_end(&ctx, md5);
|
||||
if (res <= 0)
|
||||
file->checksum_index = 0;
|
||||
if ((t->md5_file_checksums & 2) && pre_md5_valid > 0 &&
|
||||
if ((t->opts->md5_file_checksums & 2) && pre_md5_valid > 0 &&
|
||||
!was_error) {
|
||||
if (! iso_md5_match(md5, pre_md5)) {
|
||||
/* Issue MISHAP event */
|
||||
@ -619,8 +621,8 @@ ex:;
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
if (jte_begun) {
|
||||
res = libjte_end_data_file(t->libjte_handle);
|
||||
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||
res = libjte_end_data_file(t->opts->libjte_handle);
|
||||
iso_libjte_forward_msgs(t->opts->libjte_handle, t->image->id,
|
||||
ISO_LIBJTE_END_FAILED, 0);
|
||||
if (res <= 0 && ret >= 0)
|
||||
ret = ISO_LIBJTE_FILE_FAILED;
|
||||
@ -658,7 +660,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
files which have no block address:
|
||||
symbolic links, device files, empty data files.
|
||||
*/
|
||||
if (! t->old_empty) {
|
||||
if (! t->opts->old_empty) {
|
||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
|
2481
libisofs/fs_image.c
2481
libisofs/fs_image.c
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,11 @@
|
||||
#include <libgen.h>
|
||||
#include <string.h>
|
||||
|
||||
/* O_BINARY is needed for Cygwin but undefined elsewhere */
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
static
|
||||
int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
|
||||
IsoFileSource **src);
|
||||
@ -222,7 +227,7 @@ int lfs_open(IsoFileSource *src)
|
||||
data->info.dir = opendir(path);
|
||||
data->openned = data->info.dir ? 2 : 0;
|
||||
} else {
|
||||
data->info.fd = open(path, O_RDONLY);
|
||||
data->info.fd = open(path, O_RDONLY | O_BINARY);
|
||||
data->openned = data->info.fd != -1 ? 1 : 0;
|
||||
}
|
||||
free(path);
|
||||
@ -282,6 +287,9 @@ static
|
||||
int lfs_read(IsoFileSource *src, void *buf, size_t count)
|
||||
{
|
||||
_LocalFsFileSource *data;
|
||||
size_t to_read, done = 0;
|
||||
int ret;
|
||||
uint8_t *buf8;
|
||||
|
||||
if (src == NULL || buf == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -293,28 +301,28 @@ int lfs_read(IsoFileSource *src, void *buf, size_t count)
|
||||
data = src->data;
|
||||
switch (data->openned) {
|
||||
case 1: /* not dir */
|
||||
{
|
||||
int ret;
|
||||
ret = read(data->info.fd, buf, count);
|
||||
buf8 = (uint8_t *) buf; /* for pointer arithmetic */
|
||||
for (to_read = count; to_read > 0; to_read = count - done) {
|
||||
if (to_read > 1024 * 1024)
|
||||
to_read = 1024 * 1024;
|
||||
ret = read(data->info.fd, buf8 + done, to_read);
|
||||
if (ret < 0) {
|
||||
/* error on read */
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
ret = ISO_INTERRUPTED;
|
||||
break;
|
||||
return ISO_INTERRUPTED;
|
||||
case EFAULT:
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
break;
|
||||
return ISO_OUT_OF_MEM;
|
||||
case EIO:
|
||||
ret = ISO_FILE_READ_ERROR;
|
||||
break;
|
||||
default:
|
||||
ret = ISO_FILE_ERROR;
|
||||
break;
|
||||
return ISO_FILE_READ_ERROR;
|
||||
}
|
||||
return ISO_FILE_ERROR;
|
||||
}
|
||||
return ret;
|
||||
if (ret == 0) /* EOF */
|
||||
break;
|
||||
done += ret;
|
||||
}
|
||||
return done;
|
||||
case 2: /* directory */
|
||||
return ISO_FILE_IS_DIR;
|
||||
default:
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 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
|
||||
@ -34,9 +34,13 @@ int iso_local_filesystem_new(IsoFilesystem **fs);
|
||||
|
||||
|
||||
/* Rank two IsoFileSource of ifs_class by their eventual old image LBAs.
|
||||
Other IsoFileSource classes will be ranked only roughly.
|
||||
* @param cmp_ret will return the reply value -1, 0, or 1.
|
||||
* @return 1= *cmp_ret is a valid reply
|
||||
* 0= not both streams are of ifs_class,
|
||||
* *cmp_ret is only a rough estimation.
|
||||
*/
|
||||
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int flag);
|
||||
int iso_ifs_sections_cmp(IsoFileSource *s1, IsoFileSource *s2, int *cmp_ret,
|
||||
int flag);
|
||||
|
||||
|
||||
/* Create an independent copy of an ifs_class IsoFileSource.
|
||||
|
@ -115,8 +115,8 @@ uint8_t get_class (uint16_t v)
|
||||
return hfsplus_class_pages[high][low];
|
||||
}
|
||||
|
||||
static
|
||||
int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
|
||||
int iso_get_hfsplus_name(char *input_charset, int imgid, char *name,
|
||||
uint16_t **result, uint32_t *result_len, uint16_t **cmp_name)
|
||||
{
|
||||
int ret;
|
||||
uint16_t *ucs_name, *iptr, *optr;
|
||||
@ -128,19 +128,19 @@ int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
ret = str2ucs(t->input_charset, name, &ucs_name);
|
||||
ret = str2utf16be(input_charset, name, &ucs_name);
|
||||
if (ret < 0) {
|
||||
iso_msg_debug(t->image->id, "Can't convert %s", name);
|
||||
iso_msg_debug(imgid, "Cannot convert '%s'", name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
curlen = ucslen (ucs_name);
|
||||
node->name = calloc ((curlen * HFSPLUS_MAX_DECOMPOSE_LEN + 1),
|
||||
sizeof (node->name[0]));
|
||||
if (!node->name)
|
||||
return ISO_OUT_OF_MEM;
|
||||
*result = calloc ((curlen * HFSPLUS_MAX_DECOMPOSE_LEN + 1),
|
||||
sizeof (uint16_t));
|
||||
if (*result == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
for (iptr = ucs_name, optr = node->name; *iptr; iptr++)
|
||||
for (iptr = ucs_name, optr = *result; *iptr; iptr++)
|
||||
{
|
||||
const uint16_t *dptr;
|
||||
uint16_t val = iso_ntohs (*iptr);
|
||||
@ -189,7 +189,7 @@ int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
|
||||
if (!ucs_name[0])
|
||||
break;
|
||||
last_class = get_class (ucs_name[0]);
|
||||
for (optr = node->name + 1; *optr; optr++)
|
||||
for (optr = *result + 1; *optr; optr++)
|
||||
{
|
||||
uint8_t new_class = get_class (*optr);
|
||||
|
||||
@ -207,11 +207,11 @@ int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
|
||||
}
|
||||
while (done);
|
||||
|
||||
node->cmp_name = calloc ((ucslen (node->name) + 1), sizeof (node->cmp_name[0]));
|
||||
if (!node->cmp_name)
|
||||
*cmp_name = calloc ((ucslen (*result) + 1), sizeof (uint16_t));
|
||||
if (*cmp_name == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
for (iptr = node->name, optr = node->cmp_name; *iptr; iptr++)
|
||||
for (iptr = *result, optr = *cmp_name; *iptr; iptr++)
|
||||
{
|
||||
*optr = iso_hfsplus_cichar(*iptr);
|
||||
if (*optr != 0)
|
||||
@ -221,10 +221,19 @@ int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
|
||||
|
||||
free (ucs_name);
|
||||
|
||||
node->strlen = ucslen (node->name);
|
||||
*result_len = ucslen (*result);
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int set_hfsplus_name(Ecma119Image *t, char *name, HFSPlusNode *node)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iso_get_hfsplus_name(t->input_charset, t->image->id, name,
|
||||
&(node->name), &(node->strlen), &(node->cmp_name));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* >>> ts B20617
|
||||
This should be HFSPlusNode rather than IsoNode in order to have access
|
||||
@ -429,7 +438,7 @@ int hfsplus_tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
block_size = t->hfsp_block_size;
|
||||
block_size = t->opts->hfsp_block_size;
|
||||
block_fac = t->hfsp_iso_block_fac;
|
||||
|
||||
#ifdef Libisofs_ts_debuG
|
||||
@ -466,7 +475,8 @@ int hfsplus_tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
|
||||
t->hfsp_total_blocks = hfsp_curblock - t->hfsp_part_start;
|
||||
|
||||
return iso_quick_apm_entry(t, t->hfsp_part_start / block_fac,
|
||||
return iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
|
||||
t->hfsp_part_start / block_fac,
|
||||
t->hfsp_total_blocks / block_fac +
|
||||
!!(t->hfsp_total_blocks % block_fac),
|
||||
"HFSPLUS_Hybrid", "Apple_HFS");
|
||||
@ -477,17 +487,16 @@ static
|
||||
int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *t;
|
||||
uint32_t i, link_blocks, hfsp_curblock;
|
||||
uint32_t block_fac, cat_node_size, block_size;
|
||||
uint32_t i, hfsp_curblock;
|
||||
uint32_t block_fac, block_size;
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
block_size = t->hfsp_block_size;
|
||||
block_size = t->opts->hfsp_block_size;
|
||||
block_fac = t->hfsp_iso_block_fac;
|
||||
cat_node_size = t->hfsp_cat_node_size;
|
||||
|
||||
iso_msg_debug(t->image->id, "(b) curblock=%d, nodes =%d", t->curblock, t->hfsp_nnodes);
|
||||
t->hfsp_part_start = t->curblock * block_fac;
|
||||
@ -500,7 +509,7 @@ int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
t->hfsp_catalog_file_start = hfsp_curblock;
|
||||
|
||||
/*
|
||||
hfsp_curblock += (t->hfsp_nnodes * cat_node_size + block_size - 1) / block_size;
|
||||
hfsp_curblock += (t->hfsp_nnodes * t->hfsp_cat_node_size + block_size - 1) / block_size;
|
||||
*/
|
||||
hfsp_curblock += 2 * t->hfsp_nnodes;
|
||||
|
||||
@ -509,7 +518,6 @@ int hfsplus_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
|
||||
iso_msg_debug(t->image->id, "(d) hfsp_curblock=%d, nodes =%d", hfsp_curblock, t->hfsp_nnodes);
|
||||
|
||||
link_blocks = 0;
|
||||
for (i = 0; i < t->hfsp_nleafs; i++)
|
||||
if (t->hfsp_leafs[i].unix_type == UNIX_SYMLINK)
|
||||
{
|
||||
@ -584,7 +592,7 @@ write_sb (Ecma119Image *t)
|
||||
|
||||
iso_msg_debug(t->image->id, "Write HFS+ superblock");
|
||||
|
||||
block_size = t->hfsp_block_size;
|
||||
block_size = t->opts->hfsp_block_size;
|
||||
|
||||
memset (buffer, 0, sizeof (buffer));
|
||||
ret = iso_write(t, buffer, 1024);
|
||||
@ -644,7 +652,7 @@ write_sb (Ecma119Image *t)
|
||||
|
||||
}
|
||||
|
||||
memcpy (&sb.num_serial, &t->hfsp_serial_number, 8);
|
||||
memcpy (&sb.num_serial, &t->opts->hfsp_serial_number, 8);
|
||||
ret = iso_write(t, &sb, sizeof (sb));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -667,7 +675,7 @@ int hfsplus_writer_write_data(IsoImageWriter *writer)
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
block_size = t->hfsp_block_size;
|
||||
block_size = t->opts->hfsp_block_size;
|
||||
block_fac = t->hfsp_iso_block_fac;
|
||||
cat_node_size = t->hfsp_cat_node_size;
|
||||
|
||||
@ -1035,7 +1043,7 @@ int hfsplus_tail_writer_write_data(IsoImageWriter *writer)
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
block_size = t->hfsp_block_size;
|
||||
block_size = t->opts->hfsp_block_size;
|
||||
|
||||
#ifdef Libisofs_ts_debuG
|
||||
iso_msg_debug(t->image->id, "hfsplus tail writer writes at = %.f",
|
||||
@ -1227,7 +1235,7 @@ int update_symlink(Ecma119Image *target, uint32_t changed_idx, char *new_name,
|
||||
char *orig_dest, *orig_start, *orig_end;
|
||||
char *hfsp_dest, *hfsp_start, *hfsp_end;
|
||||
int ret = 0;
|
||||
unsigned int comp_len, orig_len, hfsp_len, hfsp_comp_len;
|
||||
unsigned int comp_len, orig_len, hfsp_len;
|
||||
|
||||
if (target->hfsp_leafs[link_idx].node->type != LIBISO_SYMLINK)
|
||||
return ISO_SUCCESS;
|
||||
@ -1271,7 +1279,6 @@ int update_symlink(Ecma119Image *target, uint32_t changed_idx, char *new_name,
|
||||
hfsp_end = strchr(hfsp_start, '/');
|
||||
if (hfsp_end == NULL)
|
||||
hfsp_end = hfsp_start + strlen(hfsp_start);
|
||||
hfsp_comp_len = hfsp_end - hfsp_start;
|
||||
|
||||
if (comp_len == 0 || (comp_len == 1 && orig_start[0] == '.'))
|
||||
continue;
|
||||
@ -1582,10 +1589,10 @@ int hfsplus_writer_create(Ecma119Image *target)
|
||||
make_hfsplus_decompose_pages();
|
||||
make_hfsplus_class_pages();
|
||||
|
||||
if (target->hfsp_block_size == 0)
|
||||
target->hfsp_block_size = HFSPLUS_DEFAULT_BLOCK_SIZE;
|
||||
target->hfsp_cat_node_size = 2 * target->hfsp_block_size;
|
||||
target->hfsp_iso_block_fac = 2048 / target->hfsp_block_size;
|
||||
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;
|
||||
cat_node_size = target->hfsp_cat_node_size;
|
||||
|
||||
writer->compute_data_blocks = hfsplus_writer_compute_data_blocks;
|
||||
|
@ -194,4 +194,8 @@ void make_hfsplus_class_pages();
|
||||
|
||||
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);
|
||||
|
||||
|
||||
#endif /* LIBISO_HFSPLUS_H */
|
||||
|
346
libisofs/image.c
346
libisofs/image.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 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,100 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int iso_imported_sa_new(struct iso_imported_sys_area **boots, int flag)
|
||||
{
|
||||
struct iso_imported_sys_area *b;
|
||||
|
||||
*boots = NULL;
|
||||
b = calloc(1, sizeof(struct iso_imported_sys_area));
|
||||
if (b == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
b->mbr_req = NULL;
|
||||
b->apm_req = NULL;
|
||||
|
||||
b->gpt_req = NULL;
|
||||
b->gpt_backup_comments = NULL;
|
||||
|
||||
b->mips_boot_file_paths = NULL;
|
||||
b->mips_vd_entries = NULL;
|
||||
|
||||
b->sparc_disc_label = NULL;
|
||||
b->sparc_core_node = NULL;
|
||||
b->sparc_entries = NULL;
|
||||
|
||||
b->hppa_cmdline = NULL;
|
||||
b->hppa_bootloader = NULL;
|
||||
b->hppa_kernel_32 = NULL;
|
||||
b->hppa_kernel_64 = NULL;
|
||||
b->hppa_ramdisk = NULL;
|
||||
|
||||
b->alpha_boot_image = NULL;
|
||||
|
||||
*boots = b;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int iso_imported_sa_unref(struct iso_imported_sys_area **boots, int flag)
|
||||
{
|
||||
int i;
|
||||
struct iso_imported_sys_area *b;
|
||||
|
||||
b = *boots;
|
||||
if (b == NULL)
|
||||
return 2;
|
||||
if (b->refcount > 0)
|
||||
b->refcount--;
|
||||
if (b->refcount > 0)
|
||||
return 2;
|
||||
|
||||
if (b->mbr_req != NULL) {
|
||||
for (i = 0; i < b->mbr_req_count; i++)
|
||||
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++)
|
||||
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++)
|
||||
LIBISO_FREE_MEM(b->gpt_req[i]);
|
||||
LIBISO_FREE_MEM(b->gpt_req);
|
||||
}
|
||||
LIBISO_FREE_MEM(b->gpt_backup_comments);
|
||||
|
||||
if (b->mips_boot_file_paths != NULL) {
|
||||
for (i = 0; i < b->num_mips_boot_files; i++)
|
||||
LIBISO_FREE_MEM(b->mips_boot_file_paths[i]);
|
||||
LIBISO_FREE_MEM(b->mips_boot_file_paths);
|
||||
}
|
||||
if (b->mips_vd_entries != NULL) {
|
||||
for (i = 0; i < b->num_mips_boot_files; i++)
|
||||
LIBISO_FREE_MEM(b->mips_vd_entries[i]);
|
||||
LIBISO_FREE_MEM(b->mips_vd_entries);
|
||||
}
|
||||
LIBISO_FREE_MEM(b->mipsel_boot_file_path);
|
||||
|
||||
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_entries);
|
||||
|
||||
LIBISO_FREE_MEM(b->hppa_cmdline);
|
||||
LIBISO_FREE_MEM(b->hppa_bootloader);
|
||||
LIBISO_FREE_MEM(b->hppa_kernel_32);
|
||||
LIBISO_FREE_MEM(b->hppa_kernel_64);
|
||||
LIBISO_FREE_MEM(b->hppa_ramdisk);
|
||||
LIBISO_FREE_MEM(b->alpha_boot_image);
|
||||
LIBISO_FREE_MEM(b);
|
||||
*boots = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new image, empty.
|
||||
*
|
||||
@ -78,11 +172,20 @@ int iso_image_new(const char *name, IsoImage **image)
|
||||
img->volset_id = strdup(name);
|
||||
img->volume_id = strdup(name);
|
||||
}
|
||||
memset(img->application_use, 0, 512);
|
||||
img->system_area_data = NULL;
|
||||
img->system_area_options = 0;
|
||||
img->num_mips_boot_files = 0;
|
||||
for (i = 0; i < 15; i++)
|
||||
img->mips_boot_file_paths[i] = NULL;
|
||||
img->sparc_core_node = NULL;
|
||||
img->hppa_cmdline= NULL;
|
||||
img->hppa_bootloader = NULL;
|
||||
img->hppa_kernel_32 = NULL;
|
||||
img->hppa_kernel_64 = NULL;
|
||||
img->hppa_ramdisk = NULL;
|
||||
img->alpha_boot_image = NULL;
|
||||
img->import_src = NULL;
|
||||
img->builder_ignore_acl = 1;
|
||||
img->builder_ignore_ea = 1;
|
||||
img->inode_counter = 0;
|
||||
@ -95,6 +198,8 @@ int iso_image_new(const char *name, IsoImage **image)
|
||||
img->generator_is_running = 0;
|
||||
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
|
||||
img->hfsplus_blessed[i] = NULL;
|
||||
img->collision_warnings = 0;
|
||||
img->imported_sa_info = NULL;
|
||||
|
||||
*image = img;
|
||||
return ISO_SUCCESS;
|
||||
@ -136,6 +241,13 @@ void iso_image_unref(IsoImage *image)
|
||||
iso_filesystem_unref(image->fs);
|
||||
el_torito_boot_catalog_free(image->bootcat);
|
||||
iso_image_give_up_mips_boot(image, 0);
|
||||
if (image->sparc_core_node != NULL)
|
||||
iso_node_unref((IsoNode *) image->sparc_core_node);
|
||||
iso_image_set_hppa_palo(image, NULL, NULL, NULL, NULL, NULL, 1);
|
||||
if (image->alpha_boot_image != NULL)
|
||||
free(image->alpha_boot_image);
|
||||
if (image->import_src != NULL)
|
||||
iso_data_source_unref(image->import_src);
|
||||
free(image->volset_id);
|
||||
free(image->volume_id);
|
||||
free(image->publisher_id);
|
||||
@ -154,6 +266,7 @@ void iso_image_unref(IsoImage *image)
|
||||
if (image->system_area_data != NULL)
|
||||
free(image->system_area_data);
|
||||
iso_image_free_checksums(image, 0);
|
||||
iso_imported_sa_unref(&(image->imported_sa_info), 0);
|
||||
free(image);
|
||||
}
|
||||
}
|
||||
@ -346,13 +459,18 @@ int iso_image_set_pvd_times(IsoImage *image,
|
||||
if (creation_time == NULL || modification_time == NULL ||
|
||||
expiration_time == NULL || effective_time == NULL)
|
||||
return ISO_NULL_POINTER;
|
||||
image->creation_time = strdup(creation_time);
|
||||
image->modification_time = strdup(modification_time);
|
||||
image->expiration_time = strdup(expiration_time);
|
||||
image->effective_time = strdup(effective_time);
|
||||
image->creation_time = calloc(18, 1); /* Surely including a trailing 0 */
|
||||
image->modification_time = calloc(18, 1);
|
||||
image->expiration_time = calloc(18, 1);
|
||||
image->effective_time = calloc(18, 1);
|
||||
if (image->creation_time == NULL || image->modification_time == NULL ||
|
||||
image->expiration_time == NULL || image->effective_time == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
/* (If the string is too short, a non-zero timezone will not be stored) */
|
||||
strncpy(image->creation_time, creation_time, 17);
|
||||
strncpy(image->modification_time, modification_time, 17);
|
||||
strncpy(image->expiration_time, expiration_time, 17);
|
||||
strncpy(image->effective_time, effective_time, 17);
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -370,6 +488,19 @@ int iso_image_get_pvd_times(IsoImage *image,
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
void iso_image_set_app_use(IsoImage *image, const char *app_use_data,
|
||||
int count)
|
||||
{
|
||||
if (count < 0)
|
||||
count= 0;
|
||||
else if(count > 512)
|
||||
count= 512;
|
||||
if (count > 0)
|
||||
memcpy(image->application_use, app_use_data, count);
|
||||
if (count < 512)
|
||||
memset(image->application_use + count, 0, 512 - count);
|
||||
}
|
||||
|
||||
int iso_image_get_msg_id(IsoImage *image)
|
||||
{
|
||||
return image->id;
|
||||
@ -389,21 +520,74 @@ static
|
||||
int dir_update_size(IsoImage *image, IsoDir *dir)
|
||||
{
|
||||
IsoNode *pos;
|
||||
int ret;
|
||||
|
||||
#ifdef Libisofs_update_sizes_abortablE
|
||||
char *path= NULL;
|
||||
IsoStream *base_stream;
|
||||
int cancel_ret, ret;
|
||||
uint32_t lba;
|
||||
#endif
|
||||
|
||||
pos = dir->children;
|
||||
while (pos) {
|
||||
int ret = 1;
|
||||
if (pos->type == LIBISO_FILE) {
|
||||
ret = iso_stream_update_size(ISO_FILE(pos)->stream);
|
||||
} else if (pos->type == LIBISO_DIR) {
|
||||
/* recurse */
|
||||
ret = dir_update_size(image, ISO_DIR(pos));
|
||||
|
||||
#ifdef Libisofs_update_sizes_abortablE
|
||||
if (ret == ISO_CANCELED)
|
||||
return ret; /* Message already issued by dir_update_size */
|
||||
#endif
|
||||
|
||||
} else {
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_update_sizes_abortablE
|
||||
|
||||
/* This would report error and abort according to severity threshold.
|
||||
But it is desirable to let the update_size crawler continue
|
||||
its work after e.g. a file has vanished from hard disk.
|
||||
So normally this macro case should be disabled.
|
||||
*/
|
||||
|
||||
if (ret < 0) {
|
||||
ret = iso_msg_submit(image->id, ret, 0, NULL);
|
||||
if (ret < 0) {
|
||||
return ret; /* cancel due error threshold */
|
||||
cancel_ret = iso_msg_submit(image->id, ret, 0, NULL);
|
||||
path = iso_tree_get_node_path(pos);
|
||||
if (path != NULL) {
|
||||
iso_msg_submit(image->id, ret, 0,
|
||||
"ISO path : %s", path);
|
||||
free(path);
|
||||
}
|
||||
/* Report source path with streams which do not come from
|
||||
the loaded ISO filesystem */
|
||||
if (pos->type == LIBISO_FILE &&
|
||||
iso_node_get_old_image_lba(pos, &lba, 0) == 0) {
|
||||
base_stream = iso_stream_get_input_stream(
|
||||
ISO_FILE(pos)->stream, 1);
|
||||
if (base_stream == NULL)
|
||||
base_stream = ISO_FILE(pos)->stream;
|
||||
path = iso_stream_get_source_path(base_stream, 0);
|
||||
if (path != NULL) {
|
||||
iso_msg_submit(image->id, ret, 0,
|
||||
"Local path: %s", path);
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
if (cancel_ret < 0)
|
||||
return cancel_ret; /* cancel due error threshold */
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (ret < 0)
|
||||
ret = 1; /* ignore error */
|
||||
|
||||
#endif /* ! Libisofs_update_sizes_abortablE */
|
||||
|
||||
pos = pos->next;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
@ -499,7 +683,8 @@ ex:;
|
||||
|
||||
|
||||
/**
|
||||
* A global counter for inode numbers for the ISO image filesystem.
|
||||
* A global counter for Rock Ridge inode numbers in the ISO image filesystem.
|
||||
*
|
||||
* On image import it gets maxed by the eventual inode numbers from PX
|
||||
* entries. Up to the first 32 bit rollover it simply increments the counter.
|
||||
* After the first rollover it uses a look ahead bitmap which gets filled
|
||||
@ -509,13 +694,13 @@ ex:;
|
||||
* @param image The image where the number shall be used
|
||||
* @param flag bit0= reset count (Caution: image must get new inos then)
|
||||
* @return
|
||||
* Since ino_t 0 is used as default and considered self-unique,
|
||||
* Since 0 is used as default and considered self-unique,
|
||||
* the value 0 should only be returned in case of error.
|
||||
*/
|
||||
ino_t img_give_ino_number(IsoImage *image, int flag)
|
||||
uint32_t img_give_ino_number(IsoImage *image, int flag)
|
||||
{
|
||||
int ret;
|
||||
ino_t new_ino, ino_idx;
|
||||
uint64_t new_ino, ino_idx;
|
||||
static uint64_t limit = 0xffffffff;
|
||||
|
||||
if (flag & 1) {
|
||||
@ -525,10 +710,10 @@ ino_t img_give_ino_number(IsoImage *image, int flag)
|
||||
image->used_inodes = NULL;
|
||||
image->used_inodes_start = 0;
|
||||
}
|
||||
new_ino = image->inode_counter + 1;
|
||||
new_ino = ((uint64_t) image->inode_counter) + 1;
|
||||
if (image->used_inodes == NULL) {
|
||||
if (new_ino > 0 && new_ino <= limit) {
|
||||
image->inode_counter = new_ino;
|
||||
image->inode_counter = (uint32_t) new_ino;
|
||||
return image->inode_counter;
|
||||
}
|
||||
}
|
||||
@ -767,3 +952,134 @@ int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_image_set_sparc_core(IsoImage *img, IsoFile *sparc_core, int flag)
|
||||
{
|
||||
if (img->sparc_core_node != NULL)
|
||||
iso_node_unref((IsoNode *) img->sparc_core_node);
|
||||
img->sparc_core_node = sparc_core;
|
||||
if (sparc_core != NULL)
|
||||
iso_node_ref((IsoNode *) sparc_core);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag)
|
||||
{
|
||||
*sparc_core = img->sparc_core_node;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* @param flag
|
||||
bit0= Let NULL parameters free the corresponding image properties.
|
||||
Else only the non-NULL parameters of this call have an effect.
|
||||
*/
|
||||
static int hppa_palo_set_path(IsoImage *img, char *path, char **target,
|
||||
char *what, int flag)
|
||||
{
|
||||
int ret, err;
|
||||
IsoNode *node;
|
||||
IsoFile *file;
|
||||
|
||||
if (path == NULL && !(flag & 1))
|
||||
return ISO_SUCCESS;
|
||||
if (iso_clone_mgtd_mem(path, target, 0) < 0)
|
||||
return ISO_OUT_OF_MEM;
|
||||
if (path == NULL)
|
||||
return ISO_SUCCESS;
|
||||
ret = iso_tree_path_to_node(img, path, &node);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret == 0) {
|
||||
iso_msg_submit(img->id, ISO_BOOT_FILE_MISSING, 0,
|
||||
"Cannot find in ISO image: %s file '%s'", what, path);
|
||||
return ISO_BOOT_FILE_MISSING;
|
||||
}
|
||||
if (iso_node_get_type(node) != LIBISO_FILE) {
|
||||
err = ISO_HPPA_PALO_NOTREG;
|
||||
if (strncmp(what, "DEC Alpha", 9) == 0)
|
||||
err = ISO_ALPHA_BOOT_NOTREG;
|
||||
iso_msg_submit(img->id, err, 0,
|
||||
"%s file is not a data file: '%s'", what, path);
|
||||
return err;
|
||||
}
|
||||
file = (IsoFile *) node;
|
||||
if (!(file->explicit_weight || file->from_old_session))
|
||||
file->sort_weight = 2;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
/* @param flag
|
||||
Bitfield for control purposes
|
||||
bit0= Let NULL parameters free the corresponding image properties.
|
||||
Else only the non-NULL parameters of this call have an effect.
|
||||
*/
|
||||
int iso_image_set_hppa_palo(IsoImage *img, char *cmdline, char *bootloader,
|
||||
char *kernel_32, char *kernel_64, char *ramdisk,
|
||||
int flag)
|
||||
{
|
||||
int ret;
|
||||
static char *what = "HP-PA PALO";
|
||||
|
||||
if (cmdline != NULL || (flag & 1))
|
||||
if (iso_clone_mgtd_mem(cmdline, &(img->hppa_cmdline), 0) < 0)
|
||||
return ISO_OUT_OF_MEM;
|
||||
ret = hppa_palo_set_path(img, bootloader, &(img->hppa_bootloader), what,
|
||||
flag & 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = hppa_palo_set_path(img, kernel_32, &(img->hppa_kernel_32), what,
|
||||
flag & 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = hppa_palo_set_path(img, kernel_64, &(img->hppa_kernel_64), what,
|
||||
flag & 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = hppa_palo_set_path(img, ramdisk, &(img->hppa_ramdisk), what,
|
||||
flag & 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_image_get_hppa_palo(IsoImage *img, char **cmdline, char **bootloader,
|
||||
char **kernel_32, char **kernel_64, char **ramdisk)
|
||||
{
|
||||
*cmdline = img->hppa_cmdline;
|
||||
*bootloader = img->hppa_bootloader;
|
||||
*kernel_32 = img->hppa_kernel_32;
|
||||
*kernel_64 = img->hppa_kernel_64;
|
||||
*ramdisk = img->hppa_ramdisk;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_image_set_alpha_boot(IsoImage *img, char *boot_loader_path, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = hppa_palo_set_path(img, boot_loader_path, &(img->alpha_boot_image),
|
||||
"DEC Alpha Bootloader", 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_image_get_alpha_boot(IsoImage *img, char **boot_loader_path)
|
||||
{
|
||||
*boot_loader_path = img->alpha_boot_image;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
183
libisofs/image.h
183
libisofs/image.h
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 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,9 @@
|
||||
*/
|
||||
#define ISO_USED_INODE_RANGE (1 << 18)
|
||||
|
||||
/* How many warnings to issue about name collisions during iso_image_import()
|
||||
*/
|
||||
#define ISO_IMPORT_COLL_WARN_MAX 10
|
||||
|
||||
/*
|
||||
* Image is a context for image manipulation.
|
||||
@ -53,6 +56,7 @@ struct Iso_Image
|
||||
char *modification_time;
|
||||
char *expiration_time;
|
||||
char *effective_time;
|
||||
char application_use[512];
|
||||
|
||||
/* el-torito boot catalog */
|
||||
struct el_torito_boot_catalog *bootcat;
|
||||
@ -60,6 +64,8 @@ struct Iso_Image
|
||||
/* Eventually loaded system area data, or NULL */
|
||||
char *system_area_data;
|
||||
/* Prescribed/detected options, see iso_write_opts_set_system_area() */
|
||||
/* >>> Needs to be coordinated with .imported_sa_info->system_area_options
|
||||
*/
|
||||
int system_area_options;
|
||||
|
||||
/*
|
||||
@ -69,6 +75,23 @@ struct Iso_Image
|
||||
int num_mips_boot_files;
|
||||
char *mips_boot_file_paths[15]; /* ISO 9660 Rock Ridge Paths */
|
||||
|
||||
/* A data file of which the position and size shall be written after
|
||||
a SUN Disk Label.
|
||||
*/
|
||||
IsoFile *sparc_core_node;
|
||||
|
||||
/*
|
||||
* Parameters for HP-PA PALO boot sector. cmdline is a string. The other
|
||||
* four are absolute paths to data files in the ISO image.
|
||||
*/
|
||||
char *hppa_cmdline;
|
||||
char *hppa_bootloader;
|
||||
char *hppa_kernel_32;
|
||||
char *hppa_kernel_64;
|
||||
char *hppa_ramdisk;
|
||||
|
||||
/* Absolute DEC Alpha boot image path in the ISO image */
|
||||
char *alpha_boot_image;
|
||||
|
||||
/* image identifier, for message origin identifier */
|
||||
int id;
|
||||
@ -78,6 +101,11 @@ struct Iso_Image
|
||||
*/
|
||||
IsoFilesystem *fs;
|
||||
|
||||
/**
|
||||
* Block storage of imported ISO if demanded by IsoReadOpts.
|
||||
*/
|
||||
IsoDataSource *import_src;
|
||||
|
||||
/*
|
||||
* Default builder to use when adding files to the image tree.
|
||||
*/
|
||||
@ -153,18 +181,20 @@ struct Iso_Image
|
||||
* Inode number management. inode_counter is taken over from
|
||||
* IsoImageFilesystem._ImageFsData after image import.
|
||||
* It is to be used with img_give_ino_number()
|
||||
*/
|
||||
ino_t inode_counter;
|
||||
* This is a Rock Ridge file serial number. Thus 32 bit.
|
||||
*/
|
||||
uint32_t inode_counter;
|
||||
/*
|
||||
* A bitmap of used inode numbers in an interval beginning at
|
||||
* used_inodes_start and holding ISO_USED_INODE_RANGE bits.
|
||||
* If a bit is set, then the corresponding inode number is occupied.
|
||||
* This interval is kept around inode_counter and eventually gets
|
||||
* advanced by ISO_USED_INODE_RANGE numbers in a tree traversal
|
||||
* done by img_collect_inos().
|
||||
* done by img_collect_inos(). The value will stay in the 32 bit range,
|
||||
* although used_inodes_start is 64 bit to better handle rollovers.
|
||||
*/
|
||||
uint8_t *used_inodes;
|
||||
ino_t used_inodes_start;
|
||||
uint64_t used_inodes_start;
|
||||
|
||||
/**
|
||||
* Array of MD5 checksums as announced by xattr "isofs.ca" of the
|
||||
@ -191,6 +221,12 @@ struct Iso_Image
|
||||
*/
|
||||
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
||||
|
||||
/* Counts the name collisions while iso_image_import() */
|
||||
size_t collision_warnings;
|
||||
|
||||
/* Contains the assessment of boot aspects of the loaded image */
|
||||
struct iso_imported_sys_area *imported_sa_info;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -212,10 +248,10 @@ int img_collect_inos(IsoImage *image, IsoDir *dir, int flag);
|
||||
* @param image The image where the number shall be used
|
||||
* @param flag bit0= reset count (Caution: image must get new inos then)
|
||||
* @return
|
||||
* Since ino_t 0 is used as default and considered self-unique,
|
||||
* Since 0 is used as default and considered self-unique,
|
||||
* the value 0 should only be returned in case of error.
|
||||
*/
|
||||
ino_t img_give_ino_number(IsoImage *image, int flag);
|
||||
uint32_t img_give_ino_number(IsoImage *image, int flag);
|
||||
|
||||
/* @param flag bit0= overwrite any ino, else only ino == 0
|
||||
bit1= install inode with non-data, non-directory files
|
||||
@ -242,4 +278,137 @@ int iso_image_set_pvd_times(IsoImage *image,
|
||||
char *creation_time, char *modification_time,
|
||||
char *expiration_time, char *effective_time);
|
||||
|
||||
|
||||
/* Collects boot block information obtained from the system area of
|
||||
imported images
|
||||
*/
|
||||
struct iso_imported_sys_area {
|
||||
|
||||
int refcount;
|
||||
|
||||
/* Whether there was some System Area data at all */
|
||||
int is_not_zero;
|
||||
|
||||
/* Giving the error number if the assessment ended by an error */
|
||||
int overall_return;
|
||||
|
||||
/* Block address of loaded Primar Volume Descriptor */
|
||||
uint32_t pvd_block;
|
||||
|
||||
/* Size of the imported ISO image */
|
||||
uint32_t image_size;
|
||||
|
||||
/* see libisofs.h : iso_write_opts_set_system_area() */
|
||||
int system_area_options;
|
||||
|
||||
/* The perceived MBR partitions */
|
||||
struct iso_mbr_partition_request **mbr_req;
|
||||
int mbr_req_count;
|
||||
|
||||
/* see ecma119.h : struct ecma119_image , struct iso_write_opts */
|
||||
/* Effective partition table parameter: 1 to 63, 0= disabled/default */
|
||||
int partition_secs_per_head;
|
||||
/* 1 to 255, 0= disabled/default */
|
||||
int partition_heads_per_cyl;
|
||||
|
||||
/* see ecma119.h : struct iso_write_opts */
|
||||
uint32_t partition_offset;
|
||||
|
||||
/* 2048-byte start LBA and block count of PreP partition */
|
||||
uint32_t prep_part_start;
|
||||
uint32_t prep_part_size;
|
||||
|
||||
/* see ecma119.h : struct ecma119_image */
|
||||
struct iso_apm_partition_request **apm_req;
|
||||
int apm_req_count;
|
||||
int apm_req_flags;
|
||||
/* Number of found "GapNN", "ISO9660_data" partitions in APM */
|
||||
int apm_gap_count;
|
||||
|
||||
/* see ecma119.h : struct iso_write_opts */
|
||||
int apm_block_size;
|
||||
|
||||
/* >>> see ecma119.h : struct iso_write_opts */
|
||||
int hfsp_block_size;
|
||||
|
||||
/* see ecma119.h : struct ecma119_image */
|
||||
struct iso_gpt_partition_request **gpt_req;
|
||||
int gpt_req_count;
|
||||
int gpt_req_flags;
|
||||
|
||||
/* see ecma119.h : struct ecma119_image */
|
||||
uint8_t gpt_disk_guid[16];
|
||||
/* Start of GPT entries in System Area, block size 512 */
|
||||
uint64_t gpt_part_start;
|
||||
uint32_t gpt_max_entries;
|
||||
uint64_t gpt_first_lba;
|
||||
uint64_t gpt_last_lba;
|
||||
uint64_t gpt_backup_lba;
|
||||
char *gpt_backup_comments;
|
||||
uint32_t gpt_head_crc_found;
|
||||
uint32_t gpt_head_crc_should;
|
||||
uint32_t gpt_array_crc_found;
|
||||
uint32_t gpt_array_crc_should;
|
||||
|
||||
/* see image.h : struct Iso_Image */
|
||||
int num_mips_boot_files;
|
||||
char **mips_boot_file_paths; /* ISO 9660 Rock Ridge Paths */
|
||||
struct iso_mips_voldir_entry **mips_vd_entries;
|
||||
|
||||
/* see ecma119.h : struct ecma119_image */
|
||||
/* Memorized ELF parameters from MIPS Little Endian boot file */
|
||||
uint32_t mipsel_e_entry;
|
||||
uint32_t mipsel_p_offset;
|
||||
uint32_t mipsel_p_vaddr;
|
||||
uint32_t mipsel_p_filesz;
|
||||
uint32_t mipsel_seg_start;
|
||||
char *mipsel_boot_file_path;
|
||||
|
||||
/* see image.h : struct Iso_Image */
|
||||
char *sparc_disc_label;
|
||||
int sparc_secs_per_head;
|
||||
int sparc_heads_per_cyl;
|
||||
struct iso_sun_disk_label_entry *sparc_entries;
|
||||
int sparc_entry_count;
|
||||
|
||||
/* grub2-sparc-core : a node in the ISO image
|
||||
published at bytes 0x228 to 0x233
|
||||
*/
|
||||
uint64_t sparc_grub2_core_adr;
|
||||
uint32_t sparc_grub2_core_size;
|
||||
IsoFile *sparc_core_node;
|
||||
|
||||
/* see image.h : struct Iso_Image */
|
||||
int hppa_hdrversion;
|
||||
char *hppa_cmdline;
|
||||
uint32_t hppa_kern32_adr;
|
||||
uint32_t hppa_kern32_len;
|
||||
uint32_t hppa_kern64_adr;
|
||||
uint32_t hppa_kern64_len;
|
||||
uint32_t hppa_ramdisk_adr;
|
||||
uint32_t hppa_ramdisk_len;
|
||||
uint32_t hppa_bootloader_adr;
|
||||
uint32_t hppa_bootloader_len;
|
||||
uint32_t hppa_ipl_entry;
|
||||
char *hppa_kernel_32;
|
||||
char *hppa_kernel_64;
|
||||
char *hppa_ramdisk;
|
||||
char *hppa_bootloader;
|
||||
|
||||
uint64_t alpha_boot_image_size;
|
||||
uint64_t alpha_boot_image_adr;
|
||||
char *alpha_boot_image;
|
||||
|
||||
/* Some block addresses of active and first session:
|
||||
PVD, L Pathtable, Opt L, M Pathtable, Opt M, root directory
|
||||
*/
|
||||
uint32_t meta_struct_blocks[12];
|
||||
int num_meta_struct_blocks;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
|
||||
#endif /*LIBISO_IMAGE_H_*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2011-2012 Thomas Schmitt
|
||||
* Copyright (c) 2011-2014 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
|
||||
@ -80,7 +80,8 @@ void iso1999_node_free(Iso1999Node *node)
|
||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||
iso1999_node_free(node->info.dir->children[i]);
|
||||
}
|
||||
free(node->info.dir->children);
|
||||
if (node->info.dir->children != NULL)
|
||||
free(node->info.dir->children);
|
||||
free(node->info.dir);
|
||||
}
|
||||
iso_node_unref(node->node);
|
||||
@ -111,11 +112,14 @@ int create_node(Ecma119Image *t, IsoNode *iso, Iso1999Node **node)
|
||||
free(n);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
n->info.dir->children = calloc(sizeof(void*), dir->nchildren);
|
||||
if (n->info.dir->children == NULL) {
|
||||
free(n->info.dir);
|
||||
free(n);
|
||||
return ISO_OUT_OF_MEM;
|
||||
n->info.dir->children = NULL;
|
||||
if (dir->nchildren > 0) {
|
||||
n->info.dir->children = calloc(sizeof(void*), dir->nchildren);
|
||||
if (n->info.dir->children == NULL) {
|
||||
free(n->info.dir);
|
||||
free(n);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
}
|
||||
n->type = ISO1999_DIR;
|
||||
} else if (iso->type == LIBISO_FILE) {
|
||||
@ -125,7 +129,7 @@ int create_node(Ecma119Image *t, IsoNode *iso, Iso1999Node **node)
|
||||
IsoFile *file = (IsoFile*) iso;
|
||||
|
||||
size = iso_stream_get_size(file->stream);
|
||||
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && t->iso_level != 3) {
|
||||
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && t->opts->iso_level != 3) {
|
||||
char *ipath = iso_tree_get_node_path(iso);
|
||||
ret = iso_msg_submit(t->image->id, ISO_FILE_TOO_BIG, 0,
|
||||
"File \"%s\" can't be added to image because is "
|
||||
@ -194,7 +198,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, Iso1999Node **tree, int pathlen)
|
||||
}
|
||||
|
||||
max_path = pathlen + 1 + (iso_name ? strlen(iso_name): 0);
|
||||
if (!t->allow_longer_paths && max_path > 255) {
|
||||
if (!t->opts->allow_longer_paths && max_path > 255) {
|
||||
char *ipath = iso_tree_get_node_path(iso);
|
||||
ret = iso_msg_submit(t->image->id, ISO_FILE_IMGPATH_WRONG, 0,
|
||||
"File \"%s\" can't be added to ISO 9660:1999 tree, "
|
||||
@ -293,6 +297,8 @@ void sort_tree(Iso1999Node *root)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (root->info.dir->children == NULL)
|
||||
return;
|
||||
qsort(root->info.dir->children, root->info.dir->nchildren,
|
||||
sizeof(void*), cmp_node);
|
||||
for (i = 0; i < root->info.dir->nchildren; i++) {
|
||||
@ -308,14 +314,18 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
||||
int ret;
|
||||
int i, nchildren;
|
||||
Iso1999Node **children;
|
||||
IsoHTable *table;
|
||||
IsoHTable *table = NULL;
|
||||
int need_sort = 0;
|
||||
char *full_name = NULL, *tmp = NULL;
|
||||
|
||||
nchildren = dir->info.dir->nchildren;
|
||||
if (nchildren <= 0) {
|
||||
ret = ISO_SUCCESS;
|
||||
goto ex;
|
||||
}
|
||||
children = dir->info.dir->children;
|
||||
LIBISO_ALLOC_MEM(full_name, char, 208);
|
||||
LIBISO_ALLOC_MEM(tmp, char, 208);
|
||||
nchildren = dir->info.dir->nchildren;
|
||||
children = dir->info.dir->children;
|
||||
|
||||
/* a hash table will temporary hold the names, for fast searching */
|
||||
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
||||
@ -722,13 +732,13 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
|
||||
iso_bb(rec->block, block, 4);
|
||||
iso_bb(rec->length, len, 4);
|
||||
|
||||
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||
/* was: iso_datetime_7(rec->recording_time, t->now, t->opts->always_gmt);
|
||||
*/
|
||||
iso= node->node;
|
||||
iso_datetime_7(rec->recording_time,
|
||||
(t->dir_rec_mtime & 4) ? ( t->replace_timestamps ?
|
||||
t->timestamp : iso->mtime )
|
||||
: t->now, t->always_gmt);
|
||||
(t->opts->dir_rec_mtime & 4) ? ( t->replace_timestamps ?
|
||||
t->timestamp : iso->mtime )
|
||||
: t->now, t->opts->always_gmt);
|
||||
|
||||
rec->flags[0] = ((node->type == ISO1999_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
||||
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2011-2012 Thomas Schmitt
|
||||
* Copyright (c) 2011-2014 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,31 +28,69 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static
|
||||
int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
|
||||
/* @param flag bit0= Do not issue error messages
|
||||
*/
|
||||
int iso_get_joliet_name(IsoWriteOpts *opts, char *input_charset, int imgid,
|
||||
char *node_name, enum IsoNodeType node_type,
|
||||
size_t *joliet_ucs2_failures,
|
||||
uint16_t **name, int flag)
|
||||
{
|
||||
int ret;
|
||||
uint16_t *ucs_name;
|
||||
int ret = ISO_SUCCESS;
|
||||
uint16_t *ucs_name = NULL, *utf16_name = NULL;
|
||||
uint16_t *jname = NULL;
|
||||
|
||||
if (iso->name == NULL) {
|
||||
if (node_name == NULL) {
|
||||
/* it is not necessarily an error, it can be the root */
|
||||
*name = NULL;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
ret = str2ucs(t->input_charset, iso->name, &ucs_name);
|
||||
if (ret < 0) {
|
||||
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
|
||||
return ret;
|
||||
if (opts->joliet_utf16) {
|
||||
ret = str2utf16be(input_charset, node_name, &ucs_name);
|
||||
if (ret < 0) {
|
||||
if (!(flag & 512))
|
||||
iso_msg_debug(imgid, "Cannot convert to UTF-16 : \"%s\"",
|
||||
node_name);
|
||||
goto ex;
|
||||
}
|
||||
} else {
|
||||
ret = str2ucs(input_charset, node_name, &ucs_name);
|
||||
if (ret < 0) {
|
||||
if (!(flag & 512))
|
||||
iso_msg_debug(imgid, "Cannot convert to UCS-2 : \"%s\"",
|
||||
node_name);
|
||||
goto ex;
|
||||
}
|
||||
ret = str2utf16be(input_charset, node_name, &utf16_name);
|
||||
if (ret == ISO_SUCCESS) {
|
||||
if (ucscmp(ucs_name, utf16_name) != 0) {
|
||||
(*joliet_ucs2_failures)++;
|
||||
if (*joliet_ucs2_failures <= ISO_JOLIET_UCS2_WARN_MAX &&
|
||||
!(flag & 512)) {
|
||||
iso_msg_submit(imgid, ISO_NAME_NOT_UCS2, 0,
|
||||
"Filename not suitable for Joliet character set UCS-2 : \"%s\"",
|
||||
node_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (iso->type == LIBISO_DIR) {
|
||||
jname = iso_j_dir_id(ucs_name, t->joliet_long_names << 1);
|
||||
if (node_type == LIBISO_DIR) {
|
||||
jname = iso_j_dir_id(ucs_name, opts->joliet_long_names << 1);
|
||||
} else {
|
||||
jname = iso_j_file_id(ucs_name,
|
||||
(t->joliet_long_names << 1) | !!(t->no_force_dots & 2));
|
||||
(opts->joliet_long_names << 1) | !!(opts->no_force_dots & 2));
|
||||
}
|
||||
free(ucs_name);
|
||||
if (jname != NULL) {
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (ucs_name != NULL)
|
||||
free(ucs_name);
|
||||
if (utf16_name != NULL)
|
||||
free(utf16_name);
|
||||
if (ret != ISO_SUCCESS) {
|
||||
if (jname != NULL)
|
||||
free(jname);
|
||||
return ret;
|
||||
} else if (jname != NULL) {
|
||||
*name = jname;
|
||||
return ISO_SUCCESS;
|
||||
} else {
|
||||
@ -64,6 +102,19 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = iso_get_joliet_name(t->opts, t->input_charset, t->image->id,
|
||||
iso->name, iso->type, &(t->joliet_ucs2_failures),
|
||||
name, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void joliet_node_free(JolietNode *node)
|
||||
{
|
||||
@ -75,7 +126,8 @@ void joliet_node_free(JolietNode *node)
|
||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||
joliet_node_free(node->info.dir->children[i]);
|
||||
}
|
||||
free(node->info.dir->children);
|
||||
if (node->info.dir->children != NULL)
|
||||
free(node->info.dir->children);
|
||||
free(node->info.dir);
|
||||
}
|
||||
iso_node_unref(node->node);
|
||||
@ -106,11 +158,14 @@ int create_node(Ecma119Image *t, IsoNode *iso, JolietNode **node)
|
||||
free(joliet);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
joliet->info.dir->children = calloc(sizeof(void*), dir->nchildren);
|
||||
if (joliet->info.dir->children == NULL) {
|
||||
free(joliet->info.dir);
|
||||
free(joliet);
|
||||
return ISO_OUT_OF_MEM;
|
||||
joliet->info.dir->children = NULL;
|
||||
if (dir->nchildren > 0) {
|
||||
joliet->info.dir->children = calloc(sizeof(void*), dir->nchildren);
|
||||
if (joliet->info.dir->children == NULL) {
|
||||
free(joliet->info.dir);
|
||||
free(joliet);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
}
|
||||
joliet->type = JOLIET_DIR;
|
||||
} else if (iso->type == LIBISO_FILE) {
|
||||
@ -120,7 +175,8 @@ int create_node(Ecma119Image *t, IsoNode *iso, JolietNode **node)
|
||||
IsoFile *file = (IsoFile*) iso;
|
||||
|
||||
size = iso_stream_get_size(file->stream);
|
||||
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && t->iso_level != 3) {
|
||||
if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE &&
|
||||
t->opts->iso_level != 3) {
|
||||
char *ipath = iso_tree_get_node_path(iso);
|
||||
free(joliet);
|
||||
ret = iso_msg_submit(t->image->id, ISO_FILE_TOO_BIG, 0,
|
||||
@ -188,7 +244,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
|
||||
return ret;
|
||||
}
|
||||
max_path = pathlen + 1 + (jname ? ucslen(jname) * 2 : 0);
|
||||
if (!t->joliet_longer_paths && max_path > 240) {
|
||||
if (!t->opts->joliet_longer_paths && max_path > 240) {
|
||||
char *ipath = iso_tree_get_node_path(iso);
|
||||
/*
|
||||
* Wow!! Joliet is even more restrictive than plain ISO-9660,
|
||||
@ -249,7 +305,7 @@ int create_tree(Ecma119Image *t, IsoNode *iso, JolietNode **tree, int pathlen)
|
||||
{
|
||||
char *ipath = iso_tree_get_node_path(iso);
|
||||
ret = iso_msg_submit(t->image->id, ISO_FILE_IGNORED, 0,
|
||||
"Can't add %s to Joliet tree. %s can only be added to a "
|
||||
"Cannot add %s to Joliet tree. %s can only be added to a "
|
||||
"Rock Ridge tree.", ipath, (iso->type == LIBISO_SYMLINK ?
|
||||
"Symlinks" : "Special files"));
|
||||
free(ipath);
|
||||
@ -281,6 +337,8 @@ void sort_tree(JolietNode *root)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (root->info.dir->children == NULL)
|
||||
return;
|
||||
qsort(root->info.dir->children, root->info.dir->nchildren,
|
||||
sizeof(void*), cmp_node);
|
||||
for (i = 0; i < root->info.dir->nchildren; i++) {
|
||||
@ -349,17 +407,21 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
int ret;
|
||||
int i, nchildren, maxchar = 64;
|
||||
JolietNode **children;
|
||||
IsoHTable *table;
|
||||
IsoHTable *table = NULL;
|
||||
int need_sort = 0;
|
||||
uint16_t *full_name = NULL;
|
||||
uint16_t *tmp = NULL;
|
||||
|
||||
nchildren = dir->info.dir->nchildren;
|
||||
if (nchildren <= 0) {
|
||||
ret = ISO_SUCCESS;
|
||||
goto ex;
|
||||
}
|
||||
children = dir->info.dir->children;
|
||||
LIBISO_ALLOC_MEM(full_name, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
LIBISO_ALLOC_MEM(tmp, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
nchildren = dir->info.dir->nchildren;
|
||||
children = dir->info.dir->children;
|
||||
|
||||
if (t->joliet_long_names)
|
||||
if (t->opts->joliet_long_names)
|
||||
maxchar = 103;
|
||||
|
||||
/* a hash table will temporary hold the names, for fast searching */
|
||||
@ -598,7 +660,7 @@ size_t calc_dirent_len(Ecma119Image *t, JolietNode *n)
|
||||
{
|
||||
/* note than name len is always even, so we always need the pad byte */
|
||||
int ret = n->name ? ucslen(n->name) * 2 + 34 : 34;
|
||||
if (n->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
|
||||
if (n->type == JOLIET_FILE && !(t->opts->omit_version_numbers & 3)) {
|
||||
/* take into account version numbers */
|
||||
ret += 4;
|
||||
}
|
||||
@ -717,7 +779,7 @@ int joliet_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
t->curblock += DIV_UP(path_table_size, BLOCK_SIZE);
|
||||
t->joliet_path_table_size = path_table_size;
|
||||
|
||||
if (t->partition_offset > 0) {
|
||||
if (t->opts->partition_offset > 0) {
|
||||
/* Take into respect second directory tree */
|
||||
ndirs = t->joliet_ndirs;
|
||||
t->joliet_ndirs = 0;
|
||||
@ -766,7 +828,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
||||
|
||||
memcpy(rec->file_id, name, len_fi);
|
||||
|
||||
if (node->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
|
||||
if (node->type == JOLIET_FILE && !(t->opts->omit_version_numbers & 3)) {
|
||||
len_dr += 4;
|
||||
rec->file_id[len_fi++] = 0;
|
||||
rec->file_id[len_fi++] = ';';
|
||||
@ -801,13 +863,13 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
||||
iso_bb(rec->block, block - t->eff_partition_offset, 4);
|
||||
iso_bb(rec->length, len, 4);
|
||||
|
||||
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||
/* was: iso_datetime_7(rec->recording_time, t->now, t->opts->always_gmt);
|
||||
*/
|
||||
iso= node->node;
|
||||
iso_datetime_7(rec->recording_time,
|
||||
(t->dir_rec_mtime & 2) ? ( t->replace_timestamps ?
|
||||
t->timestamp : iso->mtime )
|
||||
: t->now, t->always_gmt);
|
||||
(t->opts->dir_rec_mtime & 2) ? ( t->replace_timestamps ?
|
||||
t->timestamp : iso->mtime )
|
||||
: t->now, t->opts->always_gmt);
|
||||
|
||||
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
||||
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
|
||||
@ -828,18 +890,22 @@ void ucsncpy_pad(uint16_t *dest, const uint16_t *src, size_t max)
|
||||
csrc = (char*)src;
|
||||
|
||||
if (src != NULL) {
|
||||
len = MIN(ucslen(src) * 2, max);
|
||||
len = MIN(ucslen(src) * 2, max - (max % 2));
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
cdest[i] = csrc[i];
|
||||
if (len >= 2)
|
||||
iso_handle_split_utf16(dest + (len / 2 - 1));
|
||||
|
||||
for (i = len; i < max; i += 2) {
|
||||
for (i = len; i + 1 < max; i += 2) {
|
||||
cdest[i] = '\0';
|
||||
cdest[i + 1] = ' ';
|
||||
}
|
||||
if (max % 2)
|
||||
cdest[max - 1] = 0;
|
||||
}
|
||||
|
||||
int joliet_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
@ -958,7 +1024,8 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
|
||||
/* compute len of directory entry */
|
||||
fi_len = ucslen(child->name) * 2;
|
||||
len = fi_len + 34;
|
||||
if (child->type == JOLIET_FILE && !(t->omit_version_numbers & 3)) {
|
||||
if (child->type == JOLIET_FILE &&
|
||||
!(t->opts->omit_version_numbers & 3)) {
|
||||
len += 4;
|
||||
}
|
||||
|
||||
@ -1160,8 +1227,8 @@ int joliet_writer_write_data(IsoImageWriter *writer)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (t->partition_offset > 0) {
|
||||
t->eff_partition_offset = t->partition_offset;
|
||||
if (t->opts->partition_offset > 0) {
|
||||
t->eff_partition_offset = t->opts->partition_offset;
|
||||
ret = joliet_writer_write_dirs(writer);
|
||||
t->eff_partition_offset = 0;
|
||||
if (ret < 0)
|
||||
@ -1209,9 +1276,9 @@ int joliet_writer_create(Ecma119Image *target)
|
||||
/* add this writer to image */
|
||||
target->writers[target->nwriters++] = writer;
|
||||
|
||||
if(target->partition_offset > 0) {
|
||||
if(target->opts->partition_offset > 0) {
|
||||
/* Create second tree */
|
||||
target->eff_partition_offset = target->partition_offset;
|
||||
target->eff_partition_offset = target->opts->partition_offset;
|
||||
ret = joliet_tree_create(target);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
|
@ -63,5 +63,13 @@ int joliet_writer_create(Ecma119Image *target);
|
||||
*/
|
||||
int joliet_writer_write_vol_desc(IsoImageWriter *writer);
|
||||
|
||||
/**
|
||||
* Determine the Joliet name from node name.
|
||||
* @param flag bit0= Do not issue error messages
|
||||
*/
|
||||
int iso_get_joliet_name(IsoWriteOpts *opts, char *input_charset, int imgid,
|
||||
char *node_name, enum IsoNodeType node_type,
|
||||
size_t *joliet_ucs2_failures,
|
||||
uint16_t **name, int flag);
|
||||
|
||||
#endif /* LIBISO_JOLIET_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,6 +19,8 @@ el_torito_set_load_seg;
|
||||
el_torito_set_load_size;
|
||||
el_torito_set_no_bootable;
|
||||
el_torito_set_selection_crit;
|
||||
iso_conv_name_chars;
|
||||
iso_crc32_gpt;
|
||||
iso_data_source_new_from_file;
|
||||
iso_data_source_ref;
|
||||
iso_data_source_unref;
|
||||
@ -88,6 +90,8 @@ iso_image_fs_get_volume_id;
|
||||
iso_image_generator_is_running;
|
||||
iso_image_get_abstract_file_id;
|
||||
iso_image_get_all_boot_imgs;
|
||||
iso_image_get_alpha_boot;
|
||||
iso_image_get_app_use;
|
||||
iso_image_get_application_id;
|
||||
iso_image_get_attached_data;
|
||||
iso_image_get_biblio_file_id;
|
||||
@ -95,12 +99,14 @@ iso_image_get_bootcat;
|
||||
iso_image_get_boot_image;
|
||||
iso_image_get_copyright_file_id;
|
||||
iso_image_get_data_preparer_id;
|
||||
iso_image_get_hppa_palo;
|
||||
iso_image_get_mips_boot_files;
|
||||
iso_image_get_msg_id;
|
||||
iso_image_get_publisher_id;
|
||||
iso_image_get_pvd_times;
|
||||
iso_image_get_root;
|
||||
iso_image_get_session_md5;
|
||||
iso_image_get_sparc_core;
|
||||
iso_image_get_system_area;
|
||||
iso_image_get_system_id;
|
||||
iso_image_get_volset_id;
|
||||
@ -112,7 +118,11 @@ iso_image_import;
|
||||
iso_image_new;
|
||||
iso_image_ref;
|
||||
iso_image_remove_boot_image;
|
||||
iso_image_report_el_torito;
|
||||
iso_image_report_system_area;
|
||||
iso_image_set_abstract_file_id;
|
||||
iso_image_set_alpha_boot;
|
||||
iso_image_set_app_use;
|
||||
iso_image_set_application_id;
|
||||
iso_image_set_biblio_file_id;
|
||||
iso_image_set_boot_catalog_hidden;
|
||||
@ -120,8 +130,10 @@ iso_image_set_boot_catalog_weight;
|
||||
iso_image_set_boot_image;
|
||||
iso_image_set_copyright_file_id;
|
||||
iso_image_set_data_preparer_id;
|
||||
iso_image_set_hppa_palo;
|
||||
iso_image_set_ignore_aclea;
|
||||
iso_image_set_publisher_id;
|
||||
iso_image_set_sparc_core;
|
||||
iso_image_set_system_id;
|
||||
iso_image_set_volset_id;
|
||||
iso_image_set_volume_id;
|
||||
@ -129,6 +141,9 @@ iso_image_unref;
|
||||
iso_image_update_sizes;
|
||||
iso_init;
|
||||
iso_init_with_flag;
|
||||
iso_interval_reader_destroy;
|
||||
iso_interval_reader_new;
|
||||
iso_interval_reader_read;
|
||||
iso_lib_is_compatible;
|
||||
iso_lib_version;
|
||||
iso_local_attr_support;
|
||||
@ -204,6 +219,7 @@ iso_read_image_features_has_joliet;
|
||||
iso_read_image_features_has_rockridge;
|
||||
iso_read_opts_auto_input_charset;
|
||||
iso_read_opts_free;
|
||||
iso_read_opts_keep_import_src;
|
||||
iso_read_opts_load_system_area;
|
||||
iso_read_opts_new;
|
||||
iso_read_opts_set_default_gid;
|
||||
@ -280,6 +296,7 @@ iso_write_opts_set_allow_longer_paths;
|
||||
iso_write_opts_set_allow_lowercase;
|
||||
iso_write_opts_set_always_gmt;
|
||||
iso_write_opts_set_appendable;
|
||||
iso_write_opts_set_appended_as_gpt;
|
||||
iso_write_opts_set_default_dir_mode;
|
||||
iso_write_opts_set_default_file_mode;
|
||||
iso_write_opts_set_default_gid;
|
||||
@ -299,6 +316,7 @@ iso_write_opts_set_iso_level;
|
||||
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_ms_block;
|
||||
iso_write_opts_set_no_force_dots;
|
||||
|
@ -1,3 +1,13 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
@ -50,7 +60,7 @@ license from above stem licenses, typically from LGPL.
|
||||
In case its generosity is needed, here is the 2-clause BSD license:
|
||||
|
||||
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
|
||||
and 2008-2012 Thomas Schmitt
|
||||
and 2008-2014 Thomas Schmitt
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
@ -435,9 +445,10 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
||||
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
||||
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
||||
ret = iso_quick_gpt_entry(
|
||||
t, t->bootsrc[i]->sections[0].block,
|
||||
block_count, uuid, zero_uuid, gpt_flags,
|
||||
(uint8_t *) gpt_name);
|
||||
t->gpt_req, &(t->gpt_req_count),
|
||||
((uint64_t) t->bootsrc[i]->sections[0].block) * 4,
|
||||
((uint64_t) block_count) * 4,
|
||||
uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@ -449,13 +460,14 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
||||
block_count = 0;
|
||||
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
||||
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
||||
ret = iso_quick_apm_entry(t, t->bootsrc[i]->sections[0].block,
|
||||
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
|
||||
t->bootsrc[i]->sections[0].block,
|
||||
block_count, "EFI", "Apple_HFS");
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* Prevent gap filling */
|
||||
t->apm_req_flags |= 2;
|
||||
t->apm_block_size = 2048;
|
||||
t->opts->apm_block_size = 2048;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -466,7 +478,9 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
||||
iso_ascii_utf_16le(gpt_name);
|
||||
/* Let it be open ended. iso_write_gpt() will truncate it as needed. */
|
||||
block_count = 0xffffffff;
|
||||
ret = iso_quick_gpt_entry(t, (uint32_t) 0, block_count,
|
||||
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,
|
||||
(uint8_t *) gpt_name);
|
||||
if (ret < 0)
|
||||
@ -555,25 +569,31 @@ static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
|
||||
|
||||
/*
|
||||
* @param flag bit0= make own random MBR Id from current time
|
||||
* bit1= create protective MBR as of UEFI/GPT specs
|
||||
*/
|
||||
int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
|
||||
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;
|
||||
off_t hd_img_blocks, hd_boot_lba;
|
||||
char *wpt;
|
||||
uint32_t boot_lba, mbr_id;
|
||||
uint32_t boot_lba;
|
||||
int head_count, sector_count, ret;
|
||||
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor;
|
||||
/* For generating a weak random number */
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
||||
if (flag & 2) {
|
||||
part_number = 1;
|
||||
part_offset = 1;
|
||||
}
|
||||
|
||||
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4 -
|
||||
t->post_iso_part_pad / 512;
|
||||
|
||||
boot_lba = t->bootsrc[0]->sections[0].block;
|
||||
mbr_id = 0;
|
||||
head_count = t->partition_heads_per_cyl;
|
||||
sector_count = t->partition_secs_per_head;
|
||||
|
||||
@ -608,6 +628,8 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
|
||||
gettimeofday(&tv, &tz);
|
||||
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
||||
lsb_to_buf(&wpt, id, 32, 0);
|
||||
} else {
|
||||
wpt+= 4;
|
||||
}
|
||||
|
||||
/* write word 0 # Offset 444
|
||||
@ -634,14 +656,17 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
|
||||
wpt+= 16;
|
||||
continue;
|
||||
}
|
||||
/* write byte 0x80
|
||||
/* write byte 0x80 if bootable
|
||||
write LBA_to_CHS(partition_offset)
|
||||
write byte filesystem_type
|
||||
write LBA_to_CHS(image_size-1)
|
||||
write dword partition_offset
|
||||
write dword image_size
|
||||
*/
|
||||
lsb_to_buf(&wpt, 0x80, 8, 0);
|
||||
if (flag & 2)
|
||||
lsb_to_buf(&wpt, 0x00, 8, 0);
|
||||
else
|
||||
lsb_to_buf(&wpt, 0x80, 8, 0);
|
||||
lba512chs_to_buf(&wpt, part_offset, head_count, sector_count);
|
||||
lsb_to_buf(&wpt, fs_type, 8, 0);
|
||||
lba512chs_to_buf(&wpt, hd_img_blocks - 1, head_count, sector_count);
|
||||
|
@ -497,7 +497,7 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
||||
|
||||
if (node->type == LIBISO_FILE) {
|
||||
file = (IsoFile *) node;
|
||||
if (file->from_old_session && target->appendable) {
|
||||
if (file->from_old_session && target->opts->appendable) {
|
||||
/* Look for checksums at various places */
|
||||
|
||||
/* Try checksum directly stored with node */
|
||||
@ -527,7 +527,7 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
||||
if (md5_pt == NULL)
|
||||
return 0;
|
||||
|
||||
if (!target->will_cancel) {
|
||||
if (!target->opts->will_cancel) {
|
||||
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
|
||||
&value, 0);
|
||||
if (ret == 1 && value_length == 4) {
|
||||
@ -540,13 +540,12 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
||||
if (value != NULL)
|
||||
free(value);
|
||||
|
||||
/* ts B30114 : It is unclear why these are removed here.
|
||||
At least with the opts->will_cancel runs,
|
||||
this is not appropriate.
|
||||
/* >>> ts B30114 : It is unclear why these are removed here.
|
||||
At least with the opts->will_cancel runs,
|
||||
this is not appropriate.
|
||||
*/
|
||||
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
|
||||
}
|
||||
iso_node_remove_xinfo(node, checksum_cx_xinfo_func);
|
||||
}
|
||||
} else if (node->type == LIBISO_DIR) {
|
||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
||||
@ -572,8 +571,8 @@ int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
t = writer->target;
|
||||
|
||||
t->checksum_array_pos = t->curblock;
|
||||
/* (t->curblock already contains t->ms_block) */
|
||||
t->checksum_range_start = t->ms_block;
|
||||
/* (t->curblock already contains t->opts->ms_block) */
|
||||
t->checksum_range_start = t->opts->ms_block;
|
||||
size = (t->checksum_idx_counter + 2) / 128;
|
||||
if (size * 128 < t->checksum_idx_counter + 2)
|
||||
size++;
|
||||
@ -713,7 +712,7 @@ int checksum_writer_create(Ecma119Image *target)
|
||||
/* add this writer to image */
|
||||
target->writers[target->nwriters++] = writer;
|
||||
/* Account for superblock checksum tag */
|
||||
if (target->md5_session_checksum) {
|
||||
if (target->opts->md5_session_checksum) {
|
||||
target->checksum_sb_tag_pos = target->curblock;
|
||||
target->curblock++;
|
||||
}
|
||||
@ -743,7 +742,7 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
||||
(unsigned int) (pos % 1000000000));
|
||||
else
|
||||
sprintf(postext, "%u", (unsigned int) pos);
|
||||
sprintf(record, "%s %s ", t->scdbackup_tag_parm, postext);
|
||||
sprintf(record, "%s %s ", t->opts->scdbackup_tag_parm, postext);
|
||||
record_len = strlen(record);
|
||||
for (i = 0; i < 16; i++)
|
||||
sprintf(record + record_len + 2 * i,
|
||||
@ -765,8 +764,8 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
||||
block_len+= 32;
|
||||
tag_block[block_len++]= '\n';
|
||||
|
||||
if (t->scdbackup_tag_written != NULL)
|
||||
strncpy(t->scdbackup_tag_written, tag_block + line_start,
|
||||
if (t->opts->scdbackup_tag_written != NULL)
|
||||
strncpy(t->opts->scdbackup_tag_written, tag_block + line_start,
|
||||
block_len - line_start);
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
@ -828,7 +827,7 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
} else if (mode == 3) {
|
||||
sprintf(tag_block + l, " next=%u", t->checksum_tag_pos);
|
||||
} else if (mode == 4) {
|
||||
sprintf(tag_block + l, " session_start=%u", t->ms_block);
|
||||
sprintf(tag_block + l, " session_start=%u", t->opts->ms_block);
|
||||
}
|
||||
strcat(tag_block + l, " md5=");
|
||||
l = strlen(tag_block);
|
||||
@ -849,8 +848,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
}
|
||||
tag_block[l + 32] = '\n';
|
||||
|
||||
if (mode == 1 && t->scdbackup_tag_parm[0]) {
|
||||
if (t->ms_block > 0) {
|
||||
if (mode == 1 && t->opts->scdbackup_tag_parm[0]) {
|
||||
if (t->opts->ms_block > 0) {
|
||||
iso_msg_submit(t->image->id, ISO_SCDBACKUP_TAG_NOT_0, 0, NULL);
|
||||
} else {
|
||||
ret = iso_md5_write_scdbackup_tag(t, tag_block, 0);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2014 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
|
||||
@ -139,6 +139,7 @@ int iso_node_xinfo_dispose_cloners(int flag)
|
||||
next = assoc->next;
|
||||
free((char *) assoc);
|
||||
}
|
||||
iso_xinfo_cloner_list= NULL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -344,9 +345,9 @@ const char *iso_error_to_msg(int errcode)
|
||||
case ISO_WRONG_PVD:
|
||||
return "Wrong or damaged Primary Volume Descriptor";
|
||||
case ISO_WRONG_RR:
|
||||
return "Wrong or damaged RR entry";
|
||||
return "Wrong or damaged Rock Ridge entry";
|
||||
case ISO_UNSUPPORTED_RR:
|
||||
return "Unsupported RR feature";
|
||||
return "Unsupported Rock Ridge feature";
|
||||
case ISO_WRONG_ECMA119:
|
||||
return "Wrong or damaged ECMA-119";
|
||||
case ISO_UNSUPPORTED_ECMA119:
|
||||
@ -360,9 +361,9 @@ const char *iso_error_to_msg(int errcode)
|
||||
case ISO_UNSUPPORTED_SUSP:
|
||||
return "Unsupported SUSP feature";
|
||||
case ISO_WRONG_RR_WARN:
|
||||
return "Error on a RR entry that can be ignored";
|
||||
return "Error on a Rock Ridge entry that can be ignored";
|
||||
case ISO_SUSP_UNHANDLED:
|
||||
return "Error on a RR entry that can be ignored";
|
||||
return "Unhandled SUSP entry";
|
||||
case ISO_SUSP_MULTIPLE_ER:
|
||||
return "Multiple ER SUSP entries found";
|
||||
case ISO_UNSUPPORTED_VD:
|
||||
@ -502,6 +503,30 @@ const char *iso_error_to_msg(int errcode)
|
||||
return "Too many chained symbolic links";
|
||||
case ISO_BAD_ISO_FILETYPE:
|
||||
return "Unrecognized file type in ISO image";
|
||||
case ISO_NAME_NOT_UCS2:
|
||||
return "Filename not suitable for character set UCS-2";
|
||||
case ISO_IMPORT_COLLISION:
|
||||
return "File name collision during ISO image import";
|
||||
case ISO_HPPA_PALO_INCOMPL:
|
||||
return "Incomplete HP-PA PALO boot parameters";
|
||||
case ISO_HPPA_PALO_OFLOW:
|
||||
return "HP-PA PALO boot address exceeds 2 GB";
|
||||
case ISO_HPPA_PALO_NOTREG:
|
||||
return "HP-PA PALO file is not a data file";
|
||||
case ISO_HPPA_PALO_CMDLEN:
|
||||
return "HP-PA PALO command line too long";
|
||||
case ISO_SYSAREA_PROBLEMS:
|
||||
return "Problems encountered during inspection of System Area";
|
||||
case ISO_INQ_SYSAREA_PROP:
|
||||
return "Unrecognized inquiry for system area property";
|
||||
case ISO_ALPHA_BOOT_NOTREG:
|
||||
return "DEC Alpha Boot Loader file is not a data file";
|
||||
case ISO_NO_KEPT_DATA_SRC:
|
||||
return "No data source of imported ISO image available";
|
||||
case ISO_MALFORMED_READ_INTVL:
|
||||
return "Malformed description string for interval reader";
|
||||
case ISO_INTVL_READ_PROBLEM:
|
||||
return "Unreadable file, premature EOF, or failure to seek for interval reader";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2014 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
|
||||
@ -1048,6 +1048,7 @@ void iso_node_set_sort_weight(IsoNode *node, int w)
|
||||
}
|
||||
} else if (node->type == LIBISO_FILE) {
|
||||
((IsoFile*)node)->sort_weight = w;
|
||||
((IsoFile*)node)->explicit_weight = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1130,7 +1131,7 @@ int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag)
|
||||
}
|
||||
*lba = sections[0].block;
|
||||
free(sections);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -1172,20 +1173,27 @@ int iso_node_is_valid_name(const char *name)
|
||||
|
||||
/* guard against the empty string or big names... */
|
||||
if (name[0] == '\0')
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
goto rr_reserved;
|
||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||
return ISO_RR_NAME_TOO_LONG;
|
||||
|
||||
/* ...against "." and ".." names... */
|
||||
if (!strcmp(name, ".") || !strcmp(name, "..")) {
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
}
|
||||
if (!strcmp(name, ".") || !strcmp(name, ".."))
|
||||
goto rr_reserved;
|
||||
|
||||
/* ...and against names with '/' */
|
||||
if (strchr(name, '/') != NULL) {
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
}
|
||||
if (strchr(name, '/') != NULL)
|
||||
goto rr_reserved;
|
||||
|
||||
return 1;
|
||||
|
||||
rr_reserved:;
|
||||
/* # define Libisofs_debug_rr_reserveD */
|
||||
#ifdef Libisofs_debug_rr_reserveD
|
||||
fprintf(stderr, "libisofs_DEBUG: ISO_RR_NAME_RESERVED with '%s'\n", name);
|
||||
#endif
|
||||
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1205,8 +1213,12 @@ int iso_node_is_valid_link_dest(const char *dest)
|
||||
}
|
||||
|
||||
/* guard against the empty string or big dest... */
|
||||
if (dest[0] == '\0')
|
||||
if (dest[0] == '\0') {
|
||||
#ifdef Libisofs_debug_rr_reserveD
|
||||
fprintf(stderr, "libisofs_DEBUG: ISO_RR_NAME_RESERVED by empty link target\n");
|
||||
#endif
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
}
|
||||
if (strlen(dest) > LIBISOFS_NODE_PATH_MAX)
|
||||
return ISO_RR_PATH_TOO_LONG;
|
||||
|
||||
@ -1430,6 +1442,8 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
||||
new->node.type = LIBISO_FILE;
|
||||
new->node.name = name;
|
||||
new->node.mode = S_IFREG;
|
||||
new->from_old_session = 0;
|
||||
new->explicit_weight = 0;
|
||||
new->sort_weight = 0;
|
||||
new->stream = stream;
|
||||
|
||||
@ -2566,6 +2580,7 @@ int iso_node_set_ino(IsoNode *node, ino_t ino, int flag)
|
||||
ret = iso_stream_set_image_ino(file->stream, ino, 0);
|
||||
if (ret < 0 || ret == 1)
|
||||
return ret;
|
||||
/* ret == 0 means that the stream is not from loaded ISO image */
|
||||
|
||||
} else if (node->type == LIBISO_SYMLINK) {
|
||||
symlink = (IsoSymlink *) node;
|
||||
@ -2756,6 +2771,8 @@ int iso_node_cmp_ino(IsoNode *n1, IsoNode *n2, int flag)
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= delete isofs.cx rather than setting it
|
||||
*/
|
||||
int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
||||
int flag)
|
||||
{
|
||||
@ -2765,9 +2782,14 @@ int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
||||
char *valuept;
|
||||
int i, ret;
|
||||
|
||||
valuept= (char *) value;
|
||||
if (flag & 1) {
|
||||
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
|
||||
&names, value_lengths, &valuept, 4 | 8);
|
||||
return ret;
|
||||
}
|
||||
for(i = 0; i < 4; i++)
|
||||
value[3 - i] = (checksum_index >> (8 * i)) & 0xff;
|
||||
valuept= (char *) value;
|
||||
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
|
||||
&names, value_lengths, &valuept, 2 | 8);
|
||||
return ret;
|
||||
|
@ -149,8 +149,15 @@ struct Iso_File
|
||||
{
|
||||
IsoNode node;
|
||||
|
||||
/* 1 = The node was loaded from an existing ISO image and still refers
|
||||
to its data content there.
|
||||
*/
|
||||
unsigned int from_old_session : 1;
|
||||
|
||||
/* 1 = The node got attributed a weight by iso_node_set_sort_weight().
|
||||
*/
|
||||
unsigned int explicit_weight : 1;
|
||||
|
||||
/**
|
||||
* It sorts the order in which the file data is written to the CD image.
|
||||
* Higher weighting files are written at the beginning of image
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 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
|
||||
@ -32,10 +32,16 @@
|
||||
#define ISO_ROCKRIDGE_IN_DIR_REC 124
|
||||
#endif
|
||||
|
||||
#define ISO_CE_ENTRY_SIZE 28
|
||||
|
||||
|
||||
static
|
||||
int susp_add_ES(Ecma119Image *t, struct susp_info *susp, int to_ce, int seqno);
|
||||
|
||||
static
|
||||
int susp_make_CE(Ecma119Image *t, uint8_t **CE,
|
||||
uint32_t block_offset, uint32_t byte_offset, uint32_t size);
|
||||
|
||||
|
||||
static
|
||||
int susp_append(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
|
||||
@ -54,14 +60,76 @@ int susp_append(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
|
||||
static
|
||||
int susp_append_ce(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
|
||||
{
|
||||
susp->n_ce_susp_fields++;
|
||||
susp->ce_susp_fields = realloc(susp->ce_susp_fields, sizeof(void*)
|
||||
* susp->n_ce_susp_fields);
|
||||
if (susp->ce_susp_fields == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
int to_alloc = 1, ret;
|
||||
unsigned char *pad;
|
||||
uint8_t *CE;
|
||||
size_t next_alloc;
|
||||
|
||||
if (data[0] &&
|
||||
(susp->ce_len + data[2] + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE !=
|
||||
susp->ce_len / BLOCK_SIZE) {
|
||||
/* Linux fs/isofs wants byte_offset + ce_len <= BLOCK_SIZE.
|
||||
So this Continuation Area needs to end by a CE which points
|
||||
to the start of the next block.
|
||||
*/
|
||||
to_alloc = 2;
|
||||
if ((susp->ce_len + ISO_CE_ENTRY_SIZE) % BLOCK_SIZE)
|
||||
to_alloc = 3; /* need a PAD pseudo entry */
|
||||
}
|
||||
|
||||
if (susp->ce_susp_fields == NULL)
|
||||
susp->alloc_ce_susp_fields = 0;
|
||||
if (susp->n_ce_susp_fields + to_alloc > susp->alloc_ce_susp_fields) {
|
||||
next_alloc = susp->alloc_ce_susp_fields;
|
||||
while (susp->n_ce_susp_fields + to_alloc > next_alloc)
|
||||
next_alloc += ISO_SUSP_CE_ALLOC_STEP;
|
||||
susp->ce_susp_fields = realloc(susp->ce_susp_fields,
|
||||
sizeof(uint8_t *) * next_alloc);
|
||||
if (susp->ce_susp_fields == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
susp->alloc_ce_susp_fields = next_alloc;
|
||||
}
|
||||
|
||||
if (to_alloc >= 2) {
|
||||
/* 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);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
susp->ce_susp_fields[susp->n_ce_susp_fields] = CE;
|
||||
susp->ce_len += ISO_CE_ENTRY_SIZE;
|
||||
susp->n_ce_susp_fields++;
|
||||
}
|
||||
if (to_alloc >= 3) {
|
||||
|
||||
|
||||
#ifdef Libisofs_ce_calc_debuG
|
||||
|
||||
fprintf(stderr,
|
||||
"\nlibburn_DEBUG: Inserting %d bytes of CE padding\n\n",
|
||||
(int) (BLOCK_SIZE - (susp->ce_len % BLOCK_SIZE)));
|
||||
|
||||
#endif /* Libisofs_ce_calc_debuG */
|
||||
|
||||
pad = malloc(1);
|
||||
if (pad == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
pad[0] = 0;
|
||||
susp->ce_susp_fields[susp->n_ce_susp_fields] = pad;
|
||||
if (susp->ce_len % BLOCK_SIZE)
|
||||
susp->ce_len += BLOCK_SIZE - (susp->ce_len % BLOCK_SIZE);
|
||||
susp->n_ce_susp_fields++;
|
||||
}
|
||||
susp->ce_susp_fields[susp->n_ce_susp_fields] = data;
|
||||
susp->n_ce_susp_fields++;
|
||||
|
||||
if (data[0] == 0) {
|
||||
if (susp->ce_len % BLOCK_SIZE)
|
||||
susp->ce_len += BLOCK_SIZE - (susp->ce_len % BLOCK_SIZE);
|
||||
} else {
|
||||
susp->ce_len += data[2];
|
||||
}
|
||||
susp->ce_susp_fields[susp->n_ce_susp_fields - 1] = data;
|
||||
susp->ce_len += data[2];
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -115,7 +183,7 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
|
||||
PX[0] = 'P';
|
||||
PX[1] = 'X';
|
||||
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10 ) {
|
||||
if (t->opts->rrip_1_10_px_ino || !t->opts->rrip_version_1_10 ) {
|
||||
PX[2] = 44;
|
||||
} else {
|
||||
PX[2] = 36;
|
||||
@ -125,7 +193,7 @@ int rrip_add_PX(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
iso_bb(&PX[12], (uint32_t) n->nlink, 4);
|
||||
iso_bb(&PX[20], (uint32_t) px_get_uid(t, n), 4);
|
||||
iso_bb(&PX[28], (uint32_t) px_get_gid(t, n), 4);
|
||||
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
|
||||
if (t->opts->rrip_1_10_px_ino || !t->opts->rrip_version_1_10) {
|
||||
iso_bb(&PX[36], (uint32_t) n->ino, 4);
|
||||
}
|
||||
|
||||
@ -153,11 +221,11 @@ int rrip_add_TF(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
|
||||
iso = n->node;
|
||||
iso_datetime_7(&TF[5], t->replace_timestamps ? t->timestamp : iso->mtime,
|
||||
t->always_gmt);
|
||||
t->opts->always_gmt);
|
||||
iso_datetime_7(&TF[12], t->replace_timestamps ? t->timestamp : iso->atime,
|
||||
t->always_gmt);
|
||||
t->opts->always_gmt);
|
||||
iso_datetime_7(&TF[19], t->replace_timestamps ? t->timestamp : iso->ctime,
|
||||
t->always_gmt);
|
||||
t->opts->always_gmt);
|
||||
return susp_append(t, susp, TF);
|
||||
}
|
||||
|
||||
@ -294,29 +362,46 @@ int rrip_add_CL(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
/**
|
||||
* Convert a RR filename to the requested charset. On any conversion error,
|
||||
* the original name will be used.
|
||||
* @param flag bit0= do not issue error messages
|
||||
*/
|
||||
static
|
||||
char *get_rr_fname(Ecma119Image *t, const char *str)
|
||||
int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
|
||||
char *output_charset, int imgid,
|
||||
char *str, char **name, int flag)
|
||||
{
|
||||
int ret;
|
||||
char *name;
|
||||
|
||||
if (!strcmp(t->input_charset, t->output_charset)) {
|
||||
if (!strcmp(input_charset, output_charset)) {
|
||||
/* no conversion needed */
|
||||
return strdup(str);
|
||||
ret = iso_clone_mem(str, name, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = strconv(str, t->input_charset, t->output_charset, &name);
|
||||
ret = strconv(str, input_charset, output_charset, name);
|
||||
if (ret < 0) {
|
||||
/* TODO we should check for possible cancelation */
|
||||
iso_msg_submit(t->image->id, ISO_FILENAME_WRONG_CHARSET, ret,
|
||||
"Charset conversion error. Can't convert %s from %s to %s",
|
||||
str, t->input_charset, t->output_charset);
|
||||
if (!(flag & 1))
|
||||
iso_msg_submit(imgid, ISO_FILENAME_WRONG_CHARSET, ret,
|
||||
"Charset conversion error. Cannot convert %s from %s to %s",
|
||||
str, input_charset, output_charset);
|
||||
|
||||
/* use the original name, it's the best we can do */
|
||||
name = strdup(str);
|
||||
ret = iso_clone_mem(str, name, 0);
|
||||
return ISO_FILENAME_WRONG_CHARSET;
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
char *get_rr_fname(Ecma119Image *t, char *str)
|
||||
{
|
||||
int ret;
|
||||
char *name = NULL;
|
||||
|
||||
ret = iso_get_rr_name(t->opts, t->input_charset, t->output_charset,
|
||||
t->image->id, str, &name, 0);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -530,22 +615,56 @@ 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)
|
||||
{
|
||||
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 */
|
||||
*ce += ISO_CE_ENTRY_SIZE;
|
||||
if ((*ce + base_ce) % BLOCK_SIZE)
|
||||
*ce += BLOCK_SIZE - ((*ce + base_ce) % BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
*ce += add;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@param flag bit0= only account sizes in sua_free resp. ce_len
|
||||
parameters susp and data may be NULL in this case
|
||||
@param flag bit0= only account sizes in sua_free resp. ce_len.
|
||||
Parameter susp may be NULL in this case
|
||||
bit1= account for crossing block boundaries
|
||||
(implied by bit0 == 0)
|
||||
@param ce_len counts the freshly added CA size of the current node
|
||||
@param ce_mem tells the CA size of previous nodes in the same directory
|
||||
*/
|
||||
static
|
||||
int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
||||
uint8_t **data, size_t num_data,
|
||||
size_t *sua_free, size_t *ce_len, int flag)
|
||||
size_t *sua_free, size_t *ce_len, size_t ce_mem, int flag)
|
||||
{
|
||||
int ret, done = 0, len, es_extra = 0;
|
||||
uint8_t *aapt, *cpt;
|
||||
size_t count = 0;
|
||||
|
||||
if (!t->aaip_susp_1_10)
|
||||
if (!(flag & 1))
|
||||
flag |= 2;
|
||||
if (!t->opts->aaip_susp_1_10)
|
||||
es_extra = 5;
|
||||
if (*sua_free < num_data + es_extra || *ce_len > 0) {
|
||||
*ce_len += num_data + es_extra;
|
||||
if (es_extra > 0)
|
||||
susp_calc_add_to_ce(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);
|
||||
count += len;
|
||||
}
|
||||
} else {
|
||||
*sua_free -= num_data + es_extra;
|
||||
}
|
||||
@ -553,7 +672,7 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
||||
return ISO_SUCCESS;
|
||||
|
||||
/* If AAIP enabled and announced by ER : Write ES field to announce AAIP */
|
||||
if (t->aaip && !t->aaip_susp_1_10) {
|
||||
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
|
||||
ret = susp_add_ES(t, susp, (*ce_len > 0), 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -571,6 +690,7 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
||||
}
|
||||
|
||||
/* Multiple fields have to be handed over as single field copies */
|
||||
done = 0;
|
||||
for (aapt = *data; !done; aapt += aapt[2]) {
|
||||
done = !(aapt[4] & 1);
|
||||
len = aapt[2];
|
||||
@ -606,7 +726,7 @@ int rrip_add_ER(Ecma119Image *t, struct susp_info *susp)
|
||||
{
|
||||
unsigned char *ER;
|
||||
|
||||
if (!t->rrip_version_1_10) {
|
||||
if (!t->opts->rrip_version_1_10) {
|
||||
/*
|
||||
According to RRIP 1.12 this is the future form:
|
||||
4.3 "Specification of the ER System Use Entry Values for RRIP"
|
||||
@ -705,6 +825,35 @@ int aaip_add_ER(Ecma119Image *t, struct susp_info *susp, int flag)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the byte representation of a CE entry.
|
||||
* (SUSP, 5.1).
|
||||
*/
|
||||
static
|
||||
int susp_make_CE(Ecma119Image *t, uint8_t **CE,
|
||||
uint32_t block_offset, uint32_t byte_offset, uint32_t size)
|
||||
{
|
||||
uint8_t *data;
|
||||
|
||||
*CE = NULL;
|
||||
data = calloc(1, 28);
|
||||
if (data == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
*CE = data;
|
||||
|
||||
data[0] = 'C';
|
||||
data[1] = 'E';
|
||||
data[2] = 28;
|
||||
data[3] = 1;
|
||||
|
||||
iso_bb(&data[4], block_offset - t->eff_partition_offset, 4);
|
||||
iso_bb(&data[12], byte_offset, 4);
|
||||
iso_bb(&data[20], size, 4);
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a CE System Use Entry to the given tree node. A "CE" is used to add
|
||||
* a continuation area, where additional System Use Entry can be written.
|
||||
@ -713,20 +862,18 @@ int aaip_add_ER(Ecma119Image *t, struct susp_info *susp, int flag)
|
||||
static
|
||||
int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp)
|
||||
{
|
||||
uint8_t *CE = malloc(28);
|
||||
if (CE == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
CE[0] = 'C';
|
||||
CE[1] = 'E';
|
||||
CE[2] = 28;
|
||||
CE[3] = 1;
|
||||
|
||||
iso_bb(&CE[4], susp->ce_block - t->eff_partition_offset, 4);
|
||||
iso_bb(&CE[12], susp->ce_len, 4);
|
||||
iso_bb(&CE[20], (uint32_t) ce_len, 4);
|
||||
uint32_t block_offset, byte_offset;
|
||||
uint8_t *CE;
|
||||
int ret;
|
||||
|
||||
/* Linux fs/isofs wants byte_offset + ce_len <= BLOCK_SIZE
|
||||
* Here the byte_offset is reduced to the minimum.
|
||||
*/
|
||||
block_offset = susp->ce_block + susp->ce_len / BLOCK_SIZE;
|
||||
byte_offset = susp->ce_len % BLOCK_SIZE;
|
||||
ret = susp_make_CE(t, &CE, block_offset, byte_offset, (uint32_t) ce_len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return susp_append(t, susp, CE);
|
||||
}
|
||||
|
||||
@ -782,6 +929,27 @@ 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"
|
||||
*/
|
||||
@ -813,10 +981,12 @@ int zisofs_add_ZF(Ecma119Image *t, struct susp_info *susp, int to_ce,
|
||||
|
||||
|
||||
/* @param flag bit0= Do not add data but only count sua_free and ce_len
|
||||
bit1= account for crossing block boundaries
|
||||
(implied by bit0 == 0)
|
||||
*/
|
||||
static
|
||||
int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
size_t *sua_free, size_t *ce_len, int flag)
|
||||
size_t *sua_free, size_t *ce_len, size_t base_ce, int flag)
|
||||
{
|
||||
int ret, will_copy = 1, stream_type = 0, do_zf = 0;
|
||||
int header_size_div4 = 0, block_size_log2 = 0;
|
||||
@ -832,6 +1002,8 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
int *header_size_div4, int *block_size_log2,
|
||||
uint32_t *uncompressed_size, int flag);
|
||||
|
||||
if (!(flag & 1))
|
||||
flag |= 2;
|
||||
|
||||
if (iso_node_get_type(n->node) != LIBISO_FILE)
|
||||
return 2;
|
||||
@ -851,7 +1023,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
zisofs file header when inquired)
|
||||
*/
|
||||
|
||||
if (t->appendable && file->from_old_session)
|
||||
if (t->opts->appendable && file->from_old_session)
|
||||
will_copy = 0;
|
||||
|
||||
first_filter = first_stream = last_stream = iso_file_get_stream(file);
|
||||
@ -905,7 +1077,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
|
||||
/* Account for field size */
|
||||
if (*sua_free < 16 || *ce_len > 0) {
|
||||
*ce_len += 16;
|
||||
susp_calc_add_to_ce(ce_len, base_ce, 16, flag & 2);
|
||||
} else {
|
||||
*sua_free -= 16;
|
||||
}
|
||||
@ -953,10 +1125,15 @@ int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||
* a CE entry of 28 bytes in SUA, this computation fails if not the 28 bytes
|
||||
* are taken into account at start. In this case the caller should retry with
|
||||
* bit0 set.
|
||||
* If the resulting *ce added to base_ce is in a different block than base_ce,
|
||||
* then computation with bit0 fails and the caller should finally try bit1.
|
||||
*
|
||||
* @param flag bit0= assume CA usage (else return 0 on SUA overflow)
|
||||
* bit1= let CA start at block start (else return 0 if
|
||||
* *ce crosses a block boundary)
|
||||
* @return 1= ok, computation of *su_size and *ce is valid
|
||||
* 0= not ok, CA usage is necessary but bit0 was not set
|
||||
* or *ce crosses boundary and bit1 was not set
|
||||
* (*su_size and *ce stay unaltered in this case)
|
||||
* <0= error:
|
||||
* -1= not enough SUA space for 28 bytes of CE entry
|
||||
@ -964,19 +1141,44 @@ int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||
*/
|
||||
static
|
||||
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
size_t *su_size, size_t *ce, int flag)
|
||||
size_t *su_size, size_t *ce, size_t base_ce, int flag)
|
||||
{
|
||||
char *name;
|
||||
size_t namelen, su_mem, ce_mem;
|
||||
void *xipt;
|
||||
size_t num_aapt = 0, sua_free = 0;
|
||||
int ret;
|
||||
uint8_t *aapt;
|
||||
|
||||
#ifdef Libisofs_ce_calc_debug_extrA
|
||||
|
||||
if (n->node->name != NULL)
|
||||
fprintf(stderr, "libburn_DEBUG: susp_calc_nm_sl_al : %.f %s \n",
|
||||
(double) base_ce, n->node->name);
|
||||
|
||||
#endif /* Libisofs_ce_calc_debug_extrA */
|
||||
|
||||
su_mem = *su_size;
|
||||
ce_mem = *ce;
|
||||
if (*ce > 0 && !(flag & 1))
|
||||
goto unannounced_ca;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
name = get_rr_fname(t, n->node->name);
|
||||
namelen = strlen(name);
|
||||
free(name);
|
||||
@ -1003,7 +1205,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
of the name will always fit into the directory entry.)
|
||||
*/;
|
||||
|
||||
*ce = 5 + namelen;
|
||||
susp_calc_add_to_ce(ce, base_ce, 5 + namelen, flag & 2);
|
||||
*su_size = space;
|
||||
}
|
||||
if (n->type == ECMA119_SYMLINK) {
|
||||
@ -1073,21 +1275,26 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
* the component can be divided between this
|
||||
* and another SL entry
|
||||
*/
|
||||
*ce += 255; /* this SL, full */
|
||||
sl_len = 5 + (clen - fit);
|
||||
/* Will fill up old SL and write it */
|
||||
susp_calc_add_to_ce(ce, base_ce, 255, flag & 2);
|
||||
sl_len = 5 + (clen - fit); /* Start new SL */
|
||||
} else {
|
||||
/*
|
||||
* the component will need a 2rd SL entry in
|
||||
* any case, so we prefer to don't write
|
||||
* anything in this SL
|
||||
*/
|
||||
*ce += sl_len + 255;
|
||||
sl_len = 5 + (clen - 250) + 2;
|
||||
/* Will write non-full old SL */
|
||||
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
|
||||
/* Will write another full SL */
|
||||
susp_calc_add_to_ce(ce, base_ce, 255, flag & 2);
|
||||
sl_len = 5 + (clen - 250) + 2; /* Start new SL */
|
||||
}
|
||||
} else {
|
||||
/* case 2, create a new SL entry */
|
||||
*ce += sl_len;
|
||||
sl_len = 5 + clen;
|
||||
/* Will write non-full old SL */
|
||||
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
|
||||
sl_len = 5 + clen; /* Start new SL */
|
||||
}
|
||||
} else {
|
||||
sl_len += clen;
|
||||
@ -1109,14 +1316,14 @@ 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 {
|
||||
*ce += sl_len;
|
||||
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Find out whether ZF is to be added and account for its bytes */
|
||||
sua_free = space - *su_size;
|
||||
add_zf_field(t, n, NULL, &sua_free, ce, 1);
|
||||
add_zf_field(t, n, NULL, &sua_free, ce, base_ce, 1 | (flag & 2));
|
||||
*su_size = space - sua_free;
|
||||
if (*ce > 0 && !(flag & 1))
|
||||
goto unannounced_ca;
|
||||
@ -1124,7 +1331,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
/* obtain num_aapt from node */
|
||||
xipt = NULL;
|
||||
num_aapt = 0;
|
||||
if (t->aaip) {
|
||||
if (t->opts->aaip) {
|
||||
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
|
||||
if (ret == 1) {
|
||||
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
||||
@ -1133,12 +1340,46 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
/* let the expert decide where to add num_aapt */
|
||||
if (num_aapt > 0) {
|
||||
sua_free = space - *su_size;
|
||||
aaip_add_AL(t, NULL, NULL, num_aapt, &sua_free, ce, 1);
|
||||
aapt = (uint8_t *) xipt;
|
||||
aaip_add_AL(t, NULL, &aapt, num_aapt, &sua_free, ce, base_ce,
|
||||
1 | (flag & 2));
|
||||
*su_size = space - sua_free;
|
||||
if (*ce > 0 && !(flag & 1))
|
||||
goto unannounced_ca;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_ce_calc_debug_filetraP
|
||||
|
||||
if (n->node->name != NULL)
|
||||
if (strcmp(n->node->name, "...insert.leaf.name.here...") == 0)
|
||||
fprintf(stderr,
|
||||
"libburn_DEBUG: filename breakpoint susp_calc_nm_sl_al\n");
|
||||
|
||||
#endif /* Libisofs_ce_calc_debug_filetraP */
|
||||
|
||||
if (*ce > 0 && !(flag & 2)) {
|
||||
if (base_ce / BLOCK_SIZE !=
|
||||
(base_ce + *ce + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE) {
|
||||
|
||||
#ifdef Libisofs_ce_calc_debuG
|
||||
|
||||
fprintf(stderr,
|
||||
"\nlibburn_DEBUG: Crossed block boundary: %.f (%lu) -> %.f (%lu) : %s\n\n",
|
||||
(double) base_ce, (unsigned long) (base_ce / BLOCK_SIZE),
|
||||
(double) (base_ce + *ce - 1),
|
||||
(unsigned long)
|
||||
((base_ce + *ce + ISO_CE_ENTRY_SIZE - 1) / BLOCK_SIZE),
|
||||
n->node->name);
|
||||
|
||||
#endif /* Libisofs_ce_calc_debuG */
|
||||
|
||||
/* Crossed a block boundary */
|
||||
*su_size = su_mem;
|
||||
*ce = ce_mem;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
unannounced_ca:;
|
||||
@ -1150,17 +1391,19 @@ unannounced_ca:;
|
||||
|
||||
/* @param flag bit0= Do not add data but only count sua_free and ce_len
|
||||
param info may be NULL in this case
|
||||
bit1= account for crossing block boundaries
|
||||
(implied by bit0 == 0)
|
||||
*/
|
||||
static
|
||||
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
size_t *sua_free, size_t *ce_len, int flag)
|
||||
size_t *sua_free, size_t *ce_len, size_t base_ce, int flag)
|
||||
{
|
||||
int ret;
|
||||
uint8_t *aapt;
|
||||
void *xipt;
|
||||
size_t num_aapt= 0;
|
||||
|
||||
if (!t->aaip)
|
||||
if (!t->opts->aaip)
|
||||
return 1;
|
||||
|
||||
ret = iso_node_get_xinfo(n->node, aaip_xinfo_func, &xipt);
|
||||
@ -1168,18 +1411,20 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
||||
if (num_aapt > 0) {
|
||||
if (flag & 1) {
|
||||
ret = aaip_add_AL(t, NULL,NULL, num_aapt, sua_free, ce_len, 1);
|
||||
aapt = (unsigned char *) xipt;
|
||||
ret = aaip_add_AL(t, NULL, &aapt, num_aapt, sua_free, ce_len,
|
||||
base_ce, flag & (1 | 2));
|
||||
} else {
|
||||
aapt = malloc(num_aapt);
|
||||
if (aapt == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy(aapt, xipt, num_aapt);
|
||||
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
|
||||
0);
|
||||
base_ce, 0);
|
||||
/* aapt is NULL now and the memory is owned by t */
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
/* aapt is NULL now and the memory is owned by t */
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -1197,11 +1442,13 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
||||
* Already occupied space in the directory record.
|
||||
* @param ce
|
||||
* Will be filled with the space needed in a CE
|
||||
* @param base_ce
|
||||
* Predicted fill of continuation area by previous nodes of same dir
|
||||
* @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 *ce, size_t base_ce)
|
||||
{
|
||||
size_t su_size, space;
|
||||
int ret;
|
||||
@ -1221,7 +1468,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
su_size = 0;
|
||||
|
||||
/* If AAIP enabled and announced by ER : account for 5 bytes of ES */;
|
||||
if (t->aaip && !t->aaip_susp_1_10)
|
||||
if (t->opts->aaip && !t->opts->aaip_susp_1_10)
|
||||
su_size += 5;
|
||||
|
||||
#ifdef Libisofs_with_rrip_rR
|
||||
@ -1230,7 +1477,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
#endif
|
||||
|
||||
/* PX and TF, we are sure they always fit in SUA */
|
||||
if (t->rrip_1_10_px_ino || !t->rrip_version_1_10) {
|
||||
if (t->opts->rrip_1_10_px_ino || !t->opts->rrip_version_1_10) {
|
||||
su_size += 44 + 26;
|
||||
} else {
|
||||
su_size += 36 + 26;
|
||||
@ -1247,7 +1494,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
su_size += 4;
|
||||
}
|
||||
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
|
||||
(t->rr_reloc_flags & 1)) {
|
||||
(t->opts->rr_reloc_flags & 1)) {
|
||||
/* The dedicated relocation directory shall be marked by RE */
|
||||
su_size += 4;
|
||||
}
|
||||
@ -1264,9 +1511,11 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
if (type == 0) {
|
||||
|
||||
/* Try without CE */
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
|
||||
if (ret == 0) /* Retry with CE */
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce, 0);
|
||||
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);
|
||||
if (ret == -2)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
@ -1274,7 +1523,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
|
||||
/* "." or ".." entry */
|
||||
|
||||
if (!t->rrip_version_1_10)
|
||||
if (!t->opts->rrip_version_1_10)
|
||||
su_size += 5; /* NM field */
|
||||
|
||||
if (type == 1 && n->parent == NULL) {
|
||||
@ -1285,17 +1534,21 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
*/
|
||||
su_size += 7 + 28; /* SP + CE */
|
||||
/* ER of RRIP */
|
||||
if (t->rrip_version_1_10) {
|
||||
if (t->opts->rrip_version_1_10) {
|
||||
*ce = 237;
|
||||
} else {
|
||||
*ce = 182;
|
||||
}
|
||||
if (t->aaip && !t->aaip_susp_1_10) {
|
||||
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
|
||||
*ce += 160; /* ER of AAIP */
|
||||
}
|
||||
/* Compute length of AAIP string of root node */
|
||||
/* Compute length of AAIP string of root node.
|
||||
Will write all AIIP to CA, which already starts at
|
||||
block boundary. So no need for three tries.
|
||||
*/
|
||||
aaip_sua_free= 0;
|
||||
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
|
||||
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, base_ce,
|
||||
1 | 2);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*ce += aaip_len;
|
||||
@ -1359,7 +1612,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
size_t rrip_er_len= 182;
|
||||
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
||||
int ce_is_predicted = 0;
|
||||
size_t aaip_sua_free= 0, aaip_len= 0;
|
||||
size_t aaip_sua_free= 0, aaip_len= 0, ce_mem;
|
||||
int space;
|
||||
|
||||
if (t == NULL || n == NULL || info == NULL) {
|
||||
@ -1376,6 +1629,18 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
|
||||
/* Mark start index of node's continuation area for later update */
|
||||
info->current_ce_start = info->n_ce_susp_fields;
|
||||
ce_mem = info->ce_len;
|
||||
|
||||
#ifdef Libisofs_ce_calc_debug_filetraP
|
||||
|
||||
if (n->node->name != NULL)
|
||||
if (strcmp(n->node->name, "...put.leafname.here...") == 0)
|
||||
fprintf(stderr, "libburn_DEBUG: filename breakpoint\n");
|
||||
|
||||
#endif /* Libisofs_ce_calc_debug_filetraP */
|
||||
|
||||
if (type == 2 && n->parent != NULL) {
|
||||
node = n->parent;
|
||||
} else {
|
||||
@ -1394,7 +1659,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
}
|
||||
|
||||
/* If AAIP enabled and announced by ER : Announce RRIP by ES */
|
||||
if (t->aaip && !t->aaip_susp_1_10) {
|
||||
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
|
||||
ret = susp_add_ES(t, info, 0, 0);
|
||||
if (ret < 0)
|
||||
goto add_susp_cleanup;
|
||||
@ -1437,7 +1702,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
}
|
||||
}
|
||||
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
|
||||
(t->rr_reloc_flags & 1)) {
|
||||
(t->opts->rr_reloc_flags & 1)) {
|
||||
/* The dedicated relocation directory shall be marked by RE */
|
||||
ret = rrip_add_RE(t, node, info);
|
||||
if (ret < 0)
|
||||
@ -1485,10 +1750,14 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
su_size_pd = info->suf_len;
|
||||
ce_len_pd = ce_len;
|
||||
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
|
||||
&su_size_pd, &ce_len_pd, 0);
|
||||
&su_size_pd, &ce_len_pd, info->ce_len, 0);
|
||||
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
|
||||
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
|
||||
&su_size_pd, &ce_len_pd, 1);
|
||||
&su_size_pd, &ce_len_pd, info->ce_len, 1);
|
||||
if (ret == 0) /* Retry with aligned CE and block hopping */
|
||||
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
|
||||
&su_size_pd, &ce_len_pd, info->ce_len,
|
||||
1 | 2);
|
||||
sua_free -= 28;
|
||||
ce_is_predicted = 1;
|
||||
}
|
||||
@ -1682,6 +1951,26 @@ 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) {
|
||||
@ -1723,14 +2012,14 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
}
|
||||
|
||||
/* Eventually write zisofs ZF field */
|
||||
ret = add_zf_field(t, n, info, &sua_free, &ce_len, 0);
|
||||
ret = add_zf_field(t, n, info, &sua_free, &ce_len, ce_mem, 0);
|
||||
if (ret < 0)
|
||||
goto add_susp_cleanup;
|
||||
|
||||
/* Eventually obtain AAIP field string from node
|
||||
and write it to directory entry or CE area.
|
||||
*/
|
||||
ret = add_aa_string(t, n, info, &sua_free, &ce_len, 0);
|
||||
ret = add_aa_string(t, n, info, &sua_free, &ce_len, ce_mem, 0);
|
||||
if (ret < 0)
|
||||
goto add_susp_cleanup;
|
||||
|
||||
@ -1740,7 +2029,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
/* "." or ".." entry */
|
||||
|
||||
/* write the NM entry */
|
||||
if (t->rrip_version_1_10) {
|
||||
if (t->opts->rrip_version_1_10) {
|
||||
/* RRIP-1.10:
|
||||
"NM" System Use Fields recorded for the ISO 9660 directory
|
||||
records with names (00) and (01), used to designate the
|
||||
@ -1780,18 +2069,19 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
* Note that SP entry was already added above
|
||||
*/
|
||||
|
||||
if (t->rrip_version_1_10) {
|
||||
if (t->opts->rrip_version_1_10) {
|
||||
rrip_er_len = 237;
|
||||
} else {
|
||||
rrip_er_len = 182;
|
||||
}
|
||||
if (t->aaip && !t->aaip_susp_1_10) {
|
||||
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
|
||||
aaip_er_len = 160;
|
||||
}
|
||||
|
||||
/* Compute length of AAIP string of root node */
|
||||
aaip_sua_free= 0;
|
||||
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, 1);
|
||||
ret = add_aa_string(t, n, NULL, &aaip_sua_free, &aaip_len, ce_mem,
|
||||
1 | 2);
|
||||
if (ret < 0)
|
||||
goto add_susp_cleanup;
|
||||
|
||||
@ -1804,7 +2094,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
if (ret < 0) {
|
||||
goto add_susp_cleanup;
|
||||
}
|
||||
if (t->aaip && !t->aaip_susp_1_10) {
|
||||
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
|
||||
ret = aaip_add_ER(t, info, 0);
|
||||
if (ret < 0) {
|
||||
goto add_susp_cleanup;
|
||||
@ -1812,7 +2102,8 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
}
|
||||
/* Write AAIP string of root node */
|
||||
aaip_sua_free= aaip_len= 0;
|
||||
ret = add_aa_string(t, n, info, &aaip_sua_free, &aaip_len, 0);
|
||||
ret = add_aa_string(t, n, info, &aaip_sua_free, &aaip_len, ce_mem,
|
||||
0);
|
||||
if (ret < 0)
|
||||
goto add_susp_cleanup;
|
||||
|
||||
@ -1837,6 +2128,55 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Update the sizes of CE fields at end of info->susp_fields and in
|
||||
single node range of info->ce_susp_fields.
|
||||
*/
|
||||
static
|
||||
int susp_update_CE_sizes(Ecma119Image *t, struct susp_info *info, int flag)
|
||||
{
|
||||
size_t i, curr_pos;
|
||||
uint8_t *curr_ce;
|
||||
uint32_t size;
|
||||
|
||||
if (info->n_susp_fields == 0 ||
|
||||
info->n_ce_susp_fields - info->current_ce_start == 0)
|
||||
return ISO_SUCCESS;
|
||||
|
||||
for (i = 0; i < info->n_susp_fields; i++)
|
||||
if (info->susp_fields[i][0] == 'C')
|
||||
if(info->susp_fields[i][1] == 'E')
|
||||
break;
|
||||
if (i >= info->n_susp_fields) {
|
||||
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||
"System Use Area field contains no CE, but there are fields in Continuation Area");
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
curr_ce = info->susp_fields[i];
|
||||
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 */
|
||||
continue;
|
||||
}
|
||||
if (info->ce_susp_fields[i][0] == 'C' &&
|
||||
info->ce_susp_fields[i][1] == 'E') {
|
||||
size = (curr_pos + info->ce_susp_fields[i][2]) % BLOCK_SIZE;
|
||||
if (size == 0)
|
||||
size = BLOCK_SIZE;
|
||||
iso_bb(curr_ce + 20, size, 4);
|
||||
curr_ce = info->ce_susp_fields[i];
|
||||
}
|
||||
curr_pos = (curr_pos + info->ce_susp_fields[i][2]) % 2048;
|
||||
}
|
||||
if (curr_pos > 0) {
|
||||
size = curr_pos % BLOCK_SIZE;
|
||||
iso_bb(curr_ce + 20, size, 4);
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write the given SUSP fields into buf. Note that Continuation Area
|
||||
* fields are not written.
|
||||
@ -1849,11 +2189,16 @@ void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
|
||||
{
|
||||
size_t i;
|
||||
size_t pos = 0;
|
||||
int ret;
|
||||
|
||||
if (info->n_susp_fields == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = susp_update_CE_sizes(t, info, 0);
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < info->n_susp_fields; i++) {
|
||||
memcpy(buf + pos, info->susp_fields[i], info->susp_fields[i][2]);
|
||||
pos += info->susp_fields[i][2];
|
||||
@ -1879,6 +2224,7 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
size_t i;
|
||||
uint8_t *padding = NULL;
|
||||
int ret= ISO_SUCCESS;
|
||||
uint64_t written = 0, pad_size;
|
||||
|
||||
if (info->n_ce_susp_fields == 0) {
|
||||
goto ex;
|
||||
@ -1886,11 +2232,24 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
LIBISO_ALLOC_MEM(padding, uint8_t, BLOCK_SIZE);
|
||||
|
||||
for (i = 0; i < info->n_ce_susp_fields; i++) {
|
||||
if (info->ce_susp_fields[i][0] == 0) {
|
||||
/* Pseudo field: pad up to next block boundary */
|
||||
pad_size = BLOCK_SIZE - (written % BLOCK_SIZE);
|
||||
if (pad_size == BLOCK_SIZE)
|
||||
continue;
|
||||
memset(padding, 0, pad_size);
|
||||
ret = iso_write(t, padding, pad_size);
|
||||
if (ret < 0)
|
||||
goto write_ce_field_cleanup;
|
||||
written += pad_size;
|
||||
continue;
|
||||
}
|
||||
ret = iso_write(t, info->ce_susp_fields[i],
|
||||
info->ce_susp_fields[i][2]);
|
||||
if (ret < 0) {
|
||||
goto write_ce_field_cleanup;
|
||||
}
|
||||
written += info->ce_susp_fields[i][2];
|
||||
}
|
||||
|
||||
/* pad continuation area until block size */
|
||||
@ -1898,6 +2257,9 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
if (i > 0 && i < BLOCK_SIZE) {
|
||||
memset(padding, 0, i);
|
||||
ret = iso_write(t, padding, i);
|
||||
if (ret < 0)
|
||||
goto write_ce_field_cleanup;
|
||||
written += i;
|
||||
}
|
||||
|
||||
write_ce_field_cleanup: ;
|
||||
@ -1908,6 +2270,7 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
free(info->ce_susp_fields);
|
||||
info->ce_susp_fields = NULL;
|
||||
info->n_ce_susp_fields = 0;
|
||||
info->alloc_ce_susp_fields = 0;
|
||||
info->ce_len = 0;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(padding);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 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
|
||||
@ -63,10 +63,22 @@ struct susp_info
|
||||
uint32_t ce_block;
|
||||
uint32_t ce_len;
|
||||
|
||||
/* Storage for Continuation Area for a whole directory */
|
||||
size_t n_ce_susp_fields;
|
||||
uint8_t **ce_susp_fields;
|
||||
|
||||
/* The number of allocated members in ce_susp_fields */
|
||||
size_t alloc_ce_susp_fields;
|
||||
|
||||
/* Marks the start index in ce_susp_fields of the current node */
|
||||
size_t current_ce_start;
|
||||
|
||||
};
|
||||
|
||||
/* Step to increase allocated size of susp_info.ce_susp_fields */
|
||||
#define ISO_SUSP_CE_ALLOC_STEP 16
|
||||
|
||||
|
||||
/* SUSP 5.1 */
|
||||
struct susp_CE {
|
||||
uint8_t block[8];
|
||||
@ -186,11 +198,13 @@ struct susp_sys_user_entry
|
||||
* Available space in the System Use Area for the directory record.
|
||||
* @param ce
|
||||
* Will be filled with the space needed in a CE
|
||||
* @param base_ce
|
||||
* Fill of continuation area by previous nodes of same dir
|
||||
* @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 *ce, size_t base_ce);
|
||||
|
||||
/**
|
||||
* Fill a struct susp_info with the RR/SUSP entries needed for a given
|
||||
@ -346,4 +360,13 @@ 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);
|
||||
|
||||
/**
|
||||
* Convert a RR filename to the requested charset. On any conversion error,
|
||||
* the original name will be used.
|
||||
* @param flag bit0= do not issue error messages
|
||||
*/
|
||||
int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
|
||||
char *output_charset, int imgid,
|
||||
char *str, char **name, int flag);
|
||||
|
||||
#endif /* LIBISO_ROCKRIDGE_H */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2015 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
|
||||
@ -890,17 +890,27 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/* @param flag bit0= Obtain most fundamental stream */
|
||||
IsoStream *iso_stream_get_input_stream(IsoStream *stream, int flag)
|
||||
{
|
||||
IsoStreamIface* class;
|
||||
IsoStream *result = NULL, *next;
|
||||
|
||||
if (stream == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
class = stream->class;
|
||||
if (class->version < 2)
|
||||
return NULL;
|
||||
return class->get_input_stream(stream, 0);
|
||||
while (1) {
|
||||
class = stream->class;
|
||||
if (class->version < 2)
|
||||
return result;
|
||||
next = class->get_input_stream(stream, 0);
|
||||
if (next == NULL)
|
||||
return result;
|
||||
result = next;
|
||||
if (!(flag & 1))
|
||||
return result;
|
||||
stream = result;
|
||||
}
|
||||
}
|
||||
|
||||
char *iso_stream_get_source_path(IsoStream *stream, int flag)
|
||||
@ -933,12 +943,22 @@ ex:;
|
||||
return path;
|
||||
}
|
||||
|
||||
/* @return 1 = ok , 0 = not an ISO image stream , <0 = error */
|
||||
/*
|
||||
@param flag bit0= in case of filter stream do not dig for base stream
|
||||
@return 1 = ok , 0 = not an ISO image stream , <0 = error
|
||||
*/
|
||||
int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag)
|
||||
{
|
||||
IsoStream *base_stream;
|
||||
|
||||
if (stream == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
if (!(flag & 1)) {
|
||||
base_stream = iso_stream_get_input_stream(stream, 1);
|
||||
if (base_stream != NULL)
|
||||
stream = base_stream;
|
||||
}
|
||||
if (stream->class == &fsrc_stream_class) {
|
||||
FSrcStreamData *fsrc_data = stream->data;
|
||||
fsrc_data->ino_id = ino;
|
||||
@ -947,6 +967,23 @@ int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iso_stream_cmp_ifs_sections(IsoStream *s1, IsoStream *s2, int *cmp_ret,
|
||||
int flag)
|
||||
{
|
||||
int ret;
|
||||
FSrcStreamData *fssd1, *fssd2;
|
||||
|
||||
if (s1->class != &fsrc_stream_class || s2->class != &fsrc_stream_class)
|
||||
return 0;
|
||||
/* Compare eventual image data section LBA and sizes */
|
||||
fssd1= (FSrcStreamData *) s1->data;
|
||||
fssd2= (FSrcStreamData *) s2->data;
|
||||
ret = iso_ifs_sections_cmp(fssd1->src, fssd2->src, cmp_ret, 0);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* API */
|
||||
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
|
||||
{
|
||||
@ -955,8 +992,6 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
|
||||
dev_t dev_id1, dev_id2;
|
||||
ino_t ino_id1, ino_id2;
|
||||
off_t size1, size2;
|
||||
FSrcStreamData *fssd1, *fssd2;
|
||||
|
||||
|
||||
/*
|
||||
#define Libisofs_stream_cmp_ino_debuG 1
|
||||
@ -973,6 +1008,9 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
|
||||
if (s2 == NULL)
|
||||
return 1;
|
||||
|
||||
if (iso_stream_cmp_ifs_sections(s1, s2, &ret, 0) > 0)
|
||||
return ret; /* Both are unfiltered from loaded ISO filesystem */
|
||||
|
||||
if (s1->class->version >= 3 && !(flag & 1)) {
|
||||
/* Filters may have smarter methods to compare themselves with others */
|
||||
ret = s1->class->cmp_ino(s1, s2);
|
||||
@ -1032,14 +1070,6 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
|
||||
|
||||
if (s1->class != s2->class)
|
||||
return (s1->class < s2->class ? -1 : 1);
|
||||
if (s1->class == &fsrc_stream_class) {
|
||||
/* Compare eventual image data section LBA and sizes */
|
||||
fssd1= (FSrcStreamData *) s1->data;
|
||||
fssd2= (FSrcStreamData *) s2->data;
|
||||
ret = iso_ifs_sections_cmp(fssd1->src, fssd2->src, 0);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
if (fs_id1 == 0 && dev_id1 == 0 && ino_id1 == 0) {
|
||||
return (s1 < s2 ? -1 : 1);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Vreixo Formoso
|
||||
* Copyright (c) 2012 Thomas Schmitt
|
||||
* Copyright (c) 2012 - 2015 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
|
||||
@ -78,13 +78,13 @@ int iso_compute_append_partitions(Ecma119Image *t, int flag);
|
||||
*/
|
||||
struct iso_mbr_partition_request {
|
||||
|
||||
/* Always given in blocks of 2 KiB */
|
||||
uint32_t start_block;
|
||||
/* Always given in blocks of 512 bytes */
|
||||
uint64_t start_block;
|
||||
|
||||
/* A block count of 0 means that the partition reaches up to the start of
|
||||
the next one.
|
||||
*/
|
||||
uint32_t block_count;
|
||||
uint64_t block_count;
|
||||
|
||||
/* Partition type */
|
||||
uint8_t type_byte;
|
||||
@ -108,14 +108,16 @@ struct iso_mbr_partition_request {
|
||||
I.e. after the call the submitted storage of req can be disposed or re-used.
|
||||
Submit 0 as value flag.
|
||||
*/
|
||||
int iso_register_mbr_entry(Ecma119Image *t,
|
||||
int iso_register_mbr_entry(struct iso_mbr_partition_request **req_array,
|
||||
int *mbr_req_count,
|
||||
struct iso_mbr_partition_request *req, int flag);
|
||||
|
||||
/* Convenience frontend for iso_register_mbr_entry().
|
||||
name and type are 0-terminated strings, which may get silently truncated.
|
||||
*/
|
||||
int iso_quick_mbr_entry(Ecma119Image *t,
|
||||
uint32_t start_block, uint32_t block_count,
|
||||
int iso_quick_mbr_entry(struct iso_mbr_partition_request **req_array,
|
||||
int *mbr_req_count,
|
||||
uint64_t start_block, uint64_t block_count,
|
||||
uint8_t type_byte, uint8_t status_byte,
|
||||
int desired_slot);
|
||||
|
||||
@ -125,12 +127,13 @@ int iso_quick_mbr_entry(Ecma119Image *t,
|
||||
Return value is 0 if occupied, 1 if free, and -1 if the slot number is
|
||||
out of range.
|
||||
*/
|
||||
int iso_mbr_entry_slot_is_free(Ecma119Image *t, int slot);
|
||||
int iso_mbr_entry_slot_is_free(struct iso_mbr_partition_request **req_array,
|
||||
int mbr_req_count, int slot);
|
||||
|
||||
|
||||
/* The parameter struct for production of a single Apple Partition Map entry.
|
||||
See also the partial APM description in doc/boot_sectors.txt.
|
||||
The list of entries is stored in Ecma119Image.apm_req.
|
||||
The list of entries is stored e.g. in Ecma119Image.apm_req, .apm_req_count.
|
||||
The size of a block can be chosen by setting Ecma119Image.apm_block_size.
|
||||
If an entry has start_block <=1, then its block_count will be adjusted
|
||||
to the final size of the partition map.
|
||||
@ -144,8 +147,8 @@ struct iso_apm_partition_request {
|
||||
/* Given in blocks of 2 KiB unless (Ecma119Image.apm_req_flags & 4).
|
||||
Written to the ISO image according to Ecma119Image.apm_block_size.
|
||||
*/
|
||||
uint32_t start_block;
|
||||
uint32_t block_count;
|
||||
uint64_t start_block;
|
||||
uint64_t block_count;
|
||||
|
||||
/* All 32 bytes get copied to the system area.
|
||||
Take care to pad up short strings by 0.
|
||||
@ -158,20 +161,17 @@ struct iso_apm_partition_request {
|
||||
I.e. after the call the submitted storage of req can be disposed or re-used.
|
||||
Submit 0 as value flag.
|
||||
*/
|
||||
int iso_register_apm_entry(Ecma119Image *t,
|
||||
int iso_register_apm_entry(struct iso_apm_partition_request **req_array,
|
||||
int *apm_req_count,
|
||||
struct iso_apm_partition_request *req, int flag);
|
||||
|
||||
/* Convenience frontend for iso_register_apm_entry().
|
||||
name and type are 0-terminated strings, which may get silently truncated.
|
||||
*/
|
||||
int iso_quick_apm_entry(Ecma119Image *t,
|
||||
uint32_t start_block, uint32_t block_count, char *name, char *type);
|
||||
|
||||
|
||||
/* CRC-32 as of GPT and Ethernet.
|
||||
*/
|
||||
unsigned int iso_crc32_gpt(unsigned char *data, int count, int flag);
|
||||
|
||||
int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
|
||||
int *apm_req_count,
|
||||
uint32_t start_block, uint32_t block_count,
|
||||
char *name, char *type);
|
||||
|
||||
/* These two pseudo-random generators produce byte strings which will
|
||||
surely not duplicate in the first 256 calls. If more calls are necessary
|
||||
@ -206,11 +206,10 @@ void iso_random_uuid(Ecma119Image *t, uint8_t uuid[16]);
|
||||
*/
|
||||
struct iso_gpt_partition_request {
|
||||
|
||||
/* Always given in blocks of 2 KiB.
|
||||
Written to the ISO image in blocks of 512.
|
||||
/* Always given in blocks of 512 bytes.
|
||||
*/
|
||||
uint32_t start_block;
|
||||
uint32_t block_count;
|
||||
uint64_t start_block;
|
||||
uint64_t block_count;
|
||||
|
||||
/* The registered GUID which defines the partition type */
|
||||
uint8_t type_guid[16];
|
||||
@ -231,20 +230,26 @@ struct iso_gpt_partition_request {
|
||||
Take care to pad up short strings by 0.
|
||||
*/
|
||||
uint8_t name[72];
|
||||
|
||||
/* Only if read from imported image: Table index of partition (first = 1)
|
||||
*/
|
||||
uint32_t idx;
|
||||
};
|
||||
|
||||
/* Copies the content of req and registers it in t.gpt_req[].
|
||||
I.e. after the call the submitted storage of req can be disposed or re-used.
|
||||
Submit 0 as value flag.
|
||||
*/
|
||||
int iso_register_gpt_entry(Ecma119Image *t,
|
||||
int iso_register_gpt_entry(struct iso_gpt_partition_request **req_array,
|
||||
int *gpt_req_count,
|
||||
struct iso_gpt_partition_request *req, int flag);
|
||||
|
||||
/* Convenience frontend for iso_register_gpt_entry().
|
||||
name has to be already encoded as UTF-16LE.
|
||||
*/
|
||||
int iso_quick_gpt_entry(Ecma119Image *t,
|
||||
uint32_t start_block, uint32_t block_count,
|
||||
int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array,
|
||||
int *gpt_req_count,
|
||||
uint64_t start_block, uint64_t block_count,
|
||||
uint8_t type_guid[16], uint8_t partition_guid[16],
|
||||
uint64_t flags, uint8_t name[72]);
|
||||
|
||||
@ -255,15 +260,61 @@ int iso_write_gpt_header_block(Ecma119Image *t, uint32_t img_blocks,
|
||||
uint8_t *buf, uint32_t max_entries,
|
||||
uint32_t part_start, uint32_t p_arr_crc);
|
||||
|
||||
/* The description of a loaded MIPS Big Endian Volume Directory Entry
|
||||
*/
|
||||
struct iso_mips_voldir_entry {
|
||||
char name[9];
|
||||
uint32_t boot_block;
|
||||
uint32_t boot_bytes;
|
||||
};
|
||||
|
||||
/* The description of a loaded SUN Disk Label partition */
|
||||
struct iso_sun_disk_label_entry {
|
||||
int idx;
|
||||
uint16_t id_tag;
|
||||
uint16_t permissions;
|
||||
uint32_t start_cyl;
|
||||
uint32_t num_blocks;
|
||||
};
|
||||
|
||||
/* Creates the Partition Prepend writer.
|
||||
*/
|
||||
int partprepend_writer_create(Ecma119Image *target);
|
||||
|
||||
/* Creates the Inline Partition Append Writer
|
||||
*/
|
||||
int partappend_writer_create(Ecma119Image *target);
|
||||
|
||||
/* Creates the GPT backup tail writer.
|
||||
*/
|
||||
int gpt_tail_writer_create(Ecma119Image *target);
|
||||
|
||||
/* Not for execution but only to identify the writer by
|
||||
( writer->write_vol_desc == gpt_tail_writer_write_vol_desc )
|
||||
*/
|
||||
int gpt_tail_writer_write_vol_desc(IsoImageWriter *writer);
|
||||
|
||||
|
||||
/* Only for up to 36 characters ISO-8859-1 (or ASCII) input */
|
||||
void iso_ascii_utf_16le(uint8_t gap_name[72]);
|
||||
|
||||
|
||||
/* Parameters of MBR patching for GRUB2
|
||||
Might later become variables in Ecma119Image
|
||||
*/
|
||||
#define Libisofs_grub2_mbr_patch_poS 0x1b0
|
||||
#define Libisofs_grub2_mbr_patch_offsT 4
|
||||
|
||||
/* Parameters of SUN Disk Label patching for GRUB2
|
||||
See API iso_image_set_sparc_core().
|
||||
*/
|
||||
#define Libisofs_grub2_sparc_patch_adr_poS 0x228
|
||||
#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
|
||||
*/
|
||||
|
||||
#endif /* SYSTEM_AREA_H_ */
|
||||
|
320
libisofs/tree.c
320
libisofs/tree.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2011 Thomas Schmitt
|
||||
* Copyright (c) 2011 - 2014 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
|
||||
@ -23,6 +23,7 @@
|
||||
#include "builder.h"
|
||||
#include "messages.h"
|
||||
#include "tree.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -502,10 +503,10 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
|
||||
int result;
|
||||
IsoNode *new;
|
||||
IsoNode **pos;
|
||||
char *name;
|
||||
char *name = NULL;
|
||||
|
||||
if (parent == NULL || src == NULL || builder == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
result = ISO_NULL_POINTER; goto ex;
|
||||
}
|
||||
if (node) {
|
||||
*node = NULL;
|
||||
@ -515,23 +516,25 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
|
||||
|
||||
/* find place where to insert */
|
||||
result = iso_dir_exists(parent, name, &pos);
|
||||
free(name);
|
||||
if (result) {
|
||||
/* a node with same name already exists */
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
result = ISO_NODE_NAME_NOT_UNIQUE; goto ex;
|
||||
}
|
||||
|
||||
result = builder->create_node(builder, image, src, &new);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
result = builder->create_node(builder, image, src, name, &new);
|
||||
if (result < 0)
|
||||
goto ex;
|
||||
|
||||
if (node) {
|
||||
*node = new;
|
||||
}
|
||||
|
||||
/* finally, add node to parent */
|
||||
return iso_dir_insert(parent, (IsoNode*)new, pos, ISO_REPLACE_NEVER);
|
||||
result = iso_dir_insert(parent, (IsoNode*)new, pos, ISO_REPLACE_NEVER);
|
||||
ex:
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
return result;
|
||||
}
|
||||
|
||||
int iso_tree_add_node(IsoImage *image, IsoDir *parent, const char *path,
|
||||
@ -587,7 +590,8 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
||||
return result;
|
||||
}
|
||||
|
||||
result = image->builder->create_node(image->builder, image, file, &new);
|
||||
result = image->builder->create_node(image->builder, image, file,
|
||||
(char *) name, &new);
|
||||
|
||||
/* free the file */
|
||||
iso_file_source_unref(file);
|
||||
@ -596,12 +600,6 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
||||
return result;
|
||||
}
|
||||
|
||||
result = iso_node_set_name(new, name);
|
||||
if (result < 0) {
|
||||
iso_node_unref(new);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (node) {
|
||||
*node = new;
|
||||
}
|
||||
@ -742,6 +740,176 @@ int check_special(IsoImage *image, mode_t mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void ascii_increment(char *name, int len, int pos, int rollover_carry)
|
||||
{
|
||||
int c;
|
||||
|
||||
again:;
|
||||
if (pos < 0 || pos >= len)
|
||||
pos = len - 1;
|
||||
c = name[pos];
|
||||
if (c >= '0' && c < '9') {
|
||||
c++;
|
||||
} else if (c == '9') {
|
||||
c = 'A';
|
||||
} else if (c >= 'A' && c < 'Z') {
|
||||
c++;
|
||||
} else if (c == 'Z') {
|
||||
c = '_';
|
||||
} else if (c == '_') {
|
||||
c = 'a';
|
||||
} else if (c >= 'a' && c < 'z') {
|
||||
c++;
|
||||
} else if (c == 'z') {
|
||||
c = '0';
|
||||
name[pos] = c;
|
||||
pos--;
|
||||
if (pos >= 0 || rollover_carry)
|
||||
goto again;
|
||||
return;
|
||||
} else {
|
||||
if (pos == len - 1 || name[pos + 1] == '.')
|
||||
c = '_'; /* Make first change less riddling */
|
||||
else
|
||||
c = '0'; /* But else use the full range of valid characters */
|
||||
}
|
||||
name[pos] = c;
|
||||
}
|
||||
|
||||
static
|
||||
int insert_underscores(char *name, int *len, int *at_pos, int count,
|
||||
char **new_name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
LIBISO_ALLOC_MEM(*new_name, char, count + *len + 1);
|
||||
if (*at_pos > 0)
|
||||
memcpy(*new_name, name, *at_pos);
|
||||
if (count > 0)
|
||||
memset(*new_name + *at_pos, '_', count);
|
||||
if (*len > *at_pos)
|
||||
memcpy(*new_name + *at_pos + count, name + *at_pos, *len - *at_pos);
|
||||
(*new_name)[count + *len] = 0;
|
||||
*len += count;
|
||||
*at_pos += count;
|
||||
ret= ISO_SUCCESS;
|
||||
ex:;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
int make_incrementable_name(char **name, char **unique_name, int *low_pos,
|
||||
int *rollover_carry, int *pre_check)
|
||||
{
|
||||
char *dpt, *npt;
|
||||
int first, len, ret;
|
||||
|
||||
/* The incrementable part of the file shall have at least 7 characters.
|
||||
There may be up to pow(2.0,32.0)*2048/33 = 266548273400 files.
|
||||
The set of increment result characters has 63 elements.
|
||||
pow(63.0,7.0) is nearly 15 times larger than 266548273400.
|
||||
*/
|
||||
static int min_incr = 7;
|
||||
|
||||
/* At most two suffixes of total length up to 12, like .tar.bz2,
|
||||
shall be preserved. The incrementable part will eventually be
|
||||
padded up.
|
||||
Incrementing begins before the last suffix in any case. But when this
|
||||
rolls over on short prefixes, then long last suffixes will get used
|
||||
as high characters of the incremental part. This is indicated by
|
||||
*rollover_carry which corresponds to the parameter of ascii_increment()
|
||||
with the same name.
|
||||
*/
|
||||
static int max_suffix = 12;
|
||||
|
||||
*rollover_carry = 0;
|
||||
*pre_check = 0;
|
||||
|
||||
len = strlen(*name);
|
||||
|
||||
/* Check if the part before the first dot is long enough.
|
||||
If not, then preserve the last two short suffixes.
|
||||
*/
|
||||
dpt = strchr(*name, '.');
|
||||
if (dpt != NULL)
|
||||
if ((dpt - *name) < min_incr)
|
||||
dpt = strrchr(*name, '.');
|
||||
if (dpt != NULL) {
|
||||
first= (dpt - *name);
|
||||
if (dpt > *name && len - first < max_suffix) {
|
||||
for(npt = dpt - 1; npt >= *name && *npt != '.'; npt--);
|
||||
if (npt >= *name) {
|
||||
if (len - (npt - *name) <= max_suffix) {
|
||||
first= (npt - *name);
|
||||
dpt = npt;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
first= len;
|
||||
if (first < min_incr && (len - first) <= max_suffix) {
|
||||
ret = insert_underscores(*name, &len, &first, min_incr - first,
|
||||
unique_name);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
*pre_check = 1; /* It might now already be unique */
|
||||
|
||||
} else if (len < 64) {
|
||||
/* Insert an underscore to preserve the original name at least for the
|
||||
first few increments
|
||||
*/
|
||||
ret = insert_underscores(*name, &len, &first, 1, unique_name);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
*pre_check = 1;
|
||||
|
||||
} else {
|
||||
LIBISO_ALLOC_MEM(*unique_name, char, len + 1);
|
||||
memcpy(*unique_name, *name, len);
|
||||
if (first < min_incr)
|
||||
*rollover_carry = 1; /* Do not get caged before the dots */
|
||||
}
|
||||
(*unique_name)[len] = 0;
|
||||
*low_pos = first - 1;
|
||||
ret = 1;
|
||||
ex:;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static
|
||||
int make_really_unique_name(IsoDir *parent, char **name, char **unique_name,
|
||||
IsoNode ***pos, int flag)
|
||||
{
|
||||
int ret, rollover_carry = 0, pre_check = 0, ascii_idx = -1, len;
|
||||
|
||||
ret = make_incrementable_name(name, unique_name, &ascii_idx,
|
||||
&rollover_carry, &pre_check);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
len = strlen(*unique_name);
|
||||
while (1) {
|
||||
if (!pre_check)
|
||||
ascii_increment(*unique_name, len, ascii_idx, !!rollover_carry);
|
||||
else
|
||||
pre_check = 0;
|
||||
ret = iso_dir_exists(parent, *unique_name, pos);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
*name = *unique_name;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (ret < 0) {
|
||||
LIBISO_FREE_MEM(*unique_name);
|
||||
*unique_name = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively add a given directory to the image tree.
|
||||
*
|
||||
@ -750,12 +918,12 @@ int check_special(IsoImage *image, mode_t mode)
|
||||
*/
|
||||
int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
{
|
||||
int ret;
|
||||
int ret, dir_is_open = 0;
|
||||
IsoNodeBuilder *builder;
|
||||
IsoFileSource *file;
|
||||
IsoNode **pos;
|
||||
struct stat info;
|
||||
char *name, *path;
|
||||
char *name, *path, *allocated_name = NULL;
|
||||
IsoNode *new;
|
||||
enum iso_replace_mode replace;
|
||||
|
||||
@ -771,8 +939,9 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
|
||||
"Can't open dir. NULL pointer caught as dir name");
|
||||
}
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
dir_is_open = 1;
|
||||
|
||||
builder = image->builder;
|
||||
|
||||
@ -785,15 +954,16 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
if (ret < 0) {
|
||||
/* error reading dir */
|
||||
ret = iso_msg_submit(image->id, ret, ret, "Error reading dir");
|
||||
goto ex;
|
||||
}
|
||||
break;
|
||||
break; /* End of directory */
|
||||
}
|
||||
|
||||
path = iso_file_source_get_path(file);
|
||||
if (path == NULL) {
|
||||
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
|
||||
"NULL pointer caught as file path");
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
name = strrchr(path, '/') + 1;
|
||||
|
||||
@ -803,6 +973,8 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
ret = iso_file_source_lstat(file, &info);
|
||||
}
|
||||
if (ret < 0) {
|
||||
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
|
||||
"Error when adding file %s", path);
|
||||
goto dir_rec_continue;
|
||||
}
|
||||
|
||||
@ -825,19 +997,25 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
|
||||
/* find place where to insert */
|
||||
ret = iso_dir_exists(parent, name, &pos);
|
||||
/* TODO
|
||||
* if (ret && replace == ISO_REPLACE_ASK) {
|
||||
* replace = /....
|
||||
* }
|
||||
*/
|
||||
|
||||
/* chek if we must insert or not */
|
||||
/* TODO check for other replace behavior */
|
||||
if (ret && (replace == ISO_REPLACE_NEVER)) {
|
||||
/* skip file */
|
||||
goto dir_rec_continue;
|
||||
if (ret) {
|
||||
/* Resolve name collision
|
||||
e.g. caused by fs_image.c:make_hopefully_unique_name()
|
||||
*/
|
||||
LIBISO_FREE_MEM(allocated_name); allocated_name = NULL;
|
||||
ret = make_really_unique_name(parent, &name, &allocated_name, &pos,
|
||||
0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
image->collision_warnings++;
|
||||
if (image->collision_warnings < ISO_IMPORT_COLL_WARN_MAX) {
|
||||
ret = iso_msg_submit(image->id, ISO_IMPORT_COLLISION, 0,
|
||||
"File name collision resolved with %s . Now: %s",
|
||||
path, name);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* if we are here we must insert. Give user a chance for cancel */
|
||||
if (image->report) {
|
||||
int r = image->report(image, file);
|
||||
@ -846,7 +1024,7 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
goto dir_rec_continue;
|
||||
}
|
||||
}
|
||||
ret = builder->create_node(builder, image, file, &new);
|
||||
ret = builder->create_node(builder, image, file, name, &new);
|
||||
if (ret < 0) {
|
||||
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
|
||||
"Error when adding file %s", path);
|
||||
@ -882,14 +1060,17 @@ dir_rec_continue:;
|
||||
/* check for error severity to decide what to do */
|
||||
if (ret < 0) {
|
||||
ret = iso_msg_submit(image->id, ret, 0, NULL);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
} /* while */
|
||||
|
||||
iso_file_source_close(dir);
|
||||
return ret < 0 ? ret : ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (dir_is_open)
|
||||
iso_file_source_close(dir);
|
||||
LIBISO_FREE_MEM(allocated_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir)
|
||||
@ -1006,6 +1187,65 @@ ex:;
|
||||
return path;
|
||||
}
|
||||
|
||||
/* Note: No reference is taken to the found node.
|
||||
@param flag bit0= recursion
|
||||
*/
|
||||
int iso_tree_get_node_of_block(IsoImage *image, IsoDir *dir, uint32_t block,
|
||||
IsoNode **found, uint32_t *next_above, int flag)
|
||||
{
|
||||
int ret, section_count, i;
|
||||
IsoDirIter *iter = NULL;
|
||||
IsoNode *node;
|
||||
IsoDir *subdir;
|
||||
IsoFile *file;
|
||||
struct iso_file_section *sections = NULL;
|
||||
uint32_t na = 0;
|
||||
|
||||
if (dir == NULL)
|
||||
dir = image->root;
|
||||
|
||||
ret = iso_dir_get_children(dir, &iter);
|
||||
while (iso_dir_iter_next(iter, &node) == 1 ) {
|
||||
|
||||
if (ISO_NODE_IS_FILE(node)) {
|
||||
file = (IsoFile *) node;
|
||||
ret = iso_file_get_old_image_sections(file, §ion_count,
|
||||
§ions, 0);
|
||||
if (ret <= 0)
|
||||
continue;
|
||||
for (i = 0; i < section_count; i++) {
|
||||
if (sections[i].block <= block &&
|
||||
block - sections[i].block <
|
||||
(((off_t) sections[i].size) + 2047) / 2048) {
|
||||
*found = node;
|
||||
ret = 1; goto ex;
|
||||
}
|
||||
if ((na == 0 || sections[i].block < na) &&
|
||||
sections[i].block > block)
|
||||
na = sections[i].block;
|
||||
}
|
||||
free(sections); sections = NULL;
|
||||
} else if (ISO_NODE_IS_DIR(node)) {
|
||||
subdir = (IsoDir *) node;
|
||||
ret = iso_tree_get_node_of_block(image, subdir, block, found, &na,
|
||||
1);
|
||||
if (ret != 0)
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
if (next_above != NULL && (na > 0 || !(flag & 1)))
|
||||
if (*next_above == 0 || *next_above > na || !(flag & 1))
|
||||
*next_above = na;
|
||||
ret = 0;
|
||||
ex:
|
||||
if (sections != NULL)
|
||||
free(sections);
|
||||
if (iter != NULL)
|
||||
iso_dir_iter_free(iter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------- tree cloning ------------------------------ */
|
||||
|
||||
static
|
||||
|
@ -19,4 +19,9 @@
|
||||
*/
|
||||
int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir);
|
||||
|
||||
|
||||
int iso_tree_get_node_of_block(IsoImage *image, IsoDir *dir, uint32_t block,
|
||||
IsoNode **found, uint32_t *next_above, int flag);
|
||||
|
||||
|
||||
#endif /*LIBISO_IMAGE_TREE_H_*/
|
||||
|
265
libisofs/util.c
265
libisofs/util.c
@ -241,8 +241,8 @@ ex:;
|
||||
return retval;
|
||||
}
|
||||
|
||||
int strnconv(const char *str, const char *icharset, const char *ocharset,
|
||||
size_t len, char **output)
|
||||
int strnconvl(const char *str, const char *icharset, const char *ocharset,
|
||||
size_t len, char **output, size_t *out_len)
|
||||
{
|
||||
size_t inbytes;
|
||||
size_t outbytes;
|
||||
@ -278,7 +278,8 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
|
||||
*ret = '\0';
|
||||
iso_iconv_close(&conv, 0);
|
||||
|
||||
*output = malloc(ret - out + 1);
|
||||
*out_len = ret - out;
|
||||
*output = malloc(*out_len + 1);
|
||||
if (*output == NULL) {
|
||||
retval = ISO_OUT_OF_MEM;
|
||||
goto ex;
|
||||
@ -291,6 +292,15 @@ ex:;
|
||||
return retval;
|
||||
}
|
||||
|
||||
int strnconv(const char *str, const char *icharset, const char *ocharset,
|
||||
size_t len, char **output)
|
||||
{
|
||||
size_t l;
|
||||
|
||||
return strnconvl(str, icharset, ocharset, len, output, &l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a str in a specified codeset to WCHAR_T.
|
||||
* The result must be free() when no more needed
|
||||
@ -667,6 +677,123 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int str2utf16be(const char *icharset, const char *input, uint16_t **output)
|
||||
{
|
||||
int result;
|
||||
wchar_t *wsrc_ = NULL;
|
||||
char *src;
|
||||
char *ret = NULL;
|
||||
char *ret_ = NULL;
|
||||
struct iso_iconv_handle conv;
|
||||
int conv_ret = 0;
|
||||
int direct_conv = 0;
|
||||
size_t loop_counter = 0, loop_limit = 3;
|
||||
size_t numchars;
|
||||
size_t outbytes;
|
||||
size_t inbytes;
|
||||
size_t n;
|
||||
|
||||
if (icharset == NULL || input == NULL || output == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/*
|
||||
Try the direct conversion.
|
||||
*/
|
||||
conv_ret = iso_iconv_open(&conv, "UTF-16BE", (char *) icharset, 0);
|
||||
if (conv_ret > 0) {
|
||||
direct_conv = 1;
|
||||
src = (char *) input;
|
||||
inbytes = strlen(input);
|
||||
loop_limit = inbytes + 3;
|
||||
outbytes = (2 * inbytes + 1) * sizeof(uint16_t);
|
||||
ret_ = malloc(outbytes);
|
||||
if (ret_ == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
ret = ret_;
|
||||
} else {
|
||||
/* Try via intermediate character set WCHAR_T.
|
||||
*/
|
||||
result = str2wchar(icharset, input, &wsrc_);
|
||||
if (result == (int) ISO_SUCCESS) {
|
||||
src = (char *)wsrc_;
|
||||
numchars = wcslen(wsrc_);
|
||||
|
||||
inbytes = numchars * sizeof(wchar_t);
|
||||
loop_limit = inbytes + 3;
|
||||
|
||||
ret_ = malloc((2 * numchars+1) * sizeof(uint16_t));
|
||||
if (ret_ == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
outbytes = 2 * numchars * sizeof(uint16_t);
|
||||
ret = ret_;
|
||||
|
||||
/* initialize iconv */
|
||||
conv_ret = iso_iconv_open(&conv, "UTF-16BE", "WCHAR_T", 0);
|
||||
if (conv_ret <= 0) {
|
||||
free(wsrc_);
|
||||
free(ret_);
|
||||
}
|
||||
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (conv_ret <= 0) {
|
||||
return ISO_CHARSET_CONV_ERROR;
|
||||
}
|
||||
|
||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||
while (n == (size_t) -1) {
|
||||
/* The destination buffer is too small. Stops here. */
|
||||
if (errno == E2BIG)
|
||||
break;
|
||||
|
||||
/* An incomplete multi bytes sequence was found. We
|
||||
* can't do anything here. That's quite unlikely. */
|
||||
if (errno == EINVAL)
|
||||
break;
|
||||
|
||||
/* The last possible error is an invalid multi bytes
|
||||
* sequence. Just replace the character with a "_".
|
||||
* Probably the character doesn't exist in UCS */
|
||||
set_ucsbe((uint16_t*) ret, '_');
|
||||
ret += sizeof(uint16_t);
|
||||
outbytes -= sizeof(uint16_t);
|
||||
|
||||
if (!outbytes)
|
||||
break;
|
||||
|
||||
/* There was an error with one character but some other remain
|
||||
* to be converted. That's probably a multibyte character.
|
||||
* See above comment. */
|
||||
if (direct_conv) {
|
||||
src++;
|
||||
inbytes--;
|
||||
} else {
|
||||
src += sizeof(wchar_t);
|
||||
inbytes -= sizeof(wchar_t);
|
||||
}
|
||||
|
||||
if (!inbytes)
|
||||
break;
|
||||
|
||||
/* Just to appease my remorse about unclear loop ends */
|
||||
loop_counter++;
|
||||
if (loop_counter > loop_limit)
|
||||
break;
|
||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||
}
|
||||
iso_iconv_close(&conv, 0);
|
||||
|
||||
/* close the UTF-16 string */
|
||||
set_ucsbe((uint16_t*) ret, '\0');
|
||||
if (wsrc_ != NULL)
|
||||
free(wsrc_);
|
||||
|
||||
*output = (uint16_t*)ret_;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static int valid_d_char(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');
|
||||
@ -1080,7 +1207,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
{
|
||||
uint16_t *dot, *retval = NULL;
|
||||
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
|
||||
uint16_t *dest = NULL;
|
||||
uint16_t *dest = NULL, c;
|
||||
|
||||
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
|
||||
@ -1120,7 +1247,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
|
||||
/* Convert up to lnname characters of the filename. */
|
||||
for (i = 0; i < lnname; i++) {
|
||||
uint16_t c = src[i];
|
||||
c = src[i];
|
||||
if (valid_j_char(c)) {
|
||||
dest[pos++] = c;
|
||||
} else {
|
||||
@ -1128,6 +1255,8 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
if (pos > 0)
|
||||
iso_handle_split_utf16(dest + (pos - 1));
|
||||
|
||||
if ((flag & 1) && lnext <= 0)
|
||||
goto is_done;
|
||||
@ -1145,6 +1274,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
iso_handle_split_utf16(dest + (pos - 1));
|
||||
|
||||
is_done:;
|
||||
set_ucsbe(dest + pos, '\0');
|
||||
@ -1181,6 +1311,7 @@ uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
|
||||
set_ucsbe(dest + i, '_');
|
||||
}
|
||||
}
|
||||
iso_handle_split_utf16(dest + (len - 1));
|
||||
set_ucsbe(dest + len, '\0');
|
||||
retval = ucsdup(dest);
|
||||
ex:
|
||||
@ -1262,6 +1393,8 @@ uint16_t *ucsncpy(uint16_t *dest, const uint16_t *src, size_t n)
|
||||
{
|
||||
n = MIN(n, ucslen(src) + 1);
|
||||
memcpy(dest, src, n*2);
|
||||
if (n >= 2)
|
||||
iso_handle_split_utf16(dest + (n - 2));
|
||||
return dest;
|
||||
}
|
||||
|
||||
@ -1401,6 +1534,26 @@ uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error)
|
||||
return v1;
|
||||
}
|
||||
|
||||
uint64_t iso_read_lsb64(const uint8_t *buf)
|
||||
{
|
||||
int i;
|
||||
uint64_t ret = 0;
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
ret += ((uint64_t) buf[i]) << (i * 8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t iso_read_msb64(const uint8_t *buf)
|
||||
{
|
||||
int i;
|
||||
uint64_t ret = 0;
|
||||
|
||||
for (i=0; i < 8; i++)
|
||||
ret += ((uint64_t) buf[7 - i]) << (i * 8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
|
||||
{
|
||||
static int tzsetup = 0;
|
||||
@ -1421,8 +1574,14 @@ void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
|
||||
#else
|
||||
if (tm.tm_isdst < 0)
|
||||
tm.tm_isdst = 0;
|
||||
tzoffset = ( - timezone / 60 / 15 ) + 4 * tm.tm_isdst;
|
||||
#ifndef Libburnia_timezonE
|
||||
#define Libburnia_timezonE timezone
|
||||
#endif
|
||||
#if Libburnia_timezonE == 0
|
||||
always_gmt = 1;
|
||||
#endif
|
||||
tzoffset = ( - Libburnia_timezonE / 60 / 15 ) + 4 * tm.tm_isdst;
|
||||
#endif /* ! HAVE_TM_GMTOFF */
|
||||
|
||||
if (tzoffset > 52 || tzoffset < -48 || always_gmt) {
|
||||
/* absurd timezone offset, represent time in GMT */
|
||||
@ -1467,8 +1626,14 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
|
||||
#else
|
||||
if (tm.tm_isdst < 0)
|
||||
tm.tm_isdst = 0;
|
||||
tzoffset = ( - timezone / 60 / 15 ) + 4 * tm.tm_isdst;
|
||||
#ifndef Libburnia_timezonE
|
||||
#define Libburnia_timezonE timezone
|
||||
#endif
|
||||
#if Libburnia_timezonE == 0
|
||||
always_gmt = 1;
|
||||
#endif
|
||||
tzoffset = ( - Libburnia_timezonE / 60 / 15 ) + 4 * tm.tm_isdst;
|
||||
#endif /* ! HAVE_TM_GMTOFF */
|
||||
|
||||
if (tzoffset > 52 || tzoffset < -48 || always_gmt) {
|
||||
/* absurd timezone offset, represent time in GMT */
|
||||
@ -1878,6 +2043,17 @@ int iso_util_dec_to_uint32(char *dec, uint32_t *value, int flag)
|
||||
}
|
||||
|
||||
|
||||
int iso_util_bin_to_hex(char *target, uint8_t *bytes, int num_bytes, int flag)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_bytes; i++)
|
||||
sprintf(target + 2 * i, "%-2.2x", bytes[i]);
|
||||
target[2 * num_bytes] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
|
||||
int flag)
|
||||
{
|
||||
@ -2092,3 +2268,78 @@ uint16_t iso_htons(uint16_t v)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* If an UTF-16 surrogate pair was split : Change to UTF-16 '_'.
|
||||
(UCS-2 is promised to reserve 0xd800 to 0xdbff for UTF-16).
|
||||
*/
|
||||
void iso_handle_split_utf16(uint16_t *utf_word)
|
||||
{
|
||||
unsigned char *hb;
|
||||
|
||||
hb = (unsigned char *) utf_word;
|
||||
if ((hb[0] & 0xfc) == 0xd8)
|
||||
set_ucsbe(utf_word, '_');
|
||||
}
|
||||
|
||||
|
||||
int iso_clone_mem(char *in, char **out, size_t size)
|
||||
{
|
||||
if (in == NULL) {
|
||||
*out = NULL;
|
||||
return 1;
|
||||
}
|
||||
if (size == 0)
|
||||
size = strlen(in) + 1;
|
||||
*out = calloc(1, size);
|
||||
if (*out == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy(*out, in, size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int iso_clone_mgtd_mem(char *in, char **out, size_t size)
|
||||
{
|
||||
if (*out != NULL)
|
||||
free(*out);
|
||||
return iso_clone_mem(in, out, size);
|
||||
}
|
||||
|
||||
|
||||
/** Convert a text into a number of type double and multiply it by unit code
|
||||
[kmgt] (2^10 to 2^40) or [s] (2048) or [d] (512).
|
||||
(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
|
||||
bit1= if scaled then compute the last byte of the last unit
|
||||
@return The derived value
|
||||
*/
|
||||
off_t iso_scanf_io_size(char *text, int flag)
|
||||
{
|
||||
int c;
|
||||
off_t ret = 0, fac = 1;
|
||||
char *rpt;
|
||||
|
||||
for (rpt = text; *rpt >= '0' && *rpt <= '9'; rpt++)
|
||||
ret = ret * 10 + (*rpt - '0');
|
||||
if (rpt == text)
|
||||
return (off_t) (flag & 1 ? -1 : 0);
|
||||
c = *rpt;
|
||||
if (c=='k' || c=='K')
|
||||
fac = 1024;
|
||||
else if (c=='m' || c=='M')
|
||||
fac = 1024 * 1024;
|
||||
else if (c=='g' || c=='G')
|
||||
fac = 1024 * 1024 * 1024;
|
||||
else if (c=='t' || c=='T')
|
||||
fac = ((off_t) 1024) * 1024 * 1024 * 1024;
|
||||
else if (c=='s' || c=='S')
|
||||
fac = 2048;
|
||||
else if (c=='d' || c=='D')
|
||||
fac = 512;
|
||||
ret *= fac;
|
||||
if (flag & 2)
|
||||
ret += fac - 1;
|
||||
return ret;
|
||||
}
|
||||
|
@ -21,6 +21,12 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef MAX
|
||||
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
@ -56,9 +62,16 @@ int iso_init_locale(int flag);
|
||||
int strconv(const char *input, const char *icharset, const char *ocharset,
|
||||
char **output);
|
||||
|
||||
/* Like strconv but processing len input bytes rather than strlen(input)
|
||||
*/
|
||||
int strnconv(const char *str, const char *icharset, const char *ocharset,
|
||||
size_t len, char **output);
|
||||
|
||||
/* Like strnconv but also returning the number of bytes in *output.
|
||||
*/
|
||||
int strnconvl(const char *str, const char *icharset, const char *ocharset,
|
||||
size_t len, char **output, size_t *out_len);
|
||||
|
||||
/**
|
||||
* Convert a given string from any input charset to ASCII
|
||||
*
|
||||
@ -88,6 +101,22 @@ int str2ascii(const char *icharset, const char *input, char **output);
|
||||
*/
|
||||
int str2ucs(const char *icharset, const char *input, uint16_t **output);
|
||||
|
||||
/**
|
||||
* Convert a given string from any input charset to UTF-16BE charset,
|
||||
* used for HFS+ file identifiers.
|
||||
* (UTF-16 differs from older UCS-2 by having multi word characters.)
|
||||
*
|
||||
* @param icharset
|
||||
* Input charset. Must be supported by iconv
|
||||
* @param input
|
||||
* Input string
|
||||
* @param output
|
||||
* Location where the pointer to the ouput string will be stored
|
||||
* @return
|
||||
* 1 on success, < 0 on error
|
||||
*/
|
||||
int str2utf16be(const char *icharset, const char *input, uint16_t **output);
|
||||
|
||||
/**
|
||||
* Create a level 1 directory identifier.
|
||||
*
|
||||
@ -220,6 +249,12 @@ uint16_t *ucscpy(uint16_t *dest, const uint16_t *src);
|
||||
*/
|
||||
uint16_t *ucsncpy(uint16_t *dest, const uint16_t *src, size_t n);
|
||||
|
||||
/**
|
||||
* Check whether utf_word is the first surrogate word of a pair.
|
||||
* If so, change it to UTF-16 character '_'.
|
||||
*/
|
||||
void iso_handle_split_utf16(uint16_t *utf_word);
|
||||
|
||||
/**
|
||||
* Convert a given input string to d-chars.
|
||||
* @return
|
||||
@ -244,6 +279,9 @@ uint32_t iso_read_msb(const uint8_t *buf, int bytes);
|
||||
*/
|
||||
uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error);
|
||||
|
||||
uint64_t iso_read_lsb64(const uint8_t *buf);
|
||||
uint64_t iso_read_msb64(const uint8_t *buf);
|
||||
|
||||
/**
|
||||
* Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5)
|
||||
*
|
||||
@ -515,6 +553,12 @@ int iso_util_eval_md5_tag(char *block, int desired, uint32_t lba,
|
||||
int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag);
|
||||
|
||||
|
||||
int iso_util_bin_to_hex(char *target, uint8_t *bytes, int num_bytes, int flag);
|
||||
|
||||
int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
|
||||
int flag);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* In md5.h these function prototypes would be neighbors of (Ecma119Image *)
|
||||
@ -577,6 +621,29 @@ void *iso_alloc_mem(size_t size, size_t count, int flag);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@param in Valid memory or NULL
|
||||
@param out Returns valid memory or NULL
|
||||
@param size Number of bytes to copy. 0 means strlen(in)+1 if not NULL.
|
||||
@return 1 or ISO_OUT_OF_MEM
|
||||
*/
|
||||
int iso_clone_mem(char *in, char **out, size_t size);
|
||||
|
||||
/* Like iso_clone_mem but first freeing *out if not NULL
|
||||
*/
|
||||
int iso_clone_mgtd_mem(char *in, char **out, size_t size);
|
||||
|
||||
/** Convert a text into a number of type double and multiply it by unit code
|
||||
[kmgt] (2^10 to 2^40) or [s] (2048) or [d] (512).
|
||||
(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
|
||||
bit1= if scaled then compute the last byte of the last unit
|
||||
@return The derived value
|
||||
*/
|
||||
off_t iso_scanf_io_size(char *text, int flag);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2014 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
|
||||
@ -322,9 +323,10 @@ int iso_htable_create(size_t size, hash_funtion_t hash,
|
||||
{
|
||||
IsoHTable *t;
|
||||
|
||||
if (table == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
if (size <= 0)
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
if (table == NULL)
|
||||
return ISO_NULL_POINTER;
|
||||
|
||||
t = malloc(sizeof(IsoHTable));
|
||||
if (t == NULL) {
|
||||
|
Reference in New Issue
Block a user