Compare commits
198 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
1786ceb276 | |||
f51fc50356 | |||
02de4570d1 | |||
2a41b4817c | |||
9440e3061c | |||
122dfe7b87 | |||
03662f0832 | |||
eb09bcf9e5 | |||
5880636a50 | |||
b5fb98a2a3 | |||
b269557743 | |||
0fd7d4d7eb | |||
d8dca37d65 | |||
cd84f0927f | |||
477bbb89bb | |||
31fcdc0ba6 | |||
7c05d2a865 | |||
3d15642307 | |||
872b5c6c67 | |||
ec35bb21c0 | |||
93f3cb1823 | |||
fea7be5168 | |||
bd25db9283 | |||
97eec6162c | |||
17e8cb6697 | |||
9e01d3654e | |||
009ce1be8f | |||
c79299ba08 | |||
b3701f0b18 | |||
83b864efd2 | |||
cd0f57dd1a | |||
4c9cb6b96b | |||
9c334891cf | |||
2f6103b783 | |||
f32ee7da83 | |||
52972811f8 | |||
089982022c | |||
a6316ff05c | |||
02a972a2d7 | |||
da8ad0d2aa | |||
79e6312397 | |||
b3a183fceb | |||
355f1f7ea2 | |||
57fd669d1d | |||
6047464b6b | |||
e8b94e7b50 | |||
49dd9dc993 | |||
93e1fc52d0 | |||
4838cd59a7 | |||
d51b1738dd | |||
6252ae2065 | |||
cb1e56478a | |||
05d0ee4a37 | |||
c6aedc9eb5 | |||
505bf23aa4 | |||
ccef2f29da | |||
b904926443 | |||
7bdc4c96f5 | |||
fa5e27458a | |||
7c29a94ab6 | |||
a4c1e04820 | |||
50132d4ff7 | |||
4c1c1ea152 | |||
a16d4a28f4 | |||
4633ea3bc8 | |||
430c005666 | |||
af55722830 | |||
d1da5718c7 | |||
afb2878773 | |||
4e7432c20f | |||
7ef616f268 | |||
d5f1eb9c65 | |||
28b41bce2c | |||
5ac3216933 | |||
05a2171e04 | |||
188a41f041 | |||
fbe7f1e89d | |||
d04abdcfbd | |||
a6542e5fa9 | |||
78d2c02ad8 | |||
48453ef1da | |||
7928c4ec3f | |||
379e223a5c | |||
e4750907e3 | |||
8f76b59541 | |||
0433b7ea75 | |||
d8fb8b26a6 | |||
b9ccdeda72 | |||
d04f438ba1 | |||
e35cb88328 | |||
83fb614462 | |||
e5f6811795 | |||
f3b836194c | |||
3a870d23e3 | |||
06ea46c8d5 | |||
d427a03192 | |||
2b6071b445 | |||
fc448e09c9 | |||
7b7da47d86 | |||
01c7a0d5ec | |||
905f4f898f | |||
b9ec876c40 | |||
72ef369a40 | |||
218e26c974 | |||
395128ef5f | |||
7a3560035a | |||
7ac5b75748 | |||
6c3dc3ce4a | |||
bdbaf81e9c | |||
c8ed18695f | |||
d3fefe4735 | |||
6db3f6ca44 | |||
bf19f73ea6 | |||
6947bfe5ec | |||
94f8503b57 | |||
cb519e221e | |||
d09a317f51 | |||
2beb0d001b | |||
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 |
@ -1,7 +1,7 @@
|
|||||||
Vreixo Formoso <metalpain2002@yahoo.es>,
|
Vreixo Formoso <metalpain2002@yahoo.es>,
|
||||||
Mario Danic <mario.danic@gmail.com>,
|
Mario Danic <mario.danic@gmail.com>,
|
||||||
Thomas Schmitt <scdbackup@gmx.net>
|
Thomas Schmitt <scdbackup@gmx.net>
|
||||||
Copyright (C) 2007-2011 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
Copyright (C) 2007-2015 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||||
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
88
ChangeLog
88
ChangeLog
@ -1,3 +1,91 @@
|
|||||||
|
|
||||||
|
libisofs-1.4.4.tar.gz Fri Jul 01 2016
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: HFS+ production could cause MBR partition of type 0xEE without GPT.
|
||||||
|
* Bug fix: Protective MBR was not produced if no System Area data are given.
|
||||||
|
* Bug fix: Protective MBR was not recognized if partition is appended.
|
||||||
|
* Bug fix: The HFS+ filesystem was not marked in GPT of GRUB2 hybrid layout.
|
||||||
|
* Bug fix: HFS+ directories could announce more children than they actually
|
||||||
|
have.
|
||||||
|
* Bug fix: At image loading time GRUB2 MBR was not recognized if the partition
|
||||||
|
table is not the protective one as described by UEFI.
|
||||||
|
* Bug fix: Oversized text in ISO_SYSAREA_REPORT_DOC_ALPHA.
|
||||||
|
Thanks to Etienne Bergeron.
|
||||||
|
* New pseudo path for El Torito boot images:
|
||||||
|
--interval:appened_partition_N:all::
|
||||||
|
* New bit15 with options of iso_write_opts_set_system_area() to enforce
|
||||||
|
MBR bootable/active flag.
|
||||||
|
* New API calls iso_write_opts_set_appended_as_apm(),
|
||||||
|
iso_write_opts_set_part_like_isohybrid().
|
||||||
|
* Introduced image size tolerance of 300 kB in order to recognize SUN Disk
|
||||||
|
Label that was generated by genisoimage -B "...".
|
||||||
|
* Added "extern C" to libisofs.h
|
||||||
|
* Removed option --silent from libtool runs.
|
||||||
|
|
||||||
|
libisofs-1.4.2.tar.gz Sat Nov 28 2015
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: zisofs compression caused SIGSEGV (by reading) with files larger
|
||||||
|
than 524160 KiB.
|
||||||
|
* Bug fix: iso_node_get_name() of root node returned NULL pointer rather than
|
||||||
|
an empty string
|
||||||
|
* Bug fix: Names read from Joliet tree where stripped of trailing ";1"
|
||||||
|
* Now sorting the data file content extents by ECMA-119 tree, rather than
|
||||||
|
by the red-black tree which shall consolidate files with identical
|
||||||
|
source object.
|
||||||
|
* New API call iso_read_opts_set_ecma119_map().
|
||||||
|
* New AAIP variable isofs.nt records name truncation parameters.
|
||||||
|
* Rectified handling of oversized filenames by new API calls:
|
||||||
|
iso_image_set_truncate_mode, iso_image_get_truncate_mode,
|
||||||
|
iso_truncate_leaf_name, iso_image_set_node_name, iso_image_tree_clone,
|
||||||
|
iso_image_add_new_dir, iso_image_add_new_file, iso_image_add_new_special,
|
||||||
|
iso_image_add_new_symlink, iso_image_dir_get_node, iso_image_path_to_node
|
||||||
|
* Result of a Coverity audit: 50+ code changes, but no easy-to-trigger bugs
|
||||||
|
|
||||||
|
libisofs-1.4.0.tar.gz Sun May 17 2015
|
||||||
|
===============================================================================
|
||||||
|
* 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
|
||||||
|
or 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
|
libisofs-1.3.6.tar.gz Tue Mar 04 2014
|
||||||
===============================================================================
|
===============================================================================
|
||||||
* Bug fix: Division by zero if HFS+ was combined with TOC emulation for
|
* Bug fix: Division by zero if HFS+ was combined with TOC emulation for
|
||||||
|
@ -13,7 +13,7 @@ ACLOCAL_AMFLAGS = -I ./
|
|||||||
# Build libraries
|
# Build libraries
|
||||||
|
|
||||||
libisofs_libisofs_la_LDFLAGS = \
|
libisofs_libisofs_la_LDFLAGS = \
|
||||||
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
|
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS)
|
||||||
|
|
||||||
# Eventually enabling system adapters for ACL and EA.
|
# Eventually enabling system adapters for ACL and EA.
|
||||||
# ts A90409: Eventually enabling use of zlib.
|
# ts A90409: Eventually enabling use of zlib.
|
||||||
@ -89,7 +89,7 @@ libinclude_HEADERS = \
|
|||||||
libisofs/libisofs.h
|
libisofs/libisofs.h
|
||||||
|
|
||||||
install-exec-hook:
|
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)"
|
||||||
|
|
||||||
## ========================================================================= ##
|
## ========================================================================= ##
|
||||||
|
|
||||||
|
4
README
4
README
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
Released under GPL (see COPYING file for details).
|
Released under GPL (see COPYING file for details).
|
||||||
|
|
||||||
Copyright (C) 2008 - 2013 Vreixo Formoso,
|
Copyright (C) 2008 - 2015 Vreixo Formoso,
|
||||||
Mario Danic,
|
Mario Danic,
|
||||||
Vladimir Serbinenko,
|
Vladimir Serbinenko,
|
||||||
Thomas Schmitt
|
Thomas Schmitt
|
||||||
@ -37,7 +37,7 @@ and execute
|
|||||||
./configure --prefix=/usr
|
./configure --prefix=/usr
|
||||||
make
|
make
|
||||||
|
|
||||||
To make the libraries accessible for running resp. developing applications
|
To make the libraries accessible for running and developing applications
|
||||||
make install
|
make install
|
||||||
|
|
||||||
On GNU/Linux it will try to run program ldconfig with the library installation
|
On GNU/Linux it will try to run program ldconfig with the library installation
|
||||||
|
24
acinclude.m4
24
acinclude.m4
@ -16,15 +16,21 @@ AC_DEFUN([TARGET_SHIZZLE],
|
|||||||
|
|
||||||
AC_MSG_CHECKING([target operating system])
|
AC_MSG_CHECKING([target operating system])
|
||||||
|
|
||||||
|
LIBBURNIA_SUPP_ACL=none
|
||||||
|
LIBBURNIA_SUPP_FATTR=none
|
||||||
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
|
LIBBURNIA_LDCONFIG_CMD="echo 'No ldconfig run performed. If needed, configure manually for:'"
|
||||||
case $target in
|
case $target in
|
||||||
*-*-linux*)
|
*-*-linux*)
|
||||||
ARCH=linux
|
ARCH=linux
|
||||||
LIBBURN_ARCH_LIBS=
|
LIBBURN_ARCH_LIBS=
|
||||||
|
LIBBURNIA_SUPP_ACL=libacl
|
||||||
|
LIBBURNIA_SUPP_FATTR=xattr
|
||||||
LIBBURNIA_LDCONFIG_CMD=ldconfig
|
LIBBURNIA_LDCONFIG_CMD=ldconfig
|
||||||
;;
|
;;
|
||||||
*-*-freebsd*)
|
*-*-freebsd*)
|
||||||
ARCH=freebsd
|
ARCH=freebsd
|
||||||
|
LIBBURNIA_SUPP_ACL=libacl
|
||||||
|
LIBBURNIA_SUPP_FATTR=extattr
|
||||||
LIBBURN_ARCH_LIBS=-lcam
|
LIBBURN_ARCH_LIBS=-lcam
|
||||||
|
|
||||||
# This may later be overridden by configure --enable-libdir-pkgconfig
|
# This may later be overridden by configure --enable-libdir-pkgconfig
|
||||||
@ -141,10 +147,12 @@ AC_DEFUN([LIBISOFS_ASSERT_VERS_LIBS],
|
|||||||
LDFLAGS="$LDFLAGS -Wl,--version-script=libisofs/libisofs.ver"
|
LDFLAGS="$LDFLAGS -Wl,--version-script=libisofs/libisofs.ver"
|
||||||
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
|
AC_TRY_LINK([#include <stdio.h>], [printf("Hello\n");],
|
||||||
[vers_libs_test="yes"], [vers_libs_test="no"])
|
[vers_libs_test="yes"], [vers_libs_test="no"])
|
||||||
if test x$vers_libs_test = xno
|
if test x$vers_libs_test = xyes
|
||||||
then
|
then
|
||||||
LDFLAGS="$libburnia_save_LDFLAGS"
|
LIBLDFLAGS="-Wl,--version-script=libisofs/libisofs.ver"
|
||||||
fi
|
fi
|
||||||
|
LDFLAGS="$libburnia_save_LDFLAGS"
|
||||||
|
AC_SUBST(LIBLDFLAGS)
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@ -198,3 +206,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"
|
||||||
|
])
|
||||||
|
|
||||||
|
97
configure.ac
97
configure.ac
@ -1,4 +1,4 @@
|
|||||||
AC_INIT([libisofs], [1.3.6], [http://libburnia-project.org])
|
AC_INIT([libisofs], [1.4.4], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
@ -26,8 +26,8 @@ dnl
|
|||||||
dnl LT_CURRENT, LT_REVISION and LT_AGE get set directly now.
|
dnl LT_CURRENT, LT_REVISION and LT_AGE get set directly now.
|
||||||
dnl
|
dnl
|
||||||
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
dnl SONAME of the emerging library is LT_CURRENT - LT_AGE.
|
||||||
dnl The linker will do no finer checks. Especially no age range check for
|
dnl The linker will do no finer checks. If SONAME matches, then the couple
|
||||||
dnl the cdrskin binary. If SONAME matches, then the couple starts.
|
dnl starts.
|
||||||
dnl
|
dnl
|
||||||
dnl Therefore a run time check is provided by libisofs function
|
dnl Therefore a run time check is provided by libisofs function
|
||||||
dnl iso_lib_version(). It returns the major, minor and micro revision of the
|
dnl iso_lib_version(). It returns the major, minor and micro revision of the
|
||||||
@ -40,8 +40,8 @@ dnl
|
|||||||
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||||
dnl
|
dnl
|
||||||
LIBISOFS_MAJOR_VERSION=1
|
LIBISOFS_MAJOR_VERSION=1
|
||||||
LIBISOFS_MINOR_VERSION=3
|
LIBISOFS_MINOR_VERSION=4
|
||||||
LIBISOFS_MICRO_VERSION=6
|
LIBISOFS_MICRO_VERSION=4
|
||||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||||
|
|
||||||
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
||||||
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
|
|||||||
|
|
||||||
dnl Libtool versioning
|
dnl Libtool versioning
|
||||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||||
# 2014.03.04 development jump has not yet happened
|
# 2016.07.01 development jump has not yet happened
|
||||||
# SONAME = 78 - 72 = 6 . Library name = libisofs.6.72.0
|
# SONAME = 86 - 80 = 6 . Library name = libisofs.6.80.0
|
||||||
LT_CURRENT=78
|
LT_CURRENT=86
|
||||||
LT_AGE=72
|
LT_AGE=80
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ LIBBURNIA_ASSERT_ICONV
|
|||||||
|
|
||||||
AC_PROG_LIBTOOL
|
AC_PROG_LIBTOOL
|
||||||
AC_SUBST(LIBTOOL_DEPS)
|
AC_SUBST(LIBTOOL_DEPS)
|
||||||
LIBTOOL="$LIBTOOL --silent"
|
dnl LIBTOOL="$LIBTOOL --silent"
|
||||||
|
|
||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
|
|
||||||
@ -114,6 +114,16 @@ AC_CHECK_DECL([timegm],
|
|||||||
,
|
,
|
||||||
[#include <time.h>])
|
[#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
|
dnl Check if non standard eaccess() function is available
|
||||||
AC_CHECK_DECL([eaccess],
|
AC_CHECK_DECL([eaccess],
|
||||||
[AC_DEFINE(HAVE_EACCESS, 1, [Define this if eaccess function is available])],
|
[AC_DEFINE(HAVE_EACCESS, 1, [Define this if eaccess function is available])],
|
||||||
@ -162,39 +172,66 @@ dnl Add compiler-specific flags
|
|||||||
AC_ARG_ENABLE(libacl,
|
AC_ARG_ENABLE(libacl,
|
||||||
[ --enable-libacl Enable use of ACL functions by libisofs, default=yes],
|
[ --enable-libacl Enable use of ACL functions by libisofs, default=yes],
|
||||||
, enable_libacl=yes)
|
, enable_libacl=yes)
|
||||||
if test "x$enable_libacl" = xyes; then
|
LIBACL_DEF=
|
||||||
|
has_acl_h_but_no_func=0
|
||||||
|
if test x$LIBBURNIA_SUPP_ACL = xlibacl
|
||||||
|
then
|
||||||
|
if test x$enable_libacl = xyes; then
|
||||||
dnl Check whether there is libacl-devel and libacl-runtime.
|
dnl Check whether there is libacl-devel and libacl-runtime.
|
||||||
dnl If not, erase this macro which would enable use of acl_to_text and others
|
dnl If not, erase this macro which would enable use of acl_to_text and others
|
||||||
LIBACL_DEF="-DLibisofs_with_aaip_acL"
|
LIBACL_DEF="-DLibisofs_with_aaip_acL"
|
||||||
dnl The empty yes case obviously causes -lacl to be linked
|
dnl The empty yes case obviously causes -lacl to be linked
|
||||||
has_acl_h_but_no_func=0
|
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , has_acl_h_but_no_libacl=1 ), LIBACL_DEF= )
|
||||||
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , has_acl_h_but_no_libacl=1 ), LIBACL_DEF= )
|
if test "$has_acl_h_but_no_libacl" = 1
|
||||||
if test "$has_acl_h_but_no_libacl" = 1
|
then
|
||||||
|
AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= )
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test x$LIBACL_DEF = x-DLibisofs_with_aaip_acL
|
||||||
|
then
|
||||||
|
if test x$has_acl_h_but_no_libacl = x1
|
||||||
then
|
then
|
||||||
AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= )
|
echo "enabled local processing of ACL"
|
||||||
fi
|
else
|
||||||
|
echo "enabled libacl, local processing of ACL"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
LIBACL_DEF=
|
echo "disabled local processing of ACL"
|
||||||
fi
|
fi
|
||||||
AC_SUBST(LIBACL_DEF)
|
AC_SUBST(LIBACL_DEF)
|
||||||
|
|
||||||
|
|
||||||
dnl ts A90123
|
dnl ts A90123 - B51212
|
||||||
AC_ARG_ENABLE(xattr,
|
AC_ARG_ENABLE(xattr,
|
||||||
[ --enable-xattr Enable use of xattr by libisofs, default=yes],
|
[ --enable-xattr Enable use of extended file attributes by libisofs, default=yes],
|
||||||
, enable_xattr=yes)
|
, enable_xattr=yes)
|
||||||
if test "x$enable_xattr" = xyes; then
|
XATTR_DEF=
|
||||||
dnl Check whether there is the header for Linux xattr.
|
if test x"$LIBBURNIA_SUPP_FATTR" = xxattr
|
||||||
|
then
|
||||||
|
if test "x$enable_xattr" = xyes; then
|
||||||
|
dnl Check whether there is the header for Linux xattr.
|
||||||
dnl If not, erase this macro which would enable use of listxattr and others
|
dnl If not, erase this macro which would enable use of listxattr and others
|
||||||
XATTR_DEF="-DLibisofs_with_aaip_xattR"
|
XATTR_DEF="-DLibisofs_with_aaip_xattR"
|
||||||
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= , XATTR_DEF= ), XATTR_DEF= )
|
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= ,
|
||||||
if test "x$XATTR_DEF" = x
|
XATTR_DEF= ), XATTR_DEF= )
|
||||||
then
|
|
||||||
XATTR_DEF="-DLibisofs_with_freebsd_extattR"
|
|
||||||
AC_CHECK_HEADER(sys/extattr.h, AC_CHECK_LIB(c, extattr_list_file, X=, XATTR_DEF= ), XATTR_DEF= )
|
|
||||||
fi
|
fi
|
||||||
|
elif test x"$LIBBURNIA_SUPP_FATTR" = xextattr
|
||||||
|
then
|
||||||
|
if test "x$enable_xattr" = xyes; then
|
||||||
|
XATTR_DEF="-DLibisofs_with_freebsd_extattR"
|
||||||
|
AC_CHECK_HEADER(sys/extattr.h, AC_CHECK_LIB(c, extattr_list_file, X=,
|
||||||
|
XATTR_DEF= ), XATTR_DEF= )
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test x$XATTR_DEF = x-DLibisofs_with_aaip_xattR
|
||||||
|
then
|
||||||
|
echo "enabled xattr, local processing of extended file attributes Linux style"
|
||||||
|
elif test x$XATTR_DEF = x-DLibisofs_with_freebsd_extattR
|
||||||
|
then
|
||||||
|
echo "enabled extattr, local processing of extended file attributes FreeBSD style"
|
||||||
else
|
else
|
||||||
XATTR_DEF=
|
echo "disabled local processing of extended file attributes"
|
||||||
fi
|
fi
|
||||||
AC_SUBST(XATTR_DEF)
|
AC_SUBST(XATTR_DEF)
|
||||||
|
|
||||||
|
304
demo/demo.c
304
demo/demo.c
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 - 2009 Vreixo Formoso, Thomas Schmitt
|
* Copyright (c) 2007 - 2015 Vreixo Formoso, Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -24,7 +24,9 @@ static char helptext[][80] = {
|
|||||||
" Output the contents of an iso image.",
|
" Output the contents of an iso image.",
|
||||||
" -iso_cat image_file path_in_image",
|
" -iso_cat image_file path_in_image",
|
||||||
" Extract a file from a given ISO image and put out its content",
|
" Extract a file from a given ISO image and put out its content",
|
||||||
" to stdout. The file is addressed by path_in_image.",
|
" to stdout. The file is addressed by path_in_image. The ISO",
|
||||||
|
" image does not get loaded but rather the lookups are done",
|
||||||
|
" directly in the image file.",
|
||||||
" -iso_modify image_file absolute_directory_path output_file",
|
" -iso_modify image_file absolute_directory_path output_file",
|
||||||
" Load an iso image, add a directory, and write complete image.",
|
" Load an iso image, add a directory, and write complete image.",
|
||||||
" -iso_ms image_lba nwa image_file directory_path output_file",
|
" -iso_ms image_lba nwa image_file directory_path output_file",
|
||||||
@ -58,6 +60,22 @@ static char helptext[][80] = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------- utilities -------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
void demo_report_iso_err(int err, char *occasion)
|
||||||
|
{
|
||||||
|
char *severity;
|
||||||
|
|
||||||
|
fprintf(stderr, "%s : err = 0x%X", occasion, (unsigned int) err);
|
||||||
|
if (err < 0) {
|
||||||
|
iso_sev_to_text(iso_error_get_severity(err), &severity);
|
||||||
|
fprintf(stderr, " -> %s '%s'", severity, iso_error_to_msg(err));
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------- from demo/tree.c ----------------------- */
|
/* ------------------------- from demo/tree.c ----------------------- */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -446,7 +464,8 @@ iso_read_print_dir(IsoFileSource *dir, int level)
|
|||||||
sp[i+1] = ' ';
|
sp[i+1] = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
sp[level * 2-1] = '-';
|
if (level > 0)
|
||||||
|
sp[level * 2 - 1] = '-';
|
||||||
sp[level * 2] = '\0';
|
sp[level * 2] = '\0';
|
||||||
|
|
||||||
ret = iso_file_source_open(dir);
|
ret = iso_file_source_open(dir);
|
||||||
@ -474,37 +493,43 @@ iso_read_print_dir(IsoFileSource *dir, int level)
|
|||||||
|
|
||||||
int gesture_iso_read(int argc, char **argv)
|
int gesture_iso_read(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int result;
|
int result, initialized = 0, return_val = 1;
|
||||||
IsoImageFilesystem *fs;
|
IsoImageFilesystem *fs = NULL;
|
||||||
IsoDataSource *src;
|
IsoDataSource *src = NULL;
|
||||||
IsoFileSource *root;
|
IsoFileSource *root = NULL;
|
||||||
IsoReadOpts *ropts;
|
IsoReadOpts *ropts = NULL;
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
printf ("You need to specify a valid path\n");
|
printf ("You need to specify a valid path\n");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_init();
|
result = iso_init();
|
||||||
|
if (result < 0) {
|
||||||
|
demo_report_iso_err(result, "Cannot init libisofs");
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
initialized = 1;
|
||||||
|
|
||||||
iso_set_msgs_severities("NEVER", "ALL", "");
|
iso_set_msgs_severities("NEVER", "ALL", "");
|
||||||
|
|
||||||
result = iso_data_source_new_from_file(argv[1], &src);
|
result = iso_data_source_new_from_file(argv[1], &src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating data source\n");
|
demo_report_iso_err(result, "Error creating data source");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = iso_read_opts_new(&ropts, 0);
|
result = iso_read_opts_new(&ropts, 0);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
fprintf(stderr, "Error creating read options\n");
|
demo_report_iso_err(result, "Error creating read options");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
result = iso_image_filesystem_new(src, ropts, 1, &fs);
|
result = iso_image_filesystem_new(src, ropts, 1, &fs);
|
||||||
iso_read_opts_free(ropts);
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating filesystem\n");
|
demo_report_iso_err(result, "Error creating filesystem");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
iso_read_opts_free(ropts);
|
||||||
|
ropts = NULL;
|
||||||
|
|
||||||
printf("\nVOLUME INFORMATION\n");
|
printf("\nVOLUME INFORMATION\n");
|
||||||
printf("==================\n\n");
|
printf("==================\n\n");
|
||||||
@ -523,18 +548,27 @@ int gesture_iso_read(int argc, char **argv)
|
|||||||
|
|
||||||
result = fs->get_root(fs, &root);
|
result = fs->get_root(fs, &root);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Can't get root %d\n", result);
|
demo_report_iso_err(result, "Cannot get root object");
|
||||||
return 1;
|
goto ex;
|
||||||
}
|
}
|
||||||
/* iso_read_print_file_src(root); */
|
/* iso_read_print_file_src(root); */
|
||||||
iso_read_print_dir(root, 0);
|
iso_read_print_dir(root, 0);
|
||||||
iso_file_source_unref(root);
|
|
||||||
|
|
||||||
fs->close(fs);
|
return_val = 0;
|
||||||
iso_filesystem_unref((IsoFilesystem*)fs);
|
ex:;
|
||||||
iso_data_source_unref(src);
|
if (root != NULL)
|
||||||
iso_finish();
|
iso_file_source_unref(root);
|
||||||
return 0;
|
if (ropts != NULL)
|
||||||
|
iso_read_opts_free(ropts);
|
||||||
|
if (fs != NULL) {
|
||||||
|
fs->close(fs);
|
||||||
|
iso_filesystem_unref((IsoFilesystem*)fs);
|
||||||
|
}
|
||||||
|
if (src != NULL)
|
||||||
|
iso_data_source_unref(src);
|
||||||
|
if (initialized)
|
||||||
|
iso_finish();
|
||||||
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -543,83 +577,101 @@ int gesture_iso_read(int argc, char **argv)
|
|||||||
|
|
||||||
int gesture_iso_cat(int argc, char **argv)
|
int gesture_iso_cat(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int res, write_ret;
|
int res, write_ret, ret;
|
||||||
IsoFilesystem *fs;
|
IsoFilesystem *fs = NULL;
|
||||||
IsoFileSource *file;
|
IsoFileSource *file = NULL;
|
||||||
struct stat info;
|
struct stat info;
|
||||||
IsoDataSource *src;
|
IsoDataSource *src = NULL;
|
||||||
IsoReadOpts *opts;
|
IsoReadOpts *opts = NULL;
|
||||||
|
|
||||||
if (argc != 3) {
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = iso_init();
|
res = iso_init();
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Can't init libisofs\n");
|
demo_report_iso_err(res, "Cannot init libisofs");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Important Note:
|
||||||
|
From here on memory objects get created which need to be freed in
|
||||||
|
the end. Therefore in case of problems no direct return, but rather
|
||||||
|
a hop to label "ex:", where cleanup happens.
|
||||||
|
*/
|
||||||
|
|
||||||
res = iso_data_source_new_from_file(argv[1], &src);
|
res = iso_data_source_new_from_file(argv[1], &src);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Error creating data source\n");
|
demo_report_iso_err(res, "Error creating data source object");
|
||||||
return 1;
|
ret = 1; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = iso_read_opts_new(&opts, 0);
|
res = iso_read_opts_new(&opts, 0);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Error creating read options\n");
|
demo_report_iso_err(res, "Error creating read options object");
|
||||||
return 1;
|
ret = 1; goto ex;
|
||||||
}
|
}
|
||||||
res = iso_image_filesystem_new(src, opts, 1, &fs);
|
res = iso_image_filesystem_new(src, opts, 1, &fs);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Error creating filesystem\n");
|
demo_report_iso_err(res, "Error creating filesystem object");
|
||||||
return 1;
|
ret = 1; goto ex;
|
||||||
}
|
}
|
||||||
iso_read_opts_free(opts);
|
iso_read_opts_free(opts);
|
||||||
|
opts = NULL;
|
||||||
|
|
||||||
res = fs->get_by_path(fs, argv[2], &file);
|
res = fs->get_by_path(fs, argv[2], &file);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Can't get file, err = %d\n", res);
|
demo_report_iso_err(res, "Cannot get file object with given path");
|
||||||
return 1;
|
ret = 1; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = iso_file_source_lstat(file, &info);
|
res = iso_file_source_lstat(file, &info);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Can't stat file, err = %d\n", res);
|
demo_report_iso_err(res,
|
||||||
return 1;
|
"Cannot inquire type of file object with given path");
|
||||||
|
ret = 1; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (S_ISDIR(info.st_mode)) {
|
if (S_ISDIR(info.st_mode)) {
|
||||||
fprintf(stderr, "Path refers to a directory!!\n");
|
fprintf(stderr, "Path refers to a directory!!\n");
|
||||||
return 1;
|
ret = 1; goto ex;
|
||||||
} else {
|
} else {
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
res = iso_file_source_open(file);
|
res = iso_file_source_open(file);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Can't open file, err = %d\n", res);
|
demo_report_iso_err(res,
|
||||||
return 1;
|
"Cannot open file object with given path");
|
||||||
|
ret = 1; goto ex;
|
||||||
}
|
}
|
||||||
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
|
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
|
||||||
write_ret = fwrite(buf, 1, res, stdout);
|
write_ret = fwrite(buf, 1, res, stdout);
|
||||||
if (write_ret < res) {
|
if (write_ret < res) {
|
||||||
printf ("Cannot write block to stdout. errno= %d\n", errno);
|
printf ("Cannot write block to stdout. errno= %d\n", errno);
|
||||||
return 1;
|
iso_file_source_close(file);
|
||||||
|
ret = 1; goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (res < 0) {
|
|
||||||
fprintf(stderr, "Error reading, err = %d\n", res);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
iso_file_source_close(file);
|
iso_file_source_close(file);
|
||||||
|
if (res < 0) {
|
||||||
|
demo_report_iso_err(res, "Error while reading data content");
|
||||||
|
fprintf(stderr, "Error reading, err = 0x%X\n", (unsigned int) res);
|
||||||
|
ret = 1; goto ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_file_source_unref(file);
|
ret = 0;
|
||||||
iso_filesystem_unref(fs);
|
ex:;
|
||||||
iso_data_source_unref(src);
|
if (file != NULL)
|
||||||
|
iso_file_source_unref(file);
|
||||||
|
if (fs != NULL)
|
||||||
|
iso_filesystem_unref(fs);
|
||||||
|
if (opts != NULL)
|
||||||
|
iso_read_opts_free(opts);
|
||||||
|
if (src != NULL)
|
||||||
|
iso_data_source_unref(src);
|
||||||
iso_finish();
|
iso_finish();
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -633,14 +685,14 @@ void iso_modify_usage(char **argv)
|
|||||||
|
|
||||||
int gesture_iso_modify(int argc, char **argv)
|
int gesture_iso_modify(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int result;
|
int result, return_val = 1, initialized = 0;
|
||||||
IsoImage *image;
|
IsoImage *image = NULL;
|
||||||
IsoDataSource *src;
|
IsoDataSource *src = NULL;
|
||||||
struct burn_source *burn_src;
|
struct burn_source *burn_src = NULL;
|
||||||
unsigned char buf[2048];
|
unsigned char buf[2048];
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
IsoWriteOpts *opts;
|
IsoWriteOpts *opts = NULL;
|
||||||
IsoReadOpts *ropts;
|
IsoReadOpts *ropts = NULL;
|
||||||
|
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
iso_modify_usage(argv);
|
iso_modify_usage(argv);
|
||||||
@ -653,20 +705,25 @@ int gesture_iso_modify(int argc, char **argv)
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_init();
|
result = iso_init();
|
||||||
|
if (result < 0) {
|
||||||
|
demo_report_iso_err(result, "Cannot init libisofs");
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
initialized = 1;
|
||||||
iso_set_msgs_severities("NEVER", "ALL", "");
|
iso_set_msgs_severities("NEVER", "ALL", "");
|
||||||
|
|
||||||
/* create the data source to accesss previous image */
|
/* create the data source to accesss previous image */
|
||||||
result = iso_data_source_new_from_file(argv[1], &src);
|
result = iso_data_source_new_from_file(argv[1], &src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating data source\n");
|
demo_report_iso_err(result, "Error creating data source");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the image context */
|
/* create the image context */
|
||||||
result = iso_image_new("volume_id", &image);
|
result = iso_image_new("volume_id", &image);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating image\n");
|
demo_report_iso_err(result, "Error creating image");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_tree_set_follow_symlinks(image, 0);
|
iso_tree_set_follow_symlinks(image, 0);
|
||||||
@ -675,58 +732,75 @@ int gesture_iso_modify(int argc, char **argv)
|
|||||||
/* import previous image */
|
/* import previous image */
|
||||||
result = iso_read_opts_new(&ropts, 0);
|
result = iso_read_opts_new(&ropts, 0);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
fprintf(stderr, "Error creating read options\n");
|
demo_report_iso_err(result, "Error creating read options");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
result = iso_image_import(image, src, ropts, NULL);
|
result = iso_image_import(image, src, ropts, NULL);
|
||||||
iso_read_opts_free(ropts);
|
|
||||||
iso_data_source_unref(src);
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error importing previous session %d\n", result);
|
demo_report_iso_err(result, "Error importing previous session");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
/* (One could of course keep them alive until cleanup) */
|
||||||
|
iso_read_opts_free(ropts);
|
||||||
|
ropts = NULL;
|
||||||
|
iso_data_source_unref(src);
|
||||||
|
src = NULL;
|
||||||
|
|
||||||
/* add new dir */
|
/* add new dir */
|
||||||
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]);
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[2]);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error adding directory %d\n", result);
|
demo_report_iso_err(result, "Error adding directory");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate a new image with both previous and added contents */
|
/* Generate a new image with both previous and added contents.
|
||||||
|
Profile 1 means Rock Ridge and ISO level 3.
|
||||||
|
*/
|
||||||
result = iso_write_opts_new(&opts, 1);
|
result = iso_write_opts_new(&opts, 1);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf("Cant create write opts, error %d\n", result);
|
demo_report_iso_err(result, "Cannot create write opts");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
/* for isolinux: iso_write_opts_set_allow_full_ascii(opts, 1); */
|
/* Prefer specs violation over relocation deep directories */
|
||||||
|
iso_write_opts_set_allow_deep_paths(opts, 1);
|
||||||
|
|
||||||
|
/* For MS-Windows readers : iso_write_opts_set_joliet(opts, 1); */
|
||||||
|
|
||||||
result = iso_image_create_burn_source(image, opts, &burn_src);
|
result = iso_image_create_burn_source(image, opts, &burn_src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Cant create image, error %d\n", result);
|
demo_report_iso_err(result, "Cannot create image object");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_write_opts_free(opts);
|
iso_write_opts_free(opts);
|
||||||
|
opts = NULL;
|
||||||
|
|
||||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||||
result = fwrite(buf, 1, 2048, fp);
|
result = fwrite(buf, 1, 2048, fp);
|
||||||
if (result < 2048) {
|
if (result < 2048) {
|
||||||
printf ("Cannot write block. errno= %d\n", errno);
|
fprintf (stderr, "Cannot write block. errno= %d\n", errno);
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
|
||||||
burn_src->free_data(burn_src);
|
return_val = 0;
|
||||||
free(burn_src);
|
|
||||||
|
|
||||||
iso_image_unref(image);
|
|
||||||
iso_finish();
|
|
||||||
return 0;
|
|
||||||
ex:
|
ex:
|
||||||
if (fp != NULL)
|
if (fp != NULL)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return 1;
|
if (opts != NULL)
|
||||||
|
iso_write_opts_free(opts);
|
||||||
|
if (burn_src != NULL) {
|
||||||
|
burn_src->free_data(burn_src);
|
||||||
|
free(burn_src);
|
||||||
|
}
|
||||||
|
if (image != NULL)
|
||||||
|
iso_image_unref(image);
|
||||||
|
if (ropts != NULL)
|
||||||
|
iso_read_opts_free(ropts);
|
||||||
|
if (src != NULL)
|
||||||
|
iso_data_source_unref(src);
|
||||||
|
if (initialized)
|
||||||
|
iso_finish();
|
||||||
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -740,14 +814,14 @@ void iso_ms_usage(char **argv)
|
|||||||
|
|
||||||
int gesture_iso_ms(int argc, char **argv)
|
int gesture_iso_ms(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int result;
|
int result, return_val = 1, initialized = 0;
|
||||||
IsoImage *image;
|
IsoImage *image = NULL;
|
||||||
IsoDataSource *src;
|
IsoDataSource *src = NULL;
|
||||||
struct burn_source *burn_src;
|
struct burn_source *burn_src = NULL;
|
||||||
unsigned char buf[2048];
|
unsigned char buf[2048];
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
IsoWriteOpts *opts;
|
IsoWriteOpts *opts = NULL;
|
||||||
IsoReadOpts *ropts;
|
IsoReadOpts *ropts = NULL;
|
||||||
uint32_t ms_block;
|
uint32_t ms_block;
|
||||||
|
|
||||||
if (argc < 6) {
|
if (argc < 6) {
|
||||||
@ -767,20 +841,26 @@ int gesture_iso_ms(int argc, char **argv)
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_init();
|
result = iso_init();
|
||||||
|
if (result < 0) {
|
||||||
|
demo_report_iso_err(result, "Cannot init libisofs");
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
initialized = 1;
|
||||||
|
|
||||||
iso_set_msgs_severities("NEVER", "ALL", "");
|
iso_set_msgs_severities("NEVER", "ALL", "");
|
||||||
|
|
||||||
/* create the data source to accesss previous image */
|
/* create the data source to accesss previous image */
|
||||||
result = iso_data_source_new_from_file(argv[3], &src);
|
result = iso_data_source_new_from_file(argv[3], &src);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating data source\n");
|
demo_report_iso_err(result, "Error creating data source");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the image context */
|
/* create the image context */
|
||||||
result = iso_image_new("volume_id", &image);
|
result = iso_image_new("volume_id", &image);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error creating image\n");
|
demo_report_iso_err(result, "Error creating image");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_tree_set_follow_symlinks(image, 0);
|
iso_tree_set_follow_symlinks(image, 0);
|
||||||
@ -795,23 +875,25 @@ int gesture_iso_ms(int argc, char **argv)
|
|||||||
iso_read_opts_set_start_block(ropts, atoi(argv[1]));
|
iso_read_opts_set_start_block(ropts, atoi(argv[1]));
|
||||||
result = iso_image_import(image, src, ropts, NULL);
|
result = iso_image_import(image, src, ropts, NULL);
|
||||||
iso_read_opts_free(ropts);
|
iso_read_opts_free(ropts);
|
||||||
|
ropts = NULL;
|
||||||
iso_data_source_unref(src);
|
iso_data_source_unref(src);
|
||||||
|
src = NULL;
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error importing previous session %d\n", result);
|
demo_report_iso_err(result, "Error importing previous session");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add new dir */
|
/* add new dir */
|
||||||
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[4]);
|
result = iso_tree_add_dir_rec(image, iso_image_get_root(image), argv[4]);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf ("Error adding directory %d\n", result);
|
demo_report_iso_err(result, "Error adding directory");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate a multisession image with new contents */
|
/* generate a multisession image with new contents */
|
||||||
result = iso_write_opts_new(&opts, 1);
|
result = iso_write_opts_new(&opts, 1);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printf("Cant create write opts, error %d\n", result);
|
demo_report_iso_err(result, "Cannot create write opts");
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,6 +908,7 @@ int gesture_iso_ms(int argc, char **argv)
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
iso_write_opts_free(opts);
|
iso_write_opts_free(opts);
|
||||||
|
opts = NULL;
|
||||||
|
|
||||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||||
result = fwrite(buf, 1, 2048, fp);
|
result = fwrite(buf, 1, 2048, fp);
|
||||||
@ -834,17 +917,26 @@ int gesture_iso_ms(int argc, char **argv)
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
|
||||||
burn_src->free_data(burn_src);
|
return_val = 0;
|
||||||
free(burn_src);
|
|
||||||
|
|
||||||
iso_image_unref(image);
|
|
||||||
iso_finish();
|
|
||||||
return 0;
|
|
||||||
ex:;
|
ex:;
|
||||||
|
if (burn_src != NULL) {
|
||||||
|
burn_src->free_data(burn_src);
|
||||||
|
free(burn_src);
|
||||||
|
}
|
||||||
|
if (opts != NULL)
|
||||||
|
iso_write_opts_free(opts);
|
||||||
|
if (image)
|
||||||
|
iso_image_unref(image);
|
||||||
|
if (ropts != NULL)
|
||||||
|
iso_read_opts_free(ropts);
|
||||||
|
if (src != NULL)
|
||||||
|
iso_data_source_unref(src);
|
||||||
|
if (initialized)
|
||||||
|
iso_finish();
|
||||||
if (fp != NULL)
|
if (fp != NULL)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return 1;
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ MIPS Volume Header, for MIPS Big Endian, e.g. SGI Indigo2.
|
|||||||
DEC Boot Block, for MIPS Little Endian , e.g. DECstation.
|
DEC Boot Block, for MIPS Little Endian , e.g. DECstation.
|
||||||
|
|
||||||
SUN Disk Label and boot images, for SUN SPARC
|
SUN Disk Label and boot images, for SUN SPARC
|
||||||
|
GRUB2 SUN SPARC Core File Address
|
||||||
|
|
||||||
PowerPC Reference Platform (PReP), for IBM PowerPC
|
PowerPC Reference Platform (PReP), for IBM PowerPC
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ Sources:
|
|||||||
El Torito, Bootable CD-ROM Format Specification, Version 1.0, 1995
|
El Torito, Bootable CD-ROM Format Specification, Version 1.0, 1995
|
||||||
which refers to ECMA-119, the standard for ISO 9660 filesystems.
|
which refers to ECMA-119, the standard for ISO 9660 filesystems.
|
||||||
libisofs/eltorito.[ch] by Vreixo Formoso.
|
libisofs/eltorito.[ch] by Vreixo Formoso.
|
||||||
|
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
|
ECMA-119 prescribes that the first 32 kB of an ISO 9660 image are System Area
|
||||||
@ -66,9 +68,9 @@ intervals for:
|
|||||||
- Directory trees, tables, boot catalog, embedded partitions and filesystems.
|
- Directory trees, tables, boot catalog, embedded partitions and filesystems.
|
||||||
- Data file content, including content of El Torito boot images.
|
- Data file content, including content of El Torito boot images.
|
||||||
|
|
||||||
The Boot Record is an ECMA-119 Volume Descriptor which is eventually located
|
The Boot Record is an ECMA-119 Volume Descriptor which is located at 2 kB block
|
||||||
at 2 kB block number 17 (decimal). Its content points to the location of the
|
number 17 (decimal), if present at all. Its content points to the location of
|
||||||
Boot Catalog.
|
the Boot Catalog.
|
||||||
The format is described in part by ECMA-119 8.2 "Boot Record" and further
|
The format is described in part by ECMA-119 8.2 "Boot Record" and further
|
||||||
specified by El Torito figure 7.
|
specified by El Torito figure 7.
|
||||||
|
|
||||||
@ -123,11 +125,11 @@ Defined by El Torito are:
|
|||||||
0 = "80x86" which is used for standard PCs with Intel x86 or compatible CPU
|
0 = "80x86" which is used for standard PCs with Intel x86 or compatible CPU
|
||||||
1 = "PowerPC" (possibly for IBM machines with PowerPC CPU)
|
1 = "PowerPC" (possibly for IBM machines with PowerPC CPU)
|
||||||
2 = "Mac" (possibly for Apple computers with MC68000 or 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
|
0xef = EFI, a competitor and successor to PC-BIOS, further in use with
|
||||||
Intel ia64 Itanium and possibly with newer Apple machines.
|
Intel ia64 Itanium and newer Apple machines.
|
||||||
|
|
||||||
Words resp. numbers are represented are little-endian.
|
Words and numbers are represented as little-endian.
|
||||||
|
|
||||||
Validation Entry:
|
Validation Entry:
|
||||||
|
|
||||||
@ -175,7 +177,7 @@ Byte Range | Value | Meaning
|
|||||||
| |
|
| |
|
||||||
5 - 5 | 0 | Unused
|
5 - 5 | 0 | Unused
|
||||||
| |
|
| |
|
||||||
6 - 7 | sec_count | Sector Count.
|
6 - 7 | sec_count | Sector Count. Sector size 512:
|
||||||
| | "the number of virtual/emulated sectors the system
|
| | "the number of virtual/emulated sectors the system
|
||||||
| | will store at Load Segment during the initial boot
|
| | will store at Load Segment during the initial boot
|
||||||
| | procedure."
|
| | procedure."
|
||||||
@ -230,7 +232,7 @@ Byte Range | Value | Meaning
|
|||||||
| | 0 if not emulation == 4.
|
| | 0 if not emulation == 4.
|
||||||
5 - 5 | 0 | Unused
|
5 - 5 | 0 | Unused
|
||||||
| |
|
| |
|
||||||
6 - 7 | sec_count | Sector Count.
|
6 - 7 | sec_count | Sector Count. Sector size 512.
|
||||||
| | See above Initial/Default Entry
|
| | See above Initial/Default Entry
|
||||||
| | libisofs stores 1 for emulated boot_media and a
|
| | libisofs stores 1 for emulated boot_media and a
|
||||||
| | user defined value for boot_media == 0. Often: 4.
|
| | user defined value for boot_media == 0. Often: 4.
|
||||||
@ -384,7 +386,7 @@ on Linux a partition device file (e.g. /dev/sdb1) which cannot be used to mount
|
|||||||
the ISO filesystem.
|
the ISO filesystem.
|
||||||
|
|
||||||
libisofs is able to produce a second set of trees and meta data which is
|
libisofs is able to produce a second set of trees and meta data which is
|
||||||
suitable for being mounted at start block 16 (ISO) resp. 64 (MBR).
|
suitable for being mounted at start block 16 (ISO) which is block 64 in MBR.
|
||||||
See <libisofs/libisofs.h> for call iso_write_opts_set_part_offset()
|
See <libisofs/libisofs.h> for call iso_write_opts_set_part_offset()
|
||||||
and http://libburnia-project.org/wiki/PartitionOffset for examples with
|
and http://libburnia-project.org/wiki/PartitionOffset for examples with
|
||||||
program xorriso.
|
program xorriso.
|
||||||
@ -527,6 +529,7 @@ Sources:
|
|||||||
http://mjg59.fedorapeople.org/Fedora-LiveCD.iso
|
http://mjg59.fedorapeople.org/Fedora-LiveCD.iso
|
||||||
http://en.wikipedia.org/wiki/GUID_Partition_Table
|
http://en.wikipedia.org/wiki/GUID_Partition_Table
|
||||||
http://en.wikipedia.org/wiki/GUID
|
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.
|
GPT is the partition map format of EFI, a successor of PC-BIOS.
|
||||||
@ -534,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.
|
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.
|
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
|
GPT is particularly designed to co-exist with MBR. Officially only with a
|
||||||
booting firmware may or may not prefer it over the MBR partition table.
|
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,
|
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.
|
the primary partition table will begin after the last APM entry block.
|
||||||
|
|
||||||
@ -548,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
|
16 - 19 | head_crc | CRC-32 of this header while head_crc is 0
|
||||||
20 - 23 | reserved | = 0
|
20 - 23 | reserved | = 0
|
||||||
24 - 31 | curr_lba | Location of this header block = 1
|
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
|
40 - 47 | first_lba | First usable LBA for partitions
|
||||||
48 - 55 | last_lba | Last usable LBA for partitions
|
48 - 55 | last_lba | Last usable LBA for partitions
|
||||||
56 - 71 | guid | Disk GUID, Random
|
56 - 71 | guid | Disk GUID, Random
|
||||||
@ -573,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
|
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.
|
8 bytes. The integers are to be stored big-endian.
|
||||||
A globally registered class of GUID are the partition type GUIDs.
|
A globally registered class of GUID are the partition type GUIDs:
|
||||||
This example uses two of them
|
|
||||||
Basic data partition: a2 a0 d0 eb , e5 b9 , 33 44 , 87 c0 68 b6 b7 26 99 c7
|
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
|
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
|
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
|
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.
|
The partition table is an array of entries. Each has a size of 128 bytes.
|
||||||
A partition table entry looks like:
|
A partition table entry looks like:
|
||||||
@ -617,7 +622,7 @@ Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
|
|||||||
| | Is recomputed after the following changes.
|
| | Is recomputed after the following changes.
|
||||||
24 - 31 | curr_lba | Location of this header block.
|
24 - 31 | curr_lba | Location of this header block.
|
||||||
| | Shows own block address.
|
| | 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
|
| | Points to primary header block = 1
|
||||||
72 - 79 | part_start | Partition entries start.
|
72 - 79 | part_start | Partition entries start.
|
||||||
| | Points to start of backup partition table.
|
| | Points to start of backup partition table.
|
||||||
@ -769,8 +774,8 @@ Byte Range | Value | Meaning
|
|||||||
| | (Elf32_Phdr field p_filesz + 511) / 512;
|
| | (Elf32_Phdr field p_filesz + 511) / 512;
|
||||||
| |
|
| |
|
||||||
28 - 31 | seg_start | Segment file offset. Blocks 512 bytes.
|
28 - 31 | seg_start | Segment file offset. Blocks 512 bytes.
|
||||||
| | ISO 9660 LBA of boot file * 4 plus offset
|
| | ISO 9660 LBA of boot file * 4 plus offset which
|
||||||
| | + offset which stems from ELF header of boot file:
|
| | stems from ELF header of boot file:
|
||||||
| | (Elf32_Phdr field p_offset + 511) / 512;
|
| | (Elf32_Phdr field p_offset + 511) / 512;
|
||||||
| |
|
| |
|
||||||
32 - 431 | ========== | Boot Map Entries 2 to 51
|
32 - 431 | ========== | Boot Map Entries 2 to 51
|
||||||
@ -826,7 +831,7 @@ Sources:
|
|||||||
The Disk Label is written to the first 512 bytes of the image. It can mark
|
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
|
8 partitions (slices ) of which the first contains the ISO image. The other
|
||||||
7 may contain boot images.
|
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
|
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).
|
the ISO image so that each starts at a cylinder boundary (320 kB).
|
||||||
@ -838,7 +843,6 @@ their predecessor in the partition table:
|
|||||||
If mkisofs is called with -G image -B ... all boot partitions are
|
If mkisofs is called with -G image -B ... all boot partitions are
|
||||||
mapped to the partition that contains the ISO9660 filesystem."
|
mapped to the partition that contains the ISO9660 filesystem."
|
||||||
|
|
||||||
|
|
||||||
Disk Label components:
|
Disk Label components:
|
||||||
|
|
||||||
Byte Range | Value | Meaning
|
Byte Range | Value | Meaning
|
||||||
@ -901,7 +905,7 @@ Byte Range | Value | Meaning
|
|||||||
| |
|
| |
|
||||||
444 - 447 | start_cyl | Start cylinder
|
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
|
452 - 507 | ========== | Partition table entries #2 to #8
|
||||||
| ... | See above Partition table entry #1
|
| ... | See above Partition table entry #1
|
||||||
@ -912,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
|
||||||
|
| |
|
||||||
|
------------ | ---------- | --------------------------------------------------
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -935,6 +963,7 @@ PReP boots via a MBR partition containing only raw ELF and having type 0x41.
|
|||||||
Sources:
|
Sources:
|
||||||
Mail conversations with Vladimir Serbinenko.
|
Mail conversations with Vladimir Serbinenko.
|
||||||
http://stuff.mit.edu/afs/sipb/contrib/doc/specs/protocol/chrp/chrp1_7a.pdf
|
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
|
CHRP is marked by an MBR partition entry of type 0x96 spanning the whole
|
||||||
ISO 9660 image.
|
ISO 9660 image.
|
||||||
@ -942,12 +971,16 @@ ISO 9660 image.
|
|||||||
The specs in chrp1_7a.pdf promise that CHRP also recognizes ISO 9660 file
|
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)
|
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:
|
Vladimir Serbinenko stated:
|
||||||
PReP boot may be preferable. At least it can co-exist with other partitions
|
PReP boot may be preferable. At least it can co-exist with other partitions
|
||||||
in the ISO image [without causing overlapping between partitions].
|
in the ISO image [without causing overlapping between partitions].
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
HP-PA via PALO header version 4
|
HP-PA via PALO header version 4
|
||||||
@ -958,6 +991,10 @@ Sources:
|
|||||||
by Steve McIntyre <steve@einval.com>
|
by Steve McIntyre <steve@einval.com>
|
||||||
who states "Heavily inspired by palo"
|
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
|
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.
|
System Area: cmdline, bootloader, 32-bit kernel, 64-bit kernel, and ramdisk.
|
||||||
They are all mandatory.
|
They are all mandatory.
|
||||||
@ -984,7 +1021,7 @@ Byte Range | Value | Meaning
|
|||||||
| | genisoimage option -hppa-ramdisk
|
| | genisoimage option -hppa-ramdisk
|
||||||
20 - 23 | ramdsk_len | Byte count of the "HPPA ramdisk" file
|
20 - 23 | ramdsk_len | Byte count of the "HPPA ramdisk" file
|
||||||
| |
|
| |
|
||||||
24 - 141 | cmdline | "Command line"
|
24 - 151 | cmdline | "Command line"
|
||||||
| | genisoimage option -hppa-cmdline
|
| | genisoimage option -hppa-cmdline
|
||||||
| |
|
| |
|
||||||
232 - 235 | kern64_adr | Byte address of the "HPPA 64-bit kernel" file
|
232 - 235 | kern64_adr | Byte address of the "HPPA 64-bit kernel" file
|
||||||
@ -1009,7 +1046,11 @@ Sources:
|
|||||||
http://git.kernel.org/cgit/linux/kernel/git/deller/palo.git/tree/lib/
|
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)
|
(especially struct firstblock in common.h and struct partition in part.h)
|
||||||
|
|
||||||
There are five parameters which get encoded into the first 248 bytes of the
|
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.
|
System Area: cmdline, bootloader, 32-bit kernel, 64-bit kernel, and ramdisk.
|
||||||
They are all mandatory.
|
They are all mandatory.
|
||||||
While cmdline is simply a string of at most 1023 characters, the other four
|
While cmdline is simply a string of at most 1023 characters, the other four
|
||||||
@ -1018,10 +1059,6 @@ point to data files inside the ISO image.
|
|||||||
Several fields of the firstblock shall be hardcoded to 0, on advise of
|
Several fields of the firstblock shall be hardcoded to 0, on advise of
|
||||||
Helge Deller. Their description is shown in round brackets.
|
Helge Deller. Their description is shown in round brackets.
|
||||||
|
|
||||||
The partition table format is the same as with MBR.
|
|
||||||
>>> ??? what block range gets marked in which partition ?
|
|
||||||
>>> If this is only for CD/DVD/BD images, then no partitioning is needed.
|
|
||||||
|
|
||||||
All numbers are recorded big endian.
|
All numbers are recorded big endian.
|
||||||
Except flags, all 4-byte integers are signed.
|
Except flags, all 4-byte integers are signed.
|
||||||
|
|
||||||
@ -1060,48 +1097,9 @@ Byte Range | Value | Meaning
|
|||||||
| |
|
| |
|
||||||
244 - 247 | ipl_len | Byte count of the bootloader file
|
244 - 247 | ipl_len | Byte count of the bootloader file
|
||||||
| |
|
| |
|
||||||
248 - 251 | ipl_entry | >>> Meaning unclear
|
248 - 251 | 0 | (ipl_entry: offset to first command in bootloader)
|
||||||
| |
|
|
||||||
| |
|
|
||||||
446 - 461 | ========== | MBR/DOS Partition Table Entry for partition 1
|
|
||||||
| |
|
|
||||||
446 - 446 | status | Governs bootability:
|
|
||||||
| | 0x80 = bootable/active , 0x00 non-bootable/inactive
|
|
||||||
| |
|
|
||||||
447 - 449 | ========== | C/H/S address of partition start
|
|
||||||
447 - 447 | start_head | Heads part of start address.
|
|
||||||
448 - 448 | start_c_s | Bits 0 to 5 : Sectors part of start address.
|
|
||||||
| | Bits 6 to 7 : Bits 8 to 9 of cylinders part.
|
|
||||||
449 - 449 | start_cyl | Lower 8 bits of cylinders part of start address
|
|
||||||
| |
|
|
||||||
450 - 450 | part_type | Partition type indicates the purpose or kind of
|
|
||||||
| | filesystem in the partition.
|
|
||||||
| |
|
|
||||||
451 - 453 | ========== | C/H/S address of last absolute sector in partition
|
|
||||||
451 - 451 | end_head | Heads part of end address.
|
|
||||||
452 - 452 | end_c_s | Bits 0 to 5 : Sectors part of end address.
|
|
||||||
| Values: 1 to 63, not 0.
|
|
||||||
| | Bits 6 to 7 : Bits 8 to 9 of cylinders part.
|
|
||||||
453 - 453 | end_cyl | Lower 8 bits of cylinders part of end address
|
|
||||||
| |
|
|
||||||
454 - 457 | start_lba | LBA of first absolute sector in partiton.
|
|
||||||
| | Block size is 512. Counting starts at 0.
|
|
||||||
| |
|
|
||||||
458 - 461 | num_blocks | Number of sectors in partition.
|
|
||||||
| |
|
|
||||||
462 - 477 | ========== | Partition Table Entry for partition 2
|
|
||||||
| part_entr2 | 16 bytes. Format as with partition 1.
|
|
||||||
| | All 0 means that partition is unused/undefined.
|
|
||||||
| |
|
|
||||||
478 - 493 | ========== | Partition Table Entry for partition 3
|
|
||||||
| part_entr3 | 16 bytes. See above.
|
|
||||||
| |
|
|
||||||
494 - 509 | ========== | Partition Table Entry for partition 4
|
|
||||||
| part_entr4 | 16 bytes. See above.
|
|
||||||
| |
|
|
||||||
510 - 510 | 0x55 | MBR signature
|
|
||||||
511 - 511 | 0xaa | MBR signature
|
|
||||||
| |
|
| |
|
||||||
|
446 - 511 | 0 | (MBR partition table and signature)
|
||||||
| |
|
| |
|
||||||
1024 -2047 | cmdline | Zero terminated command line of up to
|
1024 -2047 | cmdline | Zero terminated command line of up to
|
||||||
| | 1023 characters
|
| | 1023 characters
|
||||||
@ -1111,7 +1109,44 @@ Byte Range | Value | Meaning
|
|||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
>>> ??? DEC Alpha
|
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).
|
||||||
|
| |
|
||||||
|
---------- | ---------- | ----------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -1231,7 +1266,7 @@ intentionally non-essential:
|
|||||||
They may be overwritten by other bytes which must not produce errors or
|
They may be overwritten by other bytes which must not produce errors or
|
||||||
undesirable side effects when executed as x86 machine code.
|
undesirable side effects when executed as x86 machine code.
|
||||||
The following 32 bytes from block 0 of an Apple Partiton Map (APM) are such
|
The following 32 bytes from block 0 of an Apple 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
|
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
|
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
|
They do not depend on any properties of the ISO image or the information
|
||||||
@ -1298,7 +1333,7 @@ Byte Range | Value | Meaning (little endian numbers, LBA unit is 512 byte)
|
|||||||
---------- | ---------- | ----------------------------------------------------
|
---------- | ---------- | ----------------------------------------------------
|
||||||
12 - 15 | head_size | Header size = 0x5c = 92
|
12 - 15 | head_size | Header size = 0x5c = 92
|
||||||
24 - 31 | curr_lba | Location of this header block = 0x1
|
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
|
| | This is 1 KiB before the end of MBR partition 1
|
||||||
| | (but should be 512 bytes).
|
| | (but should be 512 bytes).
|
||||||
| | (Potential isohybrid.c bug #1:
|
| | (Potential isohybrid.c bug #1:
|
||||||
@ -1449,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.
|
Last block is 0x0513 = 1299 = 164 + 1135. This end is correct.
|
||||||
(Potential isohybrid.c bug #4:
|
(Potential isohybrid.c bug #4:
|
||||||
Wrong character set and incidential bytes in GPT partition name.)
|
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:
|
Next entry at byte 0x02100 = 8448:
|
||||||
|
|
||||||
@ -1477,8 +1515,8 @@ The ISO image file gets padded up to full MiB with sufficient room for the GPT
|
|||||||
backup which is stored near the very end of the image file. There is need for
|
backup which is stored near the very end of the image file. There is need for
|
||||||
at least 16.5 KiB, which effectively occupy 18 KiB.
|
at least 16.5 KiB, which effectively occupy 18 KiB.
|
||||||
|
|
||||||
The backup partition array is stored 17 KiB before the end of MBR partition 1
|
The backup partition array is stored 17 KiB before the end of MBR partition 1,
|
||||||
resp. the image file.
|
which is also the end of the image file.
|
||||||
(Potential isohybrid.c bug #1:
|
(Potential isohybrid.c bug #1:
|
||||||
Wikipedia suggests "LBA -33" counted from end. This would be 16.5 KiB before
|
Wikipedia suggests "LBA -33" counted from end. This would be 16.5 KiB before
|
||||||
end.)
|
end.)
|
||||||
|
@ -217,7 +217,7 @@ S_IRWXG. If there is ACL_USER_N or ACL_GROUP_N there must also be ACL_MASK.
|
|||||||
|
|
||||||
A numeric qualifier is a binary number of variable length up to 4 bytes. The
|
A numeric qualifier is a binary number of variable length up to 4 bytes. The
|
||||||
Most Significant Byte comes first. The number shall be the "POSIX File User ID"
|
Most Significant Byte comes first. The number shall be the "POSIX File User ID"
|
||||||
resp. "POSIX File Group ID" as also used in RRIP PX entries. The ids of owning
|
or "POSIX File Group ID" as also used in RRIP PX entries. The ids of owning
|
||||||
user and owning group shall be taken from the PX entry of the file object.
|
user and owning group shall be taken from the PX entry of the file object.
|
||||||
|
|
||||||
Optional TRANSLATE entries may associate user or group names with numeric
|
Optional TRANSLATE entries may associate user or group names with numeric
|
||||||
|
@ -8,7 +8,9 @@
|
|||||||
|
|
||||||
|
|
||||||
The following names are defined for AAIP namespace "isofs." as mentioned in
|
The following names are defined for AAIP namespace "isofs." as mentioned in
|
||||||
specification of AAIP :
|
specification of AAIP. Unless explicitly stated otherwise, numbers with
|
||||||
|
names like *_LEN are 8 bit unsigned integers, those with *_BYTES are 32 bit
|
||||||
|
unsigned integers.
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -22,7 +24,7 @@ Purpose:
|
|||||||
END is also the block address of the start of the checksum recording
|
END is also the block address of the start of the checksum recording
|
||||||
area in the image.
|
area in the image.
|
||||||
See also isofs.cx .
|
See also isofs.cx .
|
||||||
This attribute shall eventually be attached to the root directory entry
|
This attribute shall be attached to the root directory entry
|
||||||
and be global for the whole image.
|
and be global for the whole image.
|
||||||
|
|
||||||
Format of Value:
|
Format of Value:
|
||||||
@ -65,8 +67,8 @@ Purpose:
|
|||||||
Records the name of the character set that was used as output character
|
Records the name of the character set that was used as output character
|
||||||
set when writing the RRIP name tree of the ISO 9660 image. It shall be
|
set when writing the RRIP name tree of the ISO 9660 image. It shall be
|
||||||
suitable as parameter for function iconv_open(3).
|
suitable as parameter for function iconv_open(3).
|
||||||
This attribute shall eventually be attached to the root directory entry
|
This attribute shall be attached to the root directory entry and be
|
||||||
and be global for the whole image.
|
global for the whole image.
|
||||||
|
|
||||||
Format of Value:
|
Format of Value:
|
||||||
Shall hold the character set name without terminating 0-byte.
|
Shall hold the character set name without terminating 0-byte.
|
||||||
@ -107,6 +109,7 @@ Name:
|
|||||||
Purpose:
|
Purpose:
|
||||||
Records .st_dev and .st_ino of struct stat of the file source in the
|
Records .st_dev and .st_ino of struct stat of the file source in the
|
||||||
local filesystem. See man 2 stat.
|
local filesystem. See man 2 stat.
|
||||||
|
Both values may be unsigned integers up to 255 bytes.
|
||||||
|
|
||||||
Format of Value:
|
Format of Value:
|
||||||
DEV_LEN | DEV_BYTES | INO_LEN | INO_BYTES
|
DEV_LEN | DEV_BYTES | INO_LEN | INO_BYTES
|
||||||
@ -128,7 +131,7 @@ Name:
|
|||||||
|
|
||||||
Purpose:
|
Purpose:
|
||||||
Records the IsoHfsplusBlessings blessing of a IsoNode as defined
|
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
|
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.
|
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
|
||||||
|
|
||||||
@ -152,7 +155,7 @@ Name:
|
|||||||
|
|
||||||
Purpose:
|
Purpose:
|
||||||
Records the iso_hfsplus_xinfo_data information as defined in libisofs.h.
|
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
|
attachment for iso_hfsplus_xinfo_func so that it is available for
|
||||||
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
|
the HFS+ writer when a new ISO 9660 / HFS+ image gets produced.
|
||||||
|
|
||||||
@ -172,6 +175,26 @@ Registered:
|
|||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Name:
|
||||||
|
isofs.nt
|
||||||
|
|
||||||
|
Purpose:
|
||||||
|
Records the name truncation mode and the truncation length for Rock Ridge
|
||||||
|
names. See iso_image_set_truncate_mode() in libisofs.h.
|
||||||
|
This attribute shall be attached to the root directory entry and be
|
||||||
|
global for the whole image.
|
||||||
|
|
||||||
|
Format of Value:
|
||||||
|
MODE_LEN | MODE_BYTES | LENGTH_LEN | LENGTH_BYTES
|
||||||
|
|
||||||
|
Example:
|
||||||
|
{ 1, 1, 1, 255 }
|
||||||
|
|
||||||
|
Registered:
|
||||||
|
24 Sep 2015 by Thomas Schmitt for libisofs.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
Name:
|
Name:
|
||||||
isofs.st
|
isofs.st
|
||||||
|
|
||||||
@ -183,7 +206,7 @@ Purpose:
|
|||||||
The RRIP timestamps have a blind second during which a change after
|
The RRIP timestamps have a blind second during which a change after
|
||||||
node registration would not be recognizable for incremental backups
|
node registration would not be recognizable for incremental backups
|
||||||
which are based in "isofs.di" rather than on content comparison.
|
which are based in "isofs.di" rather than on content comparison.
|
||||||
This attribute shall eventually be attached to the root directory entry
|
This attribute shall be attached to the root directory entry
|
||||||
and be global for the whole image.
|
and be global for the whole image.
|
||||||
|
|
||||||
Format of Value:
|
Format of Value:
|
||||||
|
@ -37,7 +37,7 @@ i.e. block sizes 32 kB, 64 kB, and 128 kB. Writers must not use other sizes.
|
|||||||
|
|
||||||
Block Pointers
|
Block Pointers
|
||||||
|
|
||||||
There are ceil(input_size / block_size) input resp. output blocks.
|
There are ceil(input_size / block_size) input and output blocks.
|
||||||
Each input block is of fixed size whereas the output blocks have varying
|
Each input block is of fixed size whereas the output blocks have varying
|
||||||
size (down to 0). For each output block there is an offset pointer giving
|
size (down to 0). For each output block there is an offset pointer giving
|
||||||
its byte address in the overall file content. The next block pointer in the
|
its byte address in the overall file content. The next block pointer in the
|
||||||
@ -68,7 +68,7 @@ when being read.
|
|||||||
ZF may only be applied to files with a single extent and less than 4 GiB of
|
ZF may only be applied to files with a single extent and less than 4 GiB of
|
||||||
uncompressed size.
|
uncompressed size.
|
||||||
|
|
||||||
The ZF entry follows the general layout of SUSP resp. RRIP.
|
The ZF entry follows the general layout of SUSP and RRIP.
|
||||||
Its fields are:
|
Its fields are:
|
||||||
|
|
||||||
[1] "BP 1 to BP 2 - Signature Word" shall be (5A)(46) ("ZF").
|
[1] "BP 1 to BP 2 - Signature Word" shall be (5A)(46) ("ZF").
|
||||||
@ -85,19 +85,18 @@ Its fields are:
|
|||||||
[5] "BP 7 - Header Size Div 4" shall specify as an 8-bit number the number of
|
[5] "BP 7 - Header Size Div 4" shall specify as an 8-bit number the number of
|
||||||
4-byte words in the header part of the file data recorded according
|
4-byte words in the header part of the file data recorded according
|
||||||
to ISO 9660:7.1.1.
|
to ISO 9660:7.1.1.
|
||||||
(This is a copy of header byte 12, resp. header BP 13).
|
(This is a copy of header byte 12 / BP 13).
|
||||||
|
|
||||||
[6] "BP 8 - Log2 of Block Size" shall specify as an 8-bit number the binary
|
[6] "BP 8 - Log2 of Block Size" shall specify as an 8-bit number the binary
|
||||||
logarithm of the compression block size recorded according to
|
logarithm of the compression block size recorded according to
|
||||||
ISO 9660:7.1.1.
|
ISO 9660:7.1.1.
|
||||||
(This is a copy of header byte 13, resp. header BP 14.
|
(This is a copy of header byte 13 / BP 14.
|
||||||
The value has to be 15, 16 or 17 i.e. 32 kiB, 64 kiB, or 128 kiB.)
|
The value has to be 15, 16 or 17 i.e. 32 kiB, 64 kiB, or 128 kiB.)
|
||||||
|
|
||||||
[7] "BP 9 to BP 16 - Uncompressed Size" shall tell the number of uncompressed
|
[7] "BP 9 to BP 16 - Uncompressed Size" shall tell the number of uncompressed
|
||||||
bytes represented by the given extent. This field shall be recorded
|
bytes represented by the given extent. This field shall be recorded
|
||||||
according to ISO 9660:7.3.3.
|
according to ISO 9660:7.3.3.
|
||||||
(This number is the same as in header bytes 8 to 11, resp header BP 9
|
(This number is the same as in header bytes 8 to 11 / BP 9 to BP 12.)
|
||||||
to BP 12.)
|
|
||||||
|
|
||||||
| 'Z' | 'F' | LENGTH | 1 | 'p' | 'z' | HEADER SIZE DIV 4 | LOG2 BLOCK SIZE
|
| 'Z' | 'F' | LENGTH | 1 | 'p' | 'z' | HEADER SIZE DIV 4 | LOG2 BLOCK SIZE
|
||||||
| UNCOMPRESSED SIZE |
|
| UNCOMPRESSED SIZE |
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
It is permissibile to set them to 1 already now.
|
It is permissibile to set them to 1 already now.
|
||||||
bit8 and higher: reserved, submit 0
|
bit8 and higher: reserved, submit 0
|
||||||
@return
|
@return
|
||||||
Bitfield corresponding to flag. If bits are set, th
|
Bitfield corresponding to flag.
|
||||||
bit0= ACL adapter is enabled
|
bit0= ACL adapter is enabled
|
||||||
bit1= xattr adapter is enabled
|
bit1= xattr adapter is enabled
|
||||||
bit2 - bit7= Reserved for future types.
|
bit2 - bit7= Reserved for future types.
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
Arbitrary Attribute Interchange Protocol , system adapter for getting and
|
Arbitrary Attribute Interchange Protocol , system adapter for getting and
|
||||||
setting of ACLs and xattr.
|
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>
|
#include <sys/extattr.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
/* <<< Use old ACL adapter code that is unable to deal with extattr */
|
/* <<< Use old ACL adapter code that is unable to deal with extattr */
|
||||||
/* # define Libisofs_old_freebsd_acl_adapteR */
|
/* # define Libisofs_old_freebsd_acl_adapteR */
|
||||||
|
|
||||||
@ -47,7 +49,7 @@
|
|||||||
It is permissibile to set them to 1 already now.
|
It is permissibile to set them to 1 already now.
|
||||||
bit8 and higher: reserved, submit 0
|
bit8 and higher: reserved, submit 0
|
||||||
@return
|
@return
|
||||||
Bitfield corresponding to flag. If bits are set, th
|
Bitfield corresponding to flag.
|
||||||
bit0= ACL adapter is enabled
|
bit0= ACL adapter is enabled
|
||||||
bit1= xattr adapter is enabled
|
bit1= xattr adapter is enabled
|
||||||
bit2 - bit7= Reserved for future types.
|
bit2 - bit7= Reserved for future types.
|
||||||
@ -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 --------------------------------- */
|
/* ------------------------------ Getters --------------------------------- */
|
||||||
|
|
||||||
/* Obtain the ACL of the given file in long text form.
|
/* 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);
|
*list_size= extattr_list_file(path, attrnamespace, NULL, (size_t) 0);
|
||||||
else
|
else
|
||||||
*list_size= extattr_list_link(path, attrnamespace, NULL, (size_t) 0);
|
*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);
|
return(0);
|
||||||
|
}
|
||||||
if(*list_size == 0)
|
if(*list_size == 0)
|
||||||
return(2);
|
return(2);
|
||||||
*list= calloc(*list_size, 1);
|
*list= calloc(*list_size, 1);
|
||||||
@ -309,7 +342,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
size_t **value_lengths, char ***values, int flag)
|
size_t **value_lengths, char ***values, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ssize_t i, num_names= 0, acl_names= 0;
|
ssize_t i, num_names= 0;
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_acL
|
#ifdef Libisofs_with_aaip_acL
|
||||||
unsigned char *a_acl= NULL;
|
unsigned char *a_acl= NULL;
|
||||||
@ -321,6 +354,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
ssize_t value_ret, retry= 0, list_size= 0, user_list_size= 0;
|
ssize_t value_ret, retry= 0, list_size= 0, user_list_size= 0;
|
||||||
ssize_t sys_list_size= 0;
|
ssize_t sys_list_size= 0;
|
||||||
int attrnamespace;
|
int attrnamespace;
|
||||||
|
int acl_names= 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(flag & (1 << 15)) { /* Free memory */
|
if(flag & (1 << 15)) { /* Free memory */
|
||||||
@ -375,7 +409,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
#ifdef Libisofs_with_aaip_acL
|
#ifdef Libisofs_with_aaip_acL
|
||||||
if(flag & 1) {
|
if(flag & 1) {
|
||||||
num_names++;
|
num_names++;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_freebsd_extattR
|
||||||
acl_names= 1;
|
acl_names= 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -654,7 +692,7 @@ ex:;
|
|||||||
0 no suitable ACL manipulation adapter available
|
0 no suitable ACL manipulation adapter available
|
||||||
-1 failure of system ACL service (see errno)
|
-1 failure of system ACL service (see errno)
|
||||||
-2 attempt to manipulate ACL of a symbolic link
|
-2 attempt to manipulate ACL of a symbolic link
|
||||||
without bit5 resp. with no suitable link target
|
without bit5 or with no suitable link target
|
||||||
*/
|
*/
|
||||||
int aaip_set_acl_text(char *path, char *text, int flag)
|
int aaip_set_acl_text(char *path, char *text, int flag)
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
Arbitrary Attribute Interchange Protocol , system adapter for getting and
|
Arbitrary Attribute Interchange Protocol , system adapter for getting and
|
||||||
setting of ACLs and xattr.
|
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+
|
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ int aaip_local_attr_support(int flag)
|
|||||||
or filesystem does not support ACL
|
or filesystem does not support ACL
|
||||||
-1 failure of system ACL service (see errno)
|
-1 failure of system ACL service (see errno)
|
||||||
-2 attempt to inquire ACL of a symbolic link without
|
-2 attempt to inquire ACL of a symbolic link without
|
||||||
bit4 or bit5 resp. with no suitable link target
|
bit4 or bit5 or with no suitable link target
|
||||||
*/
|
*/
|
||||||
int aaip_get_acl_text(char *path, char **text, int flag)
|
int aaip_get_acl_text(char *path, char **text, int flag)
|
||||||
{
|
{
|
||||||
@ -186,16 +186,20 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
size_t **value_lengths, char ***values, int flag)
|
size_t **value_lengths, char ***values, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ssize_t i, num_names= 0;
|
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_acL
|
#ifdef Libisofs_with_aaip_acL
|
||||||
unsigned char *acl= NULL;
|
unsigned char *acl= NULL;
|
||||||
char *a_acl_text= NULL, *d_acl_text= NULL;
|
char *a_acl_text= NULL, *d_acl_text= NULL;
|
||||||
size_t acl_len= 0;
|
size_t acl_len= 0;
|
||||||
|
#define Libisofs_aaip_get_attr_activE yes
|
||||||
#endif
|
#endif
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
char *list= NULL;
|
char *list= NULL;
|
||||||
ssize_t value_ret, retry= 0, list_size= 0;
|
ssize_t value_ret, retry= 0, list_size= 0;
|
||||||
|
#define Libisofs_aaip_get_attr_activE yes
|
||||||
|
#endif
|
||||||
|
#ifdef Libisofs_aaip_get_attr_activE
|
||||||
|
ssize_t i, num_names= 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(flag & (1 << 15)) { /* Free memory */
|
if(flag & (1 << 15)) { /* Free memory */
|
||||||
@ -207,6 +211,14 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
*value_lengths= NULL;
|
*value_lengths= NULL;
|
||||||
*values= NULL;
|
*values= NULL;
|
||||||
|
|
||||||
|
#ifndef Libisofs_aaip_get_attr_activE
|
||||||
|
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
#else /* Libisofs_aaip_get_attr_activE */
|
||||||
|
|
||||||
/* Set up arrays */
|
/* Set up arrays */
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
@ -361,6 +373,9 @@ ex:;
|
|||||||
*num_attrs= 0;
|
*num_attrs= 0;
|
||||||
}
|
}
|
||||||
return(ret);
|
return(ret);
|
||||||
|
|
||||||
|
#endif /* Libisofs_aaip_get_attr_activE */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -377,7 +392,7 @@ ex:;
|
|||||||
0 ACL support not enabled at compile time
|
0 ACL support not enabled at compile time
|
||||||
-1 failure of system ACL service (see errno)
|
-1 failure of system ACL service (see errno)
|
||||||
-2 attempt to manipulate ACL of a symbolic link
|
-2 attempt to manipulate ACL of a symbolic link
|
||||||
without bit5 resp. with no suitable link target
|
without bit5 or with no suitable link target
|
||||||
*/
|
*/
|
||||||
int aaip_set_acl_text(char *path, char *text, int flag)
|
int aaip_set_acl_text(char *path, char *text, int flag)
|
||||||
{
|
{
|
||||||
@ -444,12 +459,18 @@ ex:
|
|||||||
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||||
size_t *value_lengths, char **values, int flag)
|
size_t *value_lengths, char **values, int flag)
|
||||||
{
|
{
|
||||||
int ret, has_default_acl= 0;
|
int ret;
|
||||||
size_t i, consumed, acl_text_fill, acl_idx= 0, h_consumed;
|
size_t i, consumed, acl_text_fill, acl_idx= 0;
|
||||||
char *acl_text= NULL, *list= NULL;
|
char *acl_text= NULL;
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
|
char *list= NULL;
|
||||||
ssize_t list_size= 0;
|
ssize_t list_size= 0;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef Libisofs_with_aaip_acL
|
||||||
|
size_t h_consumed;
|
||||||
|
int has_default_acl= 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
|
|
||||||
@ -539,15 +560,14 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||||||
goto ex;
|
goto ex;
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{ret= -2; goto ex;}
|
{ret= -2; goto ex;}
|
||||||
has_default_acl= (ret == 2);
|
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_acL
|
#ifdef Libisofs_with_aaip_acL
|
||||||
|
|
||||||
|
has_default_acl= (ret == 2);
|
||||||
|
|
||||||
ret= aaip_set_acl_text(path, acl_text, flag & 32);
|
ret= aaip_set_acl_text(path, acl_text, flag & 32);
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{ret= -3; goto ex;}
|
{ret= -3; goto ex;}
|
||||||
#else
|
|
||||||
{ret= -7; goto ex;}
|
|
||||||
#endif
|
|
||||||
/* "default" ACL */
|
/* "default" ACL */
|
||||||
if(has_default_acl) {
|
if(has_default_acl) {
|
||||||
free(acl_text);
|
free(acl_text);
|
||||||
@ -582,11 +602,22 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret= 1;
|
ret= 1;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
ret= -7;
|
||||||
|
|
||||||
|
#endif /* !Libisofs_with_aaip_acL */
|
||||||
|
|
||||||
ex:;
|
ex:;
|
||||||
if(acl_text != NULL)
|
if(acl_text != NULL)
|
||||||
free(acl_text);
|
free(acl_text);
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
if(list != NULL)
|
if(list != NULL)
|
||||||
free(list);
|
free(list);
|
||||||
|
#endif
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
See libisofs/aaip_0_2.h
|
See libisofs/aaip_0_2.h
|
||||||
http://libburnia-project.org/wiki/AAIP
|
http://libburnia-project.org/wiki/AAIP
|
||||||
|
|
||||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
Copyright (c) 2009 - 2015 Thomas Schmitt, libburnia project, GPLv2+
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -62,12 +62,12 @@
|
|||||||
#define Aaip_namespace_trusteD 0x05
|
#define Aaip_namespace_trusteD 0x05
|
||||||
#define Aaip_namespace_securitY 0x06
|
#define Aaip_namespace_securitY 0x06
|
||||||
|
|
||||||
static char Aaip_namespace_textS[][16]= {"", "", "system.", "user.", "isofs.",
|
|
||||||
"trusted.", "security."};
|
|
||||||
|
|
||||||
/* maximum expansion: "security." */
|
/* maximum expansion: "security." */
|
||||||
#define Aaip_max_name_expansioN 9
|
#define Aaip_max_name_expansioN 9
|
||||||
|
|
||||||
|
static char Aaip_namespace_textS[][Aaip_max_name_expansioN + 1]=
|
||||||
|
{"", "", "system.", "user.", "isofs.", "trusted.", "security."};
|
||||||
|
|
||||||
/* --------------------------------- Encoder ---------------------------- */
|
/* --------------------------------- Encoder ---------------------------- */
|
||||||
|
|
||||||
|
|
||||||
@ -88,26 +88,30 @@ static int aaip_encode_pair(char *name, size_t attr_length, char *attr,
|
|||||||
no longer needed
|
no longer needed
|
||||||
@param flag Bitfield for control purposes
|
@param flag Bitfield for control purposes
|
||||||
bit0= set CONTINUE bit of last AAIP field to 1
|
bit0= set CONTINUE bit of last AAIP field to 1
|
||||||
@return >0 is the number of SUSP fields generated,
|
@return >= 0 is the number of SUSP fields generated,
|
||||||
0 means error
|
< 0 means error
|
||||||
*/
|
*/
|
||||||
size_t aaip_encode(size_t num_attrs, char **names,
|
ssize_t aaip_encode(size_t num_attrs, char **names,
|
||||||
size_t *value_lengths, char **values,
|
size_t *value_lengths, char **values,
|
||||||
size_t *result_len, unsigned char **result, int flag)
|
size_t *result_len, unsigned char **result, int flag)
|
||||||
{
|
{
|
||||||
size_t mem_size= 0, comp_size, ret;
|
size_t mem_size= 0, comp_size;
|
||||||
|
ssize_t ret;
|
||||||
unsigned int number_of_fields, i, num_recs;
|
unsigned int number_of_fields, i, num_recs;
|
||||||
|
|
||||||
/* Predict memory needs, number of SUSP fields and component records */
|
/* Predict memory needs, number of SUSP fields and component records */
|
||||||
|
*result = NULL;
|
||||||
*result_len= 0;
|
*result_len= 0;
|
||||||
for(i= 0; i < num_attrs; i++) {
|
for(i= 0; i < num_attrs; i++) {
|
||||||
ret= aaip_encode_pair(names[i], value_lengths[i], values[i],
|
ret= aaip_encode_pair(names[i], value_lengths[i], values[i],
|
||||||
&num_recs, &comp_size, NULL, (size_t) 0, 1);
|
&num_recs, &comp_size, NULL, (size_t) 0, 1);
|
||||||
if(ret <= 0)
|
if(ret < 0)
|
||||||
return(ret);
|
return(ret);
|
||||||
mem_size+= comp_size;
|
mem_size+= comp_size;
|
||||||
}
|
}
|
||||||
number_of_fields= mem_size / 250 + !!(mem_size % 250);
|
number_of_fields= mem_size / 250 + !!(mem_size % 250);
|
||||||
|
if(number_of_fields == 0)
|
||||||
|
return(0);
|
||||||
mem_size+= number_of_fields * 5;
|
mem_size+= number_of_fields * 5;
|
||||||
|
|
||||||
#ifdef Aaip_encode_debuG
|
#ifdef Aaip_encode_debuG
|
||||||
@ -118,14 +122,18 @@ size_t aaip_encode(size_t num_attrs, char **names,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(*result == NULL)
|
if(*result == NULL)
|
||||||
return 0;
|
return ISO_OUT_OF_MEM;
|
||||||
|
|
||||||
/* Encode pairs into result */
|
/* Encode pairs into result */
|
||||||
for(i= 0; i < num_attrs; i++) {
|
for(i= 0; i < num_attrs; i++) {
|
||||||
ret= aaip_encode_pair(names[i], value_lengths[i], values[i],
|
ret= aaip_encode_pair(names[i], value_lengths[i], values[i],
|
||||||
&num_recs, &comp_size, *result, *result_len, 0);
|
&num_recs, &comp_size, *result, *result_len, 0);
|
||||||
if(ret <= 0)
|
if(ret < 0) {
|
||||||
|
free(*result);
|
||||||
|
*result = NULL;
|
||||||
|
*result_len = 0;
|
||||||
return(ret);
|
return(ret);
|
||||||
|
}
|
||||||
(*result_len)+= comp_size;
|
(*result_len)+= comp_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,7 +412,8 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||||||
/* >>> Duplicate u:: entry. */;
|
/* >>> Duplicate u:: entry. */;
|
||||||
/* >>> ??? If it matches the previous one: ignore */
|
/* >>> ??? If it matches the previous one: ignore */
|
||||||
|
|
||||||
return((int) ISO_AAIP_ACL_MULT_OBJ);
|
ret = ISO_AAIP_ACL_MULT_OBJ;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
has_u++;
|
has_u++;
|
||||||
} else {
|
} else {
|
||||||
@ -449,7 +458,8 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||||||
/* >>> Duplicate g:: entry. */;
|
/* >>> Duplicate g:: entry. */;
|
||||||
/* >>> ??? If it matches the previous one: ignore */
|
/* >>> ??? If it matches the previous one: ignore */
|
||||||
|
|
||||||
return((int) ISO_AAIP_ACL_MULT_OBJ);
|
ret = ISO_AAIP_ACL_MULT_OBJ;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
has_g++;
|
has_g++;
|
||||||
} else {
|
} else {
|
||||||
@ -493,7 +503,8 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||||||
/* >>> Duplicate o:: entry. */;
|
/* >>> Duplicate o:: entry. */;
|
||||||
/* >>> ??? If it matches the previous one: ignore */
|
/* >>> ??? If it matches the previous one: ignore */
|
||||||
|
|
||||||
return((int) ISO_AAIP_ACL_MULT_OBJ);
|
ret = ISO_AAIP_ACL_MULT_OBJ;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
has_o++;
|
has_o++;
|
||||||
} else if(strncmp(rpt, "mask:", 5) == 0) {
|
} else if(strncmp(rpt, "mask:", 5) == 0) {
|
||||||
@ -1803,8 +1814,8 @@ int aaip_decode_attrs(struct aaip_state **handle,
|
|||||||
if(aaip->list_mem_used >= memory_limit)
|
if(aaip->list_mem_used >= memory_limit)
|
||||||
return(3);
|
return(3);
|
||||||
aaip->list_mem_used+= new_mem;
|
aaip->list_mem_used+= new_mem;
|
||||||
aaip->name_buf= calloc(sizeof(char *), Aaip_initial_name_leN);
|
aaip->name_buf= calloc(1, Aaip_initial_name_leN);
|
||||||
aaip->value_buf= calloc(sizeof(char *), Aaip_initial_value_leN);
|
aaip->value_buf= calloc(1, Aaip_initial_value_leN);
|
||||||
if(aaip->name_buf == NULL || aaip->value_buf == NULL)
|
if(aaip->name_buf == NULL || aaip->value_buf == NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
aaip->name_buf_size= Aaip_initial_name_leN;
|
aaip->name_buf_size= Aaip_initial_name_leN;
|
||||||
@ -2181,6 +2192,27 @@ ex:;
|
|||||||
|
|
||||||
#include "aaip-os-freebsd.c"
|
#include "aaip-os-freebsd.c"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __FreeBSD_kernel__
|
||||||
|
|
||||||
|
#ifdef NIX
|
||||||
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
|
/* ts B51213: xattr system library calls are only stubs */
|
||||||
|
#include "aaip-os-linux.c"
|
||||||
|
#else
|
||||||
|
/* ts B51213: extattr system library calls are not even present */
|
||||||
|
#include "aaip-os-freebsd.c"
|
||||||
|
#endif /* ! Libisofs_with_aaip_xattR */
|
||||||
|
#else /* NIX */
|
||||||
|
/* ts B51213: so we still end up at the dummy */
|
||||||
|
#include "aaip-os-dummy.c"
|
||||||
|
#endif /* ! NIX */
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef __NetBSD__
|
||||||
|
|
||||||
|
#include "aaip-os-freebsd.c"
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#ifdef __linux
|
#ifdef __linux
|
||||||
|
|
||||||
@ -2198,5 +2230,7 @@ ex:;
|
|||||||
#include "aaip-os-dummy.c"
|
#include "aaip-os-dummy.c"
|
||||||
|
|
||||||
#endif /* ! __linux */
|
#endif /* ! __linux */
|
||||||
|
#endif /* ! __NetBSD__ */
|
||||||
|
#endif /* ! __FreeBSD_kernel__ */
|
||||||
#endif /* ! __FreeBSD__ */
|
#endif /* ! __FreeBSD__ */
|
||||||
|
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
#ifndef Aaip_h_is_includeD
|
#ifndef Aaip_h_is_includeD
|
||||||
#define Aaip_h_is_includeD yes
|
#define Aaip_h_is_includeD yes
|
||||||
|
|
||||||
|
/* For ssize_t */
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------- Encoder ---------------------------- */
|
/* --------------------------------- Encoder ---------------------------- */
|
||||||
|
|
||||||
@ -30,12 +33,12 @@
|
|||||||
no longer needed
|
no longer needed
|
||||||
@param flag Bitfield for control purposes
|
@param flag Bitfield for control purposes
|
||||||
bit0= set CONTINUE bit of last AAIP field to 1
|
bit0= set CONTINUE bit of last AAIP field to 1
|
||||||
@return >0 is the number of SUSP fields generated,
|
@return >= 0 is the number of SUSP fields generated,
|
||||||
0 means error
|
< 0 means error
|
||||||
*/
|
*/
|
||||||
size_t aaip_encode(size_t num_attrs, char **names,
|
ssize_t aaip_encode(size_t num_attrs, char **names,
|
||||||
size_t *value_lengths, char **values,
|
size_t *value_lengths, char **values,
|
||||||
size_t *result_len, unsigned char **result, int flag);
|
size_t *result_len, unsigned char **result, int flag);
|
||||||
|
|
||||||
|
|
||||||
/* ------ ACL representation ------ */
|
/* ------ ACL representation ------ */
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
* Copyright (c) 2009 - 2015 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -21,6 +21,7 @@
|
|||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "aaip_0_2.h"
|
#include "aaip_0_2.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "messages.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -72,8 +73,15 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
iso_file_source_ref(src);
|
iso_file_source_ref(src);
|
||||||
|
|
||||||
name = iso_file_source_get_name(src);
|
name = iso_file_source_get_name(src);
|
||||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
if ((int) strlen(name) > image->truncate_length) {
|
||||||
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
ret = iso_truncate_rr_name(image->truncate_mode,
|
||||||
|
image->truncate_length, name, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
iso_stream_unref(stream);
|
||||||
|
free(name);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
ret = iso_node_new_file(name, stream, &node);
|
ret = iso_node_new_file(name, stream, &node);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iso_stream_unref(stream);
|
iso_stream_unref(stream);
|
||||||
@ -98,11 +106,11 @@ static
|
|||||||
int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||||
IsoFileSource *src, char *in_name, IsoNode **node)
|
IsoFileSource *src, char *in_name, IsoNode **node)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, name_is_attached = 0;
|
||||||
struct stat info;
|
struct stat info;
|
||||||
IsoNode *new;
|
IsoNode *new;
|
||||||
IsoFilesystem *fs;
|
IsoFilesystem *fs;
|
||||||
char *name;
|
char *name = NULL;
|
||||||
unsigned char *aa_string = NULL;
|
unsigned char *aa_string = NULL;
|
||||||
char *a_text = NULL, *d_text = NULL;
|
char *a_text = NULL, *d_text = NULL;
|
||||||
char *dest = NULL;
|
char *dest = NULL;
|
||||||
@ -131,8 +139,12 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
if ((int) strlen(name) > image->truncate_length) {
|
||||||
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
ret = iso_truncate_rr_name(image->truncate_mode,
|
||||||
|
image->truncate_length, name, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
fs = iso_file_source_get_filesystem(src);
|
fs = iso_file_source_get_filesystem(src);
|
||||||
new = NULL;
|
new = NULL;
|
||||||
|
|
||||||
@ -203,12 +215,14 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
|
ret = ISO_BAD_FSRC_FILETYPE;
|
||||||
if (ret < 0) {
|
|
||||||
free(name);
|
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
name_is_attached = 1;
|
||||||
|
|
||||||
/* fill fields */
|
/* fill fields */
|
||||||
iso_node_set_perms_internal(new, info.st_mode, 1);
|
iso_node_set_perms_internal(new, info.st_mode, 1);
|
||||||
@ -222,9 +236,9 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
/* Eventually set S_IRWXG from ACL */
|
/* Eventually set S_IRWXG from ACL */
|
||||||
if (image->builder_ignore_acl) {
|
if (image->builder_ignore_acl) {
|
||||||
ret = iso_file_source_get_aa_string(src, &aa_string, 4);
|
ret = iso_file_source_get_aa_string(src, &aa_string, 4);
|
||||||
if (aa_string != NULL)
|
if (ret >= 0 && aa_string != NULL)
|
||||||
iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text, 16);
|
iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text, 16);
|
||||||
if (a_text != NULL) {
|
if (ret >= 0 && a_text != NULL) {
|
||||||
aaip_cleanout_st_mode(a_text, &(info.st_mode), 4 | 16);
|
aaip_cleanout_st_mode(a_text, &(info.st_mode), 4 | 16);
|
||||||
iso_node_set_perms_internal(new, info.st_mode, 1);
|
iso_node_set_perms_internal(new, info.st_mode, 1);
|
||||||
}
|
}
|
||||||
@ -251,6 +265,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
|
|
||||||
ret = ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
ex:;
|
ex:;
|
||||||
|
if (name != NULL && !name_is_attached)
|
||||||
|
free(name);
|
||||||
LIBISO_FREE_MEM(dest);
|
LIBISO_FREE_MEM(dest);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,11 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.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
|
* Private data for File IsoDataSource
|
||||||
*/
|
*/
|
||||||
@ -65,7 +70,7 @@ int ds_open(IsoDataSource *src)
|
|||||||
return ISO_FILE_ALREADY_OPENED;
|
return ISO_FILE_ALREADY_OPENED;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open(data->path, O_RDONLY);
|
fd = open(data->path, O_RDONLY | O_BINARY);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
return ISO_FILE_ERROR;
|
return ISO_FILE_ERROR;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2013 Thomas Schmitt
|
* Copyright (c) 2009 - 2015 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -468,17 +468,33 @@ struct iso_write_opts {
|
|||||||
to HFS+/FAT and IsoFileSrc areas and marked by an MBR partition entry.
|
to HFS+/FAT and IsoFileSrc areas and marked by an MBR partition entry.
|
||||||
*/
|
*/
|
||||||
char *prep_partition;
|
char *prep_partition;
|
||||||
|
int prep_part_flag;
|
||||||
|
|
||||||
/* Eventual disk file path of an EFI system partition image which shall
|
/* 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.
|
be prepended to HFS+/FAT and IsoFileSrc areas and marked by a GPT entry.
|
||||||
*/
|
*/
|
||||||
char *efi_boot_partition;
|
char *efi_boot_partition;
|
||||||
|
int efi_boot_part_flag;
|
||||||
|
|
||||||
/* Eventual disk file paths of prepared images which shall be appended
|
/* Eventual disk file paths of prepared images which shall be appended
|
||||||
after the ISO image and described by partiton table entries in a MBR
|
after the ISO image and described by partiton table entries in a MBR
|
||||||
*/
|
*/
|
||||||
char *appended_partitions[ISO_MAX_PARTITIONS];
|
char *appended_partitions[ISO_MAX_PARTITIONS];
|
||||||
uint8_t appended_part_types[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;
|
||||||
|
|
||||||
|
/* If 1: With appended partitions: mark by APM partition
|
||||||
|
*/
|
||||||
|
int appended_as_apm;
|
||||||
|
|
||||||
|
/* If 1: Obey struct el_torito_boot_image.isolinux_options bit2-7 and bit8.
|
||||||
|
I.e. mention boot image as partition in GPT and/or APM.
|
||||||
|
*/
|
||||||
|
int part_like_isohybrid;
|
||||||
|
|
||||||
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
|
/* Eventual name of the non-ISO aspect of the image. E.g. SUN ASCII label.
|
||||||
*/
|
*/
|
||||||
@ -547,10 +563,19 @@ struct ecma119_image
|
|||||||
|
|
||||||
time_t now; /**< Time at which writing began. */
|
time_t now; /**< Time at which writing began. */
|
||||||
|
|
||||||
/** Total size of the output. This only includes the current volume. */
|
/* Total size of the output. Counted in bytes.
|
||||||
|
* Includes ISO filesystem and appended data.
|
||||||
|
*/
|
||||||
off_t total_size;
|
off_t total_size;
|
||||||
|
|
||||||
|
/** Size actually governed by the ISO filesystem part of the output */
|
||||||
uint32_t vol_space_size;
|
uint32_t vol_space_size;
|
||||||
|
|
||||||
|
/* 1= write the total size into the PVD of the ISO,
|
||||||
|
* 0= write vol_space_size
|
||||||
|
*/
|
||||||
|
int pvd_size_is_total_size;
|
||||||
|
|
||||||
/* Bytes already written to image output */
|
/* Bytes already written to image output */
|
||||||
off_t bytes_written;
|
off_t bytes_written;
|
||||||
/* just for progress notification */
|
/* just for progress notification */
|
||||||
@ -633,6 +658,11 @@ struct ecma119_image
|
|||||||
int num_bootsrc;
|
int num_bootsrc;
|
||||||
IsoFileSrc **bootsrc; /* location of the boot images in the new image */
|
IsoFileSrc **bootsrc; /* location of the boot images in the new image */
|
||||||
|
|
||||||
|
int *boot_appended_idx; /* Appended partition which serve as boot images */
|
||||||
|
|
||||||
|
uint32_t *boot_intvl_start; /* In blocks of 2048 bytes */
|
||||||
|
uint32_t *boot_intvl_size; /* In blocks of 512 bytes */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* System Area related information
|
* System Area related information
|
||||||
*/
|
*/
|
||||||
@ -695,6 +725,8 @@ struct ecma119_image
|
|||||||
/* tree of files sources */
|
/* tree of files sources */
|
||||||
IsoRBTree *files;
|
IsoRBTree *files;
|
||||||
|
|
||||||
|
struct iso_filesrc_list_item *ecma119_hidden_list;
|
||||||
|
|
||||||
unsigned int checksum_idx_counter;
|
unsigned int checksum_idx_counter;
|
||||||
void *checksum_ctx;
|
void *checksum_ctx;
|
||||||
off_t checksum_counter;
|
off_t checksum_counter;
|
||||||
@ -756,6 +788,7 @@ struct ecma119_image
|
|||||||
uint32_t appended_part_prepad[ISO_MAX_PARTITIONS];
|
uint32_t appended_part_prepad[ISO_MAX_PARTITIONS];
|
||||||
uint32_t appended_part_start[ISO_MAX_PARTITIONS];
|
uint32_t appended_part_start[ISO_MAX_PARTITIONS];
|
||||||
uint32_t appended_part_size[ISO_MAX_PARTITIONS];
|
uint32_t appended_part_size[ISO_MAX_PARTITIONS];
|
||||||
|
int have_appended_partitions;
|
||||||
|
|
||||||
/* See IsoImage and libisofs.h */
|
/* See IsoImage and libisofs.h */
|
||||||
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
||||||
@ -768,8 +801,8 @@ struct ecma119_image
|
|||||||
/* Allocation block size of HFS+
|
/* Allocation block size of HFS+
|
||||||
May be defined to 512 or 2048 before hfsplus_writer_create().
|
May be defined to 512 or 2048 before hfsplus_writer_create().
|
||||||
*/
|
*/
|
||||||
int hfsp_cat_node_size; /* 2 * apm_block_size */
|
int hfsp_cat_node_size; /* 2 * hfsp_block_size */
|
||||||
int hfsp_iso_block_fac; /* 2048 / apm_block_size */
|
int hfsp_iso_block_fac; /* 2048 / hfsp_block_size */
|
||||||
|
|
||||||
/* Apple Partition Map description. To be composed during IsoImageWriter
|
/* Apple Partition Map description. To be composed during IsoImageWriter
|
||||||
method ->compute_data_blocks() by calling iso_register_apm_entry().
|
method ->compute_data_blocks() by calling iso_register_apm_entry().
|
||||||
@ -790,6 +823,12 @@ struct ecma119_image
|
|||||||
struct iso_mbr_partition_request *mbr_req[ISO_MBR_ENTRIES_MAX];
|
struct iso_mbr_partition_request *mbr_req[ISO_MBR_ENTRIES_MAX];
|
||||||
int mbr_req_count;
|
int mbr_req_count;
|
||||||
|
|
||||||
|
/* 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;
|
uint32_t prep_part_size;
|
||||||
|
|
||||||
/* GPT description. To be composed during IsoImageWriter
|
/* GPT description. To be composed during IsoImageWriter
|
||||||
@ -802,12 +841,17 @@ struct ecma119_image
|
|||||||
/* bit0= GPT partitions may overlap */
|
/* bit0= GPT partitions may overlap */
|
||||||
int gpt_req_flags;
|
int gpt_req_flags;
|
||||||
|
|
||||||
|
/* Whether the eventual backup GPT is not part of the ISO filesystem */
|
||||||
|
int gpt_backup_outside;
|
||||||
|
|
||||||
uint32_t efi_boot_part_size;
|
uint32_t efi_boot_part_size;
|
||||||
IsoFileSrc *efi_boot_part_filesrc; /* Just a pointer. Do not free. */
|
IsoFileSrc *efi_boot_part_filesrc; /* Just a pointer. Do not free. */
|
||||||
|
|
||||||
/* Messages from gpt_tail_writer_compute_data_blocks() to
|
/* Messages from gpt_tail_writer_compute_data_blocks() to
|
||||||
iso_write_system_area().
|
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 */
|
/* Start of GPT entries in System Area, block size 512 */
|
||||||
uint32_t gpt_part_start;
|
uint32_t gpt_part_start;
|
||||||
/* The ISO block number after the backup GPT header , block size 2048 */
|
/* The ISO block number after the backup GPT header , block size 2048 */
|
||||||
@ -820,6 +864,7 @@ struct ecma119_image
|
|||||||
write_data() methods of the writers.
|
write_data() methods of the writers.
|
||||||
*/
|
*/
|
||||||
uint8_t sys_area_as_written[16 * BLOCK_SIZE];
|
uint8_t sys_area_as_written[16 * BLOCK_SIZE];
|
||||||
|
int sys_area_already_written;
|
||||||
|
|
||||||
/* Size of the filesrc_writer area (data file content).
|
/* Size of the filesrc_writer area (data file content).
|
||||||
This is available before any IsoImageWriter.compute_data_blocks()
|
This is available before any IsoImageWriter.compute_data_blocks()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* 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
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -201,23 +201,26 @@ static
|
|||||||
int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
|
int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
Ecma119Node **children;
|
Ecma119Node **children = NULL;
|
||||||
struct ecma119_dir_info *dir_info;
|
struct ecma119_dir_info *dir_info;
|
||||||
|
|
||||||
children = calloc(1, sizeof(void*) * iso->nchildren);
|
if (iso->nchildren > 0) {
|
||||||
if (children == NULL) {
|
children = calloc(1, sizeof(void*) * iso->nchildren);
|
||||||
return ISO_OUT_OF_MEM;
|
if (children == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir_info = calloc(1, sizeof(struct ecma119_dir_info));
|
dir_info = calloc(1, sizeof(struct ecma119_dir_info));
|
||||||
if (dir_info == NULL) {
|
if (dir_info == NULL) {
|
||||||
free(children);
|
if (children != NULL)
|
||||||
|
free(children);
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = create_ecma119_node(img, (IsoNode*)iso, node);
|
ret = create_ecma119_node(img, (IsoNode*)iso, node);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(children);
|
if (children != NULL)
|
||||||
|
free(children);
|
||||||
free(dir_info);
|
free(dir_info);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -353,7 +356,8 @@ void ecma119_node_free(Ecma119Node *node)
|
|||||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||||
ecma119_node_free(node->info.dir->children[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->info.dir);
|
||||||
}
|
}
|
||||||
free(node->iso_name);
|
free(node->iso_name);
|
||||||
@ -361,6 +365,35 @@ void ecma119_node_free(Ecma119Node *node)
|
|||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int add_to_hidden_list(Ecma119Image *image, IsoFileSrc *src)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct iso_filesrc_list_item *item;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(item, struct iso_filesrc_list_item, 1);
|
||||||
|
item->src = src;
|
||||||
|
item->next = image->ecma119_hidden_list;
|
||||||
|
image->ecma119_hidden_list = item;
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int iso_filesrc_list_destroy(struct iso_filesrc_list_item **start_item)
|
||||||
|
{
|
||||||
|
struct iso_filesrc_list_item *item, *next;
|
||||||
|
|
||||||
|
for (item = *start_item; item != NULL; item = next) {
|
||||||
|
next = item->next;
|
||||||
|
LIBISO_FREE_MEM(item);
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param flag
|
* @param flag
|
||||||
* bit0= iso is in a hidden directory. Thus hide it.
|
* bit0= iso is in a hidden directory. Thus hide it.
|
||||||
@ -377,11 +410,12 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
|||||||
int max_path;
|
int max_path;
|
||||||
char *iso_name= NULL, *ipath = NULL;
|
char *iso_name= NULL, *ipath = NULL;
|
||||||
IsoFileSrc *src = NULL;
|
IsoFileSrc *src = NULL;
|
||||||
IsoWriteOpts *opts = image->opts;
|
IsoWriteOpts *opts;
|
||||||
|
|
||||||
if (image == NULL || iso == NULL || tree == NULL) {
|
if (image == NULL || iso == NULL || tree == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
opts = image->opts;
|
||||||
*tree = NULL;
|
*tree = NULL;
|
||||||
|
|
||||||
hidden = flag & 1;
|
hidden = flag & 1;
|
||||||
@ -426,6 +460,9 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
|||||||
case LIBISO_FILE:
|
case LIBISO_FILE:
|
||||||
if (hidden) {
|
if (hidden) {
|
||||||
ret = create_file_src(image, (IsoFile *) iso, &src);
|
ret = create_file_src(image, (IsoFile *) iso, &src);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
ret = add_to_hidden_list(image, src);
|
||||||
} else {
|
} else {
|
||||||
ret = create_file(image, (IsoFile*)iso, &node);
|
ret = create_file(image, (IsoFile*)iso, &node);
|
||||||
}
|
}
|
||||||
@ -466,6 +503,9 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
|||||||
if (image->eltorito) {
|
if (image->eltorito) {
|
||||||
if (hidden) {
|
if (hidden) {
|
||||||
ret = el_torito_catalog_file_src_create(image, &src);
|
ret = el_torito_catalog_file_src_create(image, &src);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
ret = add_to_hidden_list(image, src);
|
||||||
} else {
|
} else {
|
||||||
ret = create_boot_cat(image, (IsoBoot*)iso, &node);
|
ret = create_boot_cat(image, (IsoBoot*)iso, &node);
|
||||||
}
|
}
|
||||||
@ -564,6 +604,8 @@ void sort_tree(Ecma119Node *root)
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
if (root->info.dir->children == NULL)
|
||||||
|
return;
|
||||||
qsort(root->info.dir->children, root->info.dir->nchildren, sizeof(void*),
|
qsort(root->info.dir->children, root->info.dir->nchildren, sizeof(void*),
|
||||||
cmp_node_name);
|
cmp_node_name);
|
||||||
for (i = 0; i < root->info.dir->nchildren; i++) {
|
for (i = 0; i < root->info.dir->nchildren; i++) {
|
||||||
@ -592,6 +634,9 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
|||||||
nchildren = dir->info.dir->nchildren;
|
nchildren = dir->info.dir->nchildren;
|
||||||
children = dir->info.dir->children;
|
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 */
|
/* a hash table will temporary hold the names, for fast searching */
|
||||||
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
||||||
(compare_function_t)strcmp, &table);
|
(compare_function_t)strcmp, &table);
|
||||||
@ -609,6 +654,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
|||||||
for (i = 0; i < nchildren; ++i) {
|
for (i = 0; i < nchildren; ++i) {
|
||||||
char *name, *ext;
|
char *name, *ext;
|
||||||
char full_name[40];
|
char full_name[40];
|
||||||
|
const int full_max_len = 40 - 1;
|
||||||
int max; /* computed max len for name, without extension */
|
int max; /* computed max len for name, without extension */
|
||||||
int j = i;
|
int j = i;
|
||||||
int digits = 1; /* characters to change per name */
|
int digits = 1; /* characters to change per name */
|
||||||
@ -647,7 +693,8 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
|||||||
int change = 0; /* number to be written */
|
int change = 0; /* number to be written */
|
||||||
|
|
||||||
/* copy name to buffer */
|
/* copy name to buffer */
|
||||||
strcpy(full_name, children[i]->iso_name);
|
strncpy(full_name, children[i]->iso_name, full_max_len);
|
||||||
|
full_name[full_max_len] = 0;
|
||||||
|
|
||||||
/* compute name and extension */
|
/* compute name and extension */
|
||||||
dot = strrchr(full_name, '.');
|
dot = strrchr(full_name, '.');
|
||||||
@ -1113,6 +1160,11 @@ int family_set_ino(Ecma119Image *img, Ecma119Node **nodes, size_t family_start,
|
|||||||
*/
|
*/
|
||||||
if (img_ino == prev_ino)
|
if (img_ino == prev_ino)
|
||||||
img_ino = 0;
|
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) {
|
if (img_ino == 0) {
|
||||||
img_ino = img_give_ino_number(img->image, 0);
|
img_ino = img_give_ino_number(img->image, 0);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* 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
|
* 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
|
* 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 */
|
IsoNode *node; /*< reference to the iso node */
|
||||||
|
|
||||||
/* >>> ts A90501 : Shouldn't this be uint32_t
|
uint32_t ino;
|
||||||
as this is what PX will take ? */
|
|
||||||
ino_t ino;
|
|
||||||
|
|
||||||
nlink_t nlink;
|
nlink_t nlink;
|
||||||
|
|
||||||
@ -81,6 +79,17 @@ struct ecma119_node
|
|||||||
} info;
|
} info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* For recording files which are hidden in ECMA-119 */
|
||||||
|
struct iso_filesrc_list_item
|
||||||
|
{
|
||||||
|
IsoFileSrc *src;
|
||||||
|
struct iso_filesrc_list_item *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
int iso_filesrc_list_destroy(struct iso_filesrc_list_item **start_item);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2010 - 2013 Thomas Schmitt
|
* Copyright (c) 2010 - 2015 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -19,6 +19,7 @@
|
|||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "writer.h"
|
#include "writer.h"
|
||||||
|
#include "ecma119.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -82,15 +83,16 @@ void el_torito_set_load_seg(ElToritoBootImage *bootimg, short segment)
|
|||||||
{
|
{
|
||||||
if (bootimg->type != 0)
|
if (bootimg->type != 0)
|
||||||
return;
|
return;
|
||||||
bootimg->load_seg = segment;
|
if (segment < 0)
|
||||||
|
bootimg->load_seg = 0x1000 + segment;
|
||||||
|
else
|
||||||
|
bootimg->load_seg = segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
int el_torito_get_load_seg(ElToritoBootImage *bootimg)
|
int el_torito_get_load_seg(ElToritoBootImage *bootimg)
|
||||||
{
|
{
|
||||||
if (bootimg->load_seg < 0)
|
return (int) bootimg->load_seg;
|
||||||
return 0xffff - bootimg->load_seg;
|
|
||||||
return bootimg->load_seg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -102,15 +104,16 @@ void el_torito_set_load_size(ElToritoBootImage *bootimg, short sectors)
|
|||||||
{
|
{
|
||||||
if (bootimg->type != 0)
|
if (bootimg->type != 0)
|
||||||
return;
|
return;
|
||||||
bootimg->load_size = sectors;
|
if (sectors < 0)
|
||||||
|
bootimg->load_size = 0x10000 + sectors;
|
||||||
|
else
|
||||||
|
bootimg->load_size = sectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
int el_torito_get_load_size(ElToritoBootImage *bootimg)
|
int el_torito_get_load_size(ElToritoBootImage *bootimg)
|
||||||
{
|
{
|
||||||
if (bootimg->load_size < 0)
|
return (int) bootimg->load_size;
|
||||||
return 0xffff - bootimg->load_size;
|
|
||||||
return bootimg->load_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -204,6 +207,8 @@ void el_torito_patch_isolinux_image(ElToritoBootImage *bootimg)
|
|||||||
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag)
|
int el_torito_set_isolinux_options(ElToritoBootImage *bootimg, int options, int flag)
|
||||||
{
|
{
|
||||||
bootimg->isolinux_options = (options & 0x03ff);
|
bootimg->isolinux_options = (options & 0x03ff);
|
||||||
|
bootimg->seems_boot_info_table = !!(options & 1);
|
||||||
|
bootimg->seems_grub2_boot_info = !!(options & (1 << 9));
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,6 +313,35 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
|||||||
return ++parent->nchildren;
|
return ++parent->nchildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get start and size from "%d_start_%lus_size_%lud" */
|
||||||
|
static
|
||||||
|
void iso_parse_start_size(char *text, unsigned long *part_start,
|
||||||
|
unsigned long *part_size)
|
||||||
|
{
|
||||||
|
char *cpt;
|
||||||
|
unsigned long start, size;
|
||||||
|
|
||||||
|
cpt = strchr(text, '_');
|
||||||
|
if (cpt == NULL)
|
||||||
|
return;
|
||||||
|
if (strncmp(cpt, "_start_", 7) != 0)
|
||||||
|
return;
|
||||||
|
sscanf(cpt + 7, "%lu", &start);
|
||||||
|
cpt = strchr(cpt + 7, '_');
|
||||||
|
if (cpt == NULL)
|
||||||
|
return;
|
||||||
|
if (*(cpt - 1) != 's')
|
||||||
|
return;
|
||||||
|
if (strncmp(cpt, "_size_", 6) != 0)
|
||||||
|
return;
|
||||||
|
sscanf(cpt + 6, "%lu", &size);
|
||||||
|
for (cpt = cpt + 6; *cpt >= '0' && *cpt <= '9'; cpt++);
|
||||||
|
if (*cpt != 'd')
|
||||||
|
return;
|
||||||
|
|
||||||
|
*part_start = start;
|
||||||
|
*part_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int create_image(IsoImage *image, const char *image_path,
|
int create_image(IsoImage *image, const char *image_path,
|
||||||
@ -319,36 +353,64 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
struct el_torito_boot_image *boot;
|
struct el_torito_boot_image *boot;
|
||||||
int boot_media_type = 0;
|
int boot_media_type = 0;
|
||||||
int load_sectors = 0; /* number of sector to load */
|
int load_sectors = 0; /* number of sector to load */
|
||||||
|
int part_idx = -1;
|
||||||
|
unsigned long part_start = 0, part_size = 0;
|
||||||
unsigned char partition_type = 0;
|
unsigned char partition_type = 0;
|
||||||
off_t size;
|
off_t size;
|
||||||
IsoNode *imgfile;
|
IsoNode *imgfile = NULL;
|
||||||
IsoStream *stream;
|
IsoStream *stream = NULL;
|
||||||
|
|
||||||
*bootnode = NULL;
|
*bootnode = NULL;
|
||||||
ret = iso_tree_path_to_node(image, image_path, &imgfile);
|
|
||||||
if (ret < 0) {
|
if (strncmp(image_path, "--interval:appended_partition_", 30) == 0) {
|
||||||
return ret;
|
/* --interval:appended_partition_N... */
|
||||||
}
|
if (type != ELTORITO_NO_EMUL) {
|
||||||
if (ret == 0) {
|
|
||||||
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
|
/* >>> ??? lift this ban by making a temporary IsoStream from
|
||||||
|
partition source, determine size,
|
||||||
|
and read ELTORITO_HARD_DISC_EMUL MBR ?
|
||||||
|
*/
|
||||||
|
|
||||||
|
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Appended partition cannot serve as El Torito boot image with FD/HD emulation");
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
sscanf(image_path + 30, "%d", &part_idx);
|
||||||
|
if (part_idx < 1 || part_idx > ISO_MAX_PARTITIONS) {
|
||||||
|
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Appended partition index for El Torito boot image is out of range");
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
iso_parse_start_size((char *) (image_path + 30),
|
||||||
|
&part_start, &part_size);
|
||||||
|
part_idx--;
|
||||||
|
size = 1;
|
||||||
|
} else {
|
||||||
|
ret = iso_tree_path_to_node(image, image_path, &imgfile);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
iso_msg_submit(image->id, ISO_NODE_DOESNT_EXIST, 0,
|
||||||
"El Torito boot image file missing in ISO image: '%s'",
|
"El Torito boot image file missing in ISO image: '%s'",
|
||||||
image_path);
|
image_path);
|
||||||
return ISO_NODE_DOESNT_EXIST;
|
return ISO_NODE_DOESNT_EXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imgfile->type != LIBISO_FILE) {
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
*bootnode = (IsoFile *) imgfile;
|
||||||
|
|
||||||
|
stream = ((IsoFile*)imgfile)->stream;
|
||||||
|
|
||||||
|
/* we need to read the image at least two times */
|
||||||
|
if (!iso_stream_is_repeatable(stream)) {
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = iso_stream_get_size(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (imgfile->type != LIBISO_FILE) {
|
|
||||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
|
||||||
}
|
|
||||||
*bootnode = (IsoFile *) imgfile;
|
|
||||||
|
|
||||||
stream = ((IsoFile*)imgfile)->stream;
|
|
||||||
|
|
||||||
/* we need to read the image at least two times */
|
|
||||||
if (!iso_stream_is_repeatable(stream)) {
|
|
||||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
size = iso_stream_get_size(stream);
|
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
"Boot image file is empty");
|
"Boot image file is empty");
|
||||||
@ -437,9 +499,15 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
boot->image = (IsoFile*)imgfile;
|
boot->image = (IsoFile*)imgfile;
|
||||||
iso_node_ref(imgfile); /* get our ref */
|
boot->appended_idx = part_idx;
|
||||||
|
boot->appended_start = part_start;
|
||||||
|
boot->appended_size = part_size;
|
||||||
|
if (imgfile != NULL)
|
||||||
|
iso_node_ref(imgfile); /* get our ref */
|
||||||
boot->bootable = 1;
|
boot->bootable = 1;
|
||||||
boot->seems_boot_info_table = 0;
|
boot->seems_boot_info_table = 0;
|
||||||
|
boot->seems_grub2_boot_info = 0;
|
||||||
|
boot->seems_isohybrid_capable = 0;
|
||||||
boot->isolinux_options = 0;
|
boot->isolinux_options = 0;
|
||||||
boot->type = boot_media_type;
|
boot->type = boot_media_type;
|
||||||
boot->partition_type = partition_type;
|
boot->partition_type = partition_type;
|
||||||
@ -448,9 +516,7 @@ int create_image(IsoImage *image, const char *image_path,
|
|||||||
boot->platform_id = 0; /* 80x86 */
|
boot->platform_id = 0; /* 80x86 */
|
||||||
memset(boot->id_string, 0, sizeof(boot->id_string));
|
memset(boot->id_string, 0, sizeof(boot->id_string));
|
||||||
memset(boot->selection_crit, 0, sizeof(boot->selection_crit));
|
memset(boot->selection_crit, 0, sizeof(boot->selection_crit));
|
||||||
if (bootimg) {
|
*bootimg = boot;
|
||||||
*bootimg = boot;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -533,9 +599,10 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
|||||||
for (i = 1; i < Libisofs_max_boot_imageS; i++)
|
for (i = 1; i < Libisofs_max_boot_imageS; i++)
|
||||||
catalog->bootimages[i] = NULL;
|
catalog->bootimages[i] = NULL;
|
||||||
catalog->node = cat_node;
|
catalog->node = cat_node;
|
||||||
catalog->sort_weight = 1000; /* slightly high */
|
catalog->sort_weight = 1000000000; /* very high */
|
||||||
if (!boot_node->explicit_weight)
|
if (boot_node != NULL)
|
||||||
boot_node->sort_weight = 2;
|
if (!(boot_node->explicit_weight || boot_node->from_old_session))
|
||||||
|
boot_node->sort_weight = 2;
|
||||||
iso_node_ref((IsoNode*)cat_node);
|
iso_node_ref((IsoNode*)cat_node);
|
||||||
image->bootcat = catalog;
|
image->bootcat = catalog;
|
||||||
|
|
||||||
@ -551,7 +618,8 @@ boot_image_cleanup:;
|
|||||||
iso_node_unref((IsoNode*)cat_node);
|
iso_node_unref((IsoNode*)cat_node);
|
||||||
}
|
}
|
||||||
if (boot_image) {
|
if (boot_image) {
|
||||||
iso_node_unref((IsoNode*)boot_image->image);
|
if (boot_image->image != NULL)
|
||||||
|
iso_node_unref((IsoNode*)boot_image->image);
|
||||||
free(boot_image);
|
free(boot_image);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@ -715,8 +783,9 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
|
|||||||
ret = create_image(image, image_path, type, &boot_img, &boot_node);
|
ret = create_image(image, image_path, type, &boot_img, &boot_node);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
if (!boot_node->explicit_weight)
|
if (boot_node != NULL)
|
||||||
boot_node->sort_weight = 2;
|
if (!(boot_node->explicit_weight || boot_node->from_old_session))
|
||||||
|
boot_node->sort_weight = 2;
|
||||||
catalog->bootimages[catalog->num_bootimages] = boot_img;
|
catalog->bootimages[catalog->num_bootimages] = boot_img;
|
||||||
catalog->num_bootimages++;
|
catalog->num_bootimages++;
|
||||||
if (boot != NULL)
|
if (boot != NULL)
|
||||||
@ -808,7 +877,8 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
|
|||||||
(struct el_torito_section_header *) buf;
|
(struct el_torito_section_header *) buf;
|
||||||
|
|
||||||
/* 0x90 = more section headers follow , 0x91 = final section */
|
/* 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->platform_id[0] = t->catalog->bootimages[idx]->platform_id;
|
||||||
e->num_entries[0] = num_entries & 0xff;
|
e->num_entries[0] = num_entries & 0xff;
|
||||||
e->num_entries[1] = (num_entries >> 8) & 0xff;;
|
e->num_entries[1] = (num_entries >> 8) & 0xff;;
|
||||||
@ -822,12 +892,13 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
|
|||||||
* Usable for the Default Entry
|
* Usable for the Default Entry
|
||||||
* and for Section Entries with Selection criteria type == 0
|
* and for Section Entries with Selection criteria type == 0
|
||||||
*/
|
*/
|
||||||
static void
|
static
|
||||||
write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
int write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
||||||
{
|
{
|
||||||
struct el_torito_boot_image *img;
|
struct el_torito_boot_image *img;
|
||||||
struct el_torito_section_entry *se =
|
struct el_torito_section_entry *se =
|
||||||
(struct el_torito_section_entry*)buf;
|
(struct el_torito_section_entry*)buf;
|
||||||
|
int app_idx, mode = 0;
|
||||||
|
|
||||||
img = t->catalog->bootimages[idx];
|
img = t->catalog->bootimages[idx];
|
||||||
|
|
||||||
@ -835,16 +906,69 @@ write_section_entry(uint8_t *buf, Ecma119Image *t, int idx)
|
|||||||
se->boot_media_type[0] = img->type;
|
se->boot_media_type[0] = img->type;
|
||||||
iso_lsb(se->load_seg, img->load_seg, 2);
|
iso_lsb(se->load_seg, img->load_seg, 2);
|
||||||
se->system_type[0] = img->partition_type;
|
se->system_type[0] = img->partition_type;
|
||||||
iso_lsb(se->sec_count, img->load_size, 2);
|
|
||||||
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4);
|
if (t->boot_appended_idx[idx] >= 0)
|
||||||
|
if (t->appended_part_size[t->boot_appended_idx[idx]] > 0)
|
||||||
|
mode = 2; /* appended partition */
|
||||||
|
if (mode == 0 && t->opts->appendable &&
|
||||||
|
(t->boot_intvl_start[idx] > 0 || t->boot_intvl_size[idx] > 0) &&
|
||||||
|
t->boot_intvl_start[idx] + (t->boot_intvl_size[idx] + 3) / 4 <=
|
||||||
|
t->opts->ms_block)
|
||||||
|
mode = 1; /* image interval */
|
||||||
|
if (mode == 0 && t->boot_appended_idx[idx] >= 0) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Appended partition which shall serve as boot image does not exist");
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == 1) {
|
||||||
|
if (t->boot_intvl_start[idx] + (t->boot_intvl_size[idx] + 3) / 4 >
|
||||||
|
t->total_size / 2048 + t->opts->ms_block - t->eff_partition_offset
|
||||||
|
) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Block interval which shall serve as boot image is outside result range");
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t->boot_intvl_size[idx] > 65535) {
|
||||||
|
if (img->platform_id == 0xef)
|
||||||
|
iso_lsb(se->sec_count, 0, 2);
|
||||||
|
else
|
||||||
|
iso_lsb(se->sec_count, 65535, 2);
|
||||||
|
} else {
|
||||||
|
if (t->boot_intvl_size[idx] == 0) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Block interval which shall serve as boot image has zero size");
|
||||||
|
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||||
|
}
|
||||||
|
iso_lsb(se->sec_count, t->boot_intvl_size[idx], 2);
|
||||||
|
}
|
||||||
|
iso_lsb(se->block, t->boot_intvl_start[idx], 4);
|
||||||
|
} else if (mode == 2) {
|
||||||
|
app_idx = t->boot_appended_idx[idx];
|
||||||
|
if (t->appended_part_size[app_idx] * 4 > 65535) {
|
||||||
|
if (img->platform_id == 0xef)
|
||||||
|
iso_lsb(se->sec_count, 0, 2);
|
||||||
|
else
|
||||||
|
iso_lsb(se->sec_count, 65535, 2);
|
||||||
|
} else {
|
||||||
|
iso_lsb(se->sec_count, t->appended_part_size[app_idx] * 4, 2);
|
||||||
|
}
|
||||||
|
iso_lsb(se->block, t->appended_part_start[app_idx], 4);
|
||||||
|
} else {
|
||||||
|
iso_lsb(se->sec_count, img->load_size, 2);
|
||||||
|
iso_lsb(se->block, t->bootsrc[idx]->sections[0].block, 4);
|
||||||
|
}
|
||||||
|
|
||||||
se->selec_criteria[0] = img->selection_crit[0];
|
se->selec_criteria[0] = img->selection_crit[0];
|
||||||
memcpy(se->vendor_sc, img->selection_crit + 1, 19);
|
memcpy(se->vendor_sc, img->selection_crit + 1, 19);
|
||||||
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int catalog_open(IsoStream *stream)
|
int catalog_open(IsoStream *stream)
|
||||||
{
|
{
|
||||||
int i, j, k, num_entries;
|
int i, j, k, num_entries, ret;
|
||||||
struct catalog_stream *data;
|
struct catalog_stream *data;
|
||||||
uint8_t *wpt;
|
uint8_t *wpt;
|
||||||
struct el_torito_boot_catalog *cat;
|
struct el_torito_boot_catalog *cat;
|
||||||
@ -868,7 +992,9 @@ int catalog_open(IsoStream *stream)
|
|||||||
boots[0]->platform_id, boots[0]->id_string);
|
boots[0]->platform_id, boots[0]->id_string);
|
||||||
|
|
||||||
/* write default entry = first boot image */
|
/* write default entry = first boot image */
|
||||||
write_section_entry(data->buffer + 32, data->target, 0);
|
ret = write_section_entry(data->buffer + 32, data->target, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */
|
/* IMPORTANT: The maximum number of boot images must fit into BLOCK_SIZE */
|
||||||
wpt = data->buffer + 64;
|
wpt = data->buffer + 64;
|
||||||
@ -889,7 +1015,9 @@ int catalog_open(IsoStream *stream)
|
|||||||
write_section_header(wpt, data->target, i, num_entries);
|
write_section_header(wpt, data->target, i, num_entries);
|
||||||
wpt += 32;
|
wpt += 32;
|
||||||
for (j = 0; j < num_entries; j++) {
|
for (j = 0; j < num_entries; j++) {
|
||||||
write_section_entry(wpt, data->target, i);
|
ret = write_section_entry(wpt, data->target, i);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
wpt += 32;
|
wpt += 32;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -951,7 +1079,8 @@ int catalog_is_repeatable(IsoStream *stream)
|
|||||||
/**
|
/**
|
||||||
* fs_id will be the id reserved for El-Torito
|
* fs_id will be the id reserved for El-Torito
|
||||||
* dev_id will be 0 for catalog, 1 for boot image (if needed)
|
* 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
|
static
|
||||||
void catalog_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
void catalog_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id,
|
||||||
@ -1126,6 +1255,9 @@ int patch_boot_info_table(uint8_t *buf, Ecma119Image *t,
|
|||||||
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
"Isolinux image too small. We won't patch it.");
|
"Isolinux image too small. We won't patch it.");
|
||||||
}
|
}
|
||||||
|
if (t->bootsrc[idx] == NULL)
|
||||||
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
|
"Cannot apply ISOLINUX patching outside of ISO 9660 filesystem.");
|
||||||
ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16,
|
ret = make_boot_info_table(buf, t->opts->ms_block + (uint32_t) 16,
|
||||||
t->bootsrc[idx]->sections[0].block,
|
t->bootsrc[idx]->sections[0].block,
|
||||||
(uint32_t) imgsize);
|
(uint32_t) imgsize);
|
||||||
@ -1145,7 +1277,10 @@ int patch_grub2_boot_image(uint8_t *buf, Ecma119Image *t,
|
|||||||
|
|
||||||
if (imgsize < pos + 8)
|
if (imgsize < pos + 8)
|
||||||
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
"Isolinux image too small for GRUB2. Will not patch it.");
|
"Boot image too small for GRUB2. Will not patch it.");
|
||||||
|
if (t->bootsrc[idx] == NULL)
|
||||||
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
|
"Cannot apply GRUB2 patching outside of ISO 9660 filesystem.");
|
||||||
blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst;
|
blk = ((uint64_t) t->bootsrc[idx]->sections[0].block) * 4 + offst;
|
||||||
iso_lsb((buf + pos), blk & 0xffffffff, 4);
|
iso_lsb((buf + pos), blk & 0xffffffff, 4);
|
||||||
iso_lsb((buf + pos + 4), blk >> 32, 4);
|
iso_lsb((buf + pos + 4), blk >> 32, 4);
|
||||||
@ -1168,12 +1303,16 @@ int iso_patch_eltoritos(Ecma119Image *t)
|
|||||||
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
|
for (idx = 0; idx < t->catalog->num_bootimages; idx++) {
|
||||||
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
|
if (!(t->catalog->bootimages[idx]->isolinux_options & 0x201))
|
||||||
continue;
|
continue;
|
||||||
|
if (t->bootsrc[idx] == NULL)
|
||||||
|
return iso_msg_submit(t->image->id, ISO_ISOLINUX_CANT_PATCH, 0,
|
||||||
|
"Cannot apply boot image patching outside of ISO 9660 filesystem");
|
||||||
|
|
||||||
original = t->bootsrc[idx]->stream;
|
original = t->bootsrc[idx]->stream;
|
||||||
size = (size_t) iso_stream_get_size(original);
|
size = (size_t) iso_stream_get_size(original);
|
||||||
|
if (size > Libisofs_elto_max_patchablE)
|
||||||
/* >>> BOOT ts B00428 :
|
return ISO_PATCH_OVERSIZED_BOOT;
|
||||||
check whether size is not too large for buffering */;
|
if (iso_stream_get_input_stream(original, 0) != NULL)
|
||||||
|
return ISO_PATCH_FILTERED_BOOT;
|
||||||
buf = calloc(1, size);
|
buf = calloc(1, size);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
@ -1186,6 +1325,9 @@ int iso_patch_eltoritos(Ecma119Image *t)
|
|||||||
ret = iso_stream_read(original, buf, size);
|
ret = iso_stream_read(original, buf, size);
|
||||||
iso_stream_close(original);
|
iso_stream_close(original);
|
||||||
if (ret != (int) size) {
|
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;
|
return (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1272,8 +1414,8 @@ int eltorito_writer_create(Ecma119Image *target)
|
|||||||
{
|
{
|
||||||
int ret, idx, outsource_efi = 0;
|
int ret, idx, outsource_efi = 0;
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
IsoFile *bootimg;
|
IsoFile *bootimg = NULL;
|
||||||
IsoFileSrc *src;
|
IsoFileSrc *src = NULL;
|
||||||
|
|
||||||
writer = calloc(1, sizeof(IsoImageWriter));
|
writer = calloc(1, sizeof(IsoImageWriter));
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
@ -1306,6 +1448,23 @@ int eltorito_writer_create(Ecma119Image *target)
|
|||||||
if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0)
|
if (strcmp(target->opts->efi_boot_partition, "--efi-boot-image") == 0)
|
||||||
outsource_efi = 1;
|
outsource_efi = 1;
|
||||||
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
|
for (idx = 0; idx < target->catalog->num_bootimages; idx++) {
|
||||||
|
target->bootsrc[idx] = NULL;
|
||||||
|
if (target->catalog->bootimages[idx]->appended_idx >= 0) {
|
||||||
|
/* Use an appended partition as boot image rather than IsoFile */
|
||||||
|
target->boot_appended_idx[idx] =
|
||||||
|
target->catalog->bootimages[idx]->appended_idx;
|
||||||
|
target->boot_intvl_start[idx] =
|
||||||
|
target->catalog->bootimages[idx]->appended_start;
|
||||||
|
target->boot_intvl_size[idx] =
|
||||||
|
target->catalog->bootimages[idx]->appended_size;
|
||||||
|
if (((target->system_area_options >> 2) & 0x3f) == 0 &&
|
||||||
|
(target->system_area_options & 3) == 1) {
|
||||||
|
/* ISO will not be a partition. It can span the whole image. */
|
||||||
|
target->pvd_size_is_total_size = 1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bootimg = target->catalog->bootimages[idx]->image;
|
bootimg = target->catalog->bootimages[idx]->image;
|
||||||
ret = iso_file_src_create(target, bootimg, &src);
|
ret = iso_file_src_create(target, bootimg, &src);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* 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
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -53,12 +53,21 @@ struct el_torito_boot_catalog {
|
|||||||
struct el_torito_boot_image {
|
struct el_torito_boot_image {
|
||||||
IsoFile *image;
|
IsoFile *image;
|
||||||
|
|
||||||
|
/* Overrides .image if >= 0 : array index of appended partition */
|
||||||
|
int appended_idx;
|
||||||
|
uint32_t appended_start; /* In blocks of 2048 bytes */
|
||||||
|
uint32_t appended_size; /* In blocks of 512 bytes */
|
||||||
|
|
||||||
unsigned int bootable:1; /**< If the entry is bootable. */
|
unsigned int bootable:1; /**< If the entry is bootable. */
|
||||||
/**
|
/**
|
||||||
* Whether the boot image seems to contain a boot_info_table
|
* Whether the boot image seems to contain a boot_info_table
|
||||||
*/
|
*/
|
||||||
unsigned int seems_boot_info_table:1;
|
unsigned int seems_boot_info_table:1;
|
||||||
unsigned int seems_grub2_boot_info: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
|
* isolinux options
|
||||||
* bit 0 -> whether to patch image
|
* bit 0 -> whether to patch image
|
||||||
@ -74,8 +83,8 @@ struct el_torito_boot_image {
|
|||||||
unsigned int isolinux_options;
|
unsigned int isolinux_options;
|
||||||
unsigned char type; /**< The type of image */
|
unsigned char type; /**< The type of image */
|
||||||
unsigned char partition_type; /**< type of partition for HD-emul images */
|
unsigned char partition_type; /**< type of partition for HD-emul images */
|
||||||
short load_seg; /**< Load segment for the initial boot image. */
|
uint16_t load_seg; /**< Load segment for the initial boot image. */
|
||||||
short load_size; /**< Number of sectors to load. */
|
uint16_t load_size; /**< Number of sectors to load. */
|
||||||
|
|
||||||
/* Byte 1 of Validation Entry or Section Header Entry:
|
/* Byte 1 of Validation Entry or Section Header Entry:
|
||||||
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
|
0= 80x86, 1= PowerPC, 2= Mac, 0xef= EFI */
|
||||||
@ -164,4 +173,11 @@ int iso_patch_eltoritos(Ecma119Image *t);
|
|||||||
#define Libisofs_grub2_elto_patch_offsT 5
|
#define Libisofs_grub2_elto_patch_offsT 5
|
||||||
|
|
||||||
|
|
||||||
|
/* Maximum size of a boot image which is marked by
|
||||||
|
el_torito_set_isolinux_options() for patching (boot info table,
|
||||||
|
GRUB2 boot info, maybe others).
|
||||||
|
*/
|
||||||
|
#define Libisofs_elto_max_patchablE (32 * 1024 * 1024)
|
||||||
|
|
||||||
|
|
||||||
#endif /* LIBISO_ELTORITO_H */
|
#endif /* LIBISO_ELTORITO_H */
|
||||||
|
@ -229,12 +229,23 @@ int shall_be_written(void *arg)
|
|||||||
return f->no_write ? 0 : 1;
|
return f->no_write ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int shall_be_written_if_not_taken(void *arg)
|
||||||
|
{
|
||||||
|
IsoFileSrc *f = (IsoFileSrc *)arg;
|
||||||
|
return f->no_write || f->taken ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
int filesrc_writer_pre_compute(IsoImageWriter *writer)
|
int filesrc_writer_pre_compute(IsoImageWriter *writer)
|
||||||
{
|
{
|
||||||
size_t i, size, is_external;
|
size_t i, size, is_external;
|
||||||
Ecma119Image *t;
|
Ecma119Image *t;
|
||||||
IsoFileSrc **filelist;
|
IsoFileSrc **filelist;
|
||||||
int (*inc_item)(void *);
|
int (*inc_item)(void *);
|
||||||
|
size_t omitted_count;
|
||||||
|
IsoFileSrc **iso_ecma119_to_filesrc_array(Ecma119Image *t,
|
||||||
|
int (*include_item)(void *),
|
||||||
|
size_t *size);
|
||||||
|
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
@ -257,7 +268,16 @@ int filesrc_writer_pre_compute(IsoImageWriter *writer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* store the filesrcs in a array */
|
/* store the filesrcs in a array */
|
||||||
filelist = (IsoFileSrc**)iso_rbtree_to_array(t->files, inc_item, &size);
|
filelist = (IsoFileSrc**) iso_ecma119_to_filesrc_array(t, inc_item, &size);
|
||||||
|
omitted_count = iso_rbtree_count_array(t->files, (size_t) 0,
|
||||||
|
shall_be_written_if_not_taken);
|
||||||
|
if (omitted_count > 0) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_NOT_REPRODUCIBLE, 0,
|
||||||
|
"Cannot arrange content of data files in surely reproducible way");
|
||||||
|
LIBISO_FREE_MEM(filelist);
|
||||||
|
filelist = (IsoFileSrc**)iso_rbtree_to_array(
|
||||||
|
t->files, inc_item, &size);
|
||||||
|
}
|
||||||
if (filelist == NULL) {
|
if (filelist == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,10 @@ struct Iso_File_Src
|
|||||||
*/
|
*/
|
||||||
unsigned int no_write :1;
|
unsigned int no_write :1;
|
||||||
|
|
||||||
|
/* Is 1 if the object was already put into the filelist array.
|
||||||
|
*/
|
||||||
|
unsigned int taken :1;
|
||||||
|
|
||||||
unsigned int checksum_index :31;
|
unsigned int checksum_index :31;
|
||||||
|
|
||||||
/** File Sections of the file in the image */
|
/** File Sections of the file in the image */
|
||||||
|
@ -655,14 +655,41 @@ IsoStreamIface extf_stream_class = {
|
|||||||
static
|
static
|
||||||
int extf_cmp_ino(IsoStream *s1, IsoStream *s2)
|
int extf_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
ExternalFilterStreamData *data1, *data2;
|
ExternalFilterStreamData *data1, *data2;
|
||||||
|
IsoExternalFilterCommand *cmd1, *cmd2;
|
||||||
|
|
||||||
|
/* This function may rely on being called by iso_stream_cmp_ino()
|
||||||
|
only with s1, s2 which both point to it as their .cmp_ino() function.
|
||||||
|
It would be a programming error to let any other than extf_stream_class
|
||||||
|
point to extf_cmp_ino(). This fallback endangers transitivity of
|
||||||
|
iso_stream_cmp_ino().
|
||||||
|
*/
|
||||||
if (s1->class != &extf_stream_class || s2->class != &extf_stream_class)
|
if (s1->class != &extf_stream_class || s2->class != &extf_stream_class)
|
||||||
return iso_stream_cmp_ino(s1, s2, 1);
|
return iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
|
||||||
data1 = (ExternalFilterStreamData*) s1->data;
|
data1 = (ExternalFilterStreamData*) s1->data;
|
||||||
data2 = (ExternalFilterStreamData*) s2->data;
|
data2 = (ExternalFilterStreamData*) s2->data;
|
||||||
if (data1->cmd != data2->cmd)
|
cmd1 = data1->cmd;
|
||||||
return (data1->cmd < data2->cmd ? -1 : 1);
|
cmd2 = data2->cmd;
|
||||||
|
if (cmd1 != cmd2) {
|
||||||
|
if (strcmp(cmd1->name, cmd2->name) != 0)
|
||||||
|
return strcmp(cmd1->name, cmd2->name);
|
||||||
|
if (strcmp(cmd1->path, cmd2->path) != 0)
|
||||||
|
return strcmp(cmd1->path, cmd2->path);
|
||||||
|
if (cmd1->argc != cmd2->argc)
|
||||||
|
return cmd1->argc < cmd2->argc ? -1 : 1;
|
||||||
|
for (i = 0; i < cmd1->argc; i++) {
|
||||||
|
if (strcmp(cmd1->argv[i], cmd2->argv[i]) != 0)
|
||||||
|
return strcmp(cmd1->argv[i], cmd2->argv[i]);
|
||||||
|
}
|
||||||
|
if (cmd1->behavior != cmd2->behavior)
|
||||||
|
return cmd1->behavior < cmd2->behavior ? -1 : 1;
|
||||||
|
if (strcmp(cmd1->suffix, cmd2->suffix) != 0)
|
||||||
|
return strcmp(cmd1->suffix, cmd2->suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Both streams apply the same treatment to their input streams */
|
||||||
return iso_stream_cmp_ino(data1->orig, data2->orig, 0);
|
return iso_stream_cmp_ino(data1->orig, data2->orig, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,6 +573,9 @@ int gzip_clone_stream(IsoStream *old_stream, IsoStream **new_stream, int flag)
|
|||||||
static
|
static
|
||||||
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
|
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||||
|
|
||||||
|
static
|
||||||
|
int gzip_uncompress_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface gzip_stream_compress_class = {
|
IsoStreamIface gzip_stream_compress_class = {
|
||||||
4,
|
4,
|
||||||
@ -603,17 +606,44 @@ IsoStreamIface gzip_stream_uncompress_class = {
|
|||||||
gzip_stream_free,
|
gzip_stream_free,
|
||||||
gzip_update_size,
|
gzip_update_size,
|
||||||
gzip_get_input_stream,
|
gzip_get_input_stream,
|
||||||
gzip_cmp_ino,
|
gzip_uncompress_cmp_ino,
|
||||||
gzip_clone_stream
|
gzip_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2)
|
int gzip_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
{
|
{
|
||||||
|
/* This function may rely on being called by iso_stream_cmp_ino()
|
||||||
|
only with s1, s2 which both point to it as their .cmp_ino() function.
|
||||||
|
It would be a programming error to let any other than
|
||||||
|
gzip_stream_compress_class point to gzip_cmp_ino().
|
||||||
|
This fallback endangers transitivity of iso_stream_cmp_ino().
|
||||||
|
*/
|
||||||
if (s1->class != s2->class || (s1->class != &gzip_stream_compress_class &&
|
if (s1->class != s2->class || (s1->class != &gzip_stream_compress_class &&
|
||||||
s2->class != &gzip_stream_compress_class))
|
s2->class != &gzip_stream_compress_class))
|
||||||
return iso_stream_cmp_ino(s1, s2, 1);
|
return iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
|
||||||
|
/* Both streams apply the same treatment to their input streams */
|
||||||
|
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
||||||
|
iso_stream_get_input_stream(s2, 0), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int gzip_uncompress_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
|
{
|
||||||
|
/* This function may rely on being called by iso_stream_cmp_ino()
|
||||||
|
only with s1, s2 which both point to it as their .cmp_ino() function.
|
||||||
|
It would be a programming error to let any other than
|
||||||
|
gzip_stream_uncompress_class point to gzip_uncompress_cmp_ino().
|
||||||
|
*/
|
||||||
|
if (s1->class != s2->class ||
|
||||||
|
(s1->class != &gzip_stream_uncompress_class &&
|
||||||
|
s2->class != &gzip_stream_uncompress_class))
|
||||||
|
return iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
|
||||||
|
/* Both streams apply the same treatment to their input streams */
|
||||||
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
||||||
iso_stream_get_input_stream(s2, 0), 0);
|
iso_stream_get_input_stream(s2, 0), 0);
|
||||||
}
|
}
|
||||||
|
@ -130,9 +130,9 @@ int ziso_running_new(ZisofsFilterRuntime **running, int flag)
|
|||||||
|
|
||||||
o->block_size = ziso_block_size;
|
o->block_size = ziso_block_size;
|
||||||
#ifdef Libisofs_with_zliB
|
#ifdef Libisofs_with_zliB
|
||||||
o->buffer_size= compressBound((uLong) ziso_block_size);
|
o->buffer_size = compressBound((uLong) ziso_block_size);
|
||||||
#else
|
#else
|
||||||
o->buffer_size= 2 * ziso_block_size;
|
o->buffer_size = 2 * ziso_block_size;
|
||||||
#endif
|
#endif
|
||||||
o->read_buffer = calloc(o->block_size, 1);
|
o->read_buffer = calloc(o->block_size, 1);
|
||||||
o->block_buffer = calloc(o->buffer_size, 1);
|
o->block_buffer = calloc(o->buffer_size, 1);
|
||||||
@ -381,7 +381,7 @@ int ziso_stream_compress(IsoStream *stream, void *buf, size_t desired)
|
|||||||
if (todo * 4 > rng->buffer_size)
|
if (todo * 4 > rng->buffer_size)
|
||||||
todo = rng->buffer_size / 4;
|
todo = rng->buffer_size / 4;
|
||||||
memcpy(rng->block_buffer,
|
memcpy(rng->block_buffer,
|
||||||
data->block_pointers + 4 * rng->block_pointer_rpos,
|
data->block_pointers + rng->block_pointer_rpos,
|
||||||
todo * 4);
|
todo * 4);
|
||||||
rng->buffer_rpos = 0;
|
rng->buffer_rpos = 0;
|
||||||
rng->buffer_fill = todo * 4;
|
rng->buffer_fill = todo * 4;
|
||||||
@ -838,6 +838,9 @@ no_mem:
|
|||||||
static
|
static
|
||||||
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2);
|
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||||
|
|
||||||
|
static
|
||||||
|
int ziso_uncompress_cmp_ino(IsoStream *s1, IsoStream *s2);
|
||||||
|
|
||||||
|
|
||||||
IsoStreamIface ziso_stream_compress_class = {
|
IsoStreamIface ziso_stream_compress_class = {
|
||||||
4,
|
4,
|
||||||
@ -868,7 +871,7 @@ IsoStreamIface ziso_stream_uncompress_class = {
|
|||||||
ziso_stream_free,
|
ziso_stream_free,
|
||||||
ziso_update_size,
|
ziso_update_size,
|
||||||
ziso_get_input_stream,
|
ziso_get_input_stream,
|
||||||
ziso_cmp_ino,
|
ziso_uncompress_cmp_ino,
|
||||||
ziso_clone_stream
|
ziso_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -876,9 +879,36 @@ IsoStreamIface ziso_stream_uncompress_class = {
|
|||||||
static
|
static
|
||||||
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2)
|
int ziso_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
{
|
{
|
||||||
|
/* This function may rely on being called by iso_stream_cmp_ino()
|
||||||
|
only with s1, s2 which both point to it as their .cmp_ino() function.
|
||||||
|
It would be a programming error to let any other than
|
||||||
|
ziso_stream_compress_class point to ziso_cmp_ino().
|
||||||
|
*/
|
||||||
if (s1->class != s2->class || (s1->class != &ziso_stream_compress_class &&
|
if (s1->class != s2->class || (s1->class != &ziso_stream_compress_class &&
|
||||||
s2->class != &ziso_stream_uncompress_class))
|
s2->class != &ziso_stream_uncompress_class))
|
||||||
iso_stream_cmp_ino(s1, s2, 1);
|
iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
|
||||||
|
/* Both streams apply the same treatment to their input streams */
|
||||||
|
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
||||||
|
iso_stream_get_input_stream(s2, 0), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int ziso_uncompress_cmp_ino(IsoStream *s1, IsoStream *s2)
|
||||||
|
{
|
||||||
|
/* This function may rely on being called by iso_stream_cmp_ino()
|
||||||
|
only with s1, s2 which both point to it as their .cmp_ino() function.
|
||||||
|
It would be a programming error to let any other than
|
||||||
|
ziso_stream_uncompress_class point to ziso_uncompress_cmp_ino().
|
||||||
|
This fallback endangers transitivity of iso_stream_cmp_ino().
|
||||||
|
*/
|
||||||
|
if (s1->class != s2->class ||
|
||||||
|
(s1->class != &ziso_stream_uncompress_class &&
|
||||||
|
s2->class != &ziso_stream_uncompress_class))
|
||||||
|
iso_stream_cmp_ino(s1, s2, 1);
|
||||||
|
|
||||||
|
/* Both streams apply the same treatment to their input streams */
|
||||||
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
return iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
||||||
iso_stream_get_input_stream(s2, 0), 0);
|
iso_stream_get_input_stream(s2, 0), 0);
|
||||||
}
|
}
|
||||||
|
2399
libisofs/fs_image.c
2399
libisofs/fs_image.c
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,11 @@
|
|||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
/* O_BINARY is needed for Cygwin but undefined elsewhere */
|
||||||
|
#ifndef O_BINARY
|
||||||
|
#define O_BINARY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
static
|
static
|
||||||
int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
|
int iso_file_source_new_lfs(IsoFileSource *parent, const char *name,
|
||||||
IsoFileSource **src);
|
IsoFileSource **src);
|
||||||
@ -222,7 +227,7 @@ int lfs_open(IsoFileSource *src)
|
|||||||
data->info.dir = opendir(path);
|
data->info.dir = opendir(path);
|
||||||
data->openned = data->info.dir ? 2 : 0;
|
data->openned = data->info.dir ? 2 : 0;
|
||||||
} else {
|
} 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;
|
data->openned = data->info.fd != -1 ? 1 : 0;
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
@ -282,6 +287,9 @@ static
|
|||||||
int lfs_read(IsoFileSource *src, void *buf, size_t count)
|
int lfs_read(IsoFileSource *src, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
_LocalFsFileSource *data;
|
_LocalFsFileSource *data;
|
||||||
|
size_t to_read, done = 0;
|
||||||
|
int ret;
|
||||||
|
uint8_t *buf8;
|
||||||
|
|
||||||
if (src == NULL || buf == NULL) {
|
if (src == NULL || buf == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -293,28 +301,28 @@ int lfs_read(IsoFileSource *src, void *buf, size_t count)
|
|||||||
data = src->data;
|
data = src->data;
|
||||||
switch (data->openned) {
|
switch (data->openned) {
|
||||||
case 1: /* not dir */
|
case 1: /* not dir */
|
||||||
{
|
buf8 = (uint8_t *) buf; /* for pointer arithmetic */
|
||||||
int ret;
|
for (to_read = count; to_read > 0; to_read = count - done) {
|
||||||
ret = read(data->info.fd, buf, count);
|
if (to_read > 1024 * 1024)
|
||||||
|
to_read = 1024 * 1024;
|
||||||
|
ret = read(data->info.fd, buf8 + done, to_read);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* error on read */
|
/* error on read */
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case EINTR:
|
case EINTR:
|
||||||
ret = ISO_INTERRUPTED;
|
return ISO_INTERRUPTED;
|
||||||
break;
|
|
||||||
case EFAULT:
|
case EFAULT:
|
||||||
ret = ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
break;
|
|
||||||
case EIO:
|
case EIO:
|
||||||
ret = ISO_FILE_READ_ERROR;
|
return ISO_FILE_READ_ERROR;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ret = ISO_FILE_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
return ISO_FILE_ERROR;
|
||||||
}
|
}
|
||||||
return ret;
|
if (ret == 0) /* EOF */
|
||||||
|
break;
|
||||||
|
done += ret;
|
||||||
}
|
}
|
||||||
|
return done;
|
||||||
case 2: /* directory */
|
case 2: /* directory */
|
||||||
return ISO_FILE_IS_DIR;
|
return ISO_FILE_IS_DIR;
|
||||||
default:
|
default:
|
||||||
@ -492,7 +500,8 @@ static
|
|||||||
int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
size_t num_attrs = 0, *value_lengths = NULL, result_len, sret;
|
size_t num_attrs = 0, *value_lengths = NULL, result_len;
|
||||||
|
ssize_t sret;
|
||||||
char *path = NULL, **names = NULL, **values = NULL;
|
char *path = NULL, **names = NULL, **values = NULL;
|
||||||
unsigned char *result = NULL;
|
unsigned char *result = NULL;
|
||||||
|
|
||||||
@ -525,10 +534,10 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||||||
else {
|
else {
|
||||||
sret = aaip_encode(num_attrs, names,
|
sret = aaip_encode(num_attrs, names,
|
||||||
value_lengths, values, &result_len, &result, 0);
|
value_lengths, values, &result_len, &result, 0);
|
||||||
if (sret == 0) {
|
if (sret < 0) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = sret;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*aa_string = result;
|
*aa_string = result;
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -536,7 +545,7 @@ ex:;
|
|||||||
if (path != NULL)
|
if (path != NULL)
|
||||||
free(path);
|
free(path);
|
||||||
if (names != NULL || value_lengths != NULL || values != NULL)
|
if (names != NULL || value_lengths != NULL || values != NULL)
|
||||||
aaip_get_attr_list(path, &num_attrs, &names, &value_lengths, &values,
|
aaip_get_attr_list(NULL, &num_attrs, &names, &value_lengths, &values,
|
||||||
1 << 15); /* free memory */
|
1 << 15); /* free memory */
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* 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
|
* 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
|
* 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.
|
/* 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.
|
/* Create an independent copy of an ifs_class IsoFileSource.
|
||||||
|
@ -137,8 +137,10 @@ int iso_get_hfsplus_name(char *input_charset, int imgid, char *name,
|
|||||||
curlen = ucslen (ucs_name);
|
curlen = ucslen (ucs_name);
|
||||||
*result = calloc ((curlen * HFSPLUS_MAX_DECOMPOSE_LEN + 1),
|
*result = calloc ((curlen * HFSPLUS_MAX_DECOMPOSE_LEN + 1),
|
||||||
sizeof (uint16_t));
|
sizeof (uint16_t));
|
||||||
if (*result == NULL)
|
if (*result == NULL) {
|
||||||
|
free(ucs_name);
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
for (iptr = ucs_name, optr = *result; *iptr; iptr++)
|
for (iptr = ucs_name, optr = *result; *iptr; iptr++)
|
||||||
{
|
{
|
||||||
@ -208,8 +210,12 @@ int iso_get_hfsplus_name(char *input_charset, int imgid, char *name,
|
|||||||
while (done);
|
while (done);
|
||||||
|
|
||||||
*cmp_name = calloc ((ucslen (*result) + 1), sizeof (uint16_t));
|
*cmp_name = calloc ((ucslen (*result) + 1), sizeof (uint16_t));
|
||||||
if (*cmp_name == NULL)
|
if (*cmp_name == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
free(ucs_name);
|
||||||
|
free(*result);
|
||||||
|
*result = NULL;
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
|
|
||||||
for (iptr = *result, optr = *cmp_name; *iptr; iptr++)
|
for (iptr = *result, optr = *cmp_name; *iptr; iptr++)
|
||||||
{
|
{
|
||||||
@ -399,7 +405,8 @@ int create_tree(Ecma119Image *t, IsoNode *iso, uint32_t parent_id)
|
|||||||
if (cret < 0)
|
if (cret < 0)
|
||||||
return cret;
|
return cret;
|
||||||
pos = pos->next;
|
pos = pos->next;
|
||||||
t->hfsp_leafs[cleaf].nchildren++;
|
if (cret > 0)
|
||||||
|
t->hfsp_leafs[cleaf].nchildren++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -475,7 +482,8 @@ int hfsplus_tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
|||||||
|
|
||||||
t->hfsp_total_blocks = hfsp_curblock - t->hfsp_part_start;
|
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 +
|
||||||
!!(t->hfsp_total_blocks % block_fac),
|
!!(t->hfsp_total_blocks % block_fac),
|
||||||
"HFSPLUS_Hybrid", "Apple_HFS");
|
"HFSPLUS_Hybrid", "Apple_HFS");
|
||||||
@ -1572,7 +1580,7 @@ int mangle_leafs(Ecma119Image *target, int flag)
|
|||||||
int hfsplus_writer_create(Ecma119Image *target)
|
int hfsplus_writer_create(Ecma119Image *target)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer = NULL;
|
||||||
int max_levels;
|
int max_levels;
|
||||||
int level = 0;
|
int level = 0;
|
||||||
IsoNode *pos;
|
IsoNode *pos;
|
||||||
@ -1582,7 +1590,8 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
|
|
||||||
writer = calloc(1, sizeof(IsoImageWriter));
|
writer = calloc(1, sizeof(IsoImageWriter));
|
||||||
if (writer == NULL) {
|
if (writer == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
make_hfsplus_decompose_pages();
|
make_hfsplus_decompose_pages();
|
||||||
@ -1606,10 +1615,8 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
target->hfsp_ndirs = 0;
|
target->hfsp_ndirs = 0;
|
||||||
target->hfsp_cat_id = 16;
|
target->hfsp_cat_id = 16;
|
||||||
ret = hfsplus_count_tree(target, (IsoNode*)target->image->root);
|
ret = hfsplus_count_tree(target, (IsoNode*)target->image->root);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
free((char *) writer);
|
goto ex;
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
|
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
|
||||||
target->hfsp_bless_id[i] = 0;
|
target->hfsp_bless_id[i] = 0;
|
||||||
@ -1619,12 +1626,13 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
|
|
||||||
target->hfsp_leafs = calloc (target->hfsp_nleafs, sizeof (target->hfsp_leafs[0]));
|
target->hfsp_leafs = calloc (target->hfsp_nleafs, sizeof (target->hfsp_leafs[0]));
|
||||||
if (target->hfsp_leafs == NULL) {
|
if (target->hfsp_leafs == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
ret = set_hfsplus_name (target, target->image->volume_id,
|
ret = set_hfsplus_name (target, target->image->volume_id,
|
||||||
&target->hfsp_leafs[target->hfsp_curleaf]);
|
&target->hfsp_leafs[target->hfsp_curleaf]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
target->hfsp_leafs[target->hfsp_curleaf].node = (IsoNode *) target->image->root;
|
target->hfsp_leafs[target->hfsp_curleaf].node = (IsoNode *) target->image->root;
|
||||||
target->hfsp_leafs[target->hfsp_curleaf].used_size = target->hfsp_leafs[target->hfsp_curleaf].strlen * 2 + 8 + 2 + sizeof (struct hfsplus_catfile_common);
|
target->hfsp_leafs[target->hfsp_curleaf].used_size = target->hfsp_leafs[target->hfsp_curleaf].strlen * 2 + 8 + 2 + sizeof (struct hfsplus_catfile_common);
|
||||||
|
|
||||||
@ -1655,10 +1663,13 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
{
|
{
|
||||||
int cret;
|
int cret;
|
||||||
cret = create_tree(target, pos, 2);
|
cret = create_tree(target, pos, 2);
|
||||||
if (cret < 0)
|
if (cret < 0) {
|
||||||
return cret;
|
ret = cret;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
pos = pos->next;
|
pos = pos->next;
|
||||||
target->hfsp_leafs[0].nchildren++;
|
if (cret > 0)
|
||||||
|
target->hfsp_leafs[0].nchildren++;
|
||||||
}
|
}
|
||||||
|
|
||||||
qsort(target->hfsp_leafs, target->hfsp_nleafs,
|
qsort(target->hfsp_leafs, target->hfsp_nleafs,
|
||||||
@ -1666,13 +1677,14 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
|
|
||||||
ret = mangle_leafs(target, 0);
|
ret = mangle_leafs(target, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
|
|
||||||
for (max_levels = 0; target->hfsp_nleafs >> max_levels; max_levels++);
|
for (max_levels = 0; target->hfsp_nleafs >> max_levels; max_levels++);
|
||||||
max_levels += 2;
|
max_levels += 2;
|
||||||
target->hfsp_levels = calloc (max_levels, sizeof (target->hfsp_levels[0]));
|
target->hfsp_levels = calloc (max_levels, sizeof (target->hfsp_levels[0]));
|
||||||
if (target->hfsp_levels == NULL) {
|
if (target->hfsp_levels == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
target->hfsp_nnodes = 1;
|
target->hfsp_nnodes = 1;
|
||||||
@ -1682,9 +1694,10 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
unsigned bytes_rem = cat_node_size - sizeof (struct hfsplus_btnode) - 2;
|
unsigned bytes_rem = cat_node_size - sizeof (struct hfsplus_btnode) - 2;
|
||||||
|
|
||||||
target->hfsp_levels[level].nodes = calloc ((target->hfsp_nleafs + 1), sizeof (target->hfsp_levels[level].nodes[0]));
|
target->hfsp_levels[level].nodes = calloc ((target->hfsp_nleafs + 1), sizeof (target->hfsp_levels[level].nodes[0]));
|
||||||
if (!target->hfsp_levels[level].nodes)
|
if (!target->hfsp_levels[level].nodes) {
|
||||||
return ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
target->hfsp_levels[level].level_size = 0;
|
target->hfsp_levels[level].level_size = 0;
|
||||||
for (i = 0; i < target->hfsp_nleafs; i++)
|
for (i = 0; i < target->hfsp_nleafs; i++)
|
||||||
{
|
{
|
||||||
@ -1739,8 +1752,10 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
level++;
|
level++;
|
||||||
|
|
||||||
target->hfsp_levels[level].nodes = calloc (((last_size + 1) / 2), sizeof (target->hfsp_levels[level].nodes[0]));
|
target->hfsp_levels[level].nodes = calloc (((last_size + 1) / 2), sizeof (target->hfsp_levels[level].nodes[0]));
|
||||||
if (!target->hfsp_levels[level].nodes)
|
if (!target->hfsp_levels[level].nodes) {
|
||||||
return ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
|
||||||
target->hfsp_levels[level].level_size = 0;
|
target->hfsp_levels[level].level_size = 0;
|
||||||
|
|
||||||
@ -1775,16 +1790,21 @@ int hfsplus_writer_create(Ecma119Image *target)
|
|||||||
|
|
||||||
if (target->hfsp_nnodes > (cat_node_size - 0x100) * 8)
|
if (target->hfsp_nnodes > (cat_node_size - 0x100) * 8)
|
||||||
{
|
{
|
||||||
return iso_msg_submit(target->image->id, ISO_MANGLE_TOO_MUCH_FILES, 0,
|
iso_msg_submit(target->image->id, ISO_MANGLE_TOO_MUCH_FILES, 0,
|
||||||
"HFS+ map nodes aren't implemented");
|
"HFS+ map nodes aren't implemented");
|
||||||
|
ret = ISO_MANGLE_TOO_MUCH_FILES;
|
||||||
return ISO_MANGLE_TOO_MUCH_FILES;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add this writer to image */
|
/* add this writer to image */
|
||||||
target->writers[target->nwriters++] = writer;
|
target->writers[target->nwriters++] = writer;
|
||||||
|
writer = NULL;
|
||||||
|
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (writer != NULL)
|
||||||
|
free(writer);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hfsplus_tail_writer_create(Ecma119Image *target)
|
int hfsplus_tail_writer_create(Ecma119Image *target)
|
||||||
@ -1831,7 +1851,7 @@ struct iso_hfsplus_xinfo_data *iso_hfsplus_xinfo_new(int flag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* The iso_node_xinfo_cloner function which gets associated to
|
/* The iso_node_xinfo_cloner function which gets associated to
|
||||||
* iso_hfsplus_xinfo_func by iso_init() resp. iso_init_with_flag() via
|
* iso_hfsplus_xinfo_func by iso_init() or iso_init_with_flag() via
|
||||||
* iso_node_xinfo_make_clonable()
|
* iso_node_xinfo_make_clonable()
|
||||||
*/
|
*/
|
||||||
int iso_hfsplus_xinfo_cloner(void *old_data, void **new_data, int flag)
|
int iso_hfsplus_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||||
|
226
libisofs/image.c
226
libisofs/image.c
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
* Copyright (c) 2009 - 2015 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -22,6 +22,100 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.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.
|
* Create a new image, empty.
|
||||||
*
|
*
|
||||||
@ -86,12 +180,17 @@ int iso_image_new(const char *name, IsoImage **image)
|
|||||||
img->mips_boot_file_paths[i] = NULL;
|
img->mips_boot_file_paths[i] = NULL;
|
||||||
img->sparc_core_node = NULL;
|
img->sparc_core_node = NULL;
|
||||||
img->hppa_cmdline= NULL;
|
img->hppa_cmdline= NULL;
|
||||||
img->hppa_bootloader= NULL;
|
img->hppa_bootloader = NULL;
|
||||||
img->hppa_kernel_32= NULL;
|
img->hppa_kernel_32 = NULL;
|
||||||
img->hppa_kernel_64= NULL;
|
img->hppa_kernel_64 = NULL;
|
||||||
img->hppa_ramdisk= NULL;
|
img->hppa_ramdisk = NULL;
|
||||||
|
img->alpha_boot_image = NULL;
|
||||||
|
img->import_src = NULL;
|
||||||
img->builder_ignore_acl = 1;
|
img->builder_ignore_acl = 1;
|
||||||
img->builder_ignore_ea = 1;
|
img->builder_ignore_ea = 1;
|
||||||
|
img->truncate_mode = 1;
|
||||||
|
img->truncate_length = LIBISOFS_NODE_NAME_MAX;
|
||||||
|
img->truncate_buffer[0] = 0;
|
||||||
img->inode_counter = 0;
|
img->inode_counter = 0;
|
||||||
img->used_inodes = NULL;
|
img->used_inodes = NULL;
|
||||||
img->used_inodes_start = 0;
|
img->used_inodes_start = 0;
|
||||||
@ -103,6 +202,7 @@ int iso_image_new(const char *name, IsoImage **image)
|
|||||||
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
|
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
|
||||||
img->hfsplus_blessed[i] = NULL;
|
img->hfsplus_blessed[i] = NULL;
|
||||||
img->collision_warnings = 0;
|
img->collision_warnings = 0;
|
||||||
|
img->imported_sa_info = NULL;
|
||||||
|
|
||||||
*image = img;
|
*image = img;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -146,13 +246,11 @@ void iso_image_unref(IsoImage *image)
|
|||||||
iso_image_give_up_mips_boot(image, 0);
|
iso_image_give_up_mips_boot(image, 0);
|
||||||
if (image->sparc_core_node != NULL)
|
if (image->sparc_core_node != NULL)
|
||||||
iso_node_unref((IsoNode *) image->sparc_core_node);
|
iso_node_unref((IsoNode *) image->sparc_core_node);
|
||||||
|
|
||||||
#ifdef Libisofs_enable_unreleased_hppa_palO
|
|
||||||
|
|
||||||
iso_image_set_hppa_palo(image, NULL, NULL, NULL, NULL, NULL, 1);
|
iso_image_set_hppa_palo(image, NULL, NULL, NULL, NULL, NULL, 1);
|
||||||
|
if (image->alpha_boot_image != NULL)
|
||||||
#endif
|
free(image->alpha_boot_image);
|
||||||
|
if (image->import_src != NULL)
|
||||||
|
iso_data_source_unref(image->import_src);
|
||||||
free(image->volset_id);
|
free(image->volset_id);
|
||||||
free(image->volume_id);
|
free(image->volume_id);
|
||||||
free(image->publisher_id);
|
free(image->publisher_id);
|
||||||
@ -171,6 +269,7 @@ void iso_image_unref(IsoImage *image)
|
|||||||
if (image->system_area_data != NULL)
|
if (image->system_area_data != NULL)
|
||||||
free(image->system_area_data);
|
free(image->system_area_data);
|
||||||
iso_image_free_checksums(image, 0);
|
iso_image_free_checksums(image, 0);
|
||||||
|
iso_imported_sa_unref(&(image->imported_sa_info), 0);
|
||||||
free(image);
|
free(image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -587,7 +686,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
|
* 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.
|
* 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
|
* After the first rollover it uses a look ahead bitmap which gets filled
|
||||||
@ -597,13 +697,13 @@ ex:;
|
|||||||
* @param image The image where the number shall be used
|
* @param image The image where the number shall be used
|
||||||
* @param flag bit0= reset count (Caution: image must get new inos then)
|
* @param flag bit0= reset count (Caution: image must get new inos then)
|
||||||
* @return
|
* @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.
|
* 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;
|
int ret;
|
||||||
ino_t new_ino, ino_idx;
|
uint64_t new_ino, ino_idx;
|
||||||
static uint64_t limit = 0xffffffff;
|
static uint64_t limit = 0xffffffff;
|
||||||
|
|
||||||
if (flag & 1) {
|
if (flag & 1) {
|
||||||
@ -613,10 +713,10 @@ ino_t img_give_ino_number(IsoImage *image, int flag)
|
|||||||
image->used_inodes = NULL;
|
image->used_inodes = NULL;
|
||||||
image->used_inodes_start = 0;
|
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 (image->used_inodes == NULL) {
|
||||||
if (new_ino > 0 && new_ino <= limit) {
|
if (new_ino > 0 && new_ino <= limit) {
|
||||||
image->inode_counter = new_ino;
|
image->inode_counter = (uint32_t) new_ino;
|
||||||
return image->inode_counter;
|
return image->inode_counter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -881,9 +981,9 @@ int iso_image_get_sparc_core(IsoImage *img, IsoFile **sparc_core, int flag)
|
|||||||
Else only the non-NULL parameters of this call have an effect.
|
Else only the non-NULL parameters of this call have an effect.
|
||||||
*/
|
*/
|
||||||
static int hppa_palo_set_path(IsoImage *img, char *path, char **target,
|
static int hppa_palo_set_path(IsoImage *img, char *path, char **target,
|
||||||
int flag)
|
char *what, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, err;
|
||||||
IsoNode *node;
|
IsoNode *node;
|
||||||
IsoFile *file;
|
IsoFile *file;
|
||||||
|
|
||||||
@ -898,16 +998,19 @@ static int hppa_palo_set_path(IsoImage *img, char *path, char **target,
|
|||||||
return ret;
|
return ret;
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
iso_msg_submit(img->id, ISO_BOOT_FILE_MISSING, 0,
|
iso_msg_submit(img->id, ISO_BOOT_FILE_MISSING, 0,
|
||||||
"Cannot find in ISO image: HP-PA file '%s'", path);
|
"Cannot find in ISO image: %s file '%s'", what, path);
|
||||||
return ISO_BOOT_FILE_MISSING;
|
return ISO_BOOT_FILE_MISSING;
|
||||||
}
|
}
|
||||||
if (iso_node_get_type(node) != LIBISO_FILE) {
|
if (iso_node_get_type(node) != LIBISO_FILE) {
|
||||||
iso_msg_submit(img->id, ISO_HPPA_PALO_NOTREG, 0,
|
err = ISO_HPPA_PALO_NOTREG;
|
||||||
"HP-PA PALO file is not a data file: '%s'", path);
|
if (strncmp(what, "DEC Alpha", 9) == 0)
|
||||||
return ISO_HPPA_PALO_NOTREG;
|
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;
|
file = (IsoFile *) node;
|
||||||
if (!file->explicit_weight)
|
if (!(file->explicit_weight || file->from_old_session))
|
||||||
file->sort_weight = 2;
|
file->sort_weight = 2;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -924,21 +1027,25 @@ int iso_image_set_hppa_palo(IsoImage *img, char *cmdline, char *bootloader,
|
|||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
static char *what = "HP-PA PALO";
|
||||||
|
|
||||||
if (cmdline != NULL || (flag & 1))
|
if (cmdline != NULL || (flag & 1))
|
||||||
if (iso_clone_mgtd_mem(cmdline, &(img->hppa_cmdline), 0) < 0)
|
if (iso_clone_mgtd_mem(cmdline, &(img->hppa_cmdline), 0) < 0)
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
ret = hppa_palo_set_path(img, bootloader, &(img->hppa_bootloader),
|
ret = hppa_palo_set_path(img, bootloader, &(img->hppa_bootloader), what,
|
||||||
flag & 1);
|
flag & 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = hppa_palo_set_path(img, kernel_32, &(img->hppa_kernel_32), flag & 1);
|
ret = hppa_palo_set_path(img, kernel_32, &(img->hppa_kernel_32), what,
|
||||||
|
flag & 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = hppa_palo_set_path(img, kernel_64, &(img->hppa_kernel_64), flag & 1);
|
ret = hppa_palo_set_path(img, kernel_64, &(img->hppa_kernel_64), what,
|
||||||
|
flag & 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = hppa_palo_set_path(img, ramdisk, &(img->hppa_ramdisk), flag & 1);
|
ret = hppa_palo_set_path(img, ramdisk, &(img->hppa_ramdisk), what,
|
||||||
|
flag & 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -958,3 +1065,66 @@ int iso_image_get_hppa_palo(IsoImage *img, char **cmdline, char **bootloader,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_set_truncate_mode(IsoImage *img, int mode, int length)
|
||||||
|
{
|
||||||
|
if (mode < 0 || mode > 1)
|
||||||
|
return ISO_WRONG_ARG_VALUE;
|
||||||
|
if (length < 64 || length > LIBISOFS_NODE_NAME_MAX)
|
||||||
|
return ISO_WRONG_ARG_VALUE;
|
||||||
|
img->truncate_mode = mode;
|
||||||
|
img->truncate_length = length;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_get_truncate_mode(IsoImage *img, int *mode, int *length)
|
||||||
|
{
|
||||||
|
*mode = img->truncate_mode;
|
||||||
|
*length = img->truncate_length;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Warning: Not thread-safe */
|
||||||
|
int iso_image_truncate_name(IsoImage *image, const char *name, char **namept,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (name == NULL)
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
|
||||||
|
if ((int) strlen(name) <= image->truncate_length) {
|
||||||
|
*namept = (char *) name;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
*namept = image->truncate_buffer;
|
||||||
|
if (name != image->truncate_buffer)
|
||||||
|
strncpy(image->truncate_buffer, name, 4095);
|
||||||
|
image->truncate_buffer[4095] = 0;
|
||||||
|
ret = iso_truncate_rr_name(image->truncate_mode, image->truncate_length,
|
||||||
|
image->truncate_buffer, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
184
libisofs/image.h
184
libisofs/image.h
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
* Copyright (c) 2009 - 2015 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -64,6 +64,8 @@ struct Iso_Image
|
|||||||
/* Eventually loaded system area data, or NULL */
|
/* Eventually loaded system area data, or NULL */
|
||||||
char *system_area_data;
|
char *system_area_data;
|
||||||
/* Prescribed/detected options, see iso_write_opts_set_system_area() */
|
/* 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;
|
int system_area_options;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -88,6 +90,9 @@ struct Iso_Image
|
|||||||
char *hppa_kernel_64;
|
char *hppa_kernel_64;
|
||||||
char *hppa_ramdisk;
|
char *hppa_ramdisk;
|
||||||
|
|
||||||
|
/* Absolute DEC Alpha boot image path in the ISO image */
|
||||||
|
char *alpha_boot_image;
|
||||||
|
|
||||||
/* image identifier, for message origin identifier */
|
/* image identifier, for message origin identifier */
|
||||||
int id;
|
int id;
|
||||||
|
|
||||||
@ -96,6 +101,11 @@ struct Iso_Image
|
|||||||
*/
|
*/
|
||||||
IsoFilesystem *fs;
|
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.
|
* Default builder to use when adding files to the image tree.
|
||||||
*/
|
*/
|
||||||
@ -150,6 +160,20 @@ struct Iso_Image
|
|||||||
/* TODO
|
/* TODO
|
||||||
enum iso_replace_mode (*confirm_replace)(IsoFileSource *src, IsoNode *node);
|
enum iso_replace_mode (*confirm_replace)(IsoFileSource *src, IsoNode *node);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What to do in case of name longer than truncate_length:
|
||||||
|
* 0= throw FAILURE
|
||||||
|
* 1= truncate to truncate_length with MD5 of whole name at end
|
||||||
|
*/
|
||||||
|
int truncate_mode;
|
||||||
|
int truncate_length;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a convenience buffer for name truncation during image
|
||||||
|
* manipulation where libisofs is not thread-safe anyway.
|
||||||
|
*/
|
||||||
|
char truncate_buffer[4096];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When this is not NULL, it is a pointer to a function that will
|
* When this is not NULL, it is a pointer to a function that will
|
||||||
@ -171,18 +195,20 @@ struct Iso_Image
|
|||||||
* Inode number management. inode_counter is taken over from
|
* Inode number management. inode_counter is taken over from
|
||||||
* IsoImageFilesystem._ImageFsData after image import.
|
* IsoImageFilesystem._ImageFsData after image import.
|
||||||
* It is to be used with img_give_ino_number()
|
* It is to be used with img_give_ino_number()
|
||||||
*/
|
* This is a Rock Ridge file serial number. Thus 32 bit.
|
||||||
ino_t inode_counter;
|
*/
|
||||||
|
uint32_t inode_counter;
|
||||||
/*
|
/*
|
||||||
* A bitmap of used inode numbers in an interval beginning at
|
* A bitmap of used inode numbers in an interval beginning at
|
||||||
* used_inodes_start and holding ISO_USED_INODE_RANGE bits.
|
* used_inodes_start and holding ISO_USED_INODE_RANGE bits.
|
||||||
* If a bit is set, then the corresponding inode number is occupied.
|
* If a bit is set, then the corresponding inode number is occupied.
|
||||||
* This interval is kept around inode_counter and eventually gets
|
* This interval is kept around inode_counter and eventually gets
|
||||||
* advanced by ISO_USED_INODE_RANGE numbers in a tree traversal
|
* 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;
|
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
|
* Array of MD5 checksums as announced by xattr "isofs.ca" of the
|
||||||
@ -212,9 +238,20 @@ struct Iso_Image
|
|||||||
/* Counts the name collisions while iso_image_import() */
|
/* Counts the name collisions while iso_image_import() */
|
||||||
size_t collision_warnings;
|
size_t collision_warnings;
|
||||||
|
|
||||||
|
/* Contains the assessment of boot aspects of the loaded image */
|
||||||
|
struct iso_imported_sys_area *imported_sa_info;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Apply truncation mode to name, using image->truncate_buffer to perform
|
||||||
|
truncation if needed.
|
||||||
|
|
||||||
|
Warning: Not thread-safe !
|
||||||
|
*/
|
||||||
|
int iso_image_truncate_name(IsoImage *image, const char *name, char **namept,
|
||||||
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
/* Collect the bitmap of used inode numbers in the range of
|
/* Collect the bitmap of used inode numbers in the range of
|
||||||
_ImageFsData.used_inodes_start + ISO_USED_INODE_RANGE
|
_ImageFsData.used_inodes_start + ISO_USED_INODE_RANGE
|
||||||
@ -233,10 +270,10 @@ int img_collect_inos(IsoImage *image, IsoDir *dir, int flag);
|
|||||||
* @param image The image where the number shall be used
|
* @param image The image where the number shall be used
|
||||||
* @param flag bit0= reset count (Caution: image must get new inos then)
|
* @param flag bit0= reset count (Caution: image must get new inos then)
|
||||||
* @return
|
* @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.
|
* 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
|
/* @param flag bit0= overwrite any ino, else only ino == 0
|
||||||
bit1= install inode with non-data, non-directory files
|
bit1= install inode with non-data, non-directory files
|
||||||
@ -263,4 +300,137 @@ int iso_image_set_pvd_times(IsoImage *image,
|
|||||||
char *creation_time, char *modification_time,
|
char *creation_time, char *modification_time,
|
||||||
char *expiration_time, char *effective_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_*/
|
#endif /*LIBISO_IMAGE_H_*/
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* 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
|
* 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
|
* 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++) {
|
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||||
iso1999_node_free(node->info.dir->children[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);
|
free(node->info.dir);
|
||||||
}
|
}
|
||||||
iso_node_unref(node->node);
|
iso_node_unref(node->node);
|
||||||
@ -111,11 +112,14 @@ int create_node(Ecma119Image *t, IsoNode *iso, Iso1999Node **node)
|
|||||||
free(n);
|
free(n);
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
n->info.dir->children = calloc(sizeof(void*), dir->nchildren);
|
n->info.dir->children = NULL;
|
||||||
if (n->info.dir->children == NULL) {
|
if (dir->nchildren > 0) {
|
||||||
free(n->info.dir);
|
n->info.dir->children = calloc(sizeof(void*), dir->nchildren);
|
||||||
free(n);
|
if (n->info.dir->children == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
free(n->info.dir);
|
||||||
|
free(n);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
n->type = ISO1999_DIR;
|
n->type = ISO1999_DIR;
|
||||||
} else if (iso->type == LIBISO_FILE) {
|
} else if (iso->type == LIBISO_FILE) {
|
||||||
@ -293,6 +297,8 @@ void sort_tree(Iso1999Node *root)
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
if (root->info.dir->children == NULL)
|
||||||
|
return;
|
||||||
qsort(root->info.dir->children, root->info.dir->nchildren,
|
qsort(root->info.dir->children, root->info.dir->nchildren,
|
||||||
sizeof(void*), cmp_node);
|
sizeof(void*), cmp_node);
|
||||||
for (i = 0; i < root->info.dir->nchildren; i++) {
|
for (i = 0; i < root->info.dir->nchildren; i++) {
|
||||||
@ -312,10 +318,14 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
|||||||
int need_sort = 0;
|
int need_sort = 0;
|
||||||
char *full_name = NULL, *tmp = NULL;
|
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(full_name, char, 208);
|
||||||
LIBISO_ALLOC_MEM(tmp, 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 */
|
/* a hash table will temporary hold the names, for fast searching */
|
||||||
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* 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
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -126,7 +126,8 @@ void joliet_node_free(JolietNode *node)
|
|||||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||||
joliet_node_free(node->info.dir->children[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);
|
free(node->info.dir);
|
||||||
}
|
}
|
||||||
iso_node_unref(node->node);
|
iso_node_unref(node->node);
|
||||||
@ -157,11 +158,14 @@ int create_node(Ecma119Image *t, IsoNode *iso, JolietNode **node)
|
|||||||
free(joliet);
|
free(joliet);
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
joliet->info.dir->children = calloc(sizeof(void*), dir->nchildren);
|
joliet->info.dir->children = NULL;
|
||||||
if (joliet->info.dir->children == NULL) {
|
if (dir->nchildren > 0) {
|
||||||
free(joliet->info.dir);
|
joliet->info.dir->children = calloc(sizeof(void*), dir->nchildren);
|
||||||
free(joliet);
|
if (joliet->info.dir->children == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
free(joliet->info.dir);
|
||||||
|
free(joliet);
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
joliet->type = JOLIET_DIR;
|
joliet->type = JOLIET_DIR;
|
||||||
} else if (iso->type == LIBISO_FILE) {
|
} else if (iso->type == LIBISO_FILE) {
|
||||||
@ -333,6 +337,8 @@ void sort_tree(JolietNode *root)
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
|
if (root->info.dir->children == NULL)
|
||||||
|
return;
|
||||||
qsort(root->info.dir->children, root->info.dir->nchildren,
|
qsort(root->info.dir->children, root->info.dir->nchildren,
|
||||||
sizeof(void*), cmp_node);
|
sizeof(void*), cmp_node);
|
||||||
for (i = 0; i < root->info.dir->nchildren; i++) {
|
for (i = 0; i < root->info.dir->nchildren; i++) {
|
||||||
@ -406,10 +412,14 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
|||||||
uint16_t *full_name = NULL;
|
uint16_t *full_name = NULL;
|
||||||
uint16_t *tmp = 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(full_name, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||||
LIBISO_ALLOC_MEM(tmp, 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->opts->joliet_long_names)
|
if (t->opts->joliet_long_names)
|
||||||
maxchar = 103;
|
maxchar = 103;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
|
/* libiso_msgs (generated from libdax_msgs : Fri Feb 22 19:42:52 CET 2008)
|
||||||
Message handling facility of libisofs.
|
Message handling facility of libisofs.
|
||||||
Copyright (C) 2006 - 2008 Thomas Schmitt <scdbackup@gmx.net>,
|
Copyright (C) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>,
|
||||||
provided under GPL version 2 or later
|
provided under GPL version 2 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -33,14 +33,13 @@ static int libiso_msgs_item_new(struct libiso_msgs_item **item,
|
|||||||
int ret;
|
int ret;
|
||||||
struct libiso_msgs_item *o;
|
struct libiso_msgs_item *o;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
|
||||||
|
|
||||||
(*item)= o=
|
(*item)= o=
|
||||||
(struct libiso_msgs_item *) malloc(sizeof(struct libiso_msgs_item));
|
(struct libiso_msgs_item *) malloc(sizeof(struct libiso_msgs_item));
|
||||||
if(o==NULL)
|
if(o==NULL)
|
||||||
return(-1);
|
return(-1);
|
||||||
o->timestamp= 0.0;
|
o->timestamp= 0.0;
|
||||||
ret= gettimeofday(&tv,&tz);
|
ret= gettimeofday(&tv, NULL);
|
||||||
if(ret==0)
|
if(ret==0)
|
||||||
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
|
o->timestamp= tv.tv_sec+0.000001*tv.tv_usec;
|
||||||
o->process_id= getpid();
|
o->process_id= getpid();
|
||||||
|
@ -221,7 +221,7 @@ struct libiso_msgs_item;
|
|||||||
*/
|
*/
|
||||||
#define LIBISO_MSGS_SEV_ABORT 0x71000000
|
#define LIBISO_MSGS_SEV_ABORT 0x71000000
|
||||||
|
|
||||||
/** A severity to exclude resp. discard any possible message.
|
/** A severity to exclude or discard any possible message.
|
||||||
Do not use this severity for submitting.
|
Do not use this severity for submitting.
|
||||||
*/
|
*/
|
||||||
#define LIBISO_MSGS_SEV_NEVER 0x7fffffff
|
#define LIBISO_MSGS_SEV_NEVER 0x7fffffff
|
||||||
@ -510,7 +510,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
|||||||
0x00020148 (SORRY,HIGH) = Cannot write desired amount of data
|
0x00020148 (SORRY,HIGH) = Cannot write desired amount of data
|
||||||
0x00020149 (SORRY,HIGH) = Unsuitable filetype for pseudo-drive
|
0x00020149 (SORRY,HIGH) = Unsuitable filetype for pseudo-drive
|
||||||
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
|
0x0002014a (SORRY,HIGH) = Cannot read desired amount of data
|
||||||
0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned
|
0x0002014b (SORRY,HIGH) = Drive is already registered and scanned
|
||||||
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
|
0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function
|
||||||
0x0002014d (SORRY,HIGH) = Asynchromous SCSI error
|
0x0002014d (SORRY,HIGH) = Asynchromous SCSI error
|
||||||
0x0002014f (SORRY,HIGH) = Timeout with asynchromous SCSI command
|
0x0002014f (SORRY,HIGH) = Timeout with asynchromous SCSI command
|
||||||
|
1317
libisofs/libisofs.h
1317
libisofs/libisofs.h
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,7 @@ el_torito_set_load_size;
|
|||||||
el_torito_set_no_bootable;
|
el_torito_set_no_bootable;
|
||||||
el_torito_set_selection_crit;
|
el_torito_set_selection_crit;
|
||||||
iso_conv_name_chars;
|
iso_conv_name_chars;
|
||||||
|
iso_crc32_gpt;
|
||||||
iso_data_source_new_from_file;
|
iso_data_source_new_from_file;
|
||||||
iso_data_source_ref;
|
iso_data_source_ref;
|
||||||
iso_data_source_unref;
|
iso_data_source_unref;
|
||||||
@ -74,6 +75,10 @@ iso_hfsplus_xinfo_func;
|
|||||||
iso_hfsplus_xinfo_new;
|
iso_hfsplus_xinfo_new;
|
||||||
iso_image_add_boot_image;
|
iso_image_add_boot_image;
|
||||||
iso_image_add_mips_boot_file;
|
iso_image_add_mips_boot_file;
|
||||||
|
iso_image_add_new_dir;
|
||||||
|
iso_image_add_new_file;
|
||||||
|
iso_image_add_new_special;
|
||||||
|
iso_image_add_new_symlink;
|
||||||
iso_image_attach_data;
|
iso_image_attach_data;
|
||||||
iso_image_create_burn_source;
|
iso_image_create_burn_source;
|
||||||
iso_image_filesystem_new;
|
iso_image_filesystem_new;
|
||||||
@ -89,6 +94,7 @@ iso_image_fs_get_volume_id;
|
|||||||
iso_image_generator_is_running;
|
iso_image_generator_is_running;
|
||||||
iso_image_get_abstract_file_id;
|
iso_image_get_abstract_file_id;
|
||||||
iso_image_get_all_boot_imgs;
|
iso_image_get_all_boot_imgs;
|
||||||
|
iso_image_get_alpha_boot;
|
||||||
iso_image_get_app_use;
|
iso_image_get_app_use;
|
||||||
iso_image_get_application_id;
|
iso_image_get_application_id;
|
||||||
iso_image_get_attached_data;
|
iso_image_get_attached_data;
|
||||||
@ -97,6 +103,8 @@ iso_image_get_bootcat;
|
|||||||
iso_image_get_boot_image;
|
iso_image_get_boot_image;
|
||||||
iso_image_get_copyright_file_id;
|
iso_image_get_copyright_file_id;
|
||||||
iso_image_get_data_preparer_id;
|
iso_image_get_data_preparer_id;
|
||||||
|
iso_image_dir_get_node;
|
||||||
|
iso_image_get_hppa_palo;
|
||||||
iso_image_get_mips_boot_files;
|
iso_image_get_mips_boot_files;
|
||||||
iso_image_get_msg_id;
|
iso_image_get_msg_id;
|
||||||
iso_image_get_publisher_id;
|
iso_image_get_publisher_id;
|
||||||
@ -106,6 +114,7 @@ iso_image_get_session_md5;
|
|||||||
iso_image_get_sparc_core;
|
iso_image_get_sparc_core;
|
||||||
iso_image_get_system_area;
|
iso_image_get_system_area;
|
||||||
iso_image_get_system_id;
|
iso_image_get_system_id;
|
||||||
|
iso_image_get_truncate_mode;
|
||||||
iso_image_get_volset_id;
|
iso_image_get_volset_id;
|
||||||
iso_image_get_volume_id;
|
iso_image_get_volume_id;
|
||||||
iso_image_give_up_mips_boot;
|
iso_image_give_up_mips_boot;
|
||||||
@ -113,9 +122,13 @@ iso_image_hfsplus_bless;
|
|||||||
iso_image_hfsplus_get_blessed;
|
iso_image_hfsplus_get_blessed;
|
||||||
iso_image_import;
|
iso_image_import;
|
||||||
iso_image_new;
|
iso_image_new;
|
||||||
|
iso_image_path_to_node;
|
||||||
iso_image_ref;
|
iso_image_ref;
|
||||||
iso_image_remove_boot_image;
|
iso_image_remove_boot_image;
|
||||||
|
iso_image_report_el_torito;
|
||||||
|
iso_image_report_system_area;
|
||||||
iso_image_set_abstract_file_id;
|
iso_image_set_abstract_file_id;
|
||||||
|
iso_image_set_alpha_boot;
|
||||||
iso_image_set_app_use;
|
iso_image_set_app_use;
|
||||||
iso_image_set_application_id;
|
iso_image_set_application_id;
|
||||||
iso_image_set_biblio_file_id;
|
iso_image_set_biblio_file_id;
|
||||||
@ -124,16 +137,23 @@ iso_image_set_boot_catalog_weight;
|
|||||||
iso_image_set_boot_image;
|
iso_image_set_boot_image;
|
||||||
iso_image_set_copyright_file_id;
|
iso_image_set_copyright_file_id;
|
||||||
iso_image_set_data_preparer_id;
|
iso_image_set_data_preparer_id;
|
||||||
|
iso_image_set_hppa_palo;
|
||||||
iso_image_set_ignore_aclea;
|
iso_image_set_ignore_aclea;
|
||||||
|
iso_image_set_node_name;
|
||||||
iso_image_set_publisher_id;
|
iso_image_set_publisher_id;
|
||||||
iso_image_set_sparc_core;
|
iso_image_set_sparc_core;
|
||||||
iso_image_set_system_id;
|
iso_image_set_system_id;
|
||||||
|
iso_image_set_truncate_mode;
|
||||||
iso_image_set_volset_id;
|
iso_image_set_volset_id;
|
||||||
iso_image_set_volume_id;
|
iso_image_set_volume_id;
|
||||||
|
iso_image_tree_clone;
|
||||||
iso_image_unref;
|
iso_image_unref;
|
||||||
iso_image_update_sizes;
|
iso_image_update_sizes;
|
||||||
iso_init;
|
iso_init;
|
||||||
iso_init_with_flag;
|
iso_init_with_flag;
|
||||||
|
iso_interval_reader_destroy;
|
||||||
|
iso_interval_reader_new;
|
||||||
|
iso_interval_reader_read;
|
||||||
iso_lib_is_compatible;
|
iso_lib_is_compatible;
|
||||||
iso_lib_version;
|
iso_lib_version;
|
||||||
iso_local_attr_support;
|
iso_local_attr_support;
|
||||||
@ -209,11 +229,13 @@ iso_read_image_features_has_joliet;
|
|||||||
iso_read_image_features_has_rockridge;
|
iso_read_image_features_has_rockridge;
|
||||||
iso_read_opts_auto_input_charset;
|
iso_read_opts_auto_input_charset;
|
||||||
iso_read_opts_free;
|
iso_read_opts_free;
|
||||||
|
iso_read_opts_keep_import_src;
|
||||||
iso_read_opts_load_system_area;
|
iso_read_opts_load_system_area;
|
||||||
iso_read_opts_new;
|
iso_read_opts_new;
|
||||||
iso_read_opts_set_default_gid;
|
iso_read_opts_set_default_gid;
|
||||||
iso_read_opts_set_default_permissions;
|
iso_read_opts_set_default_permissions;
|
||||||
iso_read_opts_set_default_uid;
|
iso_read_opts_set_default_uid;
|
||||||
|
iso_read_opts_set_ecma119_map;
|
||||||
iso_read_opts_set_input_charset;
|
iso_read_opts_set_input_charset;
|
||||||
iso_read_opts_set_new_inos;
|
iso_read_opts_set_new_inos;
|
||||||
iso_read_opts_set_no_aaip;
|
iso_read_opts_set_no_aaip;
|
||||||
@ -269,6 +291,7 @@ iso_tree_set_ignore_hidden;
|
|||||||
iso_tree_set_ignore_special;
|
iso_tree_set_ignore_special;
|
||||||
iso_tree_set_replace_mode;
|
iso_tree_set_replace_mode;
|
||||||
iso_tree_set_report_callback;
|
iso_tree_set_report_callback;
|
||||||
|
iso_truncate_leaf_name;
|
||||||
iso_util_decode_md5_tag;
|
iso_util_decode_md5_tag;
|
||||||
iso_write_opts_attach_jte;
|
iso_write_opts_attach_jte;
|
||||||
iso_write_opts_detach_jte;
|
iso_write_opts_detach_jte;
|
||||||
@ -285,6 +308,8 @@ iso_write_opts_set_allow_longer_paths;
|
|||||||
iso_write_opts_set_allow_lowercase;
|
iso_write_opts_set_allow_lowercase;
|
||||||
iso_write_opts_set_always_gmt;
|
iso_write_opts_set_always_gmt;
|
||||||
iso_write_opts_set_appendable;
|
iso_write_opts_set_appendable;
|
||||||
|
iso_write_opts_set_appended_as_apm;
|
||||||
|
iso_write_opts_set_appended_as_gpt;
|
||||||
iso_write_opts_set_default_dir_mode;
|
iso_write_opts_set_default_dir_mode;
|
||||||
iso_write_opts_set_default_file_mode;
|
iso_write_opts_set_default_file_mode;
|
||||||
iso_write_opts_set_default_gid;
|
iso_write_opts_set_default_gid;
|
||||||
@ -313,6 +338,7 @@ iso_write_opts_set_omit_version_numbers;
|
|||||||
iso_write_opts_set_output_charset;
|
iso_write_opts_set_output_charset;
|
||||||
iso_write_opts_set_overwrite_buf;
|
iso_write_opts_set_overwrite_buf;
|
||||||
iso_write_opts_set_part_offset;
|
iso_write_opts_set_part_offset;
|
||||||
|
iso_write_opts_set_part_like_isohybrid;
|
||||||
iso_write_opts_set_partition_img;
|
iso_write_opts_set_partition_img;
|
||||||
iso_write_opts_set_prep_img;
|
iso_write_opts_set_prep_img;
|
||||||
iso_write_opts_set_pvd_times;
|
iso_write_opts_set_pvd_times;
|
||||||
|
@ -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
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
@ -27,6 +37,8 @@
|
|||||||
#include "ecma119.h"
|
#include "ecma119.h"
|
||||||
#include "eltorito.h"
|
#include "eltorito.h"
|
||||||
#include "system_area.h"
|
#include "system_area.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "messages.h"
|
||||||
|
|
||||||
|
|
||||||
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
|
/* This code stems from syslinux-3.72/utils/isohybrid, a perl script
|
||||||
@ -50,7 +62,7 @@ license from above stem licenses, typically from LGPL.
|
|||||||
In case its generosity is needed, here is the 2-clause BSD license:
|
In case its generosity is needed, here is the 2-clause BSD license:
|
||||||
|
|
||||||
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
|
make_isohybrid_mbr.c is copyright 2002-2008 H. Peter Anvin
|
||||||
and 2008-2012 Thomas Schmitt
|
and 2008-2015 Thomas Schmitt
|
||||||
|
|
||||||
1. Redistributions of source code must retain the above copyright notice,
|
1. Redistributions of source code must retain the above copyright notice,
|
||||||
this list of conditions and the following disclaimer.
|
this list of conditions and the following disclaimer.
|
||||||
@ -146,7 +158,6 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
|
|||||||
|
|
||||||
/* For generating a weak random number */
|
/* For generating a weak random number */
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
|
||||||
|
|
||||||
if (bin_lba < 0 || bin_lba >= (1 << 29))
|
if (bin_lba < 0 || bin_lba >= (1 << 29))
|
||||||
return (0); /* 1 TB limit of signed 32 bit addressing of 512 byte blocks */
|
return (0); /* 1 TB limit of signed 32 bit addressing of 512 byte blocks */
|
||||||
@ -201,7 +212,7 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
|
|||||||
from. An environment variable ?
|
from. An environment variable ?
|
||||||
125: Whatever, i use some 32-bit random value with no crypto strength.
|
125: Whatever, i use some 32-bit random value with no crypto strength.
|
||||||
*/
|
*/
|
||||||
gettimeofday(&tv, &tz);
|
gettimeofday(&tv, NULL);
|
||||||
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -390,12 +401,15 @@ int lba512chs_to_buf(char **wpt, off_t lba, int head_count, int sector_count)
|
|||||||
|
|
||||||
/* Find out whether GPT and APM are desired
|
/* Find out whether GPT and APM are desired
|
||||||
flag bit0 = register APM and GPT requests in Ecma119Image
|
flag bit0 = register APM and GPT requests in Ecma119Image
|
||||||
|
bit1 = do not asses and register APM
|
||||||
|
bit2 = do not register overall GPT partition
|
||||||
*/
|
*/
|
||||||
int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
||||||
int *apm_count, int flag)
|
int *apm_count, int flag)
|
||||||
{
|
{
|
||||||
int i, ilx_opts, j, ret, num_img;
|
int i, ilx_opts, j, ret, num_img;
|
||||||
uint32_t block_count;
|
uint32_t block_count;
|
||||||
|
uint64_t start_block;
|
||||||
uint8_t gpt_name[72];
|
uint8_t gpt_name[72];
|
||||||
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
static uint8_t zero_uuid[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||||
static uint8_t basic_data_uuid[16] = {
|
static uint8_t basic_data_uuid[16] = {
|
||||||
@ -418,11 +432,13 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
|||||||
num_img = 0;
|
num_img = 0;
|
||||||
for (i = 0; i < num_img; i++) {
|
for (i = 0; i < num_img; i++) {
|
||||||
ilx_opts = t->catalog->bootimages[i]->isolinux_options;
|
ilx_opts = t->catalog->bootimages[i]->isolinux_options;
|
||||||
if (((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) {
|
if ((((ilx_opts >> 2) & 63) == 1 || ((ilx_opts >> 2) & 63) == 2) &&
|
||||||
|
!(t->boot_appended_idx[i] >= 0 && t->opts->appended_as_gpt)) {
|
||||||
if (*gpt_count < 128)
|
if (*gpt_count < 128)
|
||||||
gpt_idx[*gpt_count]= i;
|
gpt_idx[*gpt_count] = i;
|
||||||
(*gpt_count)++;
|
(*gpt_count)++;
|
||||||
if ((flag & 1) && t->bootsrc[i] != NULL) {
|
if ((flag & 1) &&
|
||||||
|
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
|
||||||
/* Register GPT entry */
|
/* Register GPT entry */
|
||||||
memset(gpt_name, 0, 72);
|
memset(gpt_name, 0, 72);
|
||||||
sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count);
|
sprintf((char *) gpt_name, "ISOHybrid%d", *gpt_count);
|
||||||
@ -431,25 +447,44 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
|||||||
uuid = hfs_uuid;
|
uuid = hfs_uuid;
|
||||||
else
|
else
|
||||||
uuid = basic_data_uuid;
|
uuid = basic_data_uuid;
|
||||||
block_count = 0;
|
if (t->boot_appended_idx[i] >= 0) {
|
||||||
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
block_count = t->appended_part_size[
|
||||||
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
t->boot_appended_idx[i]];
|
||||||
|
start_block = ((uint64_t) t->appended_part_start[
|
||||||
|
t->boot_appended_idx[i]]) * 4;
|
||||||
|
} else {
|
||||||
|
block_count = 0;
|
||||||
|
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
||||||
|
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
||||||
|
start_block = ((uint64_t) t->bootsrc[i]->sections[0].block)
|
||||||
|
* 4;
|
||||||
|
}
|
||||||
ret = iso_quick_gpt_entry(
|
ret = iso_quick_gpt_entry(
|
||||||
t, t->bootsrc[i]->sections[0].block,
|
t->gpt_req, &(t->gpt_req_count),
|
||||||
block_count, uuid, zero_uuid, gpt_flags,
|
start_block, ((uint64_t) block_count) * 4,
|
||||||
(uint8_t *) gpt_name);
|
uuid, zero_uuid, gpt_flags, (uint8_t *) gpt_name);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ilx_opts & 256) {
|
if ((ilx_opts & 256) && !(flag & 2)) {
|
||||||
(*apm_count)++;
|
(*apm_count)++;
|
||||||
if ((flag & 1) && t->bootsrc[i] != NULL) {
|
if ((flag & 1) &&
|
||||||
|
(t->bootsrc[i] != NULL || t->boot_appended_idx[i] >= 0)) {
|
||||||
/* Register APM entry */
|
/* Register APM entry */
|
||||||
block_count = 0;
|
if (t->boot_appended_idx[i] >= 0) {
|
||||||
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
block_count = t->appended_part_size[
|
||||||
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
t->boot_appended_idx[i]];
|
||||||
ret = iso_quick_apm_entry(t, t->bootsrc[i]->sections[0].block,
|
start_block = t->appended_part_start[
|
||||||
|
t->boot_appended_idx[i]];
|
||||||
|
} else {
|
||||||
|
block_count = 0;
|
||||||
|
for (j = 0; j < t->bootsrc[i]->nsections; j++)
|
||||||
|
block_count += t->bootsrc[i]->sections[j].size / 2048;
|
||||||
|
start_block = t->bootsrc[i]->sections[0].block;
|
||||||
|
}
|
||||||
|
ret = iso_quick_apm_entry(t->apm_req, &(t->apm_req_count),
|
||||||
|
(uint32_t) start_block,
|
||||||
block_count, "EFI", "Apple_HFS");
|
block_count, "EFI", "Apple_HFS");
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -459,14 +494,21 @@ int assess_isohybrid_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((flag & 1) && *gpt_count > 0) {
|
if (*gpt_count > 0 && !(flag & 4)) {
|
||||||
|
(*gpt_count)++;
|
||||||
|
if (*gpt_count < 128)
|
||||||
|
gpt_idx[*gpt_count] = -1;
|
||||||
|
}
|
||||||
|
if ((flag & 1) && *gpt_count > 0 && !(flag & 4)) {
|
||||||
/* Register overall GPT partition */
|
/* Register overall GPT partition */
|
||||||
memset(gpt_name, 0, 72);
|
memset(gpt_name, 0, 72);
|
||||||
sprintf((char *) gpt_name, "ISOHybrid");
|
sprintf((char *) gpt_name, "ISOHybrid");
|
||||||
iso_ascii_utf_16le(gpt_name);
|
iso_ascii_utf_16le(gpt_name);
|
||||||
/* Let it be open ended. iso_write_gpt() will truncate it as needed. */
|
/* Let it be open ended. iso_write_gpt() will truncate it as needed. */
|
||||||
block_count = 0xffffffff;
|
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,
|
basic_data_uuid, zero_uuid, gpt_flags,
|
||||||
(uint8_t *) gpt_name);
|
(uint8_t *) gpt_name);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -522,19 +564,28 @@ static int insert_apm_head(uint8_t *buf, int apm_count)
|
|||||||
static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
|
static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
|
||||||
int gpt_idx[128], int *gpt_cursor)
|
int gpt_idx[128], int *gpt_cursor)
|
||||||
{
|
{
|
||||||
int ilx_opts;
|
int ilx_opts, skip = 0;
|
||||||
off_t hd_blocks;
|
off_t hd_blocks;
|
||||||
static uint8_t dummy_chs[3] = {
|
static uint8_t dummy_chs[3] = {
|
||||||
0xfe, 0xff, 0xff,
|
0xfe, 0xff, 0xff,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (gpt_idx[*gpt_cursor] < 0)
|
||||||
|
skip = 1;
|
||||||
|
else if (t->bootsrc[gpt_idx[*gpt_cursor]] == NULL)
|
||||||
|
skip = 1;
|
||||||
|
if (skip) {
|
||||||
|
(*gpt_cursor)++;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
wpt[0] = 0;
|
wpt[0] = 0;
|
||||||
memcpy(wpt + 1, dummy_chs, 3);
|
memcpy(wpt + 1, dummy_chs, 3);
|
||||||
ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options;
|
ilx_opts = t->catalog->bootimages[gpt_idx[*gpt_cursor]]->isolinux_options;
|
||||||
if (((ilx_opts >> 2) & 63) == 2)
|
if (((ilx_opts >> 2) & 63) == 2)
|
||||||
wpt[4] = 0x00; /* HFS gets marked as "Empty" */
|
wpt[4] = 0x00; /* HFS gets marked as "Empty" */
|
||||||
else
|
else
|
||||||
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16/" */
|
((unsigned char *) wpt)[4] = 0xef; /* "EFI (FAT-12/16)" */
|
||||||
|
|
||||||
memcpy(wpt + 5, dummy_chs, 3);
|
memcpy(wpt + 5, dummy_chs, 3);
|
||||||
|
|
||||||
@ -555,8 +606,9 @@ static int gpt_images_as_mbr_partitions(Ecma119Image *t, char *wpt,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* @param flag bit0= make own random MBR Id from current time
|
* @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,
|
int part_offset, int part_number, int fs_type,
|
||||||
uint8_t *buf, int flag)
|
uint8_t *buf, int flag)
|
||||||
{
|
{
|
||||||
@ -565,12 +617,24 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
|
|||||||
char *wpt;
|
char *wpt;
|
||||||
uint32_t boot_lba;
|
uint32_t boot_lba;
|
||||||
int head_count, sector_count, ret;
|
int head_count, sector_count, ret;
|
||||||
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor;
|
int gpt_count = 0, gpt_idx[128], apm_count = 0, gpt_cursor, i;
|
||||||
/* For generating a weak random number */
|
/* For generating a weak random number */
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct timezone tz;
|
|
||||||
|
|
||||||
hd_img_blocks = ((off_t) *img_blocks) * (off_t) 4;
|
if (t->bootsrc[0] == NULL)
|
||||||
|
return iso_msg_submit(t->image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||||
|
"Cannot refer by isohybrid MBR to data outside of ISO 9660 filesystem.");
|
||||||
|
|
||||||
|
for (i = 0; i < 128; i++)
|
||||||
|
gpt_idx[i] = -1;
|
||||||
|
|
||||||
|
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;
|
boot_lba = t->bootsrc[0]->sections[0].block;
|
||||||
head_count = t->partition_heads_per_cyl;
|
head_count = t->partition_heads_per_cyl;
|
||||||
@ -604,7 +668,7 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
|
|||||||
(here some 32-bit random value with no crypto strength)
|
(here some 32-bit random value with no crypto strength)
|
||||||
*/
|
*/
|
||||||
if (flag & 1) {
|
if (flag & 1) {
|
||||||
gettimeofday(&tv, &tz);
|
gettimeofday(&tv, NULL);
|
||||||
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
id = 0xffffffff & (tv.tv_sec ^ (tv.tv_usec * 2000));
|
||||||
lsb_to_buf(&wpt, id, 32, 0);
|
lsb_to_buf(&wpt, id, 32, 0);
|
||||||
} else {
|
} else {
|
||||||
@ -635,14 +699,17 @@ int make_isolinux_mbr(int32_t *img_blocks, Ecma119Image *t,
|
|||||||
wpt+= 16;
|
wpt+= 16;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* write byte 0x80
|
/* write byte 0x80 if bootable
|
||||||
write LBA_to_CHS(partition_offset)
|
write LBA_to_CHS(partition_offset)
|
||||||
write byte filesystem_type
|
write byte filesystem_type
|
||||||
write LBA_to_CHS(image_size-1)
|
write LBA_to_CHS(image_size-1)
|
||||||
write dword partition_offset
|
write dword partition_offset
|
||||||
write dword image_size
|
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);
|
lba512chs_to_buf(&wpt, part_offset, head_count, sector_count);
|
||||||
lsb_to_buf(&wpt, fs_type, 8, 0);
|
lsb_to_buf(&wpt, fs_type, 8, 0);
|
||||||
lba512chs_to_buf(&wpt, hd_img_blocks - 1, head_count, sector_count);
|
lba512chs_to_buf(&wpt, hd_img_blocks - 1, head_count, sector_count);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
* Copyright (c) 2009 - 2015 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -38,6 +38,7 @@
|
|||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
|
#include "stream.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -232,6 +233,7 @@ void iso_finish()
|
|||||||
{
|
{
|
||||||
libiso_msgs_destroy(&libiso_msgr, 0);
|
libiso_msgs_destroy(&libiso_msgr, 0);
|
||||||
iso_node_xinfo_dispose_cloners(0);
|
iso_node_xinfo_dispose_cloners(0);
|
||||||
|
iso_stream_destroy_cmpranks(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso_set_abort_severity(char *severity)
|
int iso_set_abort_severity(char *severity)
|
||||||
@ -378,7 +380,7 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
case ISO_DATA_SOURCE_MISHAP:
|
case ISO_DATA_SOURCE_MISHAP:
|
||||||
case ISO_DATA_SOURCE_FAILURE:
|
case ISO_DATA_SOURCE_FAILURE:
|
||||||
case ISO_DATA_SOURCE_FATAL:
|
case ISO_DATA_SOURCE_FATAL:
|
||||||
return "Read error occured with IsoDataSource";
|
return "Read error occurred with IsoDataSource";
|
||||||
case ISO_AAIP_IGNORED:
|
case ISO_AAIP_IGNORED:
|
||||||
return "AAIP info with ACL or xattr in ISO image will be ignored";
|
return "AAIP info with ACL or xattr in ISO image will be ignored";
|
||||||
case ISO_AAIP_BAD_ACL:
|
case ISO_AAIP_BAD_ACL:
|
||||||
@ -515,6 +517,32 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "HP-PA PALO file is not a data file";
|
return "HP-PA PALO file is not a data file";
|
||||||
case ISO_HPPA_PALO_CMDLEN:
|
case ISO_HPPA_PALO_CMDLEN:
|
||||||
return "HP-PA PALO command line too long";
|
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";
|
||||||
|
case ISO_NOT_REPRODUCIBLE:
|
||||||
|
return "Cannot arrange content of data files in surely reproducible way";
|
||||||
|
case ISO_PATCH_FILTERED_BOOT:
|
||||||
|
return "May not write boot info into filtered stream of boot image";
|
||||||
|
case ISO_PATCH_OVERSIZED_BOOT:
|
||||||
|
return "Boot image to large to buffer for writing boot info";
|
||||||
|
case ISO_RR_NAME_TRUNCATED:
|
||||||
|
return "File name had to be truncated and MD5 marked";
|
||||||
|
case ISO_TRUNCATE_ISOFSNT:
|
||||||
|
return "File name truncation length changed by loaded image info";
|
||||||
|
case ISO_GENERAL_NOTE:
|
||||||
|
return "A general note message was issued";
|
||||||
|
case ISO_BAD_FSRC_FILETYPE:
|
||||||
|
return "Unrecognized file type of IsoFileSrc object";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
@ -543,7 +571,8 @@ int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...)
|
|||||||
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
|
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
} else {
|
} else {
|
||||||
strncpy(msg, iso_error_to_msg(errcode), MAX_MSG_LEN);
|
strncpy(msg, iso_error_to_msg(errcode), MAX_MSG_LEN - 1);
|
||||||
|
msg[MAX_MSG_LEN - 1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
libiso_msgs_submit(libiso_msgr, imgid, ISO_ERR_CODE(errcode),
|
libiso_msgs_submit(libiso_msgr, imgid, ISO_ERR_CODE(errcode),
|
||||||
|
227
libisofs/node.c
227
libisofs/node.c
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
* Copyright (c) 2009 - 2015 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -327,32 +327,50 @@ enum IsoNodeType iso_node_get_type(IsoNode *node)
|
|||||||
* Set the name of a node.
|
* Set the name of a node.
|
||||||
*
|
*
|
||||||
* @param name The name in UTF-8 encoding
|
* @param name The name in UTF-8 encoding
|
||||||
|
* @param truncate_length (<64 = return on oversized name )
|
||||||
|
* @param flag bit0= issue warning in case of truncation
|
||||||
*/
|
*/
|
||||||
int iso_node_set_name(IsoNode *node, const char *name)
|
int iso_node_set_name_trunc(IsoNode *node, const char *in_name,
|
||||||
|
int truncate_length, int flag)
|
||||||
{
|
{
|
||||||
char *new;
|
char *new, *name, *trunc = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((IsoNode*)node->parent == node) {
|
if ((IsoNode*)node->parent == node) {
|
||||||
/* you can't change name of the root node */
|
/* you can't change name of the root node */
|
||||||
return ISO_WRONG_ARG_VALUE;
|
ret = ISO_WRONG_ARG_VALUE;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
name = (char *) in_name;
|
||||||
|
if (truncate_length >= 64) {
|
||||||
|
trunc = strdup(name);
|
||||||
|
if (trunc == 0) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
ret = iso_truncate_rr_name(1, truncate_length, trunc, !(flag & 1));
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
name = trunc;
|
||||||
|
}
|
||||||
/* check if the name is valid */
|
/* check if the name is valid */
|
||||||
ret = iso_node_is_valid_name(name);
|
ret = iso_node_is_valid_name(name);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
|
|
||||||
if (node->parent != NULL) {
|
if (node->parent != NULL) {
|
||||||
/* check if parent already has a node with same name */
|
/* check if parent already has a node with same name */
|
||||||
if (iso_dir_get_node(node->parent, name, NULL) == 1) {
|
if (iso_dir_get_node(node->parent, name, NULL) == 1) {
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
ret = ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new = strdup(name);
|
new = strdup(name);
|
||||||
if (new == NULL) {
|
if (new == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
free(node->name);
|
free(node->name);
|
||||||
node->name = new;
|
node->name = new;
|
||||||
@ -364,10 +382,29 @@ int iso_node_set_name(IsoNode *node, const char *name)
|
|||||||
iso_node_take(node);
|
iso_node_take(node);
|
||||||
res = iso_dir_add_node(parent, node, 0);
|
res = iso_dir_add_node(parent, node, 0);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return res;
|
ret = res;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:
|
||||||
|
if (trunc != NULL)
|
||||||
|
free(trunc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_node_set_name(IsoNode *node, const char *name)
|
||||||
|
{
|
||||||
|
return iso_node_set_name_trunc(node, name, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_image_set_node_name(IsoImage *image, IsoNode *node, const char *name,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
if (image->truncate_mode == 0)
|
||||||
|
if ((int) strlen(name) > image->truncate_length)
|
||||||
|
return ISO_RR_NAME_TOO_LONG;
|
||||||
|
return iso_node_set_name_trunc(node, name, image->truncate_length, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -377,6 +414,10 @@ int iso_node_set_name(IsoNode *node, const char *name)
|
|||||||
*/
|
*/
|
||||||
const char *iso_node_get_name(const IsoNode *node)
|
const char *iso_node_get_name(const IsoNode *node)
|
||||||
{
|
{
|
||||||
|
static char *root = {""};
|
||||||
|
|
||||||
|
if (node->name == NULL)
|
||||||
|
return root;
|
||||||
return node->name;
|
return node->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,6 +651,43 @@ int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_dir_get_node_trunc(IsoDir *dir, int truncate_length,
|
||||||
|
const char *name, IsoNode **node)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *trunc = NULL;
|
||||||
|
|
||||||
|
if ((int) strlen(name) <= truncate_length) {
|
||||||
|
ret = iso_dir_get_node(dir, name, node);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
trunc = strdup(name);
|
||||||
|
if (trunc == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
|
ret = iso_truncate_rr_name(1, truncate_length, trunc, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
ret = iso_dir_get_node(dir, trunc, node);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = 2;
|
||||||
|
ex:;
|
||||||
|
LIBISO_FREE_MEM(trunc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_dir_get_node(IsoImage *image, IsoDir *dir,
|
||||||
|
const char *name, IsoNode **node, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (image->truncate_mode == 0 || (flag & 1))
|
||||||
|
ret = iso_dir_get_node(dir, name, node);
|
||||||
|
else
|
||||||
|
ret = iso_dir_get_node_trunc(dir, image->truncate_length, name, node);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of children of a directory.
|
* Get the number of children of a directory.
|
||||||
*
|
*
|
||||||
@ -1117,25 +1195,25 @@ int iso_file_get_old_image_lba(IsoFile *file, uint32_t *lba, int flag)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int section_count;
|
int section_count;
|
||||||
struct iso_file_section *sections;
|
struct iso_file_section *sections = NULL;
|
||||||
|
|
||||||
if (file == NULL || lba == NULL) {
|
if (file == NULL || lba == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
ret = iso_file_get_old_image_sections(file, §ion_count, §ions, flag);
|
ret = iso_file_get_old_image_sections(file, §ion_count, §ions, 0);
|
||||||
if (ret <= 0) {
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
if (section_count != 1) {
|
if (section_count != 1) {
|
||||||
free(sections);
|
if (sections != NULL)
|
||||||
|
free(sections);
|
||||||
return ISO_WRONG_ARG_VALUE;
|
return ISO_WRONG_ARG_VALUE;
|
||||||
}
|
}
|
||||||
*lba = sections[0].block;
|
*lba = sections[0].block;
|
||||||
free(sections);
|
free(sections);
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Like iso_file_get_old_image_lba(), but take an IsoNode.
|
* Like iso_file_get_old_image_lba(), but take an IsoNode.
|
||||||
*
|
*
|
||||||
@ -1531,11 +1609,17 @@ int attrs_cleanout_name(char *del_name, size_t *num_attrs, char **names,
|
|||||||
size_t i, w;
|
size_t i, w;
|
||||||
|
|
||||||
for (w = i = 0; i < *num_attrs; i++) {
|
for (w = i = 0; i < *num_attrs; i++) {
|
||||||
if ((strcmp(names[i], del_name) == 0) ^ (flag & 1))
|
if ((strcmp(names[i], del_name) == 0) ^ (flag & 1)) {
|
||||||
continue;
|
if (names[i] != NULL)
|
||||||
|
free(names[i]);
|
||||||
|
if (values[i] != NULL)
|
||||||
|
free(values[i]);
|
||||||
|
names[i] = values[i] = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (w == i) {
|
if (w == i) {
|
||||||
w++;
|
w++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
names[w] = names[i];
|
names[w] = names[i];
|
||||||
value_lengths[w] = value_lengths[i];
|
value_lengths[w] = value_lengths[i];
|
||||||
@ -1881,8 +1965,9 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
|
|||||||
size_t *value_lengths, char **values, int flag)
|
size_t *value_lengths, char **values, int flag)
|
||||||
{
|
{
|
||||||
int ret, acl_saved = 0;
|
int ret, acl_saved = 0;
|
||||||
size_t sret, result_len, m_num = 0, *m_value_lengths = NULL, i;
|
ssize_t sret;
|
||||||
unsigned char *result;
|
size_t result_len, m_num = 0, *m_value_lengths = NULL, i;
|
||||||
|
unsigned char *result = NULL;
|
||||||
char *a_acl = NULL, *d_acl = NULL, **m_names = NULL, **m_values = NULL;
|
char *a_acl = NULL, *d_acl = NULL, **m_names = NULL, **m_values = NULL;
|
||||||
|
|
||||||
if (!(flag & 8))
|
if (!(flag & 8))
|
||||||
@ -1921,28 +2006,34 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
|
|||||||
}
|
}
|
||||||
sret = aaip_encode(num_attrs, names, value_lengths, values,
|
sret = aaip_encode(num_attrs, names, value_lengths, values,
|
||||||
&result_len, &result, 0);
|
&result_len, &result, 0);
|
||||||
if (sret == 0) {
|
if (sret < 0) {
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = sret;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iso_node_remove_xinfo(node, aaip_xinfo_func);
|
ret = iso_node_remove_xinfo(node, aaip_xinfo_func);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
goto ex;
|
if (result != NULL)
|
||||||
ret = iso_node_add_xinfo(node, aaip_xinfo_func, result);
|
free(result);
|
||||||
if (ret < 0)
|
|
||||||
goto ex;
|
|
||||||
if (ret == 0) {
|
|
||||||
|
|
||||||
/* >>> something is messed up with xinfo: an aa_string still exists */;
|
|
||||||
|
|
||||||
ret = ISO_ERROR;
|
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
if (acl_saved) {
|
if (sret > 0) {
|
||||||
ret = iso_node_set_acl_text(node, a_acl, d_acl, 0);
|
ret = iso_node_add_xinfo(node, aaip_xinfo_func, result);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
if (ret == 0) {
|
||||||
|
|
||||||
|
/* >>> something is messed up with xinfo:
|
||||||
|
an aa_string still exists */;
|
||||||
|
|
||||||
|
ret = ISO_ERROR;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
if (acl_saved) {
|
||||||
|
ret = iso_node_set_acl_text(node, a_acl, d_acl, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret = 1;
|
ret = 1;
|
||||||
ex:;
|
ex:;
|
||||||
@ -2160,10 +2251,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
|||||||
ret = ISO_AAIP_BAD_ACL_TEXT;
|
ret = ISO_AAIP_BAD_ACL_TEXT;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
ret = 1;
|
ret = aaip_encode_both_acl(a_text, d_text, st_mode,
|
||||||
if (a_text != NULL || d_text != NULL)
|
&acl_len, &acl, 2 | 8);
|
||||||
ret = aaip_encode_both_acl(a_text, d_text, st_mode,
|
|
||||||
&acl_len, &acl, 2 | 8);
|
|
||||||
} else {
|
} else {
|
||||||
ret = 1;
|
ret = 1;
|
||||||
if (access_text != NULL || default_text != NULL)
|
if (access_text != NULL || default_text != NULL)
|
||||||
@ -2868,6 +2957,50 @@ ex:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int iso_root_set_isofsnt(IsoNode *node, uint32_t truncate_mode,
|
||||||
|
uint32_t truncate_length, int flag)
|
||||||
|
{
|
||||||
|
char buffer[5 + 5], *wpt = buffer, *valuept = buffer;
|
||||||
|
int result_len, ret;
|
||||||
|
static char *names = "isofs.nt";
|
||||||
|
static size_t value_lengths[1];
|
||||||
|
|
||||||
|
iso_util_encode_len_bytes(truncate_mode, wpt, 0, &result_len, 0);
|
||||||
|
wpt += result_len;
|
||||||
|
iso_util_encode_len_bytes(truncate_length, wpt, 0, &result_len, 0);
|
||||||
|
wpt += result_len;
|
||||||
|
value_lengths[0] = wpt - buffer;
|
||||||
|
ret = iso_node_set_attrs(node, (size_t) 1,
|
||||||
|
&names, value_lengths, &valuept, 2 | 8);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int iso_root_get_isofsnt(IsoNode *node, uint32_t *truncate_mode,
|
||||||
|
uint32_t *truncate_length, int flag)
|
||||||
|
{
|
||||||
|
int ret, len;
|
||||||
|
size_t value_len;
|
||||||
|
char *value = NULL, *rpt;
|
||||||
|
|
||||||
|
ret = iso_node_lookup_attr(node, "isofs.nt", &value_len, &value, 0);
|
||||||
|
if (ret <= 0)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
rpt = value;
|
||||||
|
iso_util_decode_len_bytes(truncate_mode, rpt, &len,
|
||||||
|
value_len - (rpt - value), 0);
|
||||||
|
rpt += len + 1;
|
||||||
|
iso_util_decode_len_bytes(truncate_length, rpt, &len,
|
||||||
|
value_len - (rpt - value), 0);
|
||||||
|
ret= ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (value != NULL)
|
||||||
|
free(value);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag)
|
int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag)
|
||||||
{
|
{
|
||||||
@ -2921,21 +3054,23 @@ int iso_file_make_md5(IsoFile *file, int flag)
|
|||||||
|
|
||||||
if (file->from_old_session)
|
if (file->from_old_session)
|
||||||
dig = 1;
|
dig = 1;
|
||||||
md5= calloc(16, 1);
|
md5 = calloc(16, 1);
|
||||||
|
if (md5 == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
ret = iso_stream_make_md5(file->stream, md5, dig);
|
ret = iso_stream_make_md5(file->stream, md5, dig);
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
goto ex;
|
free(md5);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
iso_node_remove_xinfo((IsoNode *) file, checksum_md5_xinfo_func);
|
iso_node_remove_xinfo((IsoNode *) file, checksum_md5_xinfo_func);
|
||||||
ret = iso_node_add_xinfo((IsoNode *) file, checksum_md5_xinfo_func, md5);
|
ret = iso_node_add_xinfo((IsoNode *) file, checksum_md5_xinfo_func, md5);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = ISO_ERROR; /* should not happen after iso_node_remove_xinfo() */
|
ret = ISO_ERROR; /* should not happen after iso_node_remove_xinfo() */
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
free(md5);
|
free(md5);
|
||||||
goto ex;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = 1;
|
return 1;
|
||||||
ex:;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -512,6 +512,16 @@ int iso_root_get_isofsca(IsoNode *node, uint32_t *start_lba, uint32_t *end_lba,
|
|||||||
int flag);
|
int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record and get truncation parameters as of iso_image_set_truncate_mode() by
|
||||||
|
* "isofs.nt".
|
||||||
|
*/
|
||||||
|
int iso_root_set_isofsnt(IsoNode *node, uint32_t truncate_mode,
|
||||||
|
uint32_t truncate_length, int flag);
|
||||||
|
int iso_root_get_isofsnt(IsoNode *node, uint32_t *truncate_mode,
|
||||||
|
uint32_t *truncate_length, int flag);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy the xinfo list from one node to the another.
|
* Copy the xinfo list from one node to the another.
|
||||||
*/
|
*/
|
||||||
@ -543,4 +553,10 @@ int zisofs_zf_xinfo_func(void *data, int flag);
|
|||||||
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag);
|
int zisofs_zf_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/* Performing search for possibly truncated node name.
|
||||||
|
*/
|
||||||
|
int iso_dir_get_node_trunc(IsoDir *dir, int truncate_length,
|
||||||
|
const char *name, IsoNode **node);
|
||||||
|
|
||||||
|
|
||||||
#endif /*LIBISO_NODE_H_*/
|
#endif /*LIBISO_NODE_H_*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* 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
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -32,10 +32,16 @@
|
|||||||
#define ISO_ROCKRIDGE_IN_DIR_REC 124
|
#define ISO_ROCKRIDGE_IN_DIR_REC 124
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ISO_CE_ENTRY_SIZE 28
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int susp_add_ES(Ecma119Image *t, struct susp_info *susp, int to_ce, int seqno);
|
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
|
static
|
||||||
int susp_append(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
|
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
|
static
|
||||||
int susp_append_ce(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
|
int susp_append_ce(Ecma119Image *t, struct susp_info *susp, uint8_t *data)
|
||||||
{
|
{
|
||||||
susp->n_ce_susp_fields++;
|
int to_alloc = 1, ret;
|
||||||
susp->ce_susp_fields = realloc(susp->ce_susp_fields, sizeof(void*)
|
unsigned char *pad;
|
||||||
* susp->n_ce_susp_fields);
|
uint8_t *CE;
|
||||||
if (susp->ce_susp_fields == NULL) {
|
size_t next_alloc;
|
||||||
return ISO_OUT_OF_MEM;
|
|
||||||
|
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;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,9 +383,7 @@ int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
|
|||||||
iso_msg_submit(imgid, ISO_FILENAME_WRONG_CHARSET, ret,
|
iso_msg_submit(imgid, ISO_FILENAME_WRONG_CHARSET, ret,
|
||||||
"Charset conversion error. Cannot convert %s from %s to %s",
|
"Charset conversion error. Cannot convert %s from %s to %s",
|
||||||
str, input_charset, output_charset);
|
str, input_charset, output_charset);
|
||||||
|
*name = NULL;
|
||||||
/* use the original name, it's the best we can do */
|
|
||||||
ret = iso_clone_mem(str, name, 0);
|
|
||||||
return ISO_FILENAME_WRONG_CHARSET;
|
return ISO_FILENAME_WRONG_CHARSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,6 +398,8 @@ char *get_rr_fname(Ecma119Image *t, char *str)
|
|||||||
|
|
||||||
ret = iso_get_rr_name(t->opts, t->input_charset, t->output_charset,
|
ret = iso_get_rr_name(t->opts, t->input_charset, t->output_charset,
|
||||||
t->image->id, str, &name, 0);
|
t->image->id, str, &name, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return NULL;
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,12 +577,15 @@ int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
|
|||||||
* debug purposes
|
* debug purposes
|
||||||
*/
|
*/
|
||||||
if (ce == 0) {
|
if (ce == 0) {
|
||||||
|
free(SL);
|
||||||
return ISO_ASSERT_FAILURE;
|
return ISO_ASSERT_FAILURE;
|
||||||
}
|
}
|
||||||
ret = susp_append_ce(t, susp, SL);
|
ret = susp_append_ce(t, susp, SL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
free(SL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
SL = NULL; /* now owned by susp */
|
||||||
written = i;
|
written = i;
|
||||||
total_comp_len = comp[i][1] + 2;
|
total_comp_len = comp[i][1] + 2;
|
||||||
}
|
}
|
||||||
@ -545,22 +616,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
|
@param flag bit0= only account sizes in sua_free resp. ce_len.
|
||||||
parameters susp and data may be NULL in this case
|
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
|
static
|
||||||
int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
||||||
uint8_t **data, size_t num_data,
|
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;
|
int ret, done = 0, len, es_extra = 0;
|
||||||
uint8_t *aapt, *cpt;
|
uint8_t *aapt, *cpt;
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
if (!(flag & 1))
|
||||||
|
flag |= 2;
|
||||||
if (!t->opts->aaip_susp_1_10)
|
if (!t->opts->aaip_susp_1_10)
|
||||||
es_extra = 5;
|
es_extra = 5;
|
||||||
if (*sua_free < num_data + es_extra || *ce_len > 0) {
|
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 {
|
} else {
|
||||||
*sua_free -= num_data + es_extra;
|
*sua_free -= num_data + es_extra;
|
||||||
}
|
}
|
||||||
@ -586,6 +691,7 @@ int aaip_add_AL(Ecma119Image *t, struct susp_info *susp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Multiple fields have to be handed over as single field copies */
|
/* Multiple fields have to be handed over as single field copies */
|
||||||
|
done = 0;
|
||||||
for (aapt = *data; !done; aapt += aapt[2]) {
|
for (aapt = *data; !done; aapt += aapt[2]) {
|
||||||
done = !(aapt[4] & 1);
|
done = !(aapt[4] & 1);
|
||||||
len = aapt[2];
|
len = aapt[2];
|
||||||
@ -720,6 +826,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
|
* 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.
|
* a continuation area, where additional System Use Entry can be written.
|
||||||
@ -728,20 +863,18 @@ int aaip_add_ER(Ecma119Image *t, struct susp_info *susp, int flag)
|
|||||||
static
|
static
|
||||||
int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp)
|
int susp_add_CE(Ecma119Image *t, size_t ce_len, struct susp_info *susp)
|
||||||
{
|
{
|
||||||
uint8_t *CE = malloc(28);
|
uint32_t block_offset, byte_offset;
|
||||||
if (CE == NULL) {
|
uint8_t *CE;
|
||||||
return ISO_OUT_OF_MEM;
|
int ret;
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
|
/* 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);
|
return susp_append(t, susp, CE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -797,6 +930,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"
|
* see doc/zisofs_format.txt : "ZF System Use Entry Format"
|
||||||
*/
|
*/
|
||||||
@ -828,10 +982,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
|
/* @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
|
static
|
||||||
int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
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 ret, will_copy = 1, stream_type = 0, do_zf = 0;
|
||||||
int header_size_div4 = 0, block_size_log2 = 0;
|
int header_size_div4 = 0, block_size_log2 = 0;
|
||||||
@ -847,6 +1003,8 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|||||||
int *header_size_div4, int *block_size_log2,
|
int *header_size_div4, int *block_size_log2,
|
||||||
uint32_t *uncompressed_size, int flag);
|
uint32_t *uncompressed_size, int flag);
|
||||||
|
|
||||||
|
if (!(flag & 1))
|
||||||
|
flag |= 2;
|
||||||
|
|
||||||
if (iso_node_get_type(n->node) != LIBISO_FILE)
|
if (iso_node_get_type(n->node) != LIBISO_FILE)
|
||||||
return 2;
|
return 2;
|
||||||
@ -920,7 +1078,7 @@ int add_zf_field(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|||||||
|
|
||||||
/* Account for field size */
|
/* Account for field size */
|
||||||
if (*sua_free < 16 || *ce_len > 0) {
|
if (*sua_free < 16 || *ce_len > 0) {
|
||||||
*ce_len += 16;
|
susp_calc_add_to_ce(ce_len, base_ce, 16, flag & 2);
|
||||||
} else {
|
} else {
|
||||||
*sua_free -= 16;
|
*sua_free -= 16;
|
||||||
}
|
}
|
||||||
@ -968,10 +1126,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
|
* 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
|
* are taken into account at start. In this case the caller should retry with
|
||||||
* bit0 set.
|
* 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)
|
* @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
|
* @return 1= ok, computation of *su_size and *ce is valid
|
||||||
* 0= not ok, CA usage is necessary but bit0 was not set
|
* 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)
|
* (*su_size and *ce stay unaltered in this case)
|
||||||
* <0= error:
|
* <0= error:
|
||||||
* -1= not enough SUA space for 28 bytes of CE entry
|
* -1= not enough SUA space for 28 bytes of CE entry
|
||||||
@ -979,22 +1142,50 @@ int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
|
|||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
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;
|
char *name;
|
||||||
size_t namelen, su_mem, ce_mem;
|
size_t namelen, su_mem, ce_mem;
|
||||||
void *xipt;
|
void *xipt;
|
||||||
size_t num_aapt = 0, sua_free = 0;
|
size_t num_aapt = 0, sua_free = 0;
|
||||||
int ret;
|
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;
|
su_mem = *su_size;
|
||||||
ce_mem = *ce;
|
ce_mem = *ce;
|
||||||
if (*ce > 0 && !(flag & 1))
|
if (*ce > 0 && !(flag & 1))
|
||||||
goto unannounced_ca;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namelen = 0;
|
||||||
name = get_rr_fname(t, n->node->name);
|
name = get_rr_fname(t, n->node->name);
|
||||||
namelen = strlen(name);
|
if (name != NULL) {
|
||||||
free(name);
|
namelen = strlen(name);
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
if (flag & 1) {
|
if (flag & 1) {
|
||||||
/* Account for 28 bytes of CE field */
|
/* Account for 28 bytes of CE field */
|
||||||
@ -1018,7 +1209,7 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
of the name will always fit into the directory entry.)
|
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;
|
*su_size = space;
|
||||||
}
|
}
|
||||||
if (n->type == ECMA119_SYMLINK) {
|
if (n->type == ECMA119_SYMLINK) {
|
||||||
@ -1088,21 +1279,26 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
* the component can be divided between this
|
* the component can be divided between this
|
||||||
* and another SL entry
|
* and another SL entry
|
||||||
*/
|
*/
|
||||||
*ce += 255; /* this SL, full */
|
/* Will fill up old SL and write it */
|
||||||
sl_len = 5 + (clen - fit);
|
susp_calc_add_to_ce(ce, base_ce, 255, flag & 2);
|
||||||
|
sl_len = 5 + (clen - fit); /* Start new SL */
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* the component will need a 2rd SL entry in
|
* the component will need a 2rd SL entry in
|
||||||
* any case, so we prefer to don't write
|
* any case, so we prefer to don't write
|
||||||
* anything in this SL
|
* anything in this SL
|
||||||
*/
|
*/
|
||||||
*ce += sl_len + 255;
|
/* Will write non-full old SL */
|
||||||
sl_len = 5 + (clen - 250) + 2;
|
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 {
|
} else {
|
||||||
/* case 2, create a new SL entry */
|
/* case 2, create a new SL entry */
|
||||||
*ce += sl_len;
|
/* Will write non-full old SL */
|
||||||
sl_len = 5 + clen;
|
susp_calc_add_to_ce(ce, base_ce, sl_len, flag & 2);
|
||||||
|
sl_len = 5 + clen; /* Start new SL */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sl_len += clen;
|
sl_len += clen;
|
||||||
@ -1124,14 +1320,14 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
/* the whole SL fits into the SUA */
|
/* the whole SL fits into the SUA */
|
||||||
*su_size += sl_len;
|
*su_size += sl_len;
|
||||||
} else {
|
} 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 */
|
/* Find out whether ZF is to be added and account for its bytes */
|
||||||
sua_free = space - *su_size;
|
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;
|
*su_size = space - sua_free;
|
||||||
if (*ce > 0 && !(flag & 1))
|
if (*ce > 0 && !(flag & 1))
|
||||||
goto unannounced_ca;
|
goto unannounced_ca;
|
||||||
@ -1148,12 +1344,46 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
/* let the expert decide where to add num_aapt */
|
/* let the expert decide where to add num_aapt */
|
||||||
if (num_aapt > 0) {
|
if (num_aapt > 0) {
|
||||||
sua_free = space - *su_size;
|
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;
|
*su_size = space - sua_free;
|
||||||
if (*ce > 0 && !(flag & 1))
|
if (*ce > 0 && !(flag & 1))
|
||||||
goto unannounced_ca;
|
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;
|
return 1;
|
||||||
|
|
||||||
unannounced_ca:;
|
unannounced_ca:;
|
||||||
@ -1165,10 +1395,12 @@ unannounced_ca:;
|
|||||||
|
|
||||||
/* @param flag bit0= Do not add data but only count sua_free and ce_len
|
/* @param flag bit0= Do not add data but only count sua_free and ce_len
|
||||||
param info may be NULL in this case
|
param info may be NULL in this case
|
||||||
|
bit1= account for crossing block boundaries
|
||||||
|
(implied by bit0 == 0)
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
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;
|
int ret;
|
||||||
uint8_t *aapt;
|
uint8_t *aapt;
|
||||||
@ -1183,18 +1415,20 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|||||||
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
num_aapt = aaip_count_bytes((unsigned char *) xipt, 0);
|
||||||
if (num_aapt > 0) {
|
if (num_aapt > 0) {
|
||||||
if (flag & 1) {
|
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 {
|
} else {
|
||||||
aapt = malloc(num_aapt);
|
aapt = malloc(num_aapt);
|
||||||
if (aapt == NULL)
|
if (aapt == NULL)
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
memcpy(aapt, xipt, num_aapt);
|
memcpy(aapt, xipt, num_aapt);
|
||||||
ret = aaip_add_AL(t, info, &aapt, num_aapt, sua_free, ce_len,
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
/* aapt is NULL now and the memory is owned by t */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -1212,11 +1446,13 @@ int add_aa_string(Ecma119Image *t, Ecma119Node *n, struct susp_info *info,
|
|||||||
* Already occupied space in the directory record.
|
* Already occupied space in the directory record.
|
||||||
* @param ce
|
* @param ce
|
||||||
* Will be filled with the space needed in a 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
|
* @return
|
||||||
* The size needed for the RR entries in the System Use Area
|
* 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 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;
|
size_t su_size, space;
|
||||||
int ret;
|
int ret;
|
||||||
@ -1279,9 +1515,11 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
|||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
|
|
||||||
/* Try without CE */
|
/* Try without CE */
|
||||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
|
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, base_ce, 0);
|
||||||
if (ret == 0) /* Retry with CE */
|
if (ret == 0) /* Retry with CE but no block crossing */
|
||||||
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, 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)
|
if (ret == -2)
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
|
|
||||||
@ -1308,9 +1546,13 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
|||||||
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
|
if (t->opts->aaip && !t->opts->aaip_susp_1_10) {
|
||||||
*ce += 160; /* ER of AAIP */
|
*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;
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
*ce += aaip_len;
|
*ce += aaip_len;
|
||||||
@ -1374,7 +1616,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
size_t rrip_er_len= 182;
|
size_t rrip_er_len= 182;
|
||||||
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
||||||
int ce_is_predicted = 0;
|
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;
|
int space;
|
||||||
|
|
||||||
if (t == NULL || n == NULL || info == NULL) {
|
if (t == NULL || n == NULL || info == NULL) {
|
||||||
@ -1391,6 +1633,18 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
return ISO_ASSERT_FAILURE;
|
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) {
|
if (type == 2 && n->parent != NULL) {
|
||||||
node = n->parent;
|
node = n->parent;
|
||||||
} else {
|
} else {
|
||||||
@ -1491,19 +1745,29 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
uint8_t **comps= NULL; /* components of the SL field */
|
uint8_t **comps= NULL; /* components of the SL field */
|
||||||
size_t n_comp = 0; /* number of components */
|
size_t n_comp = 0; /* number of components */
|
||||||
|
|
||||||
|
namelen = 0;
|
||||||
name = get_rr_fname(t, n->node->name);
|
name = get_rr_fname(t, n->node->name);
|
||||||
|
if (name == NULL)
|
||||||
|
name = strdup("");
|
||||||
|
if (name == NULL) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto add_susp_cleanup;
|
||||||
|
}
|
||||||
namelen = strlen(name);
|
namelen = strlen(name);
|
||||||
|
|
||||||
sua_free = space - info->suf_len;
|
sua_free = space - info->suf_len;
|
||||||
|
|
||||||
/* Try whether NM, SL, AL will fit into SUA */
|
/* Try whether NM, SL, AL will fit into SUA */
|
||||||
su_size_pd = info->suf_len;
|
su_size_pd = info->suf_len;
|
||||||
ce_len_pd = ce_len;
|
ce_len_pd = ce_len;
|
||||||
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
|
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 */
|
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
|
||||||
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
|
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;
|
sua_free -= 28;
|
||||||
ce_is_predicted = 1;
|
ce_is_predicted = 1;
|
||||||
}
|
}
|
||||||
@ -1533,6 +1797,13 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
int cew = (nm_type == 1); /* are we writing to CE? */
|
int cew = (nm_type == 1); /* are we writing to CE? */
|
||||||
|
|
||||||
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest);
|
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest);
|
||||||
|
if (dest == NULL)
|
||||||
|
dest = strdup("");
|
||||||
|
if (dest == NULL) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto add_susp_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
prev = dest;
|
prev = dest;
|
||||||
cur = strchr(prev, '/');
|
cur = strchr(prev, '/');
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -1697,6 +1968,26 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ce_is_predicted) {
|
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 */
|
/* Add the CE entry */
|
||||||
ret = susp_add_CE(t, ce_len_pd, info);
|
ret = susp_add_CE(t, ce_len_pd, info);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -1738,14 +2029,14 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Eventually write zisofs ZF field */
|
/* 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)
|
if (ret < 0)
|
||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
|
|
||||||
/* Eventually obtain AAIP field string from node
|
/* Eventually obtain AAIP field string from node
|
||||||
and write it to directory entry or CE area.
|
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)
|
if (ret < 0)
|
||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
|
|
||||||
@ -1806,7 +2097,8 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
|
|
||||||
/* Compute length of AAIP string of root node */
|
/* Compute length of AAIP string of root node */
|
||||||
aaip_sua_free= 0;
|
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)
|
if (ret < 0)
|
||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
|
|
||||||
@ -1827,7 +2119,8 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
}
|
}
|
||||||
/* Write AAIP string of root node */
|
/* Write AAIP string of root node */
|
||||||
aaip_sua_free= aaip_len= 0;
|
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)
|
if (ret < 0)
|
||||||
goto add_susp_cleanup;
|
goto add_susp_cleanup;
|
||||||
|
|
||||||
@ -1846,12 +2139,63 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
add_susp_cleanup: ;
|
add_susp_cleanup: ;
|
||||||
free(name);
|
if (name != NULL)
|
||||||
free(dest);
|
free(name);
|
||||||
|
if (dest != NULL)
|
||||||
|
free(dest);
|
||||||
susp_info_free(info);
|
susp_info_free(info);
|
||||||
return ret;
|
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
|
* Write the given SUSP fields into buf. Note that Continuation Area
|
||||||
* fields are not written.
|
* fields are not written.
|
||||||
@ -1864,11 +2208,16 @@ void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (info->n_susp_fields == 0) {
|
if (info->n_susp_fields == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = susp_update_CE_sizes(t, info, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = 0; i < info->n_susp_fields; i++) {
|
for (i = 0; i < info->n_susp_fields; i++) {
|
||||||
memcpy(buf + pos, info->susp_fields[i], info->susp_fields[i][2]);
|
memcpy(buf + pos, info->susp_fields[i], info->susp_fields[i][2]);
|
||||||
pos += info->susp_fields[i][2];
|
pos += info->susp_fields[i][2];
|
||||||
@ -1894,6 +2243,7 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
|||||||
size_t i;
|
size_t i;
|
||||||
uint8_t *padding = NULL;
|
uint8_t *padding = NULL;
|
||||||
int ret= ISO_SUCCESS;
|
int ret= ISO_SUCCESS;
|
||||||
|
uint64_t written = 0, pad_size;
|
||||||
|
|
||||||
if (info->n_ce_susp_fields == 0) {
|
if (info->n_ce_susp_fields == 0) {
|
||||||
goto ex;
|
goto ex;
|
||||||
@ -1901,11 +2251,24 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
|||||||
LIBISO_ALLOC_MEM(padding, uint8_t, BLOCK_SIZE);
|
LIBISO_ALLOC_MEM(padding, uint8_t, BLOCK_SIZE);
|
||||||
|
|
||||||
for (i = 0; i < info->n_ce_susp_fields; i++) {
|
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],
|
ret = iso_write(t, info->ce_susp_fields[i],
|
||||||
info->ce_susp_fields[i][2]);
|
info->ce_susp_fields[i][2]);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto write_ce_field_cleanup;
|
goto write_ce_field_cleanup;
|
||||||
}
|
}
|
||||||
|
written += info->ce_susp_fields[i][2];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pad continuation area until block size */
|
/* pad continuation area until block size */
|
||||||
@ -1913,6 +2276,9 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
|||||||
if (i > 0 && i < BLOCK_SIZE) {
|
if (i > 0 && i < BLOCK_SIZE) {
|
||||||
memset(padding, 0, i);
|
memset(padding, 0, i);
|
||||||
ret = iso_write(t, padding, i);
|
ret = iso_write(t, padding, i);
|
||||||
|
if (ret < 0)
|
||||||
|
goto write_ce_field_cleanup;
|
||||||
|
written += i;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_ce_field_cleanup: ;
|
write_ce_field_cleanup: ;
|
||||||
@ -1923,6 +2289,7 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
|||||||
free(info->ce_susp_fields);
|
free(info->ce_susp_fields);
|
||||||
info->ce_susp_fields = NULL;
|
info->ce_susp_fields = NULL;
|
||||||
info->n_ce_susp_fields = 0;
|
info->n_ce_susp_fields = 0;
|
||||||
|
info->alloc_ce_susp_fields = 0;
|
||||||
info->ce_len = 0;
|
info->ce_len = 0;
|
||||||
ex:;
|
ex:;
|
||||||
LIBISO_FREE_MEM(padding);
|
LIBISO_FREE_MEM(padding);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* 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
|
* 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
|
* 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_block;
|
||||||
uint32_t ce_len;
|
uint32_t ce_len;
|
||||||
|
|
||||||
|
/* Storage for Continuation Area for a whole directory */
|
||||||
size_t n_ce_susp_fields;
|
size_t n_ce_susp_fields;
|
||||||
uint8_t **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 */
|
/* SUSP 5.1 */
|
||||||
struct susp_CE {
|
struct susp_CE {
|
||||||
uint8_t block[8];
|
uint8_t block[8];
|
||||||
@ -186,11 +198,13 @@ struct susp_sys_user_entry
|
|||||||
* Available space in the System Use Area for the directory record.
|
* Available space in the System Use Area for the directory record.
|
||||||
* @param ce
|
* @param ce
|
||||||
* Will be filled with the space needed in a 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
|
* @return
|
||||||
* The size needed for the RR entries in the System Use Area
|
* 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 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
|
* Fill a struct susp_info with the RR/SUSP entries needed for a given
|
||||||
@ -347,8 +361,7 @@ int read_zisofs_ZF(struct susp_sys_user_entry *zf, uint8_t algorithm[2],
|
|||||||
uint32_t *uncompressed_size, int flag);
|
uint32_t *uncompressed_size, int flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a RR filename to the requested charset. On any conversion error,
|
* Convert a RR filename to the requested charset.
|
||||||
* the original name will be used.
|
|
||||||
* @param flag bit0= do not issue error messages
|
* @param flag bit0= do not issue error messages
|
||||||
*/
|
*/
|
||||||
int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
|
int iso_get_rr_name(IsoWriteOpts *opts, char *input_charset,
|
||||||
|
@ -211,10 +211,19 @@ int read_rr_TF(struct susp_sys_user_entry *tf, struct stat *st)
|
|||||||
|
|
||||||
/* 1. Creation time */
|
/* 1. Creation time */
|
||||||
if (tf->data.TF.flags[0] & (1 << 0)) {
|
if (tf->data.TF.flags[0] & (1 << 0)) {
|
||||||
|
/* Linux accepts ctime by Creation time and by Attributes time.
|
||||||
/* the creation is the recording time. we ignore this */
|
* If both are given, then Attribute time will win.
|
||||||
/* TODO maybe it would be good to manage it in ms discs, where
|
*/
|
||||||
* the recording time could be different than now!! */
|
if (tf->len_sue[0] < 5 + (nts+1) * s) {
|
||||||
|
/* RR TF entry too short. */
|
||||||
|
return ISO_WRONG_RR;
|
||||||
|
}
|
||||||
|
if (s == 7) {
|
||||||
|
time = iso_datetime_read_7(&tf->data.TF.t_stamps[nts*7]);
|
||||||
|
} else {
|
||||||
|
time = iso_datetime_read_17(&tf->data.TF.t_stamps[nts*17]);
|
||||||
|
}
|
||||||
|
st->st_ctime = time;
|
||||||
++nts;
|
++nts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,7 +421,7 @@ int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st)
|
|||||||
{
|
{
|
||||||
int high_shift= 0;
|
int high_shift= 0;
|
||||||
|
|
||||||
if (pn == NULL || pn == NULL) {
|
if (pn == NULL || st == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
if (pn->sig[0] != 'P' || pn->sig[1] != 'N') {
|
if (pn->sig[0] != 'P' || pn->sig[1] != 'N') {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* 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
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -164,15 +164,6 @@ IsoStream *fsrc_get_input_stream(IsoStream *stream, int flag)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
int fsrc_cmp_ino(IsoStream *s1, IsoStream *s2)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = iso_stream_cmp_ino(s1, s2, 1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
@ -227,7 +218,7 @@ IsoStreamIface fsrc_stream_class = {
|
|||||||
fsrc_free,
|
fsrc_free,
|
||||||
fsrc_update_size,
|
fsrc_update_size,
|
||||||
fsrc_get_input_stream,
|
fsrc_get_input_stream,
|
||||||
fsrc_cmp_ino,
|
NULL,
|
||||||
fsrc_clone_stream
|
fsrc_clone_stream
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -448,15 +439,6 @@ IsoStream* cut_out_get_input_stream(IsoStream *stream, int flag)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
int cut_out_cmp_ino(IsoStream *s1, IsoStream *s2)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = iso_stream_cmp_ino(s1, s2, 1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int cut_out_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
int cut_out_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||||
int flag)
|
int flag)
|
||||||
@ -517,7 +499,7 @@ IsoStreamIface cut_out_stream_class = {
|
|||||||
cut_out_free,
|
cut_out_free,
|
||||||
cut_out_update_size,
|
cut_out_update_size,
|
||||||
cut_out_get_input_stream,
|
cut_out_get_input_stream,
|
||||||
cut_out_cmp_ino,
|
NULL,
|
||||||
cut_out_clone_stream
|
cut_out_clone_stream
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -698,15 +680,6 @@ IsoStream* mem_get_input_stream(IsoStream *stream, int flag)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
int mem_cmp_ino(IsoStream *s1, IsoStream *s2)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = iso_stream_cmp_ino(s1, s2, 1);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||||
int flag)
|
int flag)
|
||||||
@ -763,7 +736,7 @@ IsoStreamIface mem_stream_class = {
|
|||||||
mem_free,
|
mem_free,
|
||||||
mem_update_size,
|
mem_update_size,
|
||||||
mem_get_input_stream,
|
mem_get_input_stream,
|
||||||
mem_cmp_ino,
|
NULL,
|
||||||
mem_clone_stream
|
mem_clone_stream
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -943,12 +916,22 @@ ex:;
|
|||||||
return path;
|
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)
|
int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag)
|
||||||
{
|
{
|
||||||
|
IsoStream *base_stream;
|
||||||
|
|
||||||
if (stream == NULL) {
|
if (stream == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
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) {
|
if (stream->class == &fsrc_stream_class) {
|
||||||
FSrcStreamData *fsrc_data = stream->data;
|
FSrcStreamData *fsrc_data = stream->data;
|
||||||
fsrc_data->ino_id = ino;
|
fsrc_data->ino_id = ino;
|
||||||
@ -957,6 +940,104 @@ int iso_stream_set_image_ino(IsoStream *stream, ino_t ino, int flag)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_stream_cmp_ifs_sections(IsoStream *s1, IsoStream *s2, int *cmp_ret,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
FSrcStreamData *fssd1, *fssd2;
|
||||||
|
IsoFileSource *src1, *src2;
|
||||||
|
|
||||||
|
/* Must keep any suspect in the game to preserve transitivity of the
|
||||||
|
calling function by ranking applicable streams lower than
|
||||||
|
non-applicable. ones.
|
||||||
|
*/
|
||||||
|
if (s1->class != &fsrc_stream_class && s2->class != &fsrc_stream_class)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Compare eventual image data section LBA and sizes */
|
||||||
|
if (s1->class == &fsrc_stream_class) {
|
||||||
|
fssd1= (FSrcStreamData *) s1->data;
|
||||||
|
src1 = fssd1->src;
|
||||||
|
} else {
|
||||||
|
src1 = NULL;
|
||||||
|
}
|
||||||
|
if (s2->class == &fsrc_stream_class) {
|
||||||
|
fssd2= (FSrcStreamData *) s2->data;
|
||||||
|
src2 = fssd2->src;
|
||||||
|
} else {
|
||||||
|
src2 = NULL;
|
||||||
|
}
|
||||||
|
ret = iso_ifs_sections_cmp(src1, src2, cmp_ret, 1);
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Maintain and exploit a list of stream compare functions seen by
|
||||||
|
iso_stream_cmp_ino(). This is needed to separate stream comparison
|
||||||
|
families in order to keep iso_stream_cmp_ino() transitive while
|
||||||
|
alternative stream->class->cmp_ino() decide inside the families.
|
||||||
|
*/
|
||||||
|
struct iso_streamcmprank {
|
||||||
|
int (*cmp_func)(IsoStream *s1, IsoStream *s2);
|
||||||
|
struct iso_streamcmprank *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct iso_streamcmprank *streamcmpranks = NULL;
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_get_streamcmprank(int (*cmp_func)(IsoStream *s1, IsoStream *s2),
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
int idx;
|
||||||
|
struct iso_streamcmprank *cpr, *last_cpr = NULL;
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
for (cpr = streamcmpranks; cpr != NULL; cpr = cpr->next) {
|
||||||
|
if (cpr->cmp_func == cmp_func)
|
||||||
|
break;
|
||||||
|
idx++;
|
||||||
|
last_cpr = cpr;
|
||||||
|
}
|
||||||
|
if (cpr != NULL)
|
||||||
|
return idx;
|
||||||
|
LIBISO_ALLOC_MEM_VOID(cpr, struct iso_streamcmprank, 1);
|
||||||
|
cpr->cmp_func = cmp_func;
|
||||||
|
cpr->next = NULL;
|
||||||
|
if (last_cpr != NULL)
|
||||||
|
last_cpr->next = cpr;
|
||||||
|
if (streamcmpranks == NULL)
|
||||||
|
streamcmpranks = cpr;
|
||||||
|
return idx;
|
||||||
|
ex:;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_cmp_streamcmpranks(int (*cf1)(IsoStream *s1, IsoStream *s2),
|
||||||
|
int (*cf2)(IsoStream *s1, IsoStream *s2))
|
||||||
|
{
|
||||||
|
int rank1, rank2;
|
||||||
|
|
||||||
|
rank1 = iso_get_streamcmprank(cf1, 0);
|
||||||
|
rank2 = iso_get_streamcmprank(cf2, 0);
|
||||||
|
return rank1 < rank2 ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_stream_destroy_cmpranks(int flag)
|
||||||
|
{
|
||||||
|
struct iso_streamcmprank *cpr, *next;
|
||||||
|
|
||||||
|
for (cpr = streamcmpranks; cpr != NULL; cpr = next) {
|
||||||
|
next = cpr->next;
|
||||||
|
LIBISO_FREE_MEM(cpr);
|
||||||
|
}
|
||||||
|
streamcmpranks = NULL;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* API */
|
/* API */
|
||||||
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
|
int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
|
||||||
{
|
{
|
||||||
@ -965,8 +1046,6 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
|
|||||||
dev_t dev_id1, dev_id2;
|
dev_t dev_id1, dev_id2;
|
||||||
ino_t ino_id1, ino_id2;
|
ino_t ino_id1, ino_id2;
|
||||||
off_t size1, size2;
|
off_t size1, size2;
|
||||||
FSrcStreamData *fssd1, *fssd2;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#define Libisofs_stream_cmp_ino_debuG 1
|
#define Libisofs_stream_cmp_ino_debuG 1
|
||||||
@ -983,10 +1062,72 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
|
|||||||
if (s2 == NULL)
|
if (s2 == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (s1->class->version >= 3 && !(flag & 1)) {
|
/* This stays transitive by the fact that
|
||||||
/* Filters may have smarter methods to compare themselves with others */
|
iso_stream_cmp_ifs_sections() is transitive,
|
||||||
ret = s1->class->cmp_ino(s1, s2);
|
returns > 0 if s1 or s2 are applicable,
|
||||||
return ret;
|
ret is -1 if s1 is applicable but s2 is not,
|
||||||
|
ret is 1 if s1 is not applicable but s2 is.
|
||||||
|
|
||||||
|
Proof:
|
||||||
|
Be A the set of applicable streams, S and G transitive and
|
||||||
|
antisymmetric relations in respect to outcome {-1, 0, 1}.
|
||||||
|
The combined relation R shall be defined by
|
||||||
|
I. R(a,b) = S(a,b) if a in A or b in A, else G(a,b)
|
||||||
|
Further S shall have the property
|
||||||
|
II. S(a,b) = -1 if a in A and b not in A
|
||||||
|
Then R can be proven to be transitive:
|
||||||
|
By enumerating the 8 combinations of a,b,c being in A or not, we get
|
||||||
|
5 cases of pure S or pure G. Three cases are mixed:
|
||||||
|
a,b not in A, c in A : G(a,b) == -1, S(b,c) == -1 -> S(a,c) == -1
|
||||||
|
Impossible because S(b,c) == -1 contradicts II.
|
||||||
|
a,c not in A, b in A : S(a,b) == -1, S(b,c) == -1 -> G(a,c) == -1
|
||||||
|
Impossible because S(a,b) == -1 contradicts II.
|
||||||
|
b,c not in A, a in A : S(a,b) == -1, G(b,c) == -1 -> S(a,c) == -1
|
||||||
|
Always true because S(a,c) == -1 by definition II.
|
||||||
|
*/
|
||||||
|
if (iso_stream_cmp_ifs_sections(s1, s2, &ret, 0) > 0)
|
||||||
|
return ret; /* Both are unfiltered from loaded ISO filesystem */
|
||||||
|
|
||||||
|
if (!(flag & 1)) {
|
||||||
|
/* Filters may have smarter methods to compare themselves with others.
|
||||||
|
Transitivity is ensured by ranking mixed pairs by the rank of their
|
||||||
|
comparison functions, and by ranking streams with .cmp_ino lower
|
||||||
|
than streams without.
|
||||||
|
(One could merge (class->version < 3) and (cmp_ino == NULL).)
|
||||||
|
|
||||||
|
Here we define S for "and" rather than "or"
|
||||||
|
I. R(a,b) = S(a,b) if a in A and b in A, else G(a,b)
|
||||||
|
and the function ranking in case of "exor" makes sure that
|
||||||
|
II. G(a,b) = -1 if a in A and b not in A
|
||||||
|
Again we get three mixed cases:
|
||||||
|
a not in A, b,c in A : G(a,b) == -1, S(b,c) == -1 -> G(a,c) == -1
|
||||||
|
Impossible because G(a,b) == -1 contradicts II.
|
||||||
|
b not in A, a,c in A : G(a,b) == -1, G(b,c) == -1 -> S(a,c) == -1
|
||||||
|
Impossible because G(b,c) == -1 contradicts II.
|
||||||
|
c not in A, a,b in A : S(a,b) == -1, G(b,c) == -1 -> G(a,c) == -1
|
||||||
|
Always true because G(a,c) == -1 by definition II.
|
||||||
|
*/
|
||||||
|
if ((s1->class->version >= 3) ^ (s2->class->version >= 3)) {
|
||||||
|
/* One of both has no own com_ino function. Rank it as larger. */
|
||||||
|
return s1->class->version >= 3 ? -1 : 1;
|
||||||
|
} else if (s1->class->version >= 3) {
|
||||||
|
if (s1->class->cmp_ino == s2->class->cmp_ino) {
|
||||||
|
if (s1->class->cmp_ino == NULL) {
|
||||||
|
/* Both are NULL. No decision by .cmp_ino(). */;
|
||||||
|
} else {
|
||||||
|
/* Both are compared by the same function */
|
||||||
|
ret = s1->class->cmp_ino(s1, s2);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Not the same cmp_ino() function. Decide by list rank of
|
||||||
|
function while building the list on the fly.
|
||||||
|
*/
|
||||||
|
ret = iso_cmp_streamcmpranks(s1->class->cmp_ino,
|
||||||
|
s2->class->cmp_ino);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iso_stream_get_id(s1, &fs_id1, &dev_id1, &ino_id1);
|
iso_stream_get_id(s1, &fs_id1, &dev_id1, &ino_id1);
|
||||||
@ -1042,14 +1183,6 @@ int iso_stream_cmp_ino(IsoStream *s1, IsoStream *s2, int flag)
|
|||||||
|
|
||||||
if (s1->class != s2->class)
|
if (s1->class != s2->class)
|
||||||
return (s1->class < s2->class ? -1 : 1);
|
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) {
|
if (fs_id1 == 0 && dev_id1 == 0 && ino_id1 == 0) {
|
||||||
return (s1 < s2 ? -1 : 1);
|
return (s1 < s2 ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
@ -112,4 +112,13 @@ int iso_stream_clone_filter_common(IsoStream *old_stream,
|
|||||||
IsoStream **new_stream,
|
IsoStream **new_stream,
|
||||||
IsoStream **new_input, int flag);
|
IsoStream **new_input, int flag);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispose the internal list of stream class cmp_ino() functions. It is
|
||||||
|
* a static global of stream.c, created and used by iso_stream_cmp_ino().
|
||||||
|
* This function is supposed to be called by iso_finish() only.
|
||||||
|
*/
|
||||||
|
int iso_stream_destroy_cmpranks(int flag);
|
||||||
|
|
||||||
|
|
||||||
#endif /*STREAM_H_*/
|
#endif /*STREAM_H_*/
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2008 Vreixo Formoso
|
* 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
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -108,13 +108,15 @@ struct iso_mbr_partition_request {
|
|||||||
I.e. after the call the submitted storage of req can be disposed or re-used.
|
I.e. after the call the submitted storage of req can be disposed or re-used.
|
||||||
Submit 0 as value flag.
|
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);
|
struct iso_mbr_partition_request *req, int flag);
|
||||||
|
|
||||||
/* Convenience frontend for iso_register_mbr_entry().
|
/* Convenience frontend for iso_register_mbr_entry().
|
||||||
name and type are 0-terminated strings, which may get silently truncated.
|
name and type are 0-terminated strings, which may get silently truncated.
|
||||||
*/
|
*/
|
||||||
int iso_quick_mbr_entry(Ecma119Image *t,
|
int iso_quick_mbr_entry(struct iso_mbr_partition_request **req_array,
|
||||||
|
int *mbr_req_count,
|
||||||
uint64_t start_block, uint64_t block_count,
|
uint64_t start_block, uint64_t block_count,
|
||||||
uint8_t type_byte, uint8_t status_byte,
|
uint8_t type_byte, uint8_t status_byte,
|
||||||
int desired_slot);
|
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
|
Return value is 0 if occupied, 1 if free, and -1 if the slot number is
|
||||||
out of range.
|
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.
|
/* The parameter struct for production of a single Apple Partition Map entry.
|
||||||
See also the partial APM description in doc/boot_sectors.txt.
|
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.
|
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
|
If an entry has start_block <=1, then its block_count will be adjusted
|
||||||
to the final size of the partition map.
|
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).
|
/* Given in blocks of 2 KiB unless (Ecma119Image.apm_req_flags & 4).
|
||||||
Written to the ISO image according to Ecma119Image.apm_block_size.
|
Written to the ISO image according to Ecma119Image.apm_block_size.
|
||||||
*/
|
*/
|
||||||
uint32_t start_block;
|
uint64_t start_block;
|
||||||
uint32_t block_count;
|
uint64_t block_count;
|
||||||
|
|
||||||
/* All 32 bytes get copied to the system area.
|
/* All 32 bytes get copied to the system area.
|
||||||
Take care to pad up short strings by 0.
|
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.
|
I.e. after the call the submitted storage of req can be disposed or re-used.
|
||||||
Submit 0 as value flag.
|
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);
|
struct iso_apm_partition_request *req, int flag);
|
||||||
|
|
||||||
/* Convenience frontend for iso_register_apm_entry().
|
/* Convenience frontend for iso_register_apm_entry().
|
||||||
name and type are 0-terminated strings, which may get silently truncated.
|
name and type are 0-terminated strings, which may get silently truncated.
|
||||||
*/
|
*/
|
||||||
int iso_quick_apm_entry(Ecma119Image *t,
|
int iso_quick_apm_entry(struct iso_apm_partition_request **req_array,
|
||||||
uint32_t start_block, uint32_t block_count, char *name, char *type);
|
int *apm_req_count,
|
||||||
|
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);
|
|
||||||
|
|
||||||
|
|
||||||
/* These two pseudo-random generators produce byte strings which will
|
/* These two pseudo-random generators produce byte strings which will
|
||||||
surely not duplicate in the first 256 calls. If more calls are necessary
|
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 {
|
struct iso_gpt_partition_request {
|
||||||
|
|
||||||
/* Always given in blocks of 2 KiB.
|
/* Always given in blocks of 512 bytes.
|
||||||
Written to the ISO image in blocks of 512.
|
|
||||||
*/
|
*/
|
||||||
uint32_t start_block;
|
uint64_t start_block;
|
||||||
uint32_t block_count;
|
uint64_t block_count;
|
||||||
|
|
||||||
/* The registered GUID which defines the partition type */
|
/* The registered GUID which defines the partition type */
|
||||||
uint8_t type_guid[16];
|
uint8_t type_guid[16];
|
||||||
@ -231,20 +230,26 @@ struct iso_gpt_partition_request {
|
|||||||
Take care to pad up short strings by 0.
|
Take care to pad up short strings by 0.
|
||||||
*/
|
*/
|
||||||
uint8_t name[72];
|
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[].
|
/* 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.
|
I.e. after the call the submitted storage of req can be disposed or re-used.
|
||||||
Submit 0 as value flag.
|
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);
|
struct iso_gpt_partition_request *req, int flag);
|
||||||
|
|
||||||
/* Convenience frontend for iso_register_gpt_entry().
|
/* Convenience frontend for iso_register_gpt_entry().
|
||||||
name has to be already encoded as UTF-16LE.
|
name has to be already encoded as UTF-16LE.
|
||||||
*/
|
*/
|
||||||
int iso_quick_gpt_entry(Ecma119Image *t,
|
int iso_quick_gpt_entry(struct iso_gpt_partition_request **req_array,
|
||||||
uint32_t start_block, uint32_t block_count,
|
int *gpt_req_count,
|
||||||
|
uint64_t start_block, uint64_t block_count,
|
||||||
uint8_t type_guid[16], uint8_t partition_guid[16],
|
uint8_t type_guid[16], uint8_t partition_guid[16],
|
||||||
uint64_t flags, uint8_t name[72]);
|
uint64_t flags, uint8_t name[72]);
|
||||||
|
|
||||||
@ -255,14 +260,41 @@ int iso_write_gpt_header_block(Ecma119Image *t, uint32_t img_blocks,
|
|||||||
uint8_t *buf, uint32_t max_entries,
|
uint8_t *buf, uint32_t max_entries,
|
||||||
uint32_t part_start, uint32_t p_arr_crc);
|
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.
|
/* Creates the Partition Prepend writer.
|
||||||
*/
|
*/
|
||||||
int partprepend_writer_create(Ecma119Image *target);
|
int partprepend_writer_create(Ecma119Image *target);
|
||||||
|
|
||||||
|
/* Creates the Inline Partition Append Writer
|
||||||
|
*/
|
||||||
|
int partappend_writer_create(Ecma119Image *target);
|
||||||
|
|
||||||
/* Creates the GPT backup tail writer.
|
/* Creates the GPT backup tail writer.
|
||||||
*/
|
*/
|
||||||
int gpt_tail_writer_create(Ecma119Image *target);
|
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 */
|
/* Only for up to 36 characters ISO-8859-1 (or ASCII) input */
|
||||||
void iso_ascii_utf_16le(uint8_t gap_name[72]);
|
void iso_ascii_utf_16le(uint8_t gap_name[72]);
|
||||||
|
|
||||||
@ -279,4 +311,10 @@ void iso_ascii_utf_16le(uint8_t gap_name[72]);
|
|||||||
#define Libisofs_grub2_sparc_patch_adr_poS 0x228
|
#define Libisofs_grub2_sparc_patch_adr_poS 0x228
|
||||||
#define Libisofs_grub2_sparc_patch_size_poS 0x230
|
#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_ */
|
#endif /* SYSTEM_AREA_H_ */
|
||||||
|
233
libisofs/tree.c
233
libisofs/tree.c
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2011 - 2014 Thomas Schmitt
|
* Copyright (c) 2011 - 2015 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -100,6 +100,19 @@ int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir)
|
|||||||
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_image_add_new_dir(IsoImage *image, IsoDir *parent, const char *name,
|
||||||
|
IsoDir **dir)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *namept;
|
||||||
|
|
||||||
|
ret = iso_image_truncate_name(image, name, &namept, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_tree_add_new_dir(parent, namept, dir);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new symlink to the directory tree. Permissions are set to 0777,
|
* Add a new symlink to the directory tree. Permissions are set to 0777,
|
||||||
* owner and hidden atts are taken from parent. You can modify any of them
|
* owner and hidden atts are taken from parent. You can modify any of them
|
||||||
@ -175,6 +188,20 @@ int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
|
|||||||
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_image_add_new_symlink(IsoImage *image, IsoDir *parent,
|
||||||
|
const char *name, const char *dest,
|
||||||
|
IsoSymlink **link)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *namept;
|
||||||
|
|
||||||
|
ret = iso_image_truncate_name(image, name, &namept, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_tree_add_new_symlink(parent, namept, dest, link);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new special file to the directory tree. As far as libisofs concerns,
|
* Add a new special file to the directory tree. As far as libisofs concerns,
|
||||||
* an special file is a block device, a character device, a FIFO (named pipe)
|
* an special file is a block device, a character device, a FIFO (named pipe)
|
||||||
@ -264,6 +291,20 @@ int iso_tree_add_new_special(IsoDir *parent, const char *name, mode_t mode,
|
|||||||
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_image_add_new_special(IsoImage *image, IsoDir *parent,
|
||||||
|
const char *name, mode_t mode,
|
||||||
|
dev_t dev, IsoSpecial **special)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *namept;
|
||||||
|
|
||||||
|
ret = iso_image_truncate_name(image, name, &namept, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_tree_add_new_special(parent, namept, mode, dev, special);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new regular file to the iso tree. Permissions are set to 0444,
|
* Add a new regular file to the iso tree. Permissions are set to 0444,
|
||||||
* owner and hidden atts are taken from parent. You can modify any of them
|
* owner and hidden atts are taken from parent. You can modify any of them
|
||||||
@ -339,6 +380,19 @@ int iso_tree_add_new_file(IsoDir *parent, const char *name, IsoStream *stream,
|
|||||||
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
return iso_dir_insert(parent, (IsoNode*)node, pos, ISO_REPLACE_NEVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_image_add_new_file(IsoImage *image, IsoDir *parent, const char *name,
|
||||||
|
IsoStream *stream, IsoFile **file)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *namept;
|
||||||
|
|
||||||
|
ret = iso_image_truncate_name(image, name, &namept, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = iso_tree_add_new_file(parent, namept, stream, file);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether to follow or not symbolic links when added a file from a source
|
* Set whether to follow or not symbolic links when added a file from a source
|
||||||
* to IsoImage.
|
* to IsoImage.
|
||||||
@ -503,7 +557,7 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
|
|||||||
int result;
|
int result;
|
||||||
IsoNode *new;
|
IsoNode *new;
|
||||||
IsoNode **pos;
|
IsoNode **pos;
|
||||||
char *name = NULL;
|
char *name = NULL, *namept;
|
||||||
|
|
||||||
if (parent == NULL || src == NULL || builder == NULL) {
|
if (parent == NULL || src == NULL || builder == NULL) {
|
||||||
result = ISO_NULL_POINTER; goto ex;
|
result = ISO_NULL_POINTER; goto ex;
|
||||||
@ -514,14 +568,18 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
|
|||||||
|
|
||||||
name = iso_file_source_get_name(src);
|
name = iso_file_source_get_name(src);
|
||||||
|
|
||||||
|
result = iso_image_truncate_name(image, name, &namept, 0);
|
||||||
|
if (result < 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
/* find place where to insert */
|
/* find place where to insert */
|
||||||
result = iso_dir_exists(parent, name, &pos);
|
result = iso_dir_exists(parent, namept, &pos);
|
||||||
if (result) {
|
if (result) {
|
||||||
/* a node with same name already exists */
|
/* a node with same name already exists */
|
||||||
result = ISO_NODE_NAME_NOT_UNIQUE; goto ex;
|
result = ISO_NODE_NAME_NOT_UNIQUE; goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = builder->create_node(builder, image, src, name, &new);
|
result = builder->create_node(builder, image, src, namept, &new);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
|
|
||||||
@ -568,6 +626,7 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
|||||||
IsoFileSource *file;
|
IsoFileSource *file;
|
||||||
IsoNode *new;
|
IsoNode *new;
|
||||||
IsoNode **pos;
|
IsoNode **pos;
|
||||||
|
char *namept;
|
||||||
|
|
||||||
if (image == NULL || parent == NULL || name == NULL || path == NULL) {
|
if (image == NULL || parent == NULL || name == NULL || path == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -577,8 +636,12 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
|||||||
*node = NULL;
|
*node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = iso_image_truncate_name(image, name, &namept, 0);
|
||||||
|
if (result < 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
/* find place where to insert */
|
/* find place where to insert */
|
||||||
result = iso_dir_exists(parent, name, &pos);
|
result = iso_dir_exists(parent, namept, &pos);
|
||||||
if (result) {
|
if (result) {
|
||||||
/* a node with same name already exists */
|
/* a node with same name already exists */
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
@ -591,7 +654,7 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
result = image->builder->create_node(image->builder, image, file,
|
result = image->builder->create_node(image->builder, image, file,
|
||||||
(char *) name, &new);
|
namept, &new);
|
||||||
|
|
||||||
/* free the file */
|
/* free the file */
|
||||||
iso_file_source_unref(file);
|
iso_file_source_unref(file);
|
||||||
@ -620,6 +683,7 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
|
|||||||
IsoFile *new;
|
IsoFile *new;
|
||||||
IsoNode **pos;
|
IsoNode **pos;
|
||||||
IsoStream *stream;
|
IsoStream *stream;
|
||||||
|
char *namept;
|
||||||
|
|
||||||
if (image == NULL || parent == NULL || name == NULL || path == NULL) {
|
if (image == NULL || parent == NULL || name == NULL || path == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
@ -629,8 +693,12 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
|
|||||||
*node = NULL;
|
*node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = iso_image_truncate_name(image, name, &namept, 0);
|
||||||
|
if (result < 0)
|
||||||
|
return result;
|
||||||
|
|
||||||
/* find place where to insert */
|
/* find place where to insert */
|
||||||
result = iso_dir_exists(parent, name, &pos);
|
result = iso_dir_exists(parent, namept, &pos);
|
||||||
if (result) {
|
if (result) {
|
||||||
/* a node with same name already exists */
|
/* a node with same name already exists */
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
@ -673,7 +741,7 @@ int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent,
|
|||||||
iso_stream_unref(new->stream);
|
iso_stream_unref(new->stream);
|
||||||
new->stream = stream;
|
new->stream = stream;
|
||||||
|
|
||||||
result = iso_node_set_name((IsoNode*)new, name);
|
result = iso_node_set_name((IsoNode*)new, namept);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
iso_node_unref((IsoNode*)new);
|
iso_node_unref((IsoNode*)new);
|
||||||
return result;
|
return result;
|
||||||
@ -1106,7 +1174,10 @@ int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
|
/* @param flag bit0= truncate according to image truncate mode and length
|
||||||
|
*/
|
||||||
|
int iso_tree_path_to_node_flag(IsoImage *image, const char *path,
|
||||||
|
IsoNode **node, int flag)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
IsoNode *n;
|
IsoNode *n;
|
||||||
@ -1128,6 +1199,8 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ptr = strdup(path);
|
ptr = strdup(path);
|
||||||
|
if (ptr == NULL)
|
||||||
|
return ISO_OUT_OF_MEM;
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
||||||
/* get the first component of the path */
|
/* get the first component of the path */
|
||||||
@ -1140,7 +1213,12 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
|
|||||||
}
|
}
|
||||||
dir = (IsoDir *)n;
|
dir = (IsoDir *)n;
|
||||||
|
|
||||||
result = iso_dir_get_node(dir, component, &n);
|
if ((flag & 1) && image->truncate_mode == 1) {
|
||||||
|
result = iso_dir_get_node_trunc(dir, image->truncate_length,
|
||||||
|
component, &n);
|
||||||
|
} else {
|
||||||
|
result = iso_dir_get_node(dir, component, &n);
|
||||||
|
}
|
||||||
if (result != 1) {
|
if (result != 1) {
|
||||||
n = NULL;
|
n = NULL;
|
||||||
break;
|
break;
|
||||||
@ -1156,6 +1234,16 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
|
||||||
|
{
|
||||||
|
return iso_tree_path_to_node_flag(image, path, node, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int iso_image_path_to_node(IsoImage *image, const char *path, IsoNode **node)
|
||||||
|
{
|
||||||
|
return iso_tree_path_to_node_flag(image, path, node, 1);
|
||||||
|
}
|
||||||
|
|
||||||
char *iso_tree_get_node_path(IsoNode *node)
|
char *iso_tree_get_node_path(IsoNode *node)
|
||||||
{
|
{
|
||||||
char *path = NULL, *parent_path = NULL;
|
char *path = NULL, *parent_path = NULL;
|
||||||
@ -1187,6 +1275,65 @@ ex:;
|
|||||||
return path;
|
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 ------------------------------ */
|
/* ------------------------- tree cloning ------------------------------ */
|
||||||
|
|
||||||
static
|
static
|
||||||
@ -1338,18 +1485,36 @@ int iso_tree_clone_special(IsoSpecial *node,
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* API */
|
|
||||||
int iso_tree_clone(IsoNode *node,
|
/* @param flag bit0= Merge directories rather than ISO_NODE_NAME_NOT_UNIQUE.
|
||||||
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
bit1= issue warning in case of truncation
|
||||||
int flag)
|
*/
|
||||||
|
int iso_tree_clone_trunc(IsoNode *node, IsoDir *new_parent,
|
||||||
|
char *new_name_in, IsoNode **new_node,
|
||||||
|
int truncate_length, int flag)
|
||||||
{
|
{
|
||||||
int ret = ISO_SUCCESS;
|
int ret = ISO_SUCCESS;
|
||||||
|
char *new_name, *trunc = NULL;
|
||||||
|
|
||||||
|
*new_node = NULL;
|
||||||
|
new_name = new_name_in;
|
||||||
|
if (truncate_length >= 64 && (int) strlen(new_name) > truncate_length) {
|
||||||
|
trunc = strdup(new_name);
|
||||||
|
if (trunc == 0) {
|
||||||
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
ret = iso_truncate_rr_name(1, truncate_length, trunc, !(flag & 2));
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
new_name = trunc;
|
||||||
|
}
|
||||||
if (iso_dir_get_node(new_parent, new_name, new_node) == 1) {
|
if (iso_dir_get_node(new_parent, new_name, new_node) == 1) {
|
||||||
if (! (node->type == LIBISO_DIR && (*new_node)->type == LIBISO_DIR &&
|
if (! (node->type == LIBISO_DIR && (*new_node)->type == LIBISO_DIR &&
|
||||||
(flag & 1))) {
|
(flag & 1))) {
|
||||||
*new_node = NULL;
|
*new_node = NULL;
|
||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
ret = ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
flag &= ~1;
|
flag &= ~1;
|
||||||
@ -1370,10 +1535,42 @@ int iso_tree_clone(IsoNode *node,
|
|||||||
ret = ISO_SUCCESS; /* API says they are silently ignored */
|
ret = ISO_SUCCESS; /* API says they are silently ignored */
|
||||||
}
|
}
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
if (flag & 1)
|
if (flag & 1) {
|
||||||
return 2; /* merged two directories, *new_node is not new */
|
ret = 2; /* merged two directories, *new_node is not new */
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
ret = iso_tree_copy_node_attr(node, *new_node, 0);
|
ret = iso_tree_copy_node_attr(node, *new_node, 0);
|
||||||
|
|
||||||
|
ex:;
|
||||||
|
if (trunc != NULL)
|
||||||
|
free(trunc);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_tree_clone(IsoNode *node,
|
||||||
|
IsoDir *new_parent, char *new_name, IsoNode **new_node,
|
||||||
|
int flag)
|
||||||
|
{
|
||||||
|
return iso_tree_clone_trunc(node, new_parent, new_name, new_node, 0,
|
||||||
|
flag & 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_image_tree_clone(IsoImage *image, IsoNode *node, IsoDir *new_parent,
|
||||||
|
char *new_name, IsoNode **new_node, int flag)
|
||||||
|
{
|
||||||
|
int length, ret;
|
||||||
|
|
||||||
|
if (image->truncate_mode == 0)
|
||||||
|
length = 0;
|
||||||
|
else
|
||||||
|
length = image->truncate_length;
|
||||||
|
ret = iso_tree_clone_trunc(node, new_parent, new_name, new_node, length,
|
||||||
|
flag & 3);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,4 +19,9 @@
|
|||||||
*/
|
*/
|
||||||
int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir);
|
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_*/
|
#endif /*LIBISO_IMAGE_TREE_H_*/
|
||||||
|
198
libisofs/util.c
198
libisofs/util.c
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* 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
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -17,6 +17,7 @@
|
|||||||
#include "libisofs.h"
|
#include "libisofs.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "joliet.h"
|
#include "joliet.h"
|
||||||
|
#include "node.h"
|
||||||
#include "../version.h"
|
#include "../version.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -435,6 +436,7 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
|||||||
|
|
||||||
ret_ = malloc(numchars + 1);
|
ret_ = malloc(numchars + 1);
|
||||||
if (ret_ == NULL) {
|
if (ret_ == NULL) {
|
||||||
|
free(wsrc_);
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
outbytes = numchars;
|
outbytes = numchars;
|
||||||
@ -444,7 +446,9 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
|||||||
conv_ret = iso_iconv_open(&conv, "ASCII", "WCHAR_T", 0);
|
conv_ret = iso_iconv_open(&conv, "ASCII", "WCHAR_T", 0);
|
||||||
if (conv_ret <= 0) {
|
if (conv_ret <= 0) {
|
||||||
free(wsrc_);
|
free(wsrc_);
|
||||||
|
wsrc_ = NULL;
|
||||||
free(ret_);
|
free(ret_);
|
||||||
|
ret = ret_ = NULL;
|
||||||
}
|
}
|
||||||
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
|
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
|
||||||
return result;
|
return result;
|
||||||
@ -593,8 +597,10 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
|||||||
loop_limit = inbytes + 3;
|
loop_limit = inbytes + 3;
|
||||||
|
|
||||||
ret_ = malloc((numchars+1) * sizeof(uint16_t));
|
ret_ = malloc((numchars+1) * sizeof(uint16_t));
|
||||||
if (ret_ == NULL)
|
if (ret_ == NULL) {
|
||||||
|
free(wsrc_);
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
outbytes = numchars * sizeof(uint16_t);
|
outbytes = numchars * sizeof(uint16_t);
|
||||||
ret = ret_;
|
ret = ret_;
|
||||||
|
|
||||||
@ -602,7 +608,9 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
|||||||
conv_ret = iso_iconv_open(&conv, "UCS-2BE", "WCHAR_T", 0);
|
conv_ret = iso_iconv_open(&conv, "UCS-2BE", "WCHAR_T", 0);
|
||||||
if (conv_ret <= 0) {
|
if (conv_ret <= 0) {
|
||||||
free(wsrc_);
|
free(wsrc_);
|
||||||
|
wsrc_ = NULL;
|
||||||
free(ret_);
|
free(ret_);
|
||||||
|
ret = ret_ = NULL;
|
||||||
}
|
}
|
||||||
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
|
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
|
||||||
return result;
|
return result;
|
||||||
@ -723,8 +731,10 @@ int str2utf16be(const char *icharset, const char *input, uint16_t **output)
|
|||||||
loop_limit = inbytes + 3;
|
loop_limit = inbytes + 3;
|
||||||
|
|
||||||
ret_ = malloc((2 * numchars+1) * sizeof(uint16_t));
|
ret_ = malloc((2 * numchars+1) * sizeof(uint16_t));
|
||||||
if (ret_ == NULL)
|
if (ret_ == NULL) {
|
||||||
|
free(wsrc_);
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
|
}
|
||||||
outbytes = 2 * numchars * sizeof(uint16_t);
|
outbytes = 2 * numchars * sizeof(uint16_t);
|
||||||
ret = ret_;
|
ret = ret_;
|
||||||
|
|
||||||
@ -1534,6 +1544,26 @@ uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error)
|
|||||||
return v1;
|
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)
|
void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
|
||||||
{
|
{
|
||||||
static int tzsetup = 0;
|
static int tzsetup = 0;
|
||||||
@ -1554,8 +1584,14 @@ void iso_datetime_7(unsigned char *buf, time_t t, int always_gmt)
|
|||||||
#else
|
#else
|
||||||
if (tm.tm_isdst < 0)
|
if (tm.tm_isdst < 0)
|
||||||
tm.tm_isdst = 0;
|
tm.tm_isdst = 0;
|
||||||
tzoffset = ( - timezone / 60 / 15 ) + 4 * tm.tm_isdst;
|
#ifndef Libburnia_timezonE
|
||||||
|
#define Libburnia_timezonE timezone
|
||||||
#endif
|
#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) {
|
if (tzoffset > 52 || tzoffset < -48 || always_gmt) {
|
||||||
/* absurd timezone offset, represent time in GMT */
|
/* absurd timezone offset, represent time in GMT */
|
||||||
@ -1600,8 +1636,14 @@ void iso_datetime_17(unsigned char *buf, time_t t, int always_gmt)
|
|||||||
#else
|
#else
|
||||||
if (tm.tm_isdst < 0)
|
if (tm.tm_isdst < 0)
|
||||||
tm.tm_isdst = 0;
|
tm.tm_isdst = 0;
|
||||||
tzoffset = ( - timezone / 60 / 15 ) + 4 * tm.tm_isdst;
|
#ifndef Libburnia_timezonE
|
||||||
|
#define Libburnia_timezonE timezone
|
||||||
#endif
|
#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) {
|
if (tzoffset > 52 || tzoffset < -48 || always_gmt) {
|
||||||
/* absurd timezone offset, represent time in GMT */
|
/* absurd timezone offset, represent time in GMT */
|
||||||
@ -1762,6 +1804,7 @@ time_t iso_datetime_read_7(const uint8_t *buf)
|
|||||||
tm.tm_hour = buf[3];
|
tm.tm_hour = buf[3];
|
||||||
tm.tm_min = buf[4];
|
tm.tm_min = buf[4];
|
||||||
tm.tm_sec = buf[5];
|
tm.tm_sec = buf[5];
|
||||||
|
tm.tm_isdst = 0;
|
||||||
|
|
||||||
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
|
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
|
||||||
}
|
}
|
||||||
@ -1778,6 +1821,7 @@ time_t iso_datetime_read_17(const uint8_t *buf)
|
|||||||
sscanf((char*)&buf[12], "%2d", &tm.tm_sec);
|
sscanf((char*)&buf[12], "%2d", &tm.tm_sec);
|
||||||
tm.tm_year -= 1900;
|
tm.tm_year -= 1900;
|
||||||
tm.tm_mon -= 1;
|
tm.tm_mon -= 1;
|
||||||
|
tm.tm_isdst = 0;
|
||||||
|
|
||||||
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
|
return timegm(&tm) - ((int8_t)buf[6]) * 60 * 15;
|
||||||
}
|
}
|
||||||
@ -2011,6 +2055,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 iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
@ -2183,6 +2238,7 @@ unexpected_type:;
|
|||||||
goto ex;
|
goto ex;
|
||||||
} else if (range_start != ctx_start_lba) {
|
} else if (range_start != ctx_start_lba) {
|
||||||
ret = ISO_MD5_TAG_MISPLACED;
|
ret = ISO_MD5_TAG_MISPLACED;
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
ret = iso_md5_clone(ctx, &cloned_ctx);
|
ret = iso_md5_clone(ctx, &cloned_ctx);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -2251,7 +2307,7 @@ int iso_clone_mem(char *in, char **out, size_t size)
|
|||||||
if (*out == NULL)
|
if (*out == NULL)
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
memcpy(*out, in, size);
|
memcpy(*out, in, size);
|
||||||
return 1;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2262,3 +2318,133 @@ int iso_clone_mgtd_mem(char *in, char **out, size_t size)
|
|||||||
return iso_clone_mem(in, out, size);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Find backward from idx the start byte of a possible UTF-8 character.
|
||||||
|
https://en.wikipedia.org/wiki/UTF-8#Description
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
int find_utf8_start(char *name, int idx, int flag)
|
||||||
|
{
|
||||||
|
unsigned char *uname, uch;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
uname= (unsigned char *) name;
|
||||||
|
if ((uname[idx] & 0xc0) != 0x80)
|
||||||
|
return idx; /* not an UTF-8 tail byte */
|
||||||
|
for (i = 0; i < 5 && idx - 1 - i >= 0; i++) { /* up to deprecated 6-byte codes */
|
||||||
|
uch = uname[idx - 1 - i];
|
||||||
|
if ((uch & 0xe0) == 0xc0 || (uch & 0xf0) == 0xe0 ||
|
||||||
|
(uch & 0xf8) == 0xf0 || (uch & 0xfc) == 0xf8 ||
|
||||||
|
(uch & 0xfe) == 0xfc)
|
||||||
|
return (idx - 1 - i); /* UTF-8 start byte found */
|
||||||
|
if ((uch & 0xc0) != 0x80)
|
||||||
|
return idx; /* not an UTF-8 tail byte, so no UTF-8 */
|
||||||
|
}
|
||||||
|
return idx; /* no UTF-8 start found */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @param flag bit0= do not issue warning message
|
||||||
|
*/
|
||||||
|
int iso_truncate_rr_name(int truncate_mode, int truncate_length,
|
||||||
|
char *name, int flag)
|
||||||
|
{
|
||||||
|
int neck, goal, ret, l, i;
|
||||||
|
static int hash_size = 32;
|
||||||
|
void *ctx = NULL;
|
||||||
|
char hashval[16];
|
||||||
|
|
||||||
|
l = strlen(name);
|
||||||
|
if (l <= truncate_length)
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
if (truncate_mode == 0)
|
||||||
|
return ISO_RR_NAME_TOO_LONG;
|
||||||
|
|
||||||
|
/* Compute hash */
|
||||||
|
ret = iso_md5_start(&ctx);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
ret = iso_md5_compute(ctx, name, l > 4095 ? 4095 : l);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
ret = iso_md5_end(&ctx, hashval);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
|
||||||
|
if (!(flag & 1))
|
||||||
|
iso_msg_submit(-1, ISO_RR_NAME_TRUNCATED, 0,
|
||||||
|
"File name had to be truncated and MD5 marked: %s", name);
|
||||||
|
|
||||||
|
/* Avoid to produce incomplete UTF-8 characters */
|
||||||
|
goal = truncate_length - hash_size - 1;
|
||||||
|
neck = find_utf8_start(name, goal, 0);
|
||||||
|
for (; neck < goal; neck++)
|
||||||
|
name[neck] = '_';
|
||||||
|
|
||||||
|
/* Write colon and hash text over end of truncated name */
|
||||||
|
name[goal] = ':';
|
||||||
|
goal++;
|
||||||
|
for (i = 0; goal < truncate_length - 1 && i < hash_size / 2; goal += 2) {
|
||||||
|
sprintf(name + goal, "%2.2x", *((unsigned char *) (hashval + i)));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
name[truncate_length] = 0;
|
||||||
|
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (ctx != NULL)
|
||||||
|
iso_md5_end(&ctx, hashval);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* API */
|
||||||
|
int iso_truncate_leaf_name(int mode, int length, char *name, int flag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mode < 0 || mode > 1)
|
||||||
|
return ISO_WRONG_ARG_VALUE;
|
||||||
|
if (length < 64 || length > LIBISOFS_NODE_NAME_MAX)
|
||||||
|
return ISO_WRONG_ARG_VALUE;
|
||||||
|
ret = iso_truncate_rr_name(mode, length, name, 1);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,12 @@
|
|||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_STDLIB_H
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#ifndef MAX
|
#ifndef MAX
|
||||||
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
@ -273,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);
|
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)
|
* Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5)
|
||||||
*
|
*
|
||||||
@ -398,6 +407,12 @@ size_t iso_rbtree_get_size(IsoRBTree *tree);
|
|||||||
void **iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
|
void **iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
|
||||||
size_t *size);
|
size_t *size);
|
||||||
|
|
||||||
|
/** Predict the size of the array which gets returned by iso_rbtree_to_array().
|
||||||
|
*/
|
||||||
|
size_t iso_rbtree_count_array(IsoRBTree *tree, size_t initial_count,
|
||||||
|
int (*include_item)(void *));
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new hash table.
|
* Create a new hash table.
|
||||||
*
|
*
|
||||||
@ -544,6 +559,14 @@ 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_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);
|
||||||
|
|
||||||
|
int iso_truncate_rr_name(int truncate_mode, int truncate_length,
|
||||||
|
char *name, int flag);
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* In md5.h these function prototypes would be neighbors of (Ecma119Image *)
|
/* In md5.h these function prototypes would be neighbors of (Ecma119Image *)
|
||||||
@ -618,6 +641,16 @@ int iso_clone_mem(char *in, char **out, size_t size);
|
|||||||
*/
|
*/
|
||||||
int iso_clone_mgtd_mem(char *in, char **out, size_t size);
|
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) 2007 Vreixo Formoso
|
||||||
|
* Copyright (c) 2014 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* 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;
|
IsoHTable *t;
|
||||||
|
|
||||||
if (table == NULL) {
|
if (size <= 0)
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_WRONG_ARG_VALUE;
|
||||||
}
|
if (table == NULL)
|
||||||
|
return ISO_NULL_POINTER;
|
||||||
|
|
||||||
t = malloc(sizeof(IsoHTable));
|
t = malloc(sizeof(IsoHTable));
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
|
@ -308,3 +308,38 @@ void ** iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *),
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
size_t rbtree_count_array_aux(struct iso_rbnode *root, size_t pos,
|
||||||
|
int (*include_item)(void *))
|
||||||
|
{
|
||||||
|
if (root == NULL) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
pos = rbtree_count_array_aux(root->ch[0], pos, include_item);
|
||||||
|
if (include_item == NULL || include_item(root->data)) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
IsoFileSrc* src = (IsoFileSrc*) root->data;
|
||||||
|
fprintf(stderr, "libisofs_DEBUG: rbtree_count_array_aux : not taken : '%s'\n",
|
||||||
|
iso_stream_get_source_path(src->stream, 0));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
pos = rbtree_count_array_aux(root->ch[1], pos, include_item);
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t iso_rbtree_count_array(IsoRBTree *tree, size_t initial_count,
|
||||||
|
int (*include_item)(void *))
|
||||||
|
{
|
||||||
|
size_t pos;
|
||||||
|
|
||||||
|
pos = rbtree_count_array_aux(tree->root, initial_count, include_item);
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user