Compare commits
123 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
125789feef | |||
37efffcf26 | |||
b2c281d0c6 | |||
8a2fa9fe2e | |||
1247edff95 | |||
a2fe1a4100 | |||
4eb4146474 | |||
ce35aefb32 | |||
269e0b19a5 | |||
0a8bb0e9b8 | |||
76f2a5f4d3 | |||
e49f9672bc | |||
37f880797d | |||
475eb36978 | |||
ac9116c64e | |||
b1c218c280 | |||
ebea7c29ef | |||
09c49f777a | |||
5f76be9d76 | |||
305fe3f496 | |||
191c3245af | |||
b5b30b1c75 | |||
6a1bbaa902 | |||
bddc44d1ca | |||
9b61ff377c | |||
22fed6bedb | |||
3433592f69 | |||
d787ecbcd9 | |||
182edb3a00 | |||
cb25d4d4e5 | |||
afdef92343 | |||
2bc7084315 | |||
6d10908a58 | |||
2ba54fafe7 | |||
ca63dac7e3 | |||
f885da8087 | |||
8438db02cf | |||
ce19db5e19 | |||
aeb5258ae2 | |||
f10c2d7779 | |||
82bfcf429a | |||
8fb8c01a0f | |||
73910e2f3c | |||
9c5fc21679 | |||
3a82f213e0 | |||
6892c734e2 | |||
66f6937c17 | |||
baa5b7cd42 | |||
f2658ef173 | |||
ecdb3aeb1d | |||
745a878884 | |||
6ae8386c23 | |||
b90e613246 | |||
bbc3caf86b | |||
b086d53274 | |||
17b36623a6 | |||
286648574d | |||
317bba395e | |||
541b41b6a1 | |||
91a8be5262 | |||
91e99703b4 | |||
dd7dac3397 | |||
43d4833dd6 | |||
dd1629b5ca | |||
bc8138ce78 | |||
2d568c1dbb | |||
842b62d111 | |||
4f3357e3ec | |||
9ffe91c372 | |||
7e2add413a | |||
004aefd0b7 | |||
00955ba85c | |||
4a79812d15 | |||
9b2f97e4b7 | |||
35cfb756be | |||
2835fccfa4 | |||
31c7f68990 | |||
4e0ca258de | |||
9653854462 | |||
6e95f8bbcb | |||
ce3aa0d5c7 | |||
d5bfc552c4 | |||
bad54a5967 | |||
49b0a89bfe | |||
265df5fbe3 | |||
f089bcf66a | |||
062e5f0bf0 | |||
d932bfcdea | |||
3ef67cb49d | |||
f08ae22dbe | |||
45d316d1ca | |||
4d8fc6ffee | |||
023e413624 | |||
d361186bca | |||
e7d9559d16 | |||
94eecbb123 | |||
777f74ea0b | |||
2b8d47ddd8 | |||
e839b7b368 | |||
1334027a83 | |||
8d3a0a6a9e | |||
7b7ea41f12 | |||
bb5886094e | |||
b076ce9b44 | |||
05f26898f3 | |||
a698f0ee22 | |||
e69854b35f | |||
228995c148 | |||
071e14f9b0 | |||
b08d6271ab | |||
431d31fff6 | |||
a37571c6c5 | |||
6e98006640 | |||
d264e818c3 | |||
d0f740facf | |||
944b5a6152 | |||
b51232fef4 | |||
99f037e210 | |||
c794a48a06 | |||
47d599e8c3 | |||
0a87e838df | |||
e945e38add | |||
6d68abc707 |
41
ChangeLog
41
ChangeLog
@ -1,3 +1,44 @@
|
||||
bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.2.2.tar.gz)
|
||||
===============================================================================
|
||||
* New API call iso_write_opts_set_rr_reloc()
|
||||
* Bug fix: Directory name mapping to ISO level 1 was too liberal if
|
||||
iso_write_opts_set_allow_dir_id_ext() was enabled
|
||||
* New API call iso_write_opts_set_allow_7bit_ascii()
|
||||
* Improved standards compliance for ISO level 1 names with partly relaxed
|
||||
constraints.
|
||||
|
||||
|
||||
libisofs-1.2.0.tar.gz Sat Jan 28 2012
|
||||
===============================================================================
|
||||
* Extended influence of iso_write_opts_set_dir_rec_mtime() to Joliet and
|
||||
ISO 9660:1999.
|
||||
|
||||
libisofs-1.1.6.tar.gz Tue Sep 27 2011
|
||||
===============================================================================
|
||||
* Bug fix: On Solaris: False out-of-memory errors when writing images.
|
||||
* Bug fix: On FreeBSD: No ACLs were recorded.
|
||||
* Bug fix: ACL entries of groups and of user id 0 were not properly recorded
|
||||
and cannot be restored.
|
||||
* Bug fix: On FreeBSD: The function for restoring ACLs and xattr returned
|
||||
error, even if no xattr were to be restored.
|
||||
* New API call iso_local_attr_support()
|
||||
* Enabled recording and restoring of extattr on FreeBSD.
|
||||
|
||||
libisofs-1.1.4.tar.gz Mon Aug 08 2011
|
||||
===============================================================================
|
||||
* Bug fix: The function for restoring ACLs and xattr returned error on systems
|
||||
other than Linux and FreeBSD, even if nothing was to be restored.
|
||||
|
||||
libisofs-1.1.2.tar.gz Fri Jul 08 2011
|
||||
===============================================================================
|
||||
* New API call iso_image_get_bootcat()
|
||||
|
||||
libisofs-1.1.0.tar.gz Sat Jun 18 2011
|
||||
===============================================================================
|
||||
* Bug fix: Padding as of iso_write_opts_set_tail_blocks() was added only
|
||||
after cylinder alignment as of iso_write_opts_set_system_area()
|
||||
and thus spoiled this alignment.
|
||||
|
||||
libisofs-1.0.8.tar.gz Thu May 12 2011
|
||||
===============================================================================
|
||||
* Bug fix: iso_write_opts_set_system_area() with system area types
|
||||
|
@ -6,6 +6,7 @@ pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
|
||||
libincludedir=$(includedir)/libisofs
|
||||
|
||||
lib_LTLIBRARIES = libisofs/libisofs.la
|
||||
ACLOCAL_AMFLAGS = -I ./
|
||||
|
||||
## ========================================================================= ##
|
||||
|
||||
@ -219,6 +220,12 @@ demo_demo_SOURCES = demo/demo.c
|
||||
# test/mocked_fsrc.h \
|
||||
# test/mocked_fsrc.c
|
||||
|
||||
# "make clean" shall remove a few stubborn .libs directories
|
||||
# which George Danchev reported Dec 03 2011.
|
||||
# Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean
|
||||
clean-local:
|
||||
-rm -rf demo/.libs
|
||||
|
||||
## ========================================================================= ##
|
||||
|
||||
## Build documentation (You need Doxygen for this to work)
|
||||
@ -249,6 +256,7 @@ nodist_pkgconfig_DATA = \
|
||||
# ts A80114 : added aaip-os*
|
||||
|
||||
EXTRA_DIST = \
|
||||
bootstrap \
|
||||
libisofs-1.pc.in \
|
||||
version.h.in \
|
||||
doc/doxygen.conf.in \
|
||||
|
@ -1,10 +1,7 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
aclocal
|
||||
aclocal -I .
|
||||
libtoolize --copy --force
|
||||
autoconf
|
||||
|
||||
# ts A61101 : libburn is not prepared for config.h
|
||||
# autoheader
|
||||
|
||||
automake --foreign --add-missing --copy --include-deps
|
||||
|
31
configure.ac
31
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libisofs], [1.0.8], [http://libburnia-project.org])
|
||||
AC_INIT([libisofs], [1.2.2], [http://libburnia-project.org])
|
||||
AC_PREREQ([2.50])
|
||||
dnl AC_CONFIG_HEADER([config.h])
|
||||
|
||||
@ -8,6 +8,7 @@ AC_CANONICAL_TARGET
|
||||
LIBBURNIA_SET_FLAGS
|
||||
|
||||
AM_INIT_AUTOMAKE([subdir-objects])
|
||||
AC_CONFIG_MACRO_DIR([./])
|
||||
|
||||
dnl
|
||||
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
|
||||
@ -39,8 +40,8 @@ dnl
|
||||
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||
dnl
|
||||
LIBISOFS_MAJOR_VERSION=1
|
||||
LIBISOFS_MINOR_VERSION=0
|
||||
LIBISOFS_MICRO_VERSION=8
|
||||
LIBISOFS_MINOR_VERSION=2
|
||||
LIBISOFS_MICRO_VERSION=2
|
||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||
|
||||
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
||||
@ -50,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
|
||||
|
||||
dnl Libtool versioning
|
||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||
# 2011.05.12 development jump has not yet happened
|
||||
# SONAME = 52 - 46 = 6 . Library name = libisofs.6.46.0
|
||||
LT_CURRENT=52
|
||||
LT_AGE=46
|
||||
# 2012.01.28 development jump has not yet happened
|
||||
# SONAME = 64 - 58 = 6 . Library name = libisofs.6.58.0
|
||||
LT_CURRENT=64
|
||||
LT_AGE=58
|
||||
LT_REVISION=0
|
||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||
|
||||
@ -139,7 +140,7 @@ if test x$enable_debug != xyes; then
|
||||
CFLAGS="-DNDEBUG $CFLAGS"
|
||||
else
|
||||
if test x$GCC = xyes; then
|
||||
CFLAGS="-g -pedantic -Wall $CFLAGS"
|
||||
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter $CFLAGS"
|
||||
fi
|
||||
CFLAGS="-DDEBUG $CFLAGS"
|
||||
fi
|
||||
@ -159,14 +160,19 @@ LIBBURNIA_SET_PKGCONFIG
|
||||
dnl Add compiler-specific flags
|
||||
|
||||
AC_ARG_ENABLE(libacl,
|
||||
[ --enable-libacl Enable use of libacl by libisofs, default=yes],
|
||||
[ --enable-libacl Enable use of ACL functions by libisofs, default=yes],
|
||||
, enable_libacl=yes)
|
||||
if test "x$enable_libacl" = xyes; then
|
||||
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
|
||||
LIBACL_DEF="-DLibisofs_with_aaip_acL"
|
||||
dnl The empty yes case obviously causes -lacl to be linked
|
||||
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , LIBACL_DEF= ), LIBACL_DEF= )
|
||||
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= )
|
||||
if test "$has_acl_h_but_no_libacl" = 1
|
||||
then
|
||||
AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= )
|
||||
fi
|
||||
else
|
||||
LIBACL_DEF=
|
||||
fi
|
||||
@ -182,6 +188,11 @@ dnl Check whether there is the header for Linux xattr.
|
||||
dnl If not, erase this macro which would enable use of listxattr and others
|
||||
XATTR_DEF="-DLibisofs_with_aaip_xattR"
|
||||
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= , XATTR_DEF= ), XATTR_DEF= )
|
||||
if test "x$XATTR_DEF" = x
|
||||
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
|
||||
else
|
||||
XATTR_DEF=
|
||||
fi
|
||||
|
159
doc/iso_hybrid_fs.txt
Normal file
159
doc/iso_hybrid_fs.txt
Normal file
@ -0,0 +1,159 @@
|
||||
|
||||
Overview of ISO 9660 hybrid filesystems as libisofs output
|
||||
|
||||
by Thomas Schmitt - mailto:scdbackup@gmx.net
|
||||
Libburnia project - mailto:libburn-hackers@pykix.org
|
||||
21 Feb 2012
|
||||
|
||||
|
||||
The overall framework for the filesystem images produced by libisofs is given
|
||||
by ECMA-119, which is also known as ISO 9660. The hybrid aspect is the
|
||||
opportunity to add access structures of other filesystems.
|
||||
|
||||
The framework suggests a logical block size of 2048 and divides the space of
|
||||
filesystem blocks into several parts:
|
||||
|
||||
- The System Area. Beginning at the image start block.
|
||||
32 KiB of arbitrary data, which are not considered to be
|
||||
part of structure or payload of the ISO image.
|
||||
|
||||
- The Volume Descriptors. Beginning at image start block + 16.
|
||||
The Primary Volume Descriptor block is the starting point of the ECMA-119
|
||||
tree of directories and files. Among other information, it records the size
|
||||
of the image block space. Other descriptor blocks may lead to boot images
|
||||
or to the directory trees of add-on filesystems (e.g. Joliet).
|
||||
|
||||
- The area of directory structures and data file content.
|
||||
libisofs divides it into two sub areas:
|
||||
|
||||
- Directory structures.
|
||||
They record the file names and attributes of the ECMA-119 tree and
|
||||
of eventual add-on filesystem.
|
||||
|
||||
- Data file content.
|
||||
The blocks in this area are referred by zero or more file entries in the
|
||||
directory trees. They store the data content or regular files. Start block
|
||||
address of a file and exact byte count are stored in the trees.
|
||||
|
||||
|
||||
libisofs may slide-in some data blocks which are neither part of the structure
|
||||
nor part of file content. See doc/checksums.txt, Checksum Array, Checksum Tags.
|
||||
In the same way, the superblocks of other filesystems could be inserted into
|
||||
the image.
|
||||
|
||||
The only block addresses which are fixely occupied are image_start+16 (Primary
|
||||
Volume Descriptor) and image_start+17 (first possible position of Volume
|
||||
Descriptor Set Terminator).
|
||||
Nevertheless, libisofs considers as reserved the blocks image_start+16 to
|
||||
image_start+31, because add-ons like El Torito, Joliet, or ISO 9660:1999
|
||||
need their own volume descriptors stored before the volume descriptor set
|
||||
terminator block. Only one volume descriptor per add-on filesystem may be
|
||||
written there, and its exact position will be chosen by libisofs.
|
||||
|
||||
|
||||
The System Area in image_start to image_start+15 may be used for a partition
|
||||
table or the superblock of an additional filesystem structure.
|
||||
Another place for superblocks is after image_start+31. E.g. UDF stores its
|
||||
Anchor at block address 256, or at media_size - 1 - 256, or at media_size - 1.
|
||||
|
||||
In both cases the superblocks would point to filesystem-specific data which
|
||||
are stored in the area of directory structures. These data would then refer to
|
||||
the same file contents as the ECMA-119 directory structure.
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
What libisofs needs to get implemented for a new add-on filesystem:
|
||||
|
||||
The emerging overall image is represented by an Ecma119Image object.
|
||||
This is an instance of quite fat struct ecma119_image which, among many
|
||||
others, holds some parameters which are specific to the implemented add-on
|
||||
filesystems. It is defined in libisofs/ecma119.h.
|
||||
It gets programmed by applications via API calls for IsoWriteOpts which is
|
||||
defined as struct iso_write_opts in libisofs/ecma119.h.
|
||||
|
||||
|
||||
The content of the System Area may be submitted opaquely via
|
||||
Ecma119Image.system_area_data or it may get generated underneath
|
||||
libisofs/system_area.c:iso_write_system_area() by a specific "System area type"
|
||||
in Ecma119Image.system_area_options. The latter happens when the block adresses
|
||||
of all components, directories, and files are determined. (One may have to
|
||||
dig deep in the graph of objects to obtain everything.)
|
||||
|
||||
If a new system area type is needed, then it has to be documented in
|
||||
libisofs/ecma119.h at struct ecma119_image.system_area_options and in
|
||||
libisofs/libisofs.h at call iso_write_opts_set_system_area(). See e.g.
|
||||
"MIPS Big Endian Volume Header".
|
||||
|
||||
|
||||
The layout of the areas above image_start+16 is defined in function
|
||||
libisofs/ecma119.c:ecma119_image_new(). This is done by creating and
|
||||
registering writer objects.
|
||||
Writers are instances of typedef struct Iso_Image_Writer IsoImageWriter.
|
||||
The struct is defined in libisofs/writer.h.
|
||||
|
||||
The Joliet writer is a comprehensive example of an add-on filesystem writer.
|
||||
|
||||
First it gets counted for the allocation of the registration array
|
||||
if (target->joliet) {
|
||||
nwriters++;
|
||||
}
|
||||
|
||||
Later it gets created and registered
|
||||
if (target->joliet) {
|
||||
ret = joliet_writer_create(target);
|
||||
|
||||
The function libisofs/joliet.c:joliet_writer_create() accounts for one block
|
||||
that will hold the Joliet volume descriptor
|
||||
/* we need the volume descriptor */
|
||||
target->curblock++;
|
||||
Not all add-on filesystems will need a volume descriptor. Joliet does.
|
||||
|
||||
joliet_writer_create() further generates a tree of JolietNode objects by
|
||||
traversing the image model tree of IsoNode objects.
|
||||
ret = joliet_tree_create(target);
|
||||
If a JolietNode represents a regular file then it refers to an IsoFileSrc
|
||||
object, which represents its data content in the emerging image.
|
||||
struct Iso_File_Src is defined in libisofs/filesrc.h.
|
||||
|
||||
|
||||
libisofs will call the methods of the writer object when it computes the
|
||||
block addresses of the various image components, when it writes volume
|
||||
descriptors, when it writes directory trees, and when it finally disposes the
|
||||
Ecma119Image object.
|
||||
|
||||
The method IsoImageWriter.compute_data_blocks() has to predict the storage
|
||||
needs in the area of directory trees.
|
||||
It computes and records Joliet-specific addresses and sizes:
|
||||
Ecma119Image.joliet_ndirs, Ecma119Image.joliet_l_path_table_pos,
|
||||
Ecma119Image.joliet_m_path_table_pos , Ecma119Image.joliet_path_table_size
|
||||
Ecma119Image.j_part_l_path_table_pos, Ecma119Image.j_part_m_path_table_pos
|
||||
as well as the sizes and block addresses of Joliet directories.
|
||||
It increases the counter of virtually written blocks:
|
||||
Ecma119Image.curblock
|
||||
which is used to determine the start addresses of the image parts and
|
||||
finally gives the overall image size.
|
||||
|
||||
The method IsoImageWriter.write_vol_desc() composes and writes the Joliet
|
||||
volume descriptor. (Such writing is not necessarily needed for add-on
|
||||
filesystems.)
|
||||
|
||||
IsoImageWriter.write_data() writes the records of the Joliet directory tree.
|
||||
This has to be exactly the same number of blocks by which Ecma119Image.curblock
|
||||
was increased during IsoImageWriter.compute_data_blocks().
|
||||
When it gets called, the number of content data extents, their sizes, and their
|
||||
addresses are known: JolietNode.IsoFileSrc->nsections, ->sections[].size,
|
||||
->sections[].block.
|
||||
struct iso_file_section is defined in libisofs/libisofs.h.
|
||||
|
||||
IsoImageWriter.free_data() disposes the writer and the JolietNode tree.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This text is under
|
||||
Copyright (c) 2012 Thomas Schmitt <scdbackup@gmx.net>
|
||||
It shall only be modified in sync with libisofs. Please mail change requests to
|
||||
mailing list <libburn-hackers@pykix.org> or to the copyright holder in private.
|
||||
If you make use of the license to derive modified versions of libisofs then
|
||||
you are entitled to modify this text under that same license.
|
||||
|
@ -157,9 +157,10 @@ types. "system." is file system dependent and often restricted in the
|
||||
choice of names. "user." is portable and allows to choose about any name.
|
||||
|
||||
Namespace "isofs." is defined for internal use of AAIP enhanced ISO 9660
|
||||
file systems. Names in this namespace should be registered at libburnia.org.
|
||||
file systems. Names in this namespace should be registered at
|
||||
libburnia-project.org.
|
||||
|
||||
Further namespaces may be registered at libburnia.org.
|
||||
Further namespaces may be registered at libburnia-project.org.
|
||||
|
||||
The reserved start bytes of names have the following meaning
|
||||
0x01 escape reserved character at start of name
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
To be included by aaip_0_2.c
|
||||
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
@ -28,6 +28,29 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
/* ------------------------------ Inquiry --------------------------------- */
|
||||
|
||||
/* See also API iso_local_attr_support().
|
||||
@param flag
|
||||
Bitfield for control purposes
|
||||
bit0= inquire availability of ACL
|
||||
bit1= inquire availability of xattr
|
||||
bit2 - bit7= Reserved for future types.
|
||||
It is permissibile to set them to 1 already now.
|
||||
bit8 and higher: reserved, submit 0
|
||||
@return
|
||||
Bitfield corresponding to flag. If bits are set, th
|
||||
bit0= ACL adapter is enabled
|
||||
bit1= xattr adapter is enabled
|
||||
bit2 - bit7= Reserved for future types.
|
||||
bit8 and higher: reserved, do not interpret these
|
||||
*/
|
||||
int aaip_local_attr_support(int flag)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------ Getters --------------------------------- */
|
||||
|
||||
/* Obtain the ACL of the given file in long text form.
|
||||
@ -89,7 +112,11 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
continue;
|
||||
}
|
||||
/* Extended Attribute */
|
||||
if(!(flag & 4))
|
||||
if(flag & 4)
|
||||
continue;
|
||||
if(!(flag & 8))
|
||||
if(strncmp(names[i], "user.", 5))
|
||||
continue;
|
||||
return(-6);
|
||||
}
|
||||
if(flag & 2)
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
To be included by aaip_0_2.c
|
||||
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
@ -24,15 +24,51 @@
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef Libisofs_with_aaip_acL
|
||||
/* It seems ACL is fixely integrated in FreeBSD libc. There is no libacl. */
|
||||
#define Libisofs_with_aaip_acL yes
|
||||
#endif
|
||||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
#include <sys/extattr.h>
|
||||
#endif
|
||||
|
||||
/* <<< Use old ACL adapter code that is unable to deal with extattr */
|
||||
/* # define Libisofs_old_freebsd_acl_adapteR */
|
||||
|
||||
|
||||
/* ------------------------------ Inquiry --------------------------------- */
|
||||
|
||||
/* See also API iso_local_attr_support().
|
||||
@param flag
|
||||
Bitfield for control purposes
|
||||
bit0= inquire availability of ACL
|
||||
bit1= inquire availability of xattr
|
||||
bit2 - bit7= Reserved for future types.
|
||||
It is permissibile to set them to 1 already now.
|
||||
bit8 and higher: reserved, submit 0
|
||||
@return
|
||||
Bitfield corresponding to flag. If bits are set, th
|
||||
bit0= ACL adapter is enabled
|
||||
bit1= xattr adapter is enabled
|
||||
bit2 - bit7= Reserved for future types.
|
||||
bit8 and higher: reserved, do not interpret these
|
||||
*/
|
||||
int aaip_local_attr_support(int flag)
|
||||
{
|
||||
int ret= 0;
|
||||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
if(flag & 1)
|
||||
ret|= 1;
|
||||
#endif
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
if(flag & 2)
|
||||
ret|= 2;
|
||||
#endif
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------ Getters --------------------------------- */
|
||||
|
||||
@ -137,6 +173,349 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
||||
}
|
||||
|
||||
|
||||
#ifndef Libisofs_old_freebsd_acl_adapteR
|
||||
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
|
||||
/*
|
||||
@param flag Bitfield for control purposes
|
||||
bit5= in case of symbolic link: inquire link target
|
||||
*/
|
||||
static int aaip_extattr_make_list(char *path, int attrnamespace,
|
||||
char **list, ssize_t *list_size, int flag)
|
||||
{
|
||||
*list= NULL;
|
||||
*list_size= 0;
|
||||
|
||||
/* man 2 extattr_list_file:
|
||||
If data is NULL in a call to extattr_get_file() and extattr_list_file()
|
||||
then the size of defined extended attribute data will be returned,
|
||||
*/
|
||||
if(flag & 32) /* follow link */
|
||||
*list_size= extattr_list_file(path, attrnamespace, NULL, (size_t) 0);
|
||||
else
|
||||
*list_size= extattr_list_link(path, attrnamespace, NULL, (size_t) 0);
|
||||
if(*list_size == -1)
|
||||
return(0);
|
||||
if(*list_size == 0)
|
||||
return(2);
|
||||
*list= calloc(*list_size, 1);
|
||||
if(*list == NULL)
|
||||
return(-1);
|
||||
if(flag & 32)
|
||||
*list_size= extattr_list_file(path, attrnamespace, *list,
|
||||
(size_t) *list_size);
|
||||
else
|
||||
*list_size= extattr_list_link(path, attrnamespace, *list,
|
||||
(size_t) *list_size);
|
||||
if(*list_size == -1)
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= preserve existing namelist content
|
||||
bit1= ignore names with NUL rather than returning error
|
||||
*/
|
||||
static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
|
||||
char *list, ssize_t list_size,
|
||||
char **namelist, ssize_t *namelist_size,
|
||||
ssize_t *num_names, int flag)
|
||||
{
|
||||
int i, j, len, new_bytes= 0, space_len;
|
||||
char *new_list= NULL, *wpt;
|
||||
|
||||
if(!(flag & 1)) {
|
||||
*namelist= NULL;
|
||||
*namelist_size= 0;
|
||||
*num_names= 0;
|
||||
}
|
||||
if(list_size <= 0)
|
||||
return(1);
|
||||
space_len= strlen(attrnamespace);
|
||||
for(i= 0; i < list_size; i+= len + 1) {
|
||||
len= *((unsigned char *) (list + i));
|
||||
if(len == 0)
|
||||
return ISO_AAIP_BAD_ATTR_NAME; /* empty name is reserved for ACL */
|
||||
for(j= 0; j < len; j++)
|
||||
if(list[i + 1 + j] == 0) {
|
||||
if(flag & 2)
|
||||
continue;
|
||||
return ISO_AAIP_BAD_ATTR_NAME; /* names may not contain 0-bytes */
|
||||
}
|
||||
new_bytes+= space_len + 1 + len + 1;
|
||||
}
|
||||
if((flag & 1) && *namelist_size > 0)
|
||||
new_bytes+= *namelist_size;
|
||||
new_list= calloc(new_bytes, 1);
|
||||
if(new_list == NULL)
|
||||
return(ISO_OUT_OF_MEM);
|
||||
wpt= new_list;
|
||||
if((flag & 1) && *namelist_size > 0) {
|
||||
memcpy(new_list, *namelist, *namelist_size);
|
||||
wpt= new_list + *namelist_size;
|
||||
}
|
||||
for(i= 0; i < list_size; i+= len + 1) {
|
||||
len= *((unsigned char *) (list + i));
|
||||
if(flag & 2) {
|
||||
for(j= 0; j < len; j++)
|
||||
if(list[i + j] == 0)
|
||||
continue;
|
||||
}
|
||||
memcpy(wpt, attrnamespace, space_len);
|
||||
wpt[space_len]= '.';
|
||||
wpt+= space_len + 1;
|
||||
memcpy(wpt, list + i + 1, len);
|
||||
wpt+= len;
|
||||
*(wpt++)= 0;
|
||||
(*num_names)++;
|
||||
}
|
||||
if((flag & 1) && *namelist != NULL)
|
||||
free(*namelist);
|
||||
*namelist= new_list;
|
||||
*namelist_size= new_bytes;
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_freebsd_extattR */
|
||||
|
||||
|
||||
/* Obtain the Extended Attributes and/or the ACLs of the given file in a form
|
||||
that is ready for aaip_encode().
|
||||
@param path Path to the file
|
||||
@param num_attrs Will return the number of name-value pairs
|
||||
@param names Will return an array of pointers to 0-terminated names
|
||||
@param value_lengths Will return an arry with the lenghts of values
|
||||
@param values Will return an array of pointers to 8-bit values
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= obtain ACL (access and eventually default)
|
||||
bit1= use numeric ACL qualifiers rather than names
|
||||
bit2= do not obtain attributes other than ACL
|
||||
bit3= do not ignore eventual non-user attributes
|
||||
I.e. those with a name which does not begin
|
||||
by "user."
|
||||
bit4= do not return trivial ACL that matches st_mode
|
||||
bit5= in case of symbolic link: inquire link target
|
||||
bit15= free memory of names, value_lengths, values
|
||||
@return >0 ok
|
||||
<=0 error
|
||||
-1= out of memory
|
||||
-2= program error with prediction of result size
|
||||
-3= error with conversion of name to uid or gid
|
||||
*/
|
||||
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
size_t **value_lengths, char ***values, int flag)
|
||||
{
|
||||
int ret;
|
||||
ssize_t i, num_names= 0, acl_names= 0;
|
||||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
unsigned char *a_acl= NULL;
|
||||
char *a_acl_text= NULL;
|
||||
size_t a_acl_len= 0;
|
||||
#endif
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
char *list= NULL, *user_list= NULL, *sys_list= NULL, *namept;
|
||||
ssize_t value_ret, retry= 0, list_size= 0, user_list_size= 0;
|
||||
ssize_t sys_list_size= 0;
|
||||
int attrnamespace;
|
||||
#endif
|
||||
|
||||
if(flag & (1 << 15)) { /* Free memory */
|
||||
{ret= 1; goto ex;}
|
||||
}
|
||||
|
||||
*num_attrs= 0;
|
||||
*names= NULL;
|
||||
*value_lengths= NULL;
|
||||
*values= NULL;
|
||||
|
||||
/* Set up arrays */
|
||||
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
|
||||
if(!(flag & 4)) { /* Get extattr names */
|
||||
|
||||
/* Linux : Names are encoded as name NUL
|
||||
FreeBSD: Names are encoded as length_byte:chars (no NUL)
|
||||
AAIP demands names not to contain NUL bytes.
|
||||
*/
|
||||
|
||||
/* Obtain lists of names
|
||||
Must be done separately for namespaces. See man 9 extattr :
|
||||
EXTATTR_NAMESPACE_USER , EXTATTR_NAMESPACE_SYSTEM
|
||||
Must then be marked by "user." and "system." for libisofs use.
|
||||
*/
|
||||
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_USER,
|
||||
&user_list, &user_list_size, flag & 32);
|
||||
if(ret <= 0)
|
||||
{ret= -1; goto ex;}
|
||||
if(flag & 8) {
|
||||
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_SYSTEM,
|
||||
&sys_list, &sys_list_size, flag & 32);
|
||||
if(ret <= 0)
|
||||
{ret= -1; goto ex;}
|
||||
}
|
||||
|
||||
/* Check for NUL in names, convert into a linuxish list of namespace.name */
|
||||
ret= aaip_extattr_make_namelist(path, "user", user_list, user_list_size,
|
||||
&list, &list_size, &num_names, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
ret= aaip_extattr_make_namelist(path, "system", sys_list, sys_list_size,
|
||||
&list, &list_size, &num_names, 1);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_freebsd_extattR */
|
||||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
if(flag & 1) {
|
||||
num_names++;
|
||||
acl_names= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(num_names == 0)
|
||||
{ret= 1; goto ex;}
|
||||
(*names)= calloc(num_names, sizeof(char *));
|
||||
(*value_lengths)= calloc(num_names, sizeof(size_t));
|
||||
(*values)= calloc(num_names, sizeof(char *));
|
||||
if(*names == NULL || *value_lengths == NULL || *values == NULL)
|
||||
{ret= -1; goto ex;}
|
||||
|
||||
for(i= 0; i < num_names; i++) {
|
||||
(*names)[i]= NULL;
|
||||
(*values)[i]= NULL;
|
||||
(*value_lengths)[i]= 0;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
|
||||
if(!(flag & 4)) { /* Get xattr values */
|
||||
for(i= 0; i < list_size && (size_t) num_names - acl_names > *num_attrs;
|
||||
i+= strlen(list + i) + 1) {
|
||||
if(!(flag & 8))
|
||||
if(strncmp(list + i, "user.", 5))
|
||||
continue;
|
||||
(*names)[(*num_attrs)++]= strdup(list + i);
|
||||
if((*names)[(*num_attrs) - 1] == NULL)
|
||||
{ret= -1; goto ex;}
|
||||
}
|
||||
|
||||
for(i= 0; (size_t) i < *num_attrs; i++) {
|
||||
if(strncmp((*names)[i], "user.", 5) == 0) {
|
||||
attrnamespace= EXTATTR_NAMESPACE_USER;
|
||||
namept= (*names)[i] + 5;
|
||||
} else {
|
||||
if(!(flag & 8))
|
||||
continue;
|
||||
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
|
||||
namept= (*names)[i] + 7;
|
||||
}
|
||||
/* Predict length of value */
|
||||
if(flag & 32) /* follow link */
|
||||
value_ret= extattr_get_file(path, attrnamespace, namept,
|
||||
NULL, (size_t) 0);
|
||||
else
|
||||
value_ret= extattr_get_link(path, attrnamespace, namept,
|
||||
NULL, (size_t) 0);
|
||||
if(value_ret == -1)
|
||||
continue;
|
||||
|
||||
(*values)[i]= calloc(value_ret + 1, 1);
|
||||
if((*values)[i] == NULL)
|
||||
{ret= -1; goto ex;}
|
||||
|
||||
/* Obtain value */
|
||||
if(flag & 32) /* follow link */
|
||||
value_ret= extattr_get_file(path, attrnamespace, namept,
|
||||
(*values)[i], (size_t) value_ret);
|
||||
else
|
||||
value_ret= extattr_get_link(path, attrnamespace, namept,
|
||||
(*values)[i], (size_t) value_ret);
|
||||
if(value_ret == -1) { /* there could be a race condition */
|
||||
|
||||
if(retry++ > 5)
|
||||
{ret= -1; goto ex;}
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
(*value_lengths)[i]= value_ret;
|
||||
retry= 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_freebsd_extattR */
|
||||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
|
||||
if(flag & 1) { /* Obtain ACL */
|
||||
/* access-ACL */
|
||||
aaip_get_acl_text(path, &a_acl_text, flag & (16 | 32));
|
||||
if(a_acl_text == NULL)
|
||||
{ret= 1; goto ex;} /* empty ACL / only st_mode info was found in ACL */
|
||||
ret= aaip_encode_acl(a_acl_text, (mode_t) 0, &a_acl_len, &a_acl, flag & 2);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
|
||||
/* Note: There are no default-ACL in FreeBSD */
|
||||
|
||||
/* Set as attribute with empty name */;
|
||||
(*names)[*num_attrs]= strdup("");
|
||||
if((*names)[*num_attrs] == NULL)
|
||||
{ret= -1; goto ex;}
|
||||
(*values)[*num_attrs]= (char *) a_acl;
|
||||
a_acl= NULL;
|
||||
(*value_lengths)[*num_attrs]= a_acl_len;
|
||||
(*num_attrs)++;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_aaip_acL */
|
||||
|
||||
ret= 1;
|
||||
ex:;
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
if(a_acl != NULL)
|
||||
free(a_acl);
|
||||
if(a_acl_text != NULL)
|
||||
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
|
||||
#endif
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
if(list != NULL)
|
||||
free(list);
|
||||
if(user_list != NULL)
|
||||
free(user_list);
|
||||
if(sys_list != NULL)
|
||||
free(sys_list);
|
||||
#endif
|
||||
|
||||
if(ret <= 0 || (flag & (1 << 15))) {
|
||||
if(*names != NULL) {
|
||||
for(i= 0; (size_t) i < *num_attrs; i++)
|
||||
free((*names)[i]);
|
||||
free(*names);
|
||||
}
|
||||
*names= NULL;
|
||||
if(*value_lengths != NULL)
|
||||
free(*value_lengths);
|
||||
*value_lengths= NULL;
|
||||
if(*values != NULL) {
|
||||
for(i= 0; (size_t) i < *num_attrs; i++)
|
||||
free((*values)[i]);
|
||||
free(*values);
|
||||
}
|
||||
*values= NULL;
|
||||
*num_attrs= 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#else /* ! Libisofs_old_freebsd_acl_adapteR */
|
||||
|
||||
/* Obtain the Extended Attributes and/or the ACLs of the given file in a form
|
||||
that is ready for aaip_encode().
|
||||
|
||||
@ -152,20 +531,28 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
||||
bit0= obtain ACL (access and eventually default)
|
||||
bit1= use numeric ACL qualifiers rather than names
|
||||
bit2= do not encode attributes other than ACL
|
||||
bit3= -reserved-
|
||||
bit3= do not ignore eventual non-user attributes
|
||||
I.e. those which are not from name space
|
||||
EXTATTR_NAMESPACE_USER
|
||||
bit4= do not return trivial ACL that matches st_mode
|
||||
bit15= free memory of names, value_lengths, values
|
||||
@return >0 ok
|
||||
<=0 error
|
||||
-1= out of memory
|
||||
-2= program error with prediction of result size
|
||||
-3= error with conversion of name to uid or gid
|
||||
*/
|
||||
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
size_t **value_lengths, char ***values, int flag)
|
||||
{
|
||||
int ret;
|
||||
ssize_t i, num_names;
|
||||
size_t a_acl_len= 0, acl_len= 0;
|
||||
unsigned char *a_acl= NULL, *d_acl= NULL, *acl= NULL;
|
||||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
size_t a_acl_len= 0;
|
||||
unsigned char *a_acl= NULL;
|
||||
char *acl_text= NULL;
|
||||
#endif
|
||||
|
||||
if(flag & (1 << 15)) { /* Free memory */
|
||||
{ret= 1; goto ex;}
|
||||
@ -211,25 +598,26 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
(*names)[*num_attrs]= strdup("");
|
||||
if((*names)[*num_attrs] == NULL)
|
||||
{ret= -1; goto ex;}
|
||||
(*values)[*num_attrs]= (char *) acl;
|
||||
(*value_lengths)[*num_attrs]= acl_len;
|
||||
(*values)[*num_attrs]= (char *) a_acl;
|
||||
a_acl= NULL;
|
||||
(*value_lengths)[*num_attrs]= a_acl_len;
|
||||
(*num_attrs)++;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_aaip_acL */
|
||||
#endif /* ! Libisofs_with_aaip_acL */
|
||||
|
||||
ret= 1;
|
||||
ex:;
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
if(a_acl != NULL)
|
||||
free(a_acl);
|
||||
if(d_acl != NULL)
|
||||
free(d_acl);
|
||||
if(acl_text != NULL)
|
||||
aaip_get_acl_text("", &acl_text, 1 << 15); /* free */
|
||||
#endif /* Libisofs_with_aaip_acL */
|
||||
|
||||
if(ret <= 0 || (flag & (1 << 15))) {
|
||||
if(*names != NULL) {
|
||||
for(i= 0; i < *num_attrs; i++)
|
||||
for(i= 0; i < (ssize_t) *num_attrs; i++)
|
||||
free((*names)[i]);
|
||||
free(*names);
|
||||
}
|
||||
@ -238,18 +626,18 @@ ex:;
|
||||
free(*value_lengths);
|
||||
*value_lengths= NULL;
|
||||
if(*values != NULL) {
|
||||
for(i= 0; i < *num_attrs; i++)
|
||||
for(i= 0; i < (ssize_t) *num_attrs; i++)
|
||||
free((*values)[i]);
|
||||
free(*values);
|
||||
}
|
||||
if(acl != NULL)
|
||||
free(acl);
|
||||
*values= NULL;
|
||||
*num_attrs= 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#endif /* Libisofs_old_freebsd_acl_adapteR */
|
||||
|
||||
|
||||
/* ------------------------------ Setters --------------------------------- */
|
||||
|
||||
@ -259,9 +647,14 @@ ex:;
|
||||
@param text The input text (0 terminated, ACL long text form)
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= set default ACL rather than access ACL
|
||||
bit5= in case of symbolic link: manipulate link target
|
||||
bit6= tolerate inappropriate presence or absence of
|
||||
directory default ACL
|
||||
@return > 0 ok
|
||||
0 no suitable ACL manipulation adapter available
|
||||
-1 failure of system ACL service (see errno)
|
||||
-2 ACL support not enabled at compile time
|
||||
-2 attempt to manipulate ACL of a symbolic link
|
||||
without bit5 resp. with no suitable link target
|
||||
*/
|
||||
int aaip_set_acl_text(char *path, char *text, int flag)
|
||||
{
|
||||
@ -302,13 +695,200 @@ ex:
|
||||
|
||||
#else /* Libisofs_with_aaip_acL */
|
||||
|
||||
return(-2);
|
||||
return(0);
|
||||
|
||||
#endif /* ! Libisofs_with_aaip_acL */
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifndef Libisofs_old_freebsd_acl_adapteR
|
||||
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
|
||||
/*
|
||||
@param flag Bitfield for control purposes
|
||||
bit5= in case of symbolic link: manipulate link target
|
||||
*/
|
||||
static int aaip_extattr_delete_names(char *path, int attrnamespace,
|
||||
char *list, ssize_t list_size, int flag)
|
||||
{
|
||||
int len;
|
||||
char name[256];
|
||||
ssize_t value_ret, i;
|
||||
|
||||
for(i= 0; i < list_size; i+= len + 1) {
|
||||
len= *((unsigned char *) (list + i));
|
||||
if(len > 0)
|
||||
strncpy(name, list + i + 1, len);
|
||||
name[len]= 0;
|
||||
if(flag & 32)
|
||||
value_ret= extattr_delete_file(path, attrnamespace, name);
|
||||
else
|
||||
value_ret= extattr_delete_file(path, attrnamespace, name);
|
||||
if(value_ret == -1)
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_freebsd_extattR */
|
||||
|
||||
|
||||
/* Bring the given attributes and/or ACLs into effect with the given file.
|
||||
@param flag Bitfield for control purposes
|
||||
bit0= decode and set ACLs
|
||||
bit1= first clear all existing attributes of the file
|
||||
bit2= do not set attributes other than ACLs
|
||||
bit3= do not ignore eventual non-user attributes.
|
||||
I.e. those with a name which does not begin
|
||||
by "user."
|
||||
bit5= in case of symbolic link: manipulate link target
|
||||
bit6= tolerate inappropriate presence or absence of
|
||||
directory default ACL
|
||||
@return 1 success
|
||||
-1 error memory allocation
|
||||
-2 error with decoding of ACL
|
||||
-3 error with setting ACL
|
||||
-4 error with setting attribute
|
||||
-5 error with deleting attributes
|
||||
-6 support of xattr not enabled at compile time
|
||||
-7 support of ACL not enabled at compile time
|
||||
-8 unsupported xattr namespace
|
||||
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag)
|
||||
{
|
||||
int ret, has_default_acl= 0;
|
||||
size_t i, consumed, acl_text_fill, acl_idx= 0;
|
||||
char *acl_text= NULL;
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
char *user_list= NULL, *sys_list= NULL, *namept;
|
||||
ssize_t user_list_size= 0, sys_list_size= 0;
|
||||
int attrnamespace;
|
||||
#endif
|
||||
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
|
||||
if(flag & 2) { /* Delete all file attributes */
|
||||
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_USER,
|
||||
&user_list, &user_list_size, flag & 32);
|
||||
if(ret <= 0)
|
||||
{ret= -1; goto ex;}
|
||||
ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_USER,
|
||||
user_list, user_list_size, flag & 32);
|
||||
if(ret <= 0)
|
||||
{ret= -5; goto ex;}
|
||||
if(flag & 8) {
|
||||
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_SYSTEM,
|
||||
&sys_list, &sys_list_size, flag & 32);
|
||||
if(ret <= 0)
|
||||
{ret= -5; goto ex;}
|
||||
ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_SYSTEM,
|
||||
sys_list, sys_list_size, flag & 32);
|
||||
if(ret <= 0)
|
||||
{ret= -5; goto ex;}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_freebsd_extattR */
|
||||
|
||||
for(i= 0; i < num_attrs; i++) {
|
||||
if(names[i] == NULL || values[i] == NULL)
|
||||
continue;
|
||||
if(names[i][0] == 0) { /* ACLs */
|
||||
if(flag & 1)
|
||||
acl_idx= i + 1;
|
||||
continue;
|
||||
}
|
||||
/* Extended Attribute */
|
||||
if(flag & 4)
|
||||
continue;
|
||||
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
|
||||
if(strncmp(names[i], "user.", 5) == 0) {
|
||||
attrnamespace= EXTATTR_NAMESPACE_USER;
|
||||
namept= names[i] + 5;
|
||||
} else if(strncmp(names[i], "isofs.", 6) == 0 || !(flag & 8)) {
|
||||
continue;
|
||||
} else if(strncmp(names[i], "system.", 7) == 0) {
|
||||
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
|
||||
namept= names[i] + 7;
|
||||
} else {
|
||||
{ret= -8; goto ex;}
|
||||
}
|
||||
if(flag & 32)
|
||||
ret= extattr_set_file(path, attrnamespace, namept,
|
||||
values[i], value_lengths[i]);
|
||||
else
|
||||
ret= extattr_set_link(path, attrnamespace, namept,
|
||||
values[i], value_lengths[i]);
|
||||
if(ret == -1)
|
||||
{ret= -4; goto ex;}
|
||||
|
||||
#else
|
||||
|
||||
if(strncmp(names[i], "user.", 5) == 0)
|
||||
;
|
||||
else if(strncmp(names[i], "isofs.", 6) == 0 || !(flag & 8))
|
||||
continue;
|
||||
{ret= -6; goto ex;}
|
||||
|
||||
#endif /* Libisofs_with_freebsd_extattR */
|
||||
|
||||
}
|
||||
|
||||
/* Decode ACLs */
|
||||
if(acl_idx == 0)
|
||||
{ret= 1; goto ex;}
|
||||
i= acl_idx - 1;
|
||||
|
||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||
&consumed, NULL, 0, &acl_text_fill, 1);
|
||||
if(ret < -3)
|
||||
goto ex;
|
||||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
acl_text= calloc(acl_text_fill, 1);
|
||||
if(acl_text == NULL)
|
||||
{ret= -1; goto ex;}
|
||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||
&consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
|
||||
if(ret < -3)
|
||||
goto ex;
|
||||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
has_default_acl= (ret == 2);
|
||||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
ret= aaip_set_acl_text(path, acl_text, flag & (32 | 64));
|
||||
if(ret <= 0)
|
||||
{ret= -3; goto ex;}
|
||||
#else
|
||||
{ret= -7; goto ex;}
|
||||
#endif
|
||||
|
||||
if(has_default_acl && !(flag & 64))
|
||||
{ret= -3; goto ex;}
|
||||
|
||||
ret= 1;
|
||||
ex:;
|
||||
if(acl_text != NULL)
|
||||
free(acl_text);
|
||||
#ifdef Libisofs_with_freebsd_extattR
|
||||
if(user_list != NULL)
|
||||
free(user_list);
|
||||
if(sys_list != NULL)
|
||||
free(sys_list);
|
||||
#endif /* Libisofs_with_freebsd_extattR */
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#else /* ! Libisofs_old_freebsd_acl_adapteR */
|
||||
|
||||
|
||||
/* Bring the given attributes and/or ACLs into effect with the given file.
|
||||
|
||||
Note: There are no Extended Attributes in FreeBSD. So only ACL get set.
|
||||
@ -317,6 +897,9 @@ ex:
|
||||
bit0= decode and set ACLs
|
||||
( bit1= first clear all existing attributes of the file )
|
||||
( bit2= do not set attributes other than ACLs )
|
||||
( bit3= do not ignore eventual non-user attributes.
|
||||
I.e. those with a name which does not begin
|
||||
by "user." )
|
||||
@return 1 success
|
||||
-1 error memory allocation
|
||||
-2 error with decoding of ACL
|
||||
@ -338,6 +921,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
continue;
|
||||
if(names[i][0] == 0) { /* Decode ACLs */
|
||||
/* access ACL */
|
||||
if(!(flag & 1))
|
||||
continue;
|
||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||
&consumed, NULL, 0, &acl_text_fill, 1);
|
||||
if(ret <= 0)
|
||||
@ -379,9 +964,15 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
if(ret <= 0)
|
||||
{ret= -3; goto ex;}
|
||||
}
|
||||
} else
|
||||
} else {
|
||||
if(flag & 4)
|
||||
continue;
|
||||
if(!(flag & 8))
|
||||
if(strncmp(names[i], "user.", 5))
|
||||
continue;
|
||||
was_xattr= 1;
|
||||
}
|
||||
}
|
||||
ret= 1;
|
||||
if(was_xattr)
|
||||
ret= -6;
|
||||
@ -393,4 +984,5 @@ ex:;
|
||||
return(ret);
|
||||
}
|
||||
|
||||
#endif /* Libisofs_old_freebsd_acl_adapteR */
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
To be included by aaip_0_2.c
|
||||
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
@ -34,6 +34,40 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* ------------------------------ Inquiry --------------------------------- */
|
||||
|
||||
/* See also API iso_local_attr_support().
|
||||
@param flag
|
||||
Bitfield for control purposes
|
||||
bit0= inquire availability of ACL
|
||||
bit1= inquire availability of xattr
|
||||
bit2 - bit7= Reserved for future types.
|
||||
It is permissibile to set them to 1 already now.
|
||||
bit8 and higher: reserved, submit 0
|
||||
@return
|
||||
Bitfield corresponding to flag. If bits are set, th
|
||||
bit0= ACL adapter is enabled
|
||||
bit1= xattr adapter is enabled
|
||||
bit2 - bit7= Reserved for future types.
|
||||
bit8 and higher: reserved, do not interpret these
|
||||
*/
|
||||
int aaip_local_attr_support(int flag)
|
||||
{
|
||||
int ret= 0;
|
||||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
if(flag & 1)
|
||||
ret|= 1;
|
||||
#endif
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
if(flag & 2)
|
||||
ret|= 2;
|
||||
#endif
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------ Getters --------------------------------- */
|
||||
|
||||
/* Obtain the ACL of the given file in long text form.
|
||||
@ -144,21 +178,24 @@ int aaip_get_acl_text(char *path, char **text, int flag)
|
||||
bit15= free memory of names, value_lengths, values
|
||||
@return >0 ok
|
||||
<=0 error
|
||||
-1= out of memory
|
||||
-2= program error with prediction of result size
|
||||
-3= error with conversion of name to uid or gid
|
||||
*/
|
||||
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
size_t **value_lengths, char ***values, int flag)
|
||||
{
|
||||
int ret;
|
||||
char *list= NULL;
|
||||
ssize_t list_size= 0, i, num_names= 0;
|
||||
unsigned char *acl= NULL;
|
||||
char *a_acl_text= NULL, *d_acl_text= NULL;
|
||||
ssize_t i, num_names= 0;
|
||||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
unsigned char *acl= NULL;
|
||||
char *a_acl_text= NULL, *d_acl_text= NULL;
|
||||
size_t acl_len= 0;
|
||||
#endif
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
ssize_t value_ret, retry= 0;
|
||||
char *list= NULL;
|
||||
ssize_t value_ret, retry= 0, list_size= 0;
|
||||
#endif
|
||||
|
||||
if(flag & (1 << 15)) { /* Free memory */
|
||||
@ -171,16 +208,21 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
*values= NULL;
|
||||
|
||||
/* Set up arrays */
|
||||
if(!(flag & 4)) { /* Get xattr names */
|
||||
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
|
||||
if(!(flag & 4)) { /* Get xattr names */
|
||||
if(flag & 32)
|
||||
list_size= listxattr(path, list, 0);
|
||||
else
|
||||
list_size= llistxattr(path, list, 0);
|
||||
if(list_size == -1)
|
||||
if(list_size == -1) {
|
||||
if(errno == ENOSYS) /* Function not implemented */
|
||||
list_size= 0; /* Handle as if xattr was disabled at compile time */
|
||||
else
|
||||
{ret= -1; goto ex;}
|
||||
}
|
||||
if(list_size > 0) {
|
||||
list= calloc(list_size, 1);
|
||||
if(list == NULL)
|
||||
{ret= -1; goto ex;}
|
||||
@ -190,20 +232,18 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
list_size= llistxattr(path, list, list_size);
|
||||
if(list_size == -1)
|
||||
{ret= -1; goto ex;}
|
||||
|
||||
#else /* Libisofs_with_aaip_xattR */
|
||||
|
||||
list= strdup("");
|
||||
|
||||
#endif /* ! Libisofs_with_aaip_xattR */
|
||||
|
||||
}
|
||||
for(i= 0; i < list_size; i+= strlen(list + i) + 1)
|
||||
num_names++;
|
||||
}
|
||||
|
||||
#endif /* ! Libisofs_with_aaip_xattR */
|
||||
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
|
||||
if(flag & 1)
|
||||
num_names++;
|
||||
|
||||
#endif
|
||||
|
||||
if(num_names == 0)
|
||||
@ -219,8 +259,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
(*values)[i]= NULL;
|
||||
(*value_lengths)[i]= 0;
|
||||
}
|
||||
if(!(flag & 4)) {
|
||||
for(i= 0; i < list_size && num_names > *num_attrs;
|
||||
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
|
||||
if(!(flag & 4)) { /* Get xattr values */
|
||||
for(i= 0; i < list_size && (size_t) num_names > *num_attrs;
|
||||
i+= strlen(list + i) + 1) {
|
||||
if(!(flag & 8))
|
||||
if(strncmp(list + i, "user.", 5))
|
||||
@ -229,12 +272,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
if((*names)[(*num_attrs) - 1] == NULL)
|
||||
{ret= -1; goto ex;}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
|
||||
if(!(flag & 4)) { /* Get xattr values */
|
||||
for(i= 0; i < *num_attrs; i++) {
|
||||
for(i= 0; (size_t) i < *num_attrs; i++) {
|
||||
if(!(flag & 8))
|
||||
if(strncmp((*names)[i], "user.", 5))
|
||||
continue;
|
||||
@ -291,15 +329,22 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
|
||||
ret= 1;
|
||||
ex:;
|
||||
#ifdef Libisofs_with_aaip_acL
|
||||
if(a_acl_text != NULL)
|
||||
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
|
||||
if(d_acl_text != NULL)
|
||||
aaip_get_acl_text("", &d_acl_text, 1 << 15); /* free */
|
||||
if(acl != NULL)
|
||||
free(acl);
|
||||
#endif
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
if(list != NULL)
|
||||
free(list);
|
||||
#endif
|
||||
|
||||
if(ret <= 0 || (flag & (1 << 15))) {
|
||||
if(*names != NULL) {
|
||||
for(i= 0; i < *num_attrs; i++)
|
||||
for(i= 0; (size_t) i < *num_attrs; i++)
|
||||
free((*names)[i]);
|
||||
free(*names);
|
||||
}
|
||||
@ -308,12 +353,10 @@ ex:;
|
||||
free(*value_lengths);
|
||||
*value_lengths= NULL;
|
||||
if(*values != NULL) {
|
||||
for(i= 0; i < *num_attrs; i++)
|
||||
for(i= 0; (size_t) i < *num_attrs; i++)
|
||||
free((*values)[i]);
|
||||
free(*values);
|
||||
}
|
||||
if(acl != NULL)
|
||||
free(acl);
|
||||
*values= NULL;
|
||||
*num_attrs= 0;
|
||||
}
|
||||
@ -385,6 +428,8 @@ ex:
|
||||
I.e. those with a name which does not begin
|
||||
by "user."
|
||||
bit5= in case of symbolic link: manipulate link target
|
||||
bit6= tolerate inappropriate presence or absense of
|
||||
directory default ACL
|
||||
@return 1 success
|
||||
-1 error memory allocation
|
||||
-2 error with decoding of ACL
|
||||
@ -393,6 +438,8 @@ ex:
|
||||
-5 error with deleting attributes
|
||||
-6 support of xattr not enabled at compile time
|
||||
-7 support of ACL not enabled at compile time
|
||||
( -8 unsupported xattr namespace )
|
||||
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag)
|
||||
@ -422,7 +469,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
list_size= llistxattr(path, list, list_size);
|
||||
if(list_size == -1)
|
||||
{ret= -5; goto ex;}
|
||||
for(i= 0; i < list_size; i+= strlen(list + i) + 1) {
|
||||
for(i= 0; i < (size_t) list_size; i+= strlen(list + i) + 1) {
|
||||
if(!(flag & 8))
|
||||
if(strncmp(list + i, "user.", 5))
|
||||
continue;
|
||||
@ -447,7 +494,11 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
continue;
|
||||
}
|
||||
/* Extended Attribute */
|
||||
if((flag & 1) && !(flag & 8))
|
||||
if(flag & 4)
|
||||
continue;
|
||||
if(strncmp(names[i], "isofs.", 6) == 0)
|
||||
continue;
|
||||
if(!(flag & 8))
|
||||
if(strncmp(names[i], "user.", 5))
|
||||
continue;
|
||||
|
||||
@ -475,6 +526,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
/* "access" ACL */
|
||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||
&consumed, NULL, 0, &acl_text_fill, 1);
|
||||
if(ret < -3)
|
||||
goto ex;
|
||||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
acl_text= calloc(acl_text_fill, 1);
|
||||
@ -482,6 +535,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
{ret= -1; goto ex;}
|
||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||
&consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
|
||||
if(ret < -3)
|
||||
goto ex;
|
||||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
has_default_acl= (ret == 2);
|
||||
@ -500,6 +555,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
ret= aaip_decode_acl((unsigned char *) (values[i] + consumed),
|
||||
value_lengths[i] - consumed, &h_consumed,
|
||||
NULL, 0, &acl_text_fill, 1);
|
||||
if(ret < -3)
|
||||
goto ex;
|
||||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
acl_text= calloc(acl_text_fill, 1);
|
||||
@ -508,11 +565,21 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
ret= aaip_decode_acl((unsigned char *) (values[i] + consumed),
|
||||
value_lengths[i] - consumed, &h_consumed,
|
||||
acl_text, acl_text_fill, &acl_text_fill, 0);
|
||||
if(ret < -3)
|
||||
goto ex;
|
||||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
|
||||
if(ret <= 0)
|
||||
{ret= -3; goto ex;}
|
||||
} else {
|
||||
if(!(flag & 64)) {
|
||||
|
||||
/* >>> ??? take offense from missing default ACL ?
|
||||
??? does Linux demand a default ACL for directories with access ACL ?
|
||||
*/;
|
||||
|
||||
}
|
||||
}
|
||||
ret= 1;
|
||||
ex:;
|
||||
|
@ -4,10 +4,10 @@
|
||||
Arbitrary Attribute Interchange Protocol , AAIP versions 0.2 , 1.0 , 2.0.
|
||||
Implementation of encoding and decoding xattr and ACL.
|
||||
|
||||
See test/aaip_0_2.h
|
||||
See libisofs/aaip_0_2.h
|
||||
http://libburnia-project.org/wiki/AAIP
|
||||
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "libisofs.h"
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
#define Aaip_encode_debuG 1
|
||||
@ -94,8 +95,8 @@ size_t aaip_encode(size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values,
|
||||
size_t *result_len, unsigned char **result, int flag)
|
||||
{
|
||||
size_t mem_size= 0, comp_size;
|
||||
unsigned int number_of_fields, i, num_recs, total_recs= 0, ret;
|
||||
size_t mem_size= 0, comp_size, ret;
|
||||
unsigned int number_of_fields, i, num_recs;
|
||||
|
||||
/* Predict memory needs, number of SUSP fields and component records */
|
||||
*result_len= 0;
|
||||
@ -105,7 +106,6 @@ size_t aaip_encode(size_t num_attrs, char **names,
|
||||
if(ret <= 0)
|
||||
return(ret);
|
||||
mem_size+= comp_size;
|
||||
total_recs= num_recs;
|
||||
}
|
||||
number_of_fields= mem_size / 250 + !!(mem_size % 250);
|
||||
mem_size+= number_of_fields * 5;
|
||||
@ -158,9 +158,9 @@ size_t aaip_encode(size_t num_attrs, char **names,
|
||||
ret= 0;
|
||||
for(i= 0; i < *result_len; i+= ((unsigned char *) (*result))[i + 2])
|
||||
ret++;
|
||||
if(ret != number_of_fields) {
|
||||
if(ret != (int) number_of_fields) {
|
||||
fprintf(stderr, "aaip_encode(): WRONG NUMBER OF FIELDS %d <> %d\n",
|
||||
number_of_fields, ret);
|
||||
(int) number_of_fields, ret);
|
||||
}
|
||||
#endif /* Aaip_encode_debuG */
|
||||
|
||||
@ -187,7 +187,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
|
||||
aaip_encode_byte(result, result_fill, 0);
|
||||
return(1);
|
||||
}
|
||||
for(rpt= data; rpt - data < l;) {
|
||||
for(rpt= data; rpt - data < (ssize_t) l;) {
|
||||
todo= l - (rpt - data) + (prefix > 0);
|
||||
aaip_encode_byte(result, result_fill, (todo > 255));
|
||||
if(todo > 255)
|
||||
@ -198,7 +198,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
|
||||
todo--;
|
||||
prefix= 0;
|
||||
}
|
||||
for(comp_start= rpt; rpt - comp_start < todo; rpt++)
|
||||
for(comp_start= rpt; rpt - comp_start < (ssize_t) todo; rpt++)
|
||||
aaip_encode_byte(result, result_fill, *((unsigned char *) rpt));
|
||||
}
|
||||
return(1);
|
||||
@ -268,7 +268,11 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
bit3= check for completeness of list and eventually
|
||||
fill up with entries deduced from st_mode
|
||||
@return >0 means ok
|
||||
0 means error
|
||||
<=0 means error
|
||||
-1= out of memory
|
||||
-2= program error with prediction of result size
|
||||
-3= error with conversion of name to uid or gid
|
||||
ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||
size_t *result_len, unsigned char **result, int flag)
|
||||
@ -279,8 +283,10 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||
*result_len= 0;
|
||||
bytes= aaip_encode_acl_text(acl_text, st_mode,
|
||||
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8)));
|
||||
if(bytes < -2)
|
||||
return(bytes);
|
||||
if(bytes < 0)
|
||||
return(0);
|
||||
return((int) bytes - 1);
|
||||
if(flag & 1) {
|
||||
*result_len= bytes;
|
||||
return(1);
|
||||
@ -292,9 +298,13 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||
*result_len= bytes;
|
||||
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
|
||||
(flag & (2 | 4 | 8)));
|
||||
if(bytes != *result_len) {
|
||||
if(bytes < -2)
|
||||
return(bytes);
|
||||
if(bytes < 0)
|
||||
return((int) bytes - 1);
|
||||
if((size_t) bytes != *result_len) {
|
||||
*result_len= 0;
|
||||
return(0);
|
||||
return(-2);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
@ -341,26 +351,31 @@ static int aaip_make_aaip_perms(int r, int w, int x)
|
||||
fill up with entries deduced from st_mode
|
||||
@return >=0 number of bytes produced resp. counted
|
||||
<0 means error
|
||||
-1: result size overflow
|
||||
-2: conversion errror with user name or group name
|
||||
ISO_AAIP_ACL_MULT_OBJ: multiple entries of user::, group::, other::
|
||||
*/
|
||||
static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
size_t result_size, unsigned char *result, int flag)
|
||||
{
|
||||
char *rpt, *npt, *cpt;
|
||||
int qualifier= 0, perms, type, i, qualifier_len= 0, num_recs, needed= 0;
|
||||
int qualifier= 0, perms, type, i, qualifier_len= 0, num_recs, needed= 0, ret;
|
||||
unsigned int has_u= 0, has_g= 0, has_o= 0, has_m= 0, is_trivial= 1;
|
||||
uid_t uid, huid;
|
||||
gid_t gid, hgid;
|
||||
ssize_t count= 0;
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
char name[1024];
|
||||
char *name = NULL;
|
||||
int name_size= 1024;
|
||||
double num;
|
||||
|
||||
LIBISO_ALLOC_MEM(name, char, name_size);
|
||||
if(flag & 4) {
|
||||
/* set SWITCH_MARK to indicate a default ACL */;
|
||||
if(!(flag & 1)) {
|
||||
if(count >= result_size)
|
||||
return(-1);
|
||||
if((size_t) count >= result_size)
|
||||
{ret= -1; goto ex;}
|
||||
result[count]= (Aaip_SWITCH_MARK << 4) | Aaip_EXEC;
|
||||
}
|
||||
count++;
|
||||
@ -384,9 +399,16 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
if(strncmp(rpt, "user:", 5) == 0) {
|
||||
if(cpt - rpt == 5) {
|
||||
type= Aaip_ACL_USER_OBJ;
|
||||
if (has_u) {
|
||||
|
||||
/* >>> Duplicate u:: entry. */;
|
||||
/* >>> ??? If it matches the previous one: ignore */
|
||||
|
||||
return((int) ISO_AAIP_ACL_MULT_OBJ);
|
||||
}
|
||||
has_u++;
|
||||
} else {
|
||||
if(cpt - (rpt + 5) >= sizeof(name))
|
||||
if(cpt - (rpt + 5) >= name_size)
|
||||
continue;
|
||||
is_trivial= 0;
|
||||
strncpy(name, rpt + 5, cpt - (rpt + 5));
|
||||
@ -396,8 +418,10 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
pwd= getpwnam(name);
|
||||
if(pwd == NULL) {
|
||||
num= aaip_numeric_id(name, 0);
|
||||
if(num <= 0)
|
||||
goto user_by_name;
|
||||
if(num <= 0) {
|
||||
/* ACL_USER is not part of AAIP 2.0 */
|
||||
{ret= -2; goto ex;}
|
||||
}
|
||||
uid= huid= num;
|
||||
} else
|
||||
uid= huid= pwd->pw_uid;
|
||||
@ -405,31 +429,44 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
for(i= 0; huid != 0; i++)
|
||||
huid= huid >> 8;
|
||||
qualifier_len= i;
|
||||
if(qualifier_len <= 0)
|
||||
qualifier_len= 1;
|
||||
for(i= 0; i < qualifier_len ; i++)
|
||||
name[i]= uid >> (8 * (qualifier_len - i - 1));
|
||||
} else {
|
||||
user_by_name:;
|
||||
type= Aaip_ACL_USER;
|
||||
qualifier_len= strlen(name);
|
||||
if(qualifier_len <= 0)
|
||||
qualifier_len= 1;
|
||||
}
|
||||
qualifier= 1;
|
||||
}
|
||||
} else if(strncmp(rpt, "group:", 6) == 0) {
|
||||
if(cpt - rpt == 6) {
|
||||
type= Aaip_ACL_GROUP_OBJ;
|
||||
if (has_g) {
|
||||
|
||||
/* >>> Duplicate g:: entry. */;
|
||||
/* >>> ??? If it matches the previous one: ignore */
|
||||
|
||||
return((int) ISO_AAIP_ACL_MULT_OBJ);
|
||||
}
|
||||
has_g++;
|
||||
} else {
|
||||
if(cpt - (rpt + 6) >= sizeof(name))
|
||||
if(cpt - (rpt + 6) >= name_size)
|
||||
continue;
|
||||
is_trivial= 0;
|
||||
strncpy(name, rpt + 6, cpt - (rpt + 6));
|
||||
name[cpt - (rpt + 6)]= 0;
|
||||
if(flag & 2) {
|
||||
type= Aaip_ACL_GROUP_N;
|
||||
grp= getgrnam(name);
|
||||
if(grp == NULL) {
|
||||
num= aaip_numeric_id(name, 0);
|
||||
if(num <= 0)
|
||||
goto group_by_name;
|
||||
if(num <= 0) {
|
||||
/* ACL_GROUP is not part of AAIP 2.0 */
|
||||
{ret= -2; goto ex;}
|
||||
}
|
||||
gid= hgid= num;
|
||||
} else
|
||||
gid= hgid= grp->gr_gid;
|
||||
@ -437,18 +474,27 @@ user_by_name:;
|
||||
for(i= 0; hgid != 0; i++)
|
||||
hgid= hgid >> 8;
|
||||
qualifier_len= i;
|
||||
if(qualifier_len <= 0)
|
||||
qualifier_len= 1;
|
||||
for(i= 0; i < qualifier_len ; i++)
|
||||
name[i]= gid >> (8 * (qualifier_len - i - 1));
|
||||
|
||||
} else {
|
||||
group_by_name:;
|
||||
type= Aaip_ACL_GROUP;
|
||||
qualifier_len= strlen(name);
|
||||
if(qualifier_len <= 0)
|
||||
qualifier_len= 1;
|
||||
}
|
||||
qualifier= 1;
|
||||
}
|
||||
} else if(strncmp(rpt, "other:", 6) == 0) {
|
||||
type= Aaip_ACL_OTHER;
|
||||
if (has_o) {
|
||||
|
||||
/* >>> Duplicate o:: entry. */;
|
||||
/* >>> ??? If it matches the previous one: ignore */
|
||||
|
||||
return((int) ISO_AAIP_ACL_MULT_OBJ);
|
||||
}
|
||||
has_o++;
|
||||
} else if(strncmp(rpt, "mask:", 5) == 0) {
|
||||
type= Aaip_ACL_MASK;
|
||||
@ -461,8 +507,8 @@ group_by_name:;
|
||||
perms= aaip_make_aaip_perms(cpt[1] == 'r', cpt[2] == 'w', cpt[3] == 'x');
|
||||
|
||||
if(!(flag & 1)) {
|
||||
if(count >= result_size)
|
||||
return(-1);
|
||||
if((size_t) count >= result_size)
|
||||
{ret= -1; goto ex;}
|
||||
result[count]= perms | ((!!qualifier) << 3) | (type << 4);
|
||||
}
|
||||
count++;
|
||||
@ -470,8 +516,8 @@ group_by_name:;
|
||||
if(qualifier) {
|
||||
num_recs= (qualifier_len / 127) + !!(qualifier_len % 127);
|
||||
if(!(flag & 1)) {
|
||||
if(count + 1 > result_size)
|
||||
return(-1);
|
||||
if((size_t) (count + 1) > result_size)
|
||||
{ret= -1; goto ex;}
|
||||
for(i= 0; i < num_recs; i++) {
|
||||
if(i < num_recs - 1)
|
||||
result[count++]= 255;
|
||||
@ -480,8 +526,8 @@ group_by_name:;
|
||||
if(result[count - 1] == 0)
|
||||
result[count - 1]= 127;
|
||||
}
|
||||
if(count + (result[count - 1] & 127) > result_size)
|
||||
return(-1);
|
||||
if((size_t) (count + (result[count - 1] & 127)) > result_size)
|
||||
{ret= -1; goto ex;}
|
||||
memcpy(result + count, name + i * 127, result[count - 1] & 127);
|
||||
count+= result[count - 1] & 127;
|
||||
}
|
||||
@ -495,8 +541,8 @@ group_by_name:;
|
||||
if(flag & 1)
|
||||
count+= needed;
|
||||
else {
|
||||
if(count + needed > result_size)
|
||||
return(-1);
|
||||
if((size_t) (count + needed) > result_size)
|
||||
{ret= -1; goto ex;}
|
||||
}
|
||||
}
|
||||
if ((flag & 8) && needed > 0 && !(flag & 1)) {
|
||||
@ -521,7 +567,10 @@ group_by_name:;
|
||||
result[count++]= perms | (Aaip_ACL_MASK << 4);
|
||||
}
|
||||
}
|
||||
return(count);
|
||||
ret= count;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(name);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
@ -1120,9 +1169,9 @@ static int aaip_consume_rec_head(struct aaip_state *aaip,
|
||||
size_t todo;
|
||||
|
||||
todo= *num_data;
|
||||
if(todo > aaip->aa_missing)
|
||||
if(todo > (size_t) aaip->aa_missing)
|
||||
todo= aaip->aa_missing;
|
||||
if(todo >= aaip->rec_head_missing)
|
||||
if(todo >= (size_t) aaip->rec_head_missing)
|
||||
todo= aaip->rec_head_missing;
|
||||
if(!aaip->recs_invalid)
|
||||
aaip_push_to_recs(aaip, *data, todo, 0);
|
||||
@ -1144,9 +1193,9 @@ static int aaip_consume_rec_data(struct aaip_state *aaip,
|
||||
size_t todo;
|
||||
|
||||
todo= *num_data;
|
||||
if(todo > aaip->aa_missing)
|
||||
if(todo > (size_t) aaip->aa_missing)
|
||||
todo= aaip->aa_missing;
|
||||
if(todo > aaip->rec_missing)
|
||||
if(todo > (size_t) aaip->rec_missing)
|
||||
todo= aaip->rec_missing;
|
||||
if(!aaip->recs_invalid)
|
||||
aaip_push_to_recs(aaip, *data, todo, 1);
|
||||
@ -1178,7 +1227,7 @@ static int aaip_consume_aa_head(struct aaip_state *aaip,
|
||||
unsigned char aa_head[5];
|
||||
|
||||
todo= *num_data;
|
||||
if(todo >= aaip->aa_head_missing)
|
||||
if(todo >= (size_t) aaip->aa_head_missing)
|
||||
todo= aaip->aa_head_missing;
|
||||
aaip_push_to_recs(aaip, *data, todo, 0);
|
||||
aaip->aa_head_missing-= todo;
|
||||
@ -1225,7 +1274,7 @@ static int aaip_consume_aa_data(struct aaip_state *aaip,
|
||||
aaip_push_to_recs(aaip, zero_char, 1, 0);
|
||||
} else {
|
||||
/* fill in missing btes */
|
||||
for(i= 0; i < aaip->rec_missing; i++)
|
||||
for(i= 0; (int) i < aaip->rec_missing; i++)
|
||||
aaip_push_to_recs(aaip, zero_char, 1, 1);
|
||||
}
|
||||
aaip->rec_head_missing= 2;
|
||||
@ -1696,7 +1745,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
|
||||
unsigned char *data, size_t num_data, size_t *consumed,
|
||||
int flag)
|
||||
{
|
||||
int ret, was_non_aa= 0;
|
||||
int ret;
|
||||
struct aaip_state *aaip;
|
||||
size_t h_num, *h_lengths, i, new_mem, pair_consumed= 0;
|
||||
char **h_names, **h_values, *hpt;
|
||||
@ -1785,7 +1834,6 @@ int aaip_decode_attrs(struct aaip_state **handle,
|
||||
return(ret);
|
||||
|
||||
} else if(ret == -1) { /* non-AAIP field detected */
|
||||
was_non_aa= 1;
|
||||
if(pair_consumed <= 0)
|
||||
return(-4); /* interpretation did not advance */
|
||||
|
||||
@ -1968,14 +2016,16 @@ static int aaip_read_qualifier(unsigned char *data, size_t num_data,
|
||||
char *name, size_t name_size, size_t *name_fill,
|
||||
int flag)
|
||||
{
|
||||
int is_done= 0, rec_len= 0;
|
||||
int is_done= 0;
|
||||
size_t rec_len= 0;
|
||||
unsigned char *rpt;
|
||||
|
||||
*name_fill= 0;
|
||||
for(rpt= data; !is_done; rpt+= rec_len) {
|
||||
rec_len= (*rpt) & 127;
|
||||
is_done= !((*rpt) & 128);
|
||||
if(*name_fill + rec_len >= name_size || rpt + 1 + rec_len - data > num_data)
|
||||
if(*name_fill + rec_len >= name_size ||
|
||||
(size_t) (rpt + 1 + rec_len - data) > num_data)
|
||||
return(-1);
|
||||
memcpy(name + *name_fill, rpt + 1, rec_len);
|
||||
rpt+= 1 + rec_len;
|
||||
@ -2013,20 +2063,21 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
size_t *acl_text_fill, int flag)
|
||||
{
|
||||
unsigned char *rpt;
|
||||
char perm_text[4], *wpt, name[1024];
|
||||
int type, qualifier= 0, perm, ret, i, cnt;
|
||||
size_t w_size, name_fill= 0;
|
||||
char perm_text[4], *wpt, *name= NULL;
|
||||
int type, qualifier= 0, perm, ret, cnt, name_size= 1024;
|
||||
size_t w_size, name_fill= 0, i;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
|
||||
LIBISO_ALLOC_MEM(name, char, name_size);
|
||||
cnt= flag & 1;
|
||||
*consumed= 0;
|
||||
wpt= acl_text;
|
||||
w_size= acl_text_size;
|
||||
*acl_text_fill= 0;
|
||||
for(rpt= data; rpt - data < num_data; ) {
|
||||
for(rpt= data; (size_t) (rpt - data) < num_data; ) {
|
||||
perm= *rpt;
|
||||
strcpy(perm_text, "---");
|
||||
if(perm & Aaip_READ)
|
||||
@ -2038,14 +2089,14 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
|
||||
type= (*rpt) >> 4;
|
||||
if(type == Aaip_FUTURE_VERSION) /* indicate to caller: version mismatch */
|
||||
return(-3);
|
||||
{ret = -3; goto ex;}
|
||||
|
||||
qualifier= !!((*rpt) & 8);
|
||||
if(qualifier) {
|
||||
ret= aaip_read_qualifier(rpt + 1, num_data - (rpt + 1 - data),
|
||||
name, sizeof(name), &name_fill, 0);
|
||||
name, name_size, &name_fill, 0);
|
||||
if(ret <= 0)
|
||||
return(-1);
|
||||
{ret = -1; goto ex;}
|
||||
}
|
||||
|
||||
/* Advance read pointer */
|
||||
@ -2086,7 +2137,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
pwd= getpwuid(uid);
|
||||
if(pwd == NULL)
|
||||
sprintf(name, "%.f", (double) uid);
|
||||
else if(strlen(pwd->pw_name) >= sizeof(name))
|
||||
else if(strlen(pwd->pw_name) >= (size_t) name_size)
|
||||
sprintf(name, "%.f", (double) uid);
|
||||
else
|
||||
strcpy(name, pwd->pw_name);
|
||||
@ -2100,7 +2151,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
grp= getgrgid(gid);
|
||||
if(grp == NULL)
|
||||
sprintf(name, "%.f", (double) gid);
|
||||
else if(strlen(grp->gr_name) >= sizeof(name))
|
||||
else if(strlen(grp->gr_name) >= (size_t) name_size)
|
||||
sprintf(name, "%.f", (double) gid);
|
||||
else
|
||||
strcpy(name, grp->gr_name);
|
||||
@ -2108,15 +2159,17 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
ret= aaip_write_acl_line(&wpt, &w_size, "group", name, perm_text, cnt);
|
||||
} else {
|
||||
/* indicate to caller: unknown type */
|
||||
return(-4);
|
||||
{ret = -4; goto ex;}
|
||||
}
|
||||
if(ret <= 0)
|
||||
return(-2);
|
||||
{ret = -2; goto ex;}
|
||||
}
|
||||
ret= 1;
|
||||
ex:;
|
||||
*acl_text_fill= w_size;
|
||||
if(flag & 1)
|
||||
*acl_text_fill= w_size + 1;
|
||||
(*acl_text_fill)++;
|
||||
LIBISO_FREE_MEM(name);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
@ -2133,6 +2186,13 @@ ex:;
|
||||
|
||||
#include "aaip-os-linux.c"
|
||||
|
||||
/* August 2011: aaip-os-linux.c would also work for GNU/Hurd : ifdef __GNU__
|
||||
Libraries and headers are present on Debian GNU/Hurd but there is no
|
||||
ACL or xattr support in the filesystems yet.
|
||||
Further, llistxattr() produces ENOSYS "Function not implemented".
|
||||
So it makes few sense to enable it here.
|
||||
*/
|
||||
|
||||
#else
|
||||
|
||||
#include "aaip-os-dummy.c"
|
||||
|
@ -56,7 +56,11 @@ size_t aaip_encode(size_t num_attrs, char **names,
|
||||
bit3= check for completeness of list and eventually
|
||||
fill up with entries deduced from st_mode
|
||||
@return >0 means ok
|
||||
0 means error
|
||||
<=0 means error
|
||||
-1= out of memory
|
||||
-2= program error with prediction of result size
|
||||
-3= error with conversion of name to uid or gid
|
||||
ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||
size_t *result_len, unsigned char **result, int flag);
|
||||
@ -80,7 +84,7 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||
bit3= check for completeness of list and eventually
|
||||
fill up with entries deduced from st_mode
|
||||
@return >0 means ok
|
||||
0 means error
|
||||
<=0 means error, see aaip_encode_acl
|
||||
*/
|
||||
int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode,
|
||||
size_t *result_len, unsigned char **result, int flag);
|
||||
@ -145,6 +149,24 @@ int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag);
|
||||
|
||||
/* ------ OS interface ------ */
|
||||
|
||||
/* See also API iso_local_attr_support().
|
||||
@param flag
|
||||
Bitfield for control purposes
|
||||
bit0= inquire availability of ACL
|
||||
bit1= inquire availability of xattr
|
||||
bit2 - bit7= Reserved for future types.
|
||||
It is permissibile to set them to 1 already now.
|
||||
bit8 and higher: reserved, submit 0
|
||||
@return
|
||||
Bitfield corresponding to flag. If bits are set, th
|
||||
bit0= ACL adapter is enabled
|
||||
bit1= xattr adapter is enabled
|
||||
bit2 - bit7= Reserved for future types.
|
||||
bit8 and higher: reserved, do not interpret these
|
||||
*/
|
||||
int aaip_local_attr_support(int flag);
|
||||
|
||||
|
||||
/* Obtain the ACL of the given file in long text form.
|
||||
@param path Path to the file
|
||||
@param text Will hold the result. This is a managed object which
|
||||
@ -478,6 +500,8 @@ int aaip_set_acl_text(char *path, char *text, int flag);
|
||||
-5 error with deleting attributes
|
||||
-6 support of xattr not enabled at compile time
|
||||
-7 support of ACL not enabled at compile time
|
||||
-8 unsupported xattr namespace
|
||||
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag);
|
||||
|
@ -150,7 +150,7 @@ void iso_ring_buffer_free(IsoRingBuffer *buf)
|
||||
int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
||||
{
|
||||
size_t len;
|
||||
int bytes_write = 0;
|
||||
size_t bytes_write = 0;
|
||||
|
||||
if (buf == NULL || data == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -206,7 +206,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
||||
int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
|
||||
{
|
||||
size_t len;
|
||||
int bytes_read = 0;
|
||||
size_t bytes_read = 0;
|
||||
|
||||
if (buf == NULL || dest == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -20,6 +20,7 @@
|
||||
#include "fsource.h"
|
||||
#include "image.h"
|
||||
#include "aaip_0_2.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -104,9 +105,11 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
char *name;
|
||||
unsigned char *aa_string = NULL;
|
||||
char *a_text = NULL, *d_text = NULL;
|
||||
char *dest = NULL;
|
||||
IsoSymlink *link;
|
||||
|
||||
if (builder == NULL || src == NULL || node == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
{ret = ISO_NULL_POINTER; goto ex;}
|
||||
}
|
||||
|
||||
/* get info about source */
|
||||
@ -116,7 +119,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
ret = iso_file_source_lstat(src, &info);
|
||||
}
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
name = iso_file_source_get_name(src);
|
||||
@ -157,9 +160,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
case S_IFLNK:
|
||||
{
|
||||
/* source is a symbolic link */
|
||||
char dest[LIBISOFS_NODE_PATH_MAX];
|
||||
IsoSymlink *link;
|
||||
|
||||
LIBISO_ALLOC_MEM(dest, char, LIBISOFS_NODE_PATH_MAX);
|
||||
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
|
||||
if (ret < 0) {
|
||||
break;
|
||||
@ -198,7 +199,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
|
||||
if (ret < 0) {
|
||||
free(name);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* fill fields */
|
||||
@ -233,14 +234,17 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
if (ret == 1 && aa_string != NULL) {
|
||||
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
} else if(aa_string != NULL) {
|
||||
free(aa_string);
|
||||
}
|
||||
|
||||
*node = new;
|
||||
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(dest);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -89,6 +89,14 @@ void ecma119_image_free(Ecma119Image *t)
|
||||
writer->free_data(writer);
|
||||
free(writer);
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
if (t->rr_reloc_dir != NULL)
|
||||
free(t->rr_reloc_dir);
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
if (t->input_charset != NULL)
|
||||
free(t->input_charset);
|
||||
if (t->output_charset != NULL)
|
||||
@ -363,7 +371,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
||||
IsoNode *iso;
|
||||
|
||||
len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1);
|
||||
len_dr = 33 + len_fi + ((len_fi % 2) ? 0 : 1);
|
||||
|
||||
memcpy(rec->file_id, name, len_fi);
|
||||
|
||||
@ -402,7 +410,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
rec->len_dr[0] = len_dr + (info != NULL ? info->suf_len : 0);
|
||||
iso_bb(rec->block, block - t->eff_partition_offset, 4);
|
||||
iso_bb(rec->length, len, 4);
|
||||
if (t->dir_rec_mtime) {
|
||||
if (t->dir_rec_mtime & 1) {
|
||||
iso= node->node;
|
||||
iso_datetime_7(rec->recording_time,
|
||||
t->replace_timestamps ? t->timestamp : iso->mtime,
|
||||
@ -576,16 +584,16 @@ static
|
||||
int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
{
|
||||
int ret;
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
uint8_t *buffer = NULL;
|
||||
size_t i;
|
||||
size_t fi_len, len;
|
||||
struct susp_info info;
|
||||
|
||||
/* buf will point to current write position on buffer */
|
||||
uint8_t *buf = buffer;
|
||||
uint8_t *buf;
|
||||
|
||||
/* initialize buffer with 0s */
|
||||
memset(buffer, 0, BLOCK_SIZE);
|
||||
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||
buf = buffer;
|
||||
|
||||
/*
|
||||
* set susp_info to 0's, this way code for both plain ECMA-119 and
|
||||
@ -602,7 +610,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
if (t->rockridge) {
|
||||
ret = rrip_get_susp_fields(t, dir, 1, 34, &info);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
len = 34 + info.suf_len;
|
||||
@ -612,7 +620,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
if (t->rockridge) {
|
||||
ret = rrip_get_susp_fields(t, dir, 2, 34, &info);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
len = 34 + info.suf_len;
|
||||
@ -629,7 +637,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
for (section = 0; section < nsections; ++section) {
|
||||
|
||||
/* compute len of directory entry */
|
||||
len = fi_len + 33 + (fi_len % 2 ? 0 : 1);
|
||||
len = fi_len + 33 + ((fi_len % 2) ? 0 : 1);
|
||||
if (need_version_number(t, child)) {
|
||||
len += 2;
|
||||
}
|
||||
@ -638,7 +646,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
if (t->rockridge) {
|
||||
ret = rrip_get_susp_fields(t, child, 0, len, &info);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
len += info.suf_len;
|
||||
}
|
||||
@ -647,7 +655,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
/* dir doesn't fit in current block */
|
||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
memset(buffer, 0, BLOCK_SIZE);
|
||||
buf = buffer;
|
||||
@ -661,7 +669,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
/* write the last block */
|
||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* write the Continuation Area if needed */
|
||||
@ -669,6 +677,8 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
||||
ret = rrip_write_ce_fields(t, &info);
|
||||
}
|
||||
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -708,6 +718,7 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
||||
uint32_t path_table_size;
|
||||
int parent = 0;
|
||||
int ret= ISO_SUCCESS;
|
||||
uint8_t *zeros = NULL;
|
||||
|
||||
path_table_size = 0;
|
||||
write_int = l_type ? iso_lsb : iso_msb;
|
||||
@ -735,7 +746,7 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
||||
ret = iso_write(t, buf, len);
|
||||
if (ret < 0) {
|
||||
/* error */
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
path_table_size += len;
|
||||
}
|
||||
@ -743,11 +754,12 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
|
||||
/* we need to fill the last block with zeros */
|
||||
path_table_size %= BLOCK_SIZE;
|
||||
if (path_table_size) {
|
||||
uint8_t zeros[BLOCK_SIZE];
|
||||
len = BLOCK_SIZE - path_table_size;
|
||||
memset(zeros, 0, len);
|
||||
LIBISO_ALLOC_MEM(zeros, uint8_t, len);
|
||||
ret = iso_write(t, zeros, len);
|
||||
}
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(zeros);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -878,28 +890,28 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
|
||||
int ret;
|
||||
Ecma119Image *t;
|
||||
uint32_t curblock;
|
||||
char *msg = NULL;
|
||||
|
||||
if (writer == NULL)
|
||||
{ret = ISO_ASSERT_FAILURE; goto ex;}
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
t = writer->target;
|
||||
|
||||
ret = ecma119_writer_write_dirs(writer);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
|
||||
if (t->partition_offset > 0) {
|
||||
t->eff_partition_offset = t->partition_offset;
|
||||
ret = ecma119_writer_write_dirs(writer);
|
||||
t->eff_partition_offset = 0;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
curblock = (t->bytes_written / 2048) + t->ms_block;
|
||||
if (curblock != t->tree_end_block) {
|
||||
char msg[100];
|
||||
|
||||
LIBISO_ALLOC_MEM(msg, char, 100);
|
||||
sprintf(msg,
|
||||
"Calculated and written ECMA-119 tree end differ: %lu <> %lu",
|
||||
(unsigned long) t->tree_end_block,
|
||||
@ -908,8 +920,10 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
|
||||
|
||||
t->tree_end_block = 1;/* Mark for harsher reaction at end of writing */
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -990,27 +1004,30 @@ int mspad_writer_write_data(IsoImageWriter *writer)
|
||||
{
|
||||
int ret;
|
||||
Ecma119Image *t;
|
||||
uint8_t pad[BLOCK_SIZE];
|
||||
uint8_t *pad = NULL;
|
||||
size_t i;
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
{ret = ISO_ASSERT_FAILURE; goto ex;}
|
||||
}
|
||||
t = writer->target;
|
||||
|
||||
if (t->mspad_blocks == 0) {
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
}
|
||||
|
||||
memset(pad, 0, BLOCK_SIZE);
|
||||
LIBISO_ALLOC_MEM(pad, uint8_t, BLOCK_SIZE);
|
||||
for (i = 0; i < t->mspad_blocks; ++i) {
|
||||
ret = iso_write(t, pad, BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(pad);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -1076,23 +1093,26 @@ int zero_writer_write_data(IsoImageWriter *writer)
|
||||
int ret;
|
||||
Ecma119Image *t;
|
||||
struct iso_zero_writer_data_struct *data;
|
||||
uint8_t pad[BLOCK_SIZE];
|
||||
uint8_t *pad = NULL;
|
||||
size_t i;
|
||||
|
||||
if (writer == NULL)
|
||||
return ISO_ASSERT_FAILURE;
|
||||
{ret = ISO_ASSERT_FAILURE; goto ex;}
|
||||
t = writer->target;
|
||||
data = (struct iso_zero_writer_data_struct *) writer->data;
|
||||
|
||||
if (data->num_blocks == 0)
|
||||
return ISO_SUCCESS;
|
||||
memset(pad, 0, BLOCK_SIZE);
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
LIBISO_ALLOC_MEM(pad, uint8_t, BLOCK_SIZE);
|
||||
for (i = 0; i < data->num_blocks; ++i) {
|
||||
ret = iso_write(t, pad, BLOCK_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(pad);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -1113,7 +1133,7 @@ int tail_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
int ret;
|
||||
Ecma119Image *target;
|
||||
struct iso_zero_writer_data_struct *data;
|
||||
char msg[160];
|
||||
char msg[80];
|
||||
|
||||
target = writer->target;
|
||||
ret = iso_align_isohybrid(target, 0);
|
||||
@ -1185,11 +1205,11 @@ int transplant_checksum_buffer(Ecma119Image *target, int flag)
|
||||
static
|
||||
int write_vol_desc_terminator(Ecma119Image *target)
|
||||
{
|
||||
int res;
|
||||
uint8_t buf[BLOCK_SIZE];
|
||||
int ret;
|
||||
uint8_t *buf = NULL;
|
||||
struct ecma119_vol_desc_terminator *vol;
|
||||
|
||||
memset(buf, 0, BLOCK_SIZE);
|
||||
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
|
||||
|
||||
vol = (struct ecma119_vol_desc_terminator *) buf;
|
||||
|
||||
@ -1197,8 +1217,10 @@ int write_vol_desc_terminator(Ecma119Image *target)
|
||||
memcpy(vol->std_identifier, "CD001", 5);
|
||||
vol->vol_desc_version[0] = 1;
|
||||
|
||||
res = iso_write(target, buf, BLOCK_SIZE);
|
||||
return res;
|
||||
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||
ex:
|
||||
LIBISO_FREE_MEM(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -1229,7 +1251,7 @@ int write_head_part1(Ecma119Image *target, int *write_count, int flag)
|
||||
|
||||
/* write volume descriptors, one per writer */
|
||||
iso_msg_debug(target->image->id, "Write volume descriptors");
|
||||
for (i = 0; i < target->nwriters; ++i) {
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
writer = target->writers[i];
|
||||
res = writer->write_vol_desc(writer);
|
||||
if (res < 0)
|
||||
@ -1257,26 +1279,27 @@ write_error:;
|
||||
static
|
||||
int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
||||
{
|
||||
int res, i;
|
||||
uint8_t buf[BLOCK_SIZE];
|
||||
int ret, i;
|
||||
uint8_t *buf = NULL;
|
||||
IsoImageWriter *writer;
|
||||
|
||||
if (target->partition_offset <= 0)
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
|
||||
/* Write multi-session padding up to target->partition_offset + 16 */
|
||||
memset(buf, 0, BLOCK_SIZE);
|
||||
for(; *write_count < target->partition_offset + 16; (*write_count)++) {
|
||||
res = iso_write(target, buf, BLOCK_SIZE);
|
||||
if (res < 0)
|
||||
goto write_error;
|
||||
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
|
||||
for(; *write_count < (int) target->partition_offset + 16;
|
||||
(*write_count)++) {
|
||||
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* Write volume descriptors subtracting
|
||||
target->partiton_offset from any LBA pointer.
|
||||
*/
|
||||
target->eff_partition_offset = target->partition_offset;
|
||||
for (i = 0; i < target->nwriters; ++i) {
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
writer = target->writers[i];
|
||||
/* Not all writers have an entry in the partion volume descriptor set.
|
||||
It must be guaranteed that they write exactly one block.
|
||||
@ -1287,23 +1310,23 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
|
||||
if(writer->write_vol_desc != ecma119_writer_write_vol_desc &&
|
||||
writer->write_vol_desc != joliet_writer_write_vol_desc)
|
||||
continue;
|
||||
res = writer->write_vol_desc(writer);
|
||||
if (res < 0)
|
||||
goto write_error;
|
||||
ret = writer->write_vol_desc(writer);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
(*write_count)++;
|
||||
}
|
||||
res = write_vol_desc_terminator(target);
|
||||
if (res < 0)
|
||||
goto write_error;
|
||||
ret = write_vol_desc_terminator(target);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
(*write_count)++;
|
||||
target->eff_partition_offset = 0;
|
||||
|
||||
/* >>> TWINTREE: Postponed for now:
|
||||
Write second superblock checksum tag */;
|
||||
|
||||
return ISO_SUCCESS;
|
||||
write_error:;
|
||||
return res;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -1359,19 +1382,19 @@ static int write_mbr_partition_file(Ecma119Image *target, char *path,
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
uint32_t i;
|
||||
uint8_t buf[BLOCK_SIZE];
|
||||
uint8_t *buf = NULL;
|
||||
int ret;
|
||||
|
||||
memset(buf, 0, BLOCK_SIZE);
|
||||
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
|
||||
for (i = 0; i < prepad; i++) {
|
||||
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
if (fp == NULL)
|
||||
return ISO_BAD_PARTITION_FILE;
|
||||
{ret = ISO_BAD_PARTITION_FILE; goto ex;}
|
||||
|
||||
for (i = 0; i < blocks; i++) {
|
||||
memset(buf, 0, BLOCK_SIZE);
|
||||
@ -1385,12 +1408,15 @@ static int write_mbr_partition_file(Ecma119Image *target, char *path,
|
||||
ret = iso_write(target, buf, BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
fclose(fp);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -1412,7 +1438,7 @@ void *write_function(void *arg)
|
||||
goto write_error;
|
||||
|
||||
/* write data for each writer */
|
||||
for (i = 0; i < target->nwriters; ++i) {
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
writer = target->writers[i];
|
||||
res = writer->write_data(writer);
|
||||
if (res < 0) {
|
||||
@ -1469,10 +1495,10 @@ void *write_function(void *arg)
|
||||
#endif
|
||||
|
||||
write_error: ;
|
||||
if (res != ISO_LIBJTE_END_FAILED)
|
||||
if (res != (int) ISO_LIBJTE_END_FAILED)
|
||||
finish_libjte(target);
|
||||
target->eff_partition_offset = 0;
|
||||
if (res == ISO_CANCELED) {
|
||||
if (res == (int) ISO_CANCELED) {
|
||||
/* canceled */
|
||||
if (!target->will_cancel)
|
||||
iso_msg_submit(target->image->id, ISO_IMAGE_WRITE_CANCELED,
|
||||
@ -1648,6 +1674,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->no_force_dots = opts->no_force_dots;
|
||||
target->allow_lowercase = opts->allow_lowercase;
|
||||
target->allow_full_ascii = opts->allow_full_ascii;
|
||||
target->allow_7bit_ascii = opts->allow_7bit_ascii;
|
||||
target->relaxed_vol_atts = opts->relaxed_vol_atts;
|
||||
target->joliet_longer_paths = opts->joliet_longer_paths;
|
||||
target->joliet_long_names = opts->joliet_long_names;
|
||||
@ -1655,6 +1682,22 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
|
||||
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
|
||||
target->dir_rec_mtime = opts->dir_rec_mtime;
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
target->rr_reloc_dir = NULL;
|
||||
if (opts->rr_reloc_dir != NULL) {
|
||||
target->rr_reloc_dir = strdup(opts->rr_reloc_dir);
|
||||
if (target->rr_reloc_dir == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto target_cleanup;
|
||||
}
|
||||
}
|
||||
target->rr_reloc_flags = opts->rr_reloc_flags;
|
||||
target->rr_reloc_node = NULL;
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
target->sort_files = opts->sort_files;
|
||||
|
||||
target->replace_uid = opts->replace_uid ? 1 : 0;
|
||||
@ -1949,7 +1992,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->curblock = target->ms_block + target->partition_offset + 16;
|
||||
|
||||
/* Account for partition tree volume descriptors */
|
||||
for (i = 0; i < target->nwriters; ++i) {
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
/* Not all writers have an entry in the partition
|
||||
volume descriptor set.
|
||||
*/
|
||||
@ -1975,7 +2018,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
* That function computes the size needed by its structures and
|
||||
* increments image current block propertly.
|
||||
*/
|
||||
for (i = 0; i < target->nwriters; ++i) {
|
||||
for (i = 0; i < (int) target->nwriters; ++i) {
|
||||
IsoImageWriter *writer = target->writers[i];
|
||||
|
||||
/* Delaying boot image patching until new LBA is known */
|
||||
@ -2292,6 +2335,69 @@ int bs_set_size(struct burn_source *bs, off_t size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
static
|
||||
int dive_to_depth_8(IsoDir *dir, int depth)
|
||||
{
|
||||
int ret;
|
||||
IsoNode *pos;
|
||||
|
||||
if (depth >= 8)
|
||||
return 1;
|
||||
pos = dir->children;
|
||||
for (pos = dir->children; pos != NULL; pos = pos->next) {
|
||||
if (pos->type != LIBISO_DIR)
|
||||
continue;
|
||||
ret = dive_to_depth_8((IsoDir *) pos, depth + 1);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int make_reloc_dir_if_needed(IsoImage *img, IsoWriteOpts *opts, int flag)
|
||||
{
|
||||
int ret;
|
||||
IsoDir *dir;
|
||||
|
||||
/* Two forms to express the root directory */
|
||||
if (opts->rr_reloc_dir == NULL)
|
||||
return 1;
|
||||
if (opts->rr_reloc_dir[0] == 0)
|
||||
return 1;
|
||||
|
||||
if (strchr(opts->rr_reloc_dir, '/') != NULL)
|
||||
return 0;
|
||||
|
||||
/* Check existence of opts->rr_reloc_dir */
|
||||
ret = iso_dir_get_node(img->root, opts->rr_reloc_dir, NULL);
|
||||
if (ret > 0)
|
||||
return 1;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Check whether there is a directory of depth 8 (root is depth 1) */
|
||||
ret = dive_to_depth_8(img->root, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret == 0)
|
||||
return 1;
|
||||
|
||||
/* Make IsoDir with same permissions as root directory */
|
||||
ret = iso_tree_add_new_dir(img->root, opts->rr_reloc_dir, &dir);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
opts->rr_reloc_flags |= 2; /* Auto-created relocation directory */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
|
||||
int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
|
||||
struct burn_source **burn_src)
|
||||
{
|
||||
@ -2308,6 +2414,18 @@ int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
if (!opts->allow_deep_paths) {
|
||||
ret = make_reloc_dir_if_needed(image, opts, 0);
|
||||
if (ret < 0) {
|
||||
free(source);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
ret = ecma119_image_new(image, opts, &target);
|
||||
if (ret < 0) {
|
||||
free(source);
|
||||
@ -2416,6 +2534,13 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
|
||||
wopts->fifo_size = 1024; /* 2 MB buffer */
|
||||
wopts->sort_files = 1; /* file sorting is always good */
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
wopts->rr_reloc_dir = NULL;
|
||||
wopts->rr_reloc_flags = 0;
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
wopts->system_area_data = NULL;
|
||||
wopts->system_area_options = 0;
|
||||
wopts->vol_creation_time = 0;
|
||||
@ -2452,6 +2577,14 @@ void iso_write_opts_free(IsoWriteOpts *opts)
|
||||
return;
|
||||
}
|
||||
free(opts->output_charset);
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
if (opts->rr_reloc_dir != NULL)
|
||||
free(opts->rr_reloc_dir);
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
if (opts->system_area_data != NULL)
|
||||
free(opts->system_area_data);
|
||||
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
|
||||
@ -2624,6 +2757,16 @@ int iso_write_opts_set_allow_full_ascii(IsoWriteOpts *opts, int allow)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_allow_7bit_ascii(IsoWriteOpts *opts, int allow)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->allow_7bit_ascii = allow ? 1 : 0;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
@ -2683,7 +2826,29 @@ int iso_write_opts_set_dir_rec_mtime(IsoWriteOpts *opts, int allow)
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->dir_rec_mtime = allow ? 1 : 0;
|
||||
if (allow < 0)
|
||||
allow = 1;
|
||||
else if (allow & (1 << 14))
|
||||
allow &= ~1;
|
||||
else if (allow & 6)
|
||||
allow |= 1;
|
||||
opts->dir_rec_mtime = allow & 7;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_rr_reloc(IsoWriteOpts *opts, char *name, int flags)
|
||||
{
|
||||
if (opts->rr_reloc_dir != name) {
|
||||
if (opts->rr_reloc_dir != NULL)
|
||||
free(opts->rr_reloc_dir);
|
||||
opts->rr_reloc_dir = NULL;
|
||||
if (name != NULL) {
|
||||
opts->rr_reloc_dir = strdup(name);
|
||||
if (opts->rr_reloc_dir == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
}
|
||||
opts->rr_reloc_flags = flags & 1;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -149,6 +149,13 @@ struct iso_write_opts {
|
||||
*/
|
||||
unsigned int allow_full_ascii :1;
|
||||
|
||||
/**
|
||||
* If not allow_full_ascii is set: allow all 7 bit characters that would
|
||||
* be allowed by allow_full_ascii. But still map lowercase to uppercase if
|
||||
* not allow_lowercase is set to 1.
|
||||
*/
|
||||
unsigned int allow_7bit_ascii :1;
|
||||
|
||||
/**
|
||||
* Allow all characters to be part of Volume and Volset identifiers on
|
||||
* the Primary Volume Descriptor. This breaks ISO-9660 contraints, but
|
||||
@ -202,8 +209,27 @@ struct iso_write_opts {
|
||||
* to expect that we do have a creation timestamp with the source.
|
||||
* mkisofs writes mtimes and the result seems more suitable if mounted
|
||||
* without Rock Ridge support.)
|
||||
* bit0= ECMA-119, bit1= Joliet, bit2= ISO 9660:1999
|
||||
*/
|
||||
unsigned int dir_rec_mtime :3;
|
||||
|
||||
/**
|
||||
* This describes the directory where to store Rock Ridge relocated
|
||||
* directories.
|
||||
* If not relaxation "allow_deep_paths" is in effect, it is necessary to
|
||||
* relocate directories so that no ECMA-119 file path has more than
|
||||
* 8 components. For Rock Ridge the relocated directories are linked forth
|
||||
* and back to a placeholder at their original position in path level 8
|
||||
* (entries CL and PL). Directories marked by entry RE are to be considered
|
||||
* artefacts of relocation and shall not be read into a Rock Ridge tree.
|
||||
* For plain ECMA-119, the relocation directory is just a normal directory
|
||||
* which contains normal files and directories.
|
||||
*/
|
||||
char *rr_reloc_dir; /* IsoNode name in root directory */
|
||||
int rr_reloc_flags; /* bit0= mark auto-created rr_reloc_dir by RE
|
||||
bit1= directory was auto-created
|
||||
(cannot be set via API)
|
||||
*/
|
||||
unsigned int dir_rec_mtime :1;
|
||||
|
||||
/**
|
||||
* Compute MD5 checksum for the whole session and record it as index 0 of
|
||||
@ -458,6 +484,7 @@ struct ecma119_image
|
||||
unsigned int no_force_dots :2;
|
||||
unsigned int allow_lowercase :1;
|
||||
unsigned int allow_full_ascii :1;
|
||||
unsigned int allow_7bit_ascii :1;
|
||||
|
||||
unsigned int relaxed_vol_atts : 1;
|
||||
|
||||
@ -476,8 +503,16 @@ struct ecma119_image
|
||||
/* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12. */
|
||||
unsigned int aaip_susp_1_10 :1;
|
||||
|
||||
/* Store in ECMA-119 timestamp mtime of source */
|
||||
unsigned int dir_rec_mtime :1;
|
||||
/* Store in ECMA-119, Joliet, ISO 9660:1999 timestamp the mtime of source
|
||||
bit0= ECMA-119, bit1= Joliet, bit2= ISO 9660:1999.
|
||||
*/
|
||||
unsigned int dir_rec_mtime :3;
|
||||
|
||||
/* The ECMA-119 directory where to store Rock Ridge relocated directories.
|
||||
*/
|
||||
char *rr_reloc_dir; /* IsoNode name in root directory */
|
||||
int rr_reloc_flags;
|
||||
Ecma119Node *rr_reloc_node; /* Directory node in ecma119_image */
|
||||
|
||||
unsigned int md5_session_checksum :1;
|
||||
unsigned int md5_file_checksums :2;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -32,7 +32,7 @@
|
||||
static
|
||||
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
||||
{
|
||||
int ret, relaxed, free_ascii_name= 0, force_dots = 0, max_len;
|
||||
int ret, relaxed, free_ascii_name= 0, force_dots = 0;
|
||||
char *ascii_name;
|
||||
char *isoname= NULL;
|
||||
|
||||
@ -59,6 +59,8 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
|
||||
} else {
|
||||
relaxed = (int)img->allow_lowercase;
|
||||
}
|
||||
if (img->allow_7bit_ascii)
|
||||
relaxed |= 4;
|
||||
if (iso->type == LIBISO_DIR && !(img->allow_dir_id_ext)) {
|
||||
if (img->untranslated_name_len > 0) {
|
||||
if (strlen(ascii_name) > img->untranslated_name_len) {
|
||||
@ -73,11 +75,22 @@ needs_transl:;
|
||||
} else if (img->max_37_char_filenames) {
|
||||
isoname = iso_r_dirid(ascii_name, 37, relaxed);
|
||||
} else if (img->iso_level == 1) {
|
||||
|
||||
#ifdef Libisofs_old_ecma119_nameS
|
||||
|
||||
if (relaxed) {
|
||||
isoname = iso_r_dirid(ascii_name, 8, relaxed);
|
||||
} else {
|
||||
isoname = iso_1_dirid(ascii_name);
|
||||
isoname = iso_1_dirid(ascii_name, 0);
|
||||
}
|
||||
|
||||
#else /* Libisofs_old_ecma119_nameS */
|
||||
|
||||
isoname = iso_1_dirid(ascii_name, relaxed);
|
||||
|
||||
#endif /* ! Libisofs_old_ecma119_nameS */
|
||||
|
||||
|
||||
} else {
|
||||
if (relaxed) {
|
||||
isoname = iso_r_dirid(ascii_name, 31, relaxed);
|
||||
@ -94,7 +107,12 @@ needs_transl:;
|
||||
} else if (img->max_37_char_filenames) {
|
||||
isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots);
|
||||
} else if (img->iso_level == 1) {
|
||||
if (relaxed || !force_dots) {
|
||||
|
||||
#ifdef Libisofs_old_ecma119_nameS
|
||||
|
||||
int max_len;
|
||||
|
||||
if (relaxed) {
|
||||
if (strchr(ascii_name, '.') == NULL)
|
||||
max_len = 8;
|
||||
else
|
||||
@ -102,8 +120,15 @@ needs_transl:;
|
||||
isoname = iso_r_fileid(ascii_name, max_len, relaxed,
|
||||
force_dots);
|
||||
} else {
|
||||
isoname = iso_1_fileid(ascii_name);
|
||||
isoname = iso_1_fileid(ascii_name, 0, force_dots);
|
||||
}
|
||||
|
||||
#else /* Libisofs_old_ecma119_nameS */
|
||||
|
||||
isoname = iso_1_fileid(ascii_name, relaxed, force_dots);
|
||||
|
||||
#endif /* ! Libisofs_old_ecma119_nameS */
|
||||
|
||||
} else {
|
||||
if (relaxed || !force_dots) {
|
||||
isoname = iso_r_fileid(ascii_name, 30, relaxed, force_dots);
|
||||
@ -126,6 +151,21 @@ needs_transl:;
|
||||
}
|
||||
}
|
||||
|
||||
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
|
||||
{
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
if (img->rr_reloc_node == node &&
|
||||
node != img->root && node != img->partition_root &&
|
||||
(img->rr_reloc_flags & 2))
|
||||
return 1;
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int create_ecma119_node(Ecma119Image *img, IsoNode *iso, Ecma119Node **node)
|
||||
{
|
||||
@ -299,7 +339,7 @@ void ecma119_node_free(Ecma119Node *node)
|
||||
return;
|
||||
}
|
||||
if (node->type == ECMA119_DIR) {
|
||||
int i;
|
||||
size_t i;
|
||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||
ecma119_node_free(node->info.dir->children[i]);
|
||||
}
|
||||
@ -434,6 +474,22 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
|
||||
if (ret < 0) {
|
||||
goto ex;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
if (depth == 1) { /* root is default */
|
||||
image->rr_reloc_node = node;
|
||||
} else if (depth == 2) {
|
||||
/* Directories in root may be used as relocation dir */
|
||||
if (image->rr_reloc_dir != NULL)
|
||||
if (image->rr_reloc_dir[0] != 0 &&
|
||||
strcmp(iso->name, image->rr_reloc_dir) == 0)
|
||||
image->rr_reloc_node = node;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
|
||||
}
|
||||
ret = ISO_SUCCESS;
|
||||
pos = dir->children;
|
||||
@ -643,7 +699,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
max = max_file_len - digits;
|
||||
}
|
||||
name = full_name;
|
||||
if (max < strlen(name)) {
|
||||
if ((size_t) max < strlen(name)) {
|
||||
name[max] = '\0';
|
||||
}
|
||||
/* let ext be an empty string */
|
||||
@ -750,7 +806,7 @@ int mangle_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
|
||||
}
|
||||
|
||||
static
|
||||
int mangle_tree(Ecma119Image *img, int recurse)
|
||||
int mangle_tree(Ecma119Image *img, Ecma119Node *dir, int recurse)
|
||||
{
|
||||
int max_file, max_dir;
|
||||
Ecma119Node *root;
|
||||
@ -765,7 +821,9 @@ int mangle_tree(Ecma119Image *img, int recurse)
|
||||
} else {
|
||||
max_file = max_dir = 31;
|
||||
}
|
||||
if (img->eff_partition_offset > 0) {
|
||||
if (dir != NULL) {
|
||||
root = dir;
|
||||
} else if (img->eff_partition_offset > 0) {
|
||||
root = img->partition_root;
|
||||
} else {
|
||||
root = img->root;
|
||||
@ -887,43 +945,77 @@ int reparent(Ecma119Node *child, Ecma119Node *parent)
|
||||
* 1 success, < 0 error
|
||||
*/
|
||||
static
|
||||
int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int level, int pathlen)
|
||||
int reorder_tree(Ecma119Image *img, Ecma119Node *dir,
|
||||
int dir_level, int dir_pathlen)
|
||||
{
|
||||
int ret;
|
||||
size_t max_path;
|
||||
Ecma119Node *root;
|
||||
int ret, level, pathlen, newpathlen;
|
||||
size_t max_path, i;
|
||||
Ecma119Node *reloc, *child;
|
||||
|
||||
/* might change by relocation */
|
||||
level = dir_level;
|
||||
pathlen = dir_pathlen;
|
||||
|
||||
max_path = pathlen + 1 + max_child_name_len(dir);
|
||||
|
||||
if (level > 8 || max_path > 255) {
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
reloc = img->rr_reloc_node;
|
||||
if (reloc == NULL) {
|
||||
if (img->eff_partition_offset > 0) {
|
||||
root = img->partition_root;
|
||||
reloc = img->partition_root;
|
||||
} else {
|
||||
root = img->root;
|
||||
reloc = img->root;
|
||||
}
|
||||
ret = reparent(dir, root);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (img->eff_partition_offset > 0) {
|
||||
reloc = img->partition_root;
|
||||
} else {
|
||||
reloc = img->root;
|
||||
}
|
||||
|
||||
#endif /* ! Libisofs_with_rr_reloc_diR */
|
||||
|
||||
ret = reparent(dir, reloc);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (reloc == img->root || reloc == img->partition_root) {
|
||||
/*
|
||||
* we are appended to the root's children now, so there is no
|
||||
* need to recurse (the root will hit us again)
|
||||
*/
|
||||
} else {
|
||||
size_t i;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
/* dir is now the relocated Ecma119Node */
|
||||
pathlen = 37 + 1; /* The dir name might get longer by mangling */
|
||||
level = 2;
|
||||
if (img->rr_reloc_dir != NULL) {
|
||||
pathlen += strlen(img->rr_reloc_node->iso_name) + 1;
|
||||
if(img->rr_reloc_dir[0] != 0)
|
||||
level = 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (ecma119_is_dedicated_reloc_dir(img, (Ecma119Node *) dir))
|
||||
return ISO_SUCCESS;
|
||||
|
||||
for (i = 0; i < dir->info.dir->nchildren; i++) {
|
||||
Ecma119Node *child = dir->info.dir->children[i];
|
||||
child = dir->info.dir->children[i];
|
||||
if (child->type == ECMA119_DIR) {
|
||||
int newpathlen = pathlen + 1 + strlen(child->iso_name);
|
||||
newpathlen = pathlen + 1 + strlen(child->iso_name);
|
||||
ret = reorder_tree(img, child, level + 1, newpathlen);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1125,14 +1217,14 @@ int ecma119_tree_create(Ecma119Image *img)
|
||||
sort_tree(root);
|
||||
|
||||
iso_msg_debug(img->image->id, "Mangling names...");
|
||||
ret = mangle_tree(img, 1);
|
||||
ret = mangle_tree(img, NULL, 1);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (img->rockridge && !img->allow_deep_paths) {
|
||||
|
||||
/* reorder the tree, acording to RRIP, 4.1.5 */
|
||||
/* Relocate deep directories, acording to RRIP, 4.1.5 */
|
||||
ret = reorder_tree(img, root, 1, 0);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
@ -1140,10 +1232,16 @@ int ecma119_tree_create(Ecma119Image *img)
|
||||
|
||||
/*
|
||||
* and we need to remangle the root directory, as the function
|
||||
* above could insert new directories into the root.
|
||||
* above could insert new directories into the relocation directory.
|
||||
* Note that recurse = 0, as we don't need to recurse.
|
||||
*/
|
||||
ret = mangle_tree(img, 0);
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
ret = mangle_tree(img, img->rr_reloc_node, 0);
|
||||
#else
|
||||
ret = mangle_tree(img, NULL, 0);
|
||||
#endif
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -96,5 +97,11 @@ void ecma119_node_free(Ecma119Node *node);
|
||||
*/
|
||||
Ecma119Node *ecma119_search_iso_node(Ecma119Image *img, IsoNode *node);
|
||||
|
||||
/**
|
||||
* Tell whether node is a dedicated relocation directory which only contains
|
||||
* relocated directories.
|
||||
*/
|
||||
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node);
|
||||
|
||||
|
||||
#endif /*LIBISO_ECMA119_TREE_H_*/
|
||||
|
@ -275,6 +275,9 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
||||
free(node);
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
node->lba = 0;
|
||||
node->size = 0;
|
||||
node->content = NULL;
|
||||
|
||||
/* atributes from parent */
|
||||
node->node.mode = S_IFREG | (parent->node.mode & 0444);
|
||||
@ -384,14 +387,14 @@ int create_image(IsoImage *image, const char *image_path,
|
||||
if (ret != sizeof(mbr)) {
|
||||
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||
"Can't read MBR from image file.");
|
||||
return ret < 0 ? ret : ISO_FILE_READ_ERROR;
|
||||
return ret < 0 ? ret : (int) ISO_FILE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* check valid MBR signature */
|
||||
if ( mbr.sign1 != 0x55 || mbr.sign2 != 0xAA ) {
|
||||
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
|
||||
"Invalid MBR. Wrong signature.");
|
||||
return ISO_BOOT_IMAGE_NOT_VALID;
|
||||
return (int) ISO_BOOT_IMAGE_NOT_VALID;
|
||||
}
|
||||
|
||||
/* ensure single partition */
|
||||
@ -487,7 +490,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
|
||||
"Cannot find directory for El Torito boot catalog in ISO image: '%s'",
|
||||
catdir);
|
||||
free(catdir);
|
||||
return ret < 0 ? ret : ISO_NODE_DOESNT_EXIST;
|
||||
return ret < 0 ? ret : (int) ISO_NODE_DOESNT_EXIST;
|
||||
}
|
||||
if (p->type != LIBISO_DIR) {
|
||||
free(catdir);
|
||||
@ -598,6 +601,30 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
|
||||
char **content, off_t *size)
|
||||
{
|
||||
IsoBoot *bootcat;
|
||||
|
||||
*catnode = NULL;
|
||||
*lba = 0;
|
||||
*content = NULL;
|
||||
*size = 0;
|
||||
bootcat = image->bootcat->node;
|
||||
if (bootcat == NULL)
|
||||
return 0;
|
||||
*catnode = bootcat;
|
||||
*lba = bootcat->lba;
|
||||
*size = bootcat->size;
|
||||
if (bootcat->size > 0 && bootcat->content != NULL) {
|
||||
*content = calloc(1, bootcat->size);
|
||||
if (*content == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
memcpy(*content, bootcat->content, bootcat->size);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int iso_image_get_all_boot_imgs(IsoImage *image, int *num_boots,
|
||||
ElToritoBootImage ***boots, IsoFile ***bootnodes, int flag)
|
||||
{
|
||||
@ -760,7 +787,6 @@ write_validation_entry(uint8_t *buf, uint8_t platform_id,
|
||||
static void
|
||||
write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
|
||||
{
|
||||
int pi;
|
||||
char *id_string;
|
||||
|
||||
struct el_torito_section_header *e =
|
||||
@ -768,7 +794,7 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
|
||||
|
||||
/* 0x90 = more section headers follow , 0x91 = final section */
|
||||
e->header_indicator[0] = 0x90 + (idx == t->catalog->num_bootimages - 1);
|
||||
pi= 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[1] = (num_entries >> 8) & 0xff;;
|
||||
id_string = (char *) e->id_string;
|
||||
@ -837,10 +863,10 @@ int catalog_open(IsoStream *stream)
|
||||
for (j = i + 1; j < cat->num_bootimages; j++) {
|
||||
if (boots[i]->platform_id != boots[j]->platform_id)
|
||||
break;
|
||||
for (k = 0; k < sizeof(boots[i]->id_string); k++)
|
||||
for (k = 0; k < (int) sizeof(boots[i]->id_string); k++)
|
||||
if (boots[i]->id_string[k] != boots[j]->id_string[k])
|
||||
break;
|
||||
if (k < sizeof(boots[i]->id_string))
|
||||
if (k < (int) sizeof(boots[i]->id_string))
|
||||
break;
|
||||
}
|
||||
num_entries = j - i;
|
||||
@ -896,7 +922,7 @@ int catalog_read(IsoStream *stream, void *buf, size_t count)
|
||||
return ISO_FILE_NOT_OPENED;
|
||||
}
|
||||
|
||||
len = MIN(count, BLOCK_SIZE - data->offset);
|
||||
len = MIN(count, (size_t) (BLOCK_SIZE - data->offset));
|
||||
memcpy(buf, data->buffer + data->offset, len);
|
||||
return len;
|
||||
}
|
||||
@ -936,7 +962,11 @@ IsoStreamIface catalog_stream_class = {
|
||||
catalog_read,
|
||||
catalog_is_repeatable,
|
||||
catalog_get_id,
|
||||
catalog_free
|
||||
catalog_free,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1127,8 +1157,8 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
}
|
||||
ret = iso_stream_read(original, buf, size);
|
||||
iso_stream_close(original);
|
||||
if (ret != size) {
|
||||
return (ret < 0) ? ret : ISO_FILE_READ_ERROR;
|
||||
if (ret != (int) size) {
|
||||
return (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR;
|
||||
}
|
||||
|
||||
/* ok, patch the read buffer */
|
||||
@ -1156,7 +1186,6 @@ static
|
||||
int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
{
|
||||
Ecma119Image *t;
|
||||
struct el_torito_boot_catalog *cat;
|
||||
struct ecma119_boot_rec_vol_desc vol;
|
||||
|
||||
if (writer == NULL) {
|
||||
@ -1164,7 +1193,6 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
cat = t->catalog;
|
||||
iso_msg_debug(t->image->id, "Write El-Torito boot record");
|
||||
|
||||
memset(&vol, 0, sizeof(struct ecma119_boot_rec_vol_desc));
|
||||
|
@ -26,6 +26,14 @@
|
||||
struct Iso_Boot
|
||||
{
|
||||
IsoNode node;
|
||||
|
||||
/* Want to get content of loaded boot catalog.
|
||||
Vreixo took care not to make it an IsoFile at load time.
|
||||
So this is implemented independently of IsoStream.
|
||||
*/
|
||||
uint32_t lba;
|
||||
off_t size;
|
||||
char *content;
|
||||
};
|
||||
|
||||
/* Not more than 32 so that all entries fit into 2048 bytes */
|
||||
|
@ -26,6 +26,8 @@
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* <<< */
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef Xorriso_standalonE
|
||||
|
||||
@ -335,25 +337,27 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
{
|
||||
int res, ret, was_error;
|
||||
size_t i, b;
|
||||
Ecma119Image *t;
|
||||
Ecma119Image *t = NULL;
|
||||
IsoFileSrc *file;
|
||||
IsoFileSrc **filelist;
|
||||
char name[PATH_MAX];
|
||||
char buffer[BLOCK_SIZE];
|
||||
char *name = NULL;
|
||||
char *buffer = NULL;
|
||||
off_t file_size;
|
||||
uint32_t nblocks;
|
||||
void *ctx= NULL;
|
||||
char md5[16], pre_md5[16];
|
||||
int pre_md5_valid = 0;
|
||||
IsoStream *stream, *inp;
|
||||
#ifdef Libisofs_with_libjtE
|
||||
int jte_begun = 0;
|
||||
#endif
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
ret = ISO_ASSERT_FAILURE; goto ex;
|
||||
}
|
||||
|
||||
memset(buffer, 0, BLOCK_SIZE);
|
||||
LIBISO_ALLOC_MEM(name, char, PATH_MAX);
|
||||
LIBISO_ALLOC_MEM(buffer, char, BLOCK_SIZE);
|
||||
t = writer->target;
|
||||
filelist = writer->data;
|
||||
|
||||
@ -380,7 +384,14 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
|
||||
}
|
||||
res = filesrc_open(file);
|
||||
iso_stream_get_file_name(file->stream, name);
|
||||
|
||||
/* Get file name from end of filter chain */
|
||||
for (stream = file->stream; ; stream = inp) {
|
||||
inp = iso_stream_get_input_stream(stream, 0);
|
||||
if (inp == NULL)
|
||||
break;
|
||||
}
|
||||
iso_stream_get_file_name(stream, name);
|
||||
if (res < 0) {
|
||||
/*
|
||||
* UPS, very ugly error, the best we can do is just to write
|
||||
@ -562,13 +573,15 @@ ex:;
|
||||
iso_md5_end(&ctx, md5);
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
if (jte_begun) {
|
||||
if (jte_begun && t != NULL) {
|
||||
libjte_end_data_file(t->libjte_handle);
|
||||
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||
ISO_LIBJTE_END_FAILED, 0);
|
||||
}
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
LIBISO_FREE_MEM(name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -394,7 +394,7 @@ int gzip_stream_convert(IsoStream *stream, void *buf, size_t desired, int flag)
|
||||
if (cnv_ret == Z_STREAM_ERROR || cnv_ret == Z_BUF_ERROR) {
|
||||
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
|
||||
}
|
||||
if (strm->avail_out < rng->out_buffer_size)
|
||||
if ((int) strm->avail_out < rng->out_buffer_size)
|
||||
break; /* output is available */
|
||||
if (strm->avail_in == 0) /* all pending input consumed */
|
||||
break;
|
||||
|
@ -576,7 +576,8 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
|
||||
rng->block_pointers[i] =
|
||||
iso_read_lsb((uint8_t *) (rng->block_pointers + i), 4);
|
||||
if (i > 0)
|
||||
if (rng->block_pointers[i] - rng->block_pointers[i - 1]
|
||||
if ((int) (rng->block_pointers[i] -
|
||||
rng->block_pointers[i - 1])
|
||||
> block_max)
|
||||
block_max = rng->block_pointers[i]
|
||||
- rng->block_pointers[i - 1];
|
||||
@ -619,7 +620,7 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
|
||||
if (ret != Z_OK)
|
||||
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
|
||||
rng->buffer_fill = buf_len;
|
||||
if (buf_len < rng->block_size &&
|
||||
if ((int) buf_len < rng->block_size &&
|
||||
i != rng->block_pointer_fill - 1)
|
||||
return (rng->error_ret = ISO_ZISOFS_WRONG_INPUT);
|
||||
} else if(ret == 0) {
|
||||
|
@ -141,11 +141,12 @@ void update_next(IsoDirIter *iter)
|
||||
static
|
||||
int find_iter_next(IsoDirIter *iter, IsoNode **node)
|
||||
{
|
||||
struct find_iter_data *data = iter->data;
|
||||
struct find_iter_data *data;
|
||||
|
||||
if (iter == NULL || node == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
data = iter->data;
|
||||
|
||||
if (data->err < 0) {
|
||||
return data->err;
|
||||
|
@ -293,6 +293,8 @@ typedef struct
|
||||
uint32_t bootblocks[Libisofs_max_boot_imageS];
|
||||
|
||||
uint32_t catblock; /**< Block for El-Torito catalog */
|
||||
off_t catsize; /* Size of boot catalog in bytes */
|
||||
char *catcontent;
|
||||
|
||||
/* Whether inode numbers from PX entries shall be discarded */
|
||||
unsigned int make_new_ino : 1 ;
|
||||
@ -392,6 +394,8 @@ char* ifs_get_path(IsoFileSource *src)
|
||||
char *path, *new_path;
|
||||
int pathlen;
|
||||
|
||||
if (data->name == NULL)
|
||||
return NULL;
|
||||
path = ifs_get_path(data->parent);
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
@ -470,15 +474,16 @@ int read_dir(ImageFileSourceData *data)
|
||||
IsoImageFilesystem *fs;
|
||||
_ImageFsData *fsdata;
|
||||
struct ecma119_dir_record *record;
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
uint8_t *buffer = NULL;
|
||||
IsoFileSource *child = NULL;
|
||||
uint32_t pos = 0;
|
||||
uint32_t tlen = 0;
|
||||
|
||||
if (data == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
ret = ISO_NULL_POINTER; goto ex;
|
||||
}
|
||||
|
||||
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||
fs = data->fs;
|
||||
fsdata = fs->data;
|
||||
|
||||
@ -486,7 +491,7 @@ int read_dir(ImageFileSourceData *data)
|
||||
block = data->sections[0].block;
|
||||
ret = fsdata->src->read_block(fsdata->src, block, buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* "." entry, get size of the dir and skip */
|
||||
@ -510,25 +515,37 @@ int read_dir(ImageFileSourceData *data)
|
||||
*/
|
||||
ret = fsdata->src->read_block(fsdata->src, ++block, buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
tlen += 2048 - pos;
|
||||
pos = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
/* (Vreixo:)
|
||||
* What about ignoring files with existence flag?
|
||||
* if (record->flags[0] & 0x01)
|
||||
* continue;
|
||||
* ts B20306 : >>> One should rather record that flag and write it
|
||||
* >>> to the new image.
|
||||
*/
|
||||
|
||||
/*
|
||||
#ifdef Libisofs_wrongly_skip_rr_moveD
|
||||
/* ts B20306 :
|
||||
This skipping by name is wrong resp. redundant:
|
||||
If no rr reading is enabled, then it is the only access point for
|
||||
the content of relocated directories. So one should not ignore it.
|
||||
If rr reading is enabled, then the RE entry of mkisofs' RR_MOVED
|
||||
will cause it to be skipped.
|
||||
*/
|
||||
|
||||
/* (Vreixo:)
|
||||
* For a extrange reason, mkisofs relocates directories under
|
||||
* a RR_MOVED dir. It seems that it is only used for that purposes,
|
||||
* and thus it should be removed from the iso tree before
|
||||
* generating a new image with libisofs, that don't uses it.
|
||||
*/
|
||||
|
||||
if (data->parent == NULL && record->len_fi[0] == 8
|
||||
&& !strncmp((char*)record->file_id, "RR_MOVED", 8)) {
|
||||
|
||||
@ -539,6 +556,8 @@ int read_dir(ImageFileSourceData *data)
|
||||
continue;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_wrongly_skip_rr_moveD */
|
||||
|
||||
/*
|
||||
* We pass a NULL parent instead of dir, to prevent the circular
|
||||
* reference from child to parent.
|
||||
@ -555,7 +574,7 @@ int read_dir(ImageFileSourceData *data)
|
||||
free(ifsdata);
|
||||
free(child);
|
||||
}
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* add to the child list */
|
||||
@ -564,7 +583,7 @@ int read_dir(ImageFileSourceData *data)
|
||||
node = malloc(sizeof(struct child_list));
|
||||
if (node == NULL) {
|
||||
iso_file_source_unref(child);
|
||||
return ISO_OUT_OF_MEM;
|
||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||
}
|
||||
/*
|
||||
* Note that we insert in reverse order. This leads to faster
|
||||
@ -581,7 +600,10 @@ int read_dir(ImageFileSourceData *data)
|
||||
pos += record->len_dr[0];
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -1245,7 +1267,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
int aa_done = 0;
|
||||
char *cs_value = NULL;
|
||||
size_t cs_value_length = 0;
|
||||
char msg[160];
|
||||
char *msg = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
|
||||
int has_px = 0;
|
||||
|
||||
@ -1255,7 +1278,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
#endif
|
||||
|
||||
if (fs == NULL || fs->data == NULL || record == NULL || src == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
ret = ISO_NULL_POINTER; goto ex;
|
||||
}
|
||||
|
||||
fsdata = (_ImageFsData*)fs->data;
|
||||
@ -1274,7 +1297,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
"in interleaved mode. We do not support this mode, as we think "
|
||||
"it is not used. If you are reading this, then we are wrong :) "
|
||||
"Please contact libisofs developers, so we can fix this.");
|
||||
return ISO_UNSUPPORTED_ECMA119;
|
||||
{ret = ISO_UNSUPPORTED_ECMA119; goto ex;}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1285,7 +1308,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_ECMA119, 0,
|
||||
"Unsupported image. This image has at least one file with "
|
||||
"ECMA-119 Extended Attributes, that are not supported");
|
||||
return ISO_UNSUPPORTED_ECMA119;
|
||||
{ret = ISO_UNSUPPORTED_ECMA119; goto ex;}
|
||||
}
|
||||
|
||||
/* TODO #00013 : check for unsupported flags when reading a dir record */
|
||||
@ -1300,13 +1323,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
if (new_name == NULL) {
|
||||
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||
"Cannot retrieve file name");
|
||||
return ISO_WRONG_ECMA119;
|
||||
{ret = ISO_WRONG_ECMA119; goto ex;}
|
||||
}
|
||||
if (strcmp(new_name, data->name)) {
|
||||
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||
"Multi-extent file lacks last entry.");
|
||||
free(new_name);
|
||||
return ISO_WRONG_ECMA119;
|
||||
{ret = ISO_WRONG_ECMA119; goto ex;}
|
||||
}
|
||||
free(new_name);
|
||||
}
|
||||
@ -1321,7 +1344,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
if (record->flags[0] & 0x02) {
|
||||
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||
"Directories with more than one section are not allowed.");
|
||||
return ISO_WRONG_ECMA119;
|
||||
{ret = ISO_WRONG_ECMA119; goto ex;}
|
||||
}
|
||||
|
||||
if (*src == NULL) {
|
||||
@ -1362,7 +1385,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
|
||||
ifsdata->info.st_size += (off_t) ifsdata->sections[ifsdata->nsections].size;
|
||||
ifsdata->nsections++;
|
||||
return 2;
|
||||
{ret = 2; goto ex;}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1380,7 +1403,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
iter = susp_iter_new(fsdata->src, record, fsdata->len_skp,
|
||||
fsdata->msgid);
|
||||
if (iter == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||
}
|
||||
|
||||
while ((ret = susp_iter_next(iter, &sue)) > 0) {
|
||||
@ -1449,7 +1472,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
*/
|
||||
susp_iter_free(iter);
|
||||
free(name);
|
||||
return 0; /* it's not an error */
|
||||
{ret = 0; goto ex;} /* it's not an error */
|
||||
} else if (SUSP_SIG(sue, 'C', 'L')) {
|
||||
/*
|
||||
* This entry is a placeholder for a relocated dir.
|
||||
@ -1581,13 +1604,14 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
|
||||
if (ret < 0) {
|
||||
free(name);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
if ((flag & 1) && aa_string != NULL) {
|
||||
ret = iso_aa_lookup_attr(aa_string, "isofs.cs",
|
||||
&cs_value_length, &cs_value, 0);
|
||||
if (ret == 1) {
|
||||
LIBISO_ALLOC_MEM(msg, char, 160);
|
||||
if (fsdata->auto_input_charset & 1) {
|
||||
if (fsdata->input_charset != NULL)
|
||||
free(fsdata->input_charset);
|
||||
@ -1621,7 +1645,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
free(newname);
|
||||
if (ret < 0) {
|
||||
free(name);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
} else {
|
||||
free(name);
|
||||
@ -1643,7 +1667,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
free(newlinkdest);
|
||||
if (ret < 0) {
|
||||
free(name);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
} else {
|
||||
free(linkdest);
|
||||
@ -1676,15 +1700,17 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
if (record->len_fi[0] == 1 && record->file_id[0] == 0) {
|
||||
/* "." entry, we can call this for root node, so... */
|
||||
if (!(atts.st_mode & S_IFDIR)) {
|
||||
return iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||
"Wrong ISO file name. \".\" not dir");
|
||||
goto ex;
|
||||
}
|
||||
} else {
|
||||
|
||||
name = get_name(fsdata, (char*)record->file_id, record->len_fi[0]);
|
||||
if (name == NULL) {
|
||||
return iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
|
||||
"Cannot retrieve file name");
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* remove trailing version number */
|
||||
@ -1710,24 +1736,24 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
* Thus, we need to read attributes for this directory from the "."
|
||||
* entry of the relocated dir.
|
||||
*/
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
|
||||
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||
ret = fsdata->src->read_block(fsdata->src, relocated_dir, buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
ret = iso_file_source_new_ifs(fs, parent, (struct ecma119_dir_record*)
|
||||
buffer, src, 0);
|
||||
if (ret <= 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* but the real name is the name of the placeholder */
|
||||
ifsdata = (ImageFileSourceData*) (*src)->data;
|
||||
ifsdata->name = name;
|
||||
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
}
|
||||
|
||||
/* Production of missing inode numbers is delayed until the image is
|
||||
@ -1763,7 +1789,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
|
||||
"Link without destination.");
|
||||
free(name);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* ok, we can now create the file source */
|
||||
@ -1831,13 +1857,17 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
ifsrc->refcount = 1;
|
||||
|
||||
*src = ifsrc;
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
|
||||
ifs_cleanup: ;
|
||||
free(name);
|
||||
free(linkdest);
|
||||
free(ifsdata);
|
||||
free(ifsrc);
|
||||
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(msg);
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1846,25 +1876,26 @@ int ifs_get_root(IsoFilesystem *fs, IsoFileSource **root)
|
||||
{
|
||||
int ret;
|
||||
_ImageFsData *data;
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
uint8_t *buffer = NULL;
|
||||
|
||||
if (fs == NULL || fs->data == NULL || root == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
ret = ISO_NULL_POINTER; goto ex;
|
||||
}
|
||||
|
||||
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||
data = (_ImageFsData*)fs->data;
|
||||
|
||||
/* open the filesystem */
|
||||
ret = ifs_fs_open((IsoImageFilesystem*)fs);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* read extend for root record */
|
||||
ret = data->src->read_block(data->src, data->iso_root_block, buffer);
|
||||
if (ret < 0) {
|
||||
ifs_fs_close((IsoImageFilesystem*)fs);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* get root attributes from "." entry */
|
||||
@ -1873,6 +1904,8 @@ int ifs_get_root(IsoFilesystem *fs, IsoFileSource **root)
|
||||
(struct ecma119_dir_record*) buffer, root, 1);
|
||||
|
||||
ifs_fs_close((IsoImageFilesystem*)fs);
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1913,7 +1946,6 @@ static
|
||||
int ifs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file)
|
||||
{
|
||||
int ret;
|
||||
_ImageFsData *data;
|
||||
IsoFileSource *src;
|
||||
char *ptr, *brk_info, *component;
|
||||
|
||||
@ -1926,8 +1958,6 @@ int ifs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file)
|
||||
return ISO_FILE_BAD_PATH;
|
||||
}
|
||||
|
||||
data = (_ImageFsData*)fs->data;
|
||||
|
||||
/* open the filesystem */
|
||||
ret = ifs_fs_open((IsoImageFilesystem*)fs);
|
||||
if (ret < 0) {
|
||||
@ -2035,10 +2065,8 @@ int ifs_fs_close(IsoImageFilesystem *fs)
|
||||
static
|
||||
void ifs_fs_free(IsoFilesystem *fs)
|
||||
{
|
||||
IsoImageFilesystem *ifs;
|
||||
_ImageFsData *data;
|
||||
|
||||
ifs = (IsoImageFilesystem*)fs;
|
||||
data = (_ImageFsData*) fs->data;
|
||||
|
||||
/* close data source if already openned */
|
||||
@ -2061,6 +2089,10 @@ void ifs_fs_free(IsoFilesystem *fs)
|
||||
free(data->biblio_file_id);
|
||||
free(data->input_charset);
|
||||
free(data->local_charset);
|
||||
|
||||
if(data->catcontent != NULL)
|
||||
free(data->catcontent);
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
@ -2075,14 +2107,15 @@ static
|
||||
int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
||||
{
|
||||
int ret;
|
||||
unsigned char buffer[2048];
|
||||
unsigned char *buffer = NULL;
|
||||
struct ecma119_dir_record *record;
|
||||
struct susp_sys_user_entry *sue;
|
||||
SuspIterator *iter;
|
||||
|
||||
LIBISO_ALLOC_MEM(buffer, unsigned char, 2048);
|
||||
ret = data->src->read_block(data->src, block, buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* record will be the "." directory entry for the root record */
|
||||
@ -2097,7 +2130,7 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
||||
|
||||
iter = susp_iter_new(data->src, record, data->len_skp, data->msgid);
|
||||
if (iter == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
ret = ISO_OUT_OF_MEM; goto ex;
|
||||
}
|
||||
|
||||
/* first entry must be an SP system use entry */
|
||||
@ -2105,11 +2138,11 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
||||
if (ret < 0) {
|
||||
/* error */
|
||||
susp_iter_free(iter);
|
||||
return ret;
|
||||
goto ex;
|
||||
} else if (ret == 0 || !SUSP_SIG(sue, 'S', 'P') ) {
|
||||
iso_msg_debug(data->msgid, "SUSP/RR is not being used.");
|
||||
susp_iter_free(iter);
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
}
|
||||
|
||||
/* it is a SP system use entry */
|
||||
@ -2117,9 +2150,10 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
||||
|| sue->data.SP.ef[0] != 0xEF) {
|
||||
|
||||
susp_iter_free(iter);
|
||||
return iso_msg_submit(data->msgid, ISO_UNSUPPORTED_SUSP, 0,
|
||||
ret = iso_msg_submit(data->msgid, ISO_UNSUPPORTED_SUSP, 0,
|
||||
"SUSP SP system use entry seems to be wrong. "
|
||||
"Ignoring Rock Ridge Extensions.");
|
||||
goto ex;
|
||||
}
|
||||
|
||||
iso_msg_debug(data->msgid, "SUSP/RR is being used.");
|
||||
@ -2204,10 +2238,13 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|
||||
susp_iter_free(iter);
|
||||
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -2240,11 +2277,12 @@ int read_pvm(_ImageFsData *data, uint32_t block)
|
||||
int ret;
|
||||
struct ecma119_pri_vol_desc *pvm;
|
||||
struct ecma119_dir_record *rootdr;
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
uint8_t *buffer = NULL;
|
||||
|
||||
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||
ret = read_pvd_block(data->src, block, buffer, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
/* ok, it is a valid PVD */
|
||||
pvm = (struct ecma119_pri_vol_desc *)buffer;
|
||||
|
||||
@ -2292,7 +2330,10 @@ int read_pvm(_ImageFsData *data, uint32_t block)
|
||||
* example.
|
||||
*/
|
||||
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2302,16 +2343,18 @@ int read_pvm(_ImageFsData *data, uint32_t block)
|
||||
static
|
||||
int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
||||
{
|
||||
int ret, i, rx, last_done, idx;
|
||||
int ret, i, rx, last_done, idx, bufsize;
|
||||
struct el_torito_validation_entry *ve;
|
||||
struct el_torito_section_header *sh;
|
||||
struct el_torito_section_entry *entry; /* also usable as default_entry */
|
||||
unsigned char buffer[BLOCK_SIZE];
|
||||
unsigned char *buffer = NULL, *rpt;
|
||||
|
||||
LIBISO_ALLOC_MEM(buffer, unsigned char, BLOCK_SIZE);
|
||||
data->num_bootimgs = 0;
|
||||
data->catsize = 0;
|
||||
ret = data->src->read_block(data->src, block, buffer);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
ve = (struct el_torito_validation_entry*)buffer;
|
||||
@ -2322,7 +2365,7 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
||||
iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0,
|
||||
"Wrong or damaged El-Torito Catalog. El-Torito info "
|
||||
"will be ignored.");
|
||||
return ISO_WRONG_EL_TORITO;
|
||||
{ret = ISO_WRONG_EL_TORITO; goto ex;}
|
||||
}
|
||||
|
||||
/* check for a valid platform */
|
||||
@ -2330,7 +2373,7 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
||||
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
|
||||
"Unsupported El-Torito platform. Only 80x86 and EFI are "
|
||||
"supported. El-Torito info will be ignored.");
|
||||
return ISO_UNSUPPORTED_EL_TORITO;
|
||||
{ret = ISO_UNSUPPORTED_EL_TORITO; goto ex;}
|
||||
}
|
||||
|
||||
/* ok, once we are here we assume it is a valid catalog */
|
||||
@ -2340,6 +2383,7 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
||||
|
||||
data->eltorito = 1;
|
||||
/* The Default Entry is declared mandatory */
|
||||
data->catsize = 64;
|
||||
data->num_bootimgs = 1;
|
||||
data->platform_ids[0] = ve->platform_id[0];
|
||||
memcpy(data->id_strings[0], ve->id_string, 24);
|
||||
@ -2358,10 +2402,21 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
||||
for (rx = 64; (buffer[rx] & 0xfe) == 0x90 && !last_done; rx += 32) {
|
||||
last_done = buffer[rx] & 1;
|
||||
/* Read Section Header */
|
||||
|
||||
/* >>> ts B10703 : load a new buffer if needed */;
|
||||
|
||||
sh = (struct el_torito_section_header *) (buffer + rx);
|
||||
data->catsize += 32;
|
||||
for (i = 0; i < sh->num_entries[0]; i++) {
|
||||
rx += 32;
|
||||
data->catsize += 32;
|
||||
|
||||
/* >>> ts B10703 : load a new buffer if needed */;
|
||||
|
||||
if (data->num_bootimgs >= Libisofs_max_boot_imageS) {
|
||||
|
||||
/* >>> ts B10703 : need to continue rather than abort */;
|
||||
|
||||
ret = iso_msg_submit(data->msgid, ISO_EL_TORITO_WARN, 0,
|
||||
"Too many boot images found. List truncated.");
|
||||
goto after_bootblocks;
|
||||
@ -2383,7 +2438,31 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
||||
}
|
||||
}
|
||||
after_bootblocks:;
|
||||
return ISO_SUCCESS;
|
||||
if(data->catsize > 0) {
|
||||
if(data->catcontent != NULL)
|
||||
free(data->catcontent);
|
||||
if(data->catsize > 10 * BLOCK_SIZE)
|
||||
data->catsize = 10 * BLOCK_SIZE;
|
||||
bufsize = data->catsize;
|
||||
if (bufsize % BLOCK_SIZE)
|
||||
bufsize += BLOCK_SIZE - (bufsize % BLOCK_SIZE);
|
||||
data->catcontent = calloc(bufsize , 1);
|
||||
if(data->catcontent == NULL) {
|
||||
data->catsize = 0;
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto ex;
|
||||
}
|
||||
for(rx = 0; rx < bufsize; rx += BLOCK_SIZE) {
|
||||
rpt = (unsigned char *) (data->catcontent + rx);
|
||||
ret = data->src->read_block(data->src, block + rx / BLOCK_SIZE, rpt);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -2397,11 +2476,12 @@ static
|
||||
int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
||||
{
|
||||
int tag_type, ret;
|
||||
char block[2048], md5[16];
|
||||
char *block = NULL, md5[16];
|
||||
int desired = (1 << 2);
|
||||
void *ctx = NULL;
|
||||
uint32_t next_tag = 0, i;
|
||||
|
||||
LIBISO_ALLOC_MEM(block, char, 2048);
|
||||
ret = iso_md5_start(&ctx);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
@ -2416,11 +2496,12 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
||||
ret = iso_util_eval_md5_tag(block, desired, start_lba + i,
|
||||
ctx, start_lba, &tag_type, &next_tag, 0);
|
||||
iso_md5_compute(ctx, block, 2048);
|
||||
if (ret == ISO_MD5_TAG_COPIED) { /* growing without emulated TOC */
|
||||
if (ret == (int) ISO_MD5_TAG_COPIED) {/* growing without emulated TOC */
|
||||
ret = 2;
|
||||
goto ex;
|
||||
}
|
||||
if (ret == ISO_MD5_AREA_CORRUPTED || ret == ISO_MD5_TAG_MISMATCH)
|
||||
if (ret == (int) ISO_MD5_AREA_CORRUPTED ||
|
||||
ret == (int) ISO_MD5_TAG_MISMATCH)
|
||||
ret = ISO_SB_TREE_CORRUPTED;
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
@ -2454,7 +2535,8 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
||||
}
|
||||
ret = iso_util_eval_md5_tag(block, (1 << 3), start_lba + i - 1,
|
||||
ctx, start_lba, &tag_type, &next_tag, 0);
|
||||
if (ret == ISO_MD5_AREA_CORRUPTED || ret == ISO_MD5_TAG_MISMATCH)
|
||||
if (ret == (int) ISO_MD5_AREA_CORRUPTED ||
|
||||
ret == (int) ISO_MD5_TAG_MISMATCH)
|
||||
ret = ISO_SB_TREE_CORRUPTED;
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
@ -2463,6 +2545,7 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
|
||||
ex:
|
||||
if (ctx != NULL)
|
||||
iso_md5_end(&ctx, md5);
|
||||
LIBISO_FREE_MEM(block);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2474,21 +2557,22 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
||||
uint32_t block;
|
||||
IsoImageFilesystem *ifs;
|
||||
_ImageFsData *data;
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
uint8_t *buffer = NULL;
|
||||
|
||||
if (src == NULL || opts == NULL || fs == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
ret = ISO_NULL_POINTER; goto ex;
|
||||
}
|
||||
|
||||
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||
data = calloc(1, sizeof(_ImageFsData));
|
||||
if (data == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
ret = ISO_OUT_OF_MEM; goto ex;
|
||||
}
|
||||
|
||||
ifs = calloc(1, sizeof(IsoImageFilesystem));
|
||||
if (ifs == NULL) {
|
||||
free(data);
|
||||
return ISO_OUT_OF_MEM;
|
||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||
}
|
||||
|
||||
/* get our ref to IsoDataSource */
|
||||
@ -2496,6 +2580,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
||||
iso_data_source_ref(src);
|
||||
data->open_count = 0;
|
||||
|
||||
data->catcontent = NULL;
|
||||
|
||||
/* get an id for the filesystem */
|
||||
data->id = ++fs_dev_id;
|
||||
|
||||
@ -2590,8 +2676,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
||||
} else {
|
||||
data->catblock = iso_read_lsb(vol->boot_catalog, 4);
|
||||
ret = read_el_torito_boot_catalog(data, data->catblock);
|
||||
if (ret < 0 && ret != ISO_UNSUPPORTED_EL_TORITO &&
|
||||
ret != ISO_WRONG_EL_TORITO) {
|
||||
if (ret < 0 && ret != (int) ISO_UNSUPPORTED_EL_TORITO &&
|
||||
ret != (int) ISO_WRONG_EL_TORITO) {
|
||||
goto fs_cleanup;
|
||||
}
|
||||
}
|
||||
@ -2712,11 +2798,14 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
|
||||
/* and finally return. Note that we keep the DataSource opened */
|
||||
|
||||
*fs = ifs;
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
|
||||
fs_cleanup: ;
|
||||
fs_cleanup: ;
|
||||
ifs_fs_free(ifs);
|
||||
free(ifs);
|
||||
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2764,10 +2853,12 @@ static
|
||||
int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
IsoFileSource *src, IsoNode **node)
|
||||
{
|
||||
int ret, idx;
|
||||
int ret, idx, to_copy;
|
||||
struct stat info;
|
||||
IsoNode *new;
|
||||
IsoBoot *bootcat;
|
||||
char *name;
|
||||
char *dest = NULL;
|
||||
ImageFileSourceData *data;
|
||||
_ImageFsData *fsdata;
|
||||
|
||||
@ -2780,7 +2871,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
|
||||
|
||||
if (builder == NULL || src == NULL || node == NULL || src->data == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
ret = ISO_NULL_POINTER; goto ex;
|
||||
}
|
||||
|
||||
data = (ImageFileSourceData*)src->data;
|
||||
@ -2791,7 +2882,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
/* get info about source */
|
||||
ret = iso_file_source_lstat(src, &info);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
new = NULL;
|
||||
@ -2809,7 +2900,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
"We can continue, but that could lead to "
|
||||
"problems");
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
iso_node_unref((IsoNode*)image->bootcat->node);
|
||||
}
|
||||
@ -2820,11 +2911,30 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
if (new == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
free(name);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
bootcat = (IsoBoot *) new;
|
||||
bootcat->lba = data->sections[0].block;
|
||||
bootcat->size = info.st_size;
|
||||
if (bootcat->size > 10 * BLOCK_SIZE)
|
||||
bootcat->size = 10 * BLOCK_SIZE;
|
||||
bootcat->content = NULL;
|
||||
if (bootcat->size > 0) {
|
||||
bootcat->content = calloc(1, bootcat->size);
|
||||
if (bootcat->content == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
free(name);
|
||||
free(new);
|
||||
goto ex;
|
||||
}
|
||||
to_copy = bootcat->size;
|
||||
if (bootcat->size > fsdata->catsize)
|
||||
to_copy = fsdata->catsize;
|
||||
memcpy(bootcat->content, fsdata->catcontent, to_copy);
|
||||
}
|
||||
|
||||
/* and set the image node */
|
||||
image->bootcat->node = (IsoBoot*)new;
|
||||
image->bootcat->node = bootcat;
|
||||
new->type = LIBISO_BOOT;
|
||||
new->refcount = 1;
|
||||
} else {
|
||||
@ -2834,7 +2944,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
ret = iso_file_source_stream_new(src, &stream);
|
||||
if (ret < 0) {
|
||||
free(name);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
/* take a ref to the src, as stream has taken our ref */
|
||||
iso_file_source_ref(src);
|
||||
@ -2843,7 +2953,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
if (file == NULL) {
|
||||
free(name);
|
||||
iso_stream_unref(stream);
|
||||
return ISO_OUT_OF_MEM;
|
||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||
}
|
||||
|
||||
/* mark file as from old session */
|
||||
@ -2867,7 +2977,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
if (ret < 0) {
|
||||
free(name);
|
||||
iso_stream_unref(stream);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2898,7 +3008,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
if (ret < 0) {
|
||||
free(name);
|
||||
iso_stream_unref(stream);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
} else {
|
||||
/* and set the image node */
|
||||
@ -2915,7 +3025,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
new = calloc(1, sizeof(IsoDir));
|
||||
if (new == NULL) {
|
||||
free(name);
|
||||
return ISO_OUT_OF_MEM;
|
||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||
}
|
||||
new->type = LIBISO_DIR;
|
||||
new->refcount = 0;
|
||||
@ -2924,18 +3034,19 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
case S_IFLNK:
|
||||
{
|
||||
/* source is a symbolic link */
|
||||
char dest[LIBISOFS_NODE_PATH_MAX];
|
||||
IsoSymlink *link;
|
||||
|
||||
LIBISO_ALLOC_MEM(dest, char, LIBISOFS_NODE_PATH_MAX);
|
||||
|
||||
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
|
||||
if (ret < 0) {
|
||||
free(name);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
link = calloc(1, sizeof(IsoSymlink));
|
||||
if (link == NULL) {
|
||||
free(name);
|
||||
return ISO_OUT_OF_MEM;
|
||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||
}
|
||||
link->dest = strdup(dest);
|
||||
link->node.type = LIBISO_SYMLINK;
|
||||
@ -2956,7 +3067,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
special = calloc(1, sizeof(IsoSpecial));
|
||||
if (special == NULL) {
|
||||
free(name);
|
||||
return ISO_OUT_OF_MEM;
|
||||
{ret = ISO_OUT_OF_MEM; goto ex;}
|
||||
}
|
||||
special->dev = info.st_rdev;
|
||||
special->node.type = LIBISO_SPECIAL;
|
||||
@ -2998,13 +3109,15 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
}
|
||||
|
||||
*node = new;
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
|
||||
failure:;
|
||||
/* todo: stuff any possible memory leak here */
|
||||
if (name != NULL)
|
||||
free(name);
|
||||
free(new);
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(dest);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3130,12 +3243,13 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
|
||||
uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
|
||||
struct iso_file_section *sections = NULL;
|
||||
struct el_torito_boot_image *boot;
|
||||
uint8_t *boot_image_buf = NULL, boot_info_found[16], buf[BLOCK_SIZE];
|
||||
uint8_t *boot_image_buf = NULL, boot_info_found[16], *buf = NULL;
|
||||
IsoStream *stream = NULL;
|
||||
IsoFile *boot_file;
|
||||
|
||||
if (image->bootcat == NULL)
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
|
||||
for (i = 0; i < image->bootcat->num_bootimages; i++) {
|
||||
boot = image->bootcat->bootimages[i];
|
||||
boot_file = boot->image;
|
||||
@ -3175,7 +3289,7 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
|
||||
ret = iso_stream_read(stream, boot_image_buf + (img_size - todo),
|
||||
chunk);
|
||||
if (ret != chunk) {
|
||||
ret = (ret < 0) ? ret : ISO_FILE_READ_ERROR;
|
||||
ret = (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR;
|
||||
goto ex;
|
||||
}
|
||||
todo -= chunk;
|
||||
@ -3214,6 +3328,7 @@ ex:;
|
||||
free(boot_image_buf);
|
||||
if (stream != NULL)
|
||||
iso_stream_close(stream);
|
||||
LIBISO_FREE_MEM(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3232,9 +3347,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
uint8_t *rpt;
|
||||
IsoFileSource *boot_src;
|
||||
IsoNode *node;
|
||||
uint32_t old_checksum_start_lba;
|
||||
uint32_t old_checksum_end_lba;
|
||||
uint32_t old_checksum_idx_count;
|
||||
char *old_checksum_array = NULL;
|
||||
char checksum_type[81];
|
||||
uint32_t checksum_size;
|
||||
@ -3284,9 +3396,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
oldroot = image->root;
|
||||
oldbootcat = image->bootcat; /* could be NULL */
|
||||
image->bootcat = NULL;
|
||||
old_checksum_start_lba = image->checksum_start_lba;
|
||||
old_checksum_end_lba = image->checksum_end_lba;
|
||||
old_checksum_idx_count = image->checksum_idx_count;
|
||||
old_checksum_array = image->checksum_array;
|
||||
image->checksum_array = NULL;
|
||||
|
||||
@ -3419,11 +3528,25 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
"patching may lead to bad results.");
|
||||
}
|
||||
if (image->bootcat->node == NULL) {
|
||||
IsoNode *node = calloc(1, sizeof(IsoBoot));
|
||||
IsoNode *node;
|
||||
IsoBoot *bootcat;
|
||||
node = calloc(1, sizeof(IsoBoot));
|
||||
if (node == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto import_revert;
|
||||
}
|
||||
bootcat = (IsoBoot *) node;
|
||||
bootcat->lba = data->catblock;
|
||||
bootcat->size = data->catsize;
|
||||
bootcat->content = NULL;
|
||||
if (bootcat->size > 0) {
|
||||
bootcat->content = calloc(1, bootcat->size);
|
||||
if (bootcat->content == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto import_revert;
|
||||
}
|
||||
memcpy(bootcat->content, data->catcontent, bootcat->size);
|
||||
}
|
||||
node->type = LIBISO_BOOT;
|
||||
node->mode = S_IFREG;
|
||||
node->refcount = 1;
|
||||
@ -3484,7 +3607,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
}
|
||||
|
||||
/* Load from image->checksum_end_lba */;
|
||||
for (i = 0; i < size; i++) {
|
||||
for (i = 0; i < (int) size; i++) {
|
||||
rpt = (uint8_t *) (image->checksum_array + i * 2048);
|
||||
ret = src->read_block(src, image->checksum_end_lba + i, rpt);
|
||||
if (ret <= 0)
|
||||
@ -3497,7 +3620,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto import_revert;
|
||||
}
|
||||
for (i = 0; i < image->checksum_idx_count - 1; i++)
|
||||
for (i = 0; i < (int) image->checksum_idx_count - 1; i++)
|
||||
iso_md5_compute(ctx, image->checksum_array + i * 16, 16);
|
||||
iso_md5_end(&ctx, md5);
|
||||
for (i = 0; i < 16; i++)
|
||||
@ -3528,9 +3651,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
el_torito_boot_catalog_free(image->bootcat);
|
||||
image->root = oldroot;
|
||||
image->bootcat = oldbootcat;
|
||||
old_checksum_start_lba = image->checksum_start_lba;
|
||||
old_checksum_end_lba = image->checksum_end_lba;
|
||||
old_checksum_idx_count = image->checksum_idx_count;
|
||||
image->checksum_array = old_checksum_array;
|
||||
old_checksum_array = NULL;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -95,14 +95,14 @@ char* lfs_get_name(IsoFileSource *src)
|
||||
static
|
||||
int lfs_lstat(IsoFileSource *src, struct stat *info)
|
||||
{
|
||||
_LocalFsFileSource *data;
|
||||
char *path;
|
||||
|
||||
if (src == NULL || info == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
data = src->data;
|
||||
path = lfs_get_path(src);
|
||||
if (path == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
if (lstat(path, info) != 0) {
|
||||
int err;
|
||||
@ -128,6 +128,7 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
|
||||
err = ISO_FILE_ERROR;
|
||||
break;
|
||||
}
|
||||
free(path);
|
||||
return err;
|
||||
}
|
||||
free(path);
|
||||
@ -137,14 +138,14 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
|
||||
static
|
||||
int lfs_stat(IsoFileSource *src, struct stat *info)
|
||||
{
|
||||
_LocalFsFileSource *data;
|
||||
char *path;
|
||||
|
||||
if (src == NULL || info == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
data = src->data;
|
||||
path = lfs_get_path(src);
|
||||
if (path == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
if (stat(path, info) != 0) {
|
||||
int err;
|
||||
@ -170,6 +171,7 @@ int lfs_stat(IsoFileSource *src, struct stat *info)
|
||||
err = ISO_FILE_ERROR;
|
||||
break;
|
||||
}
|
||||
free(path);
|
||||
return err;
|
||||
}
|
||||
free(path);
|
||||
@ -180,13 +182,11 @@ static
|
||||
int lfs_access(IsoFileSource *src)
|
||||
{
|
||||
int ret;
|
||||
_LocalFsFileSource *data;
|
||||
char *path;
|
||||
|
||||
if (src == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
data = src->data;
|
||||
path = lfs_get_path(src);
|
||||
|
||||
ret = iso_eaccess(path);
|
||||
@ -413,7 +413,6 @@ static
|
||||
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
{
|
||||
int size, ret;
|
||||
_LocalFsFileSource *data;
|
||||
char *path;
|
||||
|
||||
if (src == NULL || buf == NULL) {
|
||||
@ -424,7 +423,6 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
|
||||
data = src->data;
|
||||
path = lfs_get_path(src);
|
||||
|
||||
/*
|
||||
@ -456,7 +454,7 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
|
||||
/* NULL-terminate the buf */
|
||||
ret = ISO_SUCCESS;
|
||||
if (size >= bufsiz) {
|
||||
if ((size_t) size >= bufsiz) {
|
||||
ret = ISO_RR_PATH_TOO_LONG;
|
||||
size = bufsiz - 1;
|
||||
}
|
||||
@ -497,9 +495,6 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
||||
size_t num_attrs = 0, *value_lengths = NULL, result_len, sret;
|
||||
char *path = NULL, **names = NULL, **values = NULL;
|
||||
unsigned char *result = NULL;
|
||||
_LocalFsFileSource *data;
|
||||
|
||||
data = src->data;
|
||||
|
||||
*aa_string = NULL;
|
||||
|
||||
@ -511,10 +506,17 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
||||
to AAIP ACL representation. Clean out st_mode ACL entries.
|
||||
*/
|
||||
path = iso_file_source_get_path(src);
|
||||
if (path == NULL) {
|
||||
ret = ISO_NULL_POINTER;
|
||||
goto ex;
|
||||
}
|
||||
ret = aaip_get_attr_list(path, &num_attrs, &names,
|
||||
&value_lengths, &values,
|
||||
(!(flag & 2)) | 2 | (flag & 4) | 16);
|
||||
if (ret <= 0) {
|
||||
if (ret == -2)
|
||||
ret = ISO_AAIP_NO_GET_LOCAL;
|
||||
else
|
||||
ret = ISO_FILE_ERROR;
|
||||
goto ex;
|
||||
}
|
||||
@ -817,6 +819,15 @@ int iso_local_filesystem_new(IsoFilesystem **fs)
|
||||
}
|
||||
|
||||
|
||||
int iso_local_attr_support(int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret= aaip_local_attr_support(flag & 255);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int iso_local_get_acl_text(char *disk_path, char **text, int flag)
|
||||
{
|
||||
int ret;
|
||||
@ -857,13 +868,19 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
|
||||
int ret;
|
||||
|
||||
ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths,
|
||||
values, (flag & (8 | 32)) | !(flag & 1));
|
||||
values, (flag & (8 | 32 | 64)) | !(flag & 1));
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
return ISO_OUT_OF_MEM;
|
||||
if (ret == -2)
|
||||
return ISO_AAIP_BAD_AASTRING;
|
||||
if (ret >= -5)
|
||||
return ISO_AAIP_NO_SET_LOCAL;
|
||||
if (ret == -6 || ret == -7)
|
||||
return ISO_AAIP_NOT_ENABLED;
|
||||
if (ret == -8)
|
||||
return ISO_AAIP_BAD_ATTR_NAME;
|
||||
return ret;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2011-2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -17,6 +18,7 @@
|
||||
#include "image.h"
|
||||
#include "filesrc.h"
|
||||
#include "eltorito.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -73,7 +75,7 @@ void iso1999_node_free(Iso1999Node *node)
|
||||
return;
|
||||
}
|
||||
if (node->type == ISO1999_DIR) {
|
||||
int i;
|
||||
size_t i;
|
||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||
iso1999_node_free(node->info.dir->children[i]);
|
||||
}
|
||||
@ -307,7 +309,10 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
||||
Iso1999Node **children;
|
||||
IsoHTable *table;
|
||||
int need_sort = 0;
|
||||
char *full_name = NULL, *tmp = NULL;
|
||||
|
||||
LIBISO_ALLOC_MEM(full_name, char, 208);
|
||||
LIBISO_ALLOC_MEM(tmp, char, 208);
|
||||
nchildren = dir->info.dir->nchildren;
|
||||
children = dir->info.dir->children;
|
||||
|
||||
@ -315,19 +320,18 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
||||
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
||||
(compare_function_t)strcmp, &table);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
for (i = 0; i < nchildren; ++i) {
|
||||
char *name = children[i]->name;
|
||||
ret = iso_htable_add(table, name, name);
|
||||
if (ret < 0) {
|
||||
goto mangle_cleanup;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nchildren; ++i) {
|
||||
char *name, *ext;
|
||||
char full_name[208];
|
||||
int max; /* computed max len for name, without extension */
|
||||
int j = i;
|
||||
int digits = 1; /* characters to change per name */
|
||||
@ -384,7 +388,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
||||
* This can't happen with current limit of digits.
|
||||
*/
|
||||
ret = ISO_ERROR;
|
||||
goto mangle_cleanup;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
/* ok, reduce name by digits */
|
||||
@ -398,7 +402,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
||||
}
|
||||
max = 207 - digits;
|
||||
name = full_name;
|
||||
if (max < strlen(name)) {
|
||||
if ((size_t) max < strlen(name)) {
|
||||
name[max] = '\0';
|
||||
}
|
||||
/* let ext be an empty string */
|
||||
@ -408,7 +412,6 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
||||
ok = 1;
|
||||
/* change name of each file */
|
||||
for (k = i; k <= j; ++k) {
|
||||
char tmp[208];
|
||||
char fmt[16];
|
||||
if (dot != NULL) {
|
||||
sprintf(fmt, "%%s%%0%dd.%%s", digits);
|
||||
@ -431,7 +434,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
||||
char *new = strdup(tmp);
|
||||
if (new == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto mangle_cleanup;
|
||||
goto ex;
|
||||
}
|
||||
iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"",
|
||||
children[k]->name, new);
|
||||
@ -459,7 +462,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
||||
}
|
||||
if (digits == 8) {
|
||||
ret = ISO_MANGLE_TOO_MUCH_FILES;
|
||||
goto mangle_cleanup;
|
||||
goto ex;
|
||||
}
|
||||
i = j;
|
||||
}
|
||||
@ -473,8 +476,10 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
|
||||
|
||||
ret = ISO_SUCCESS;
|
||||
|
||||
mangle_cleanup : ;
|
||||
ex:;
|
||||
iso_htable_destroy(table, NULL);
|
||||
LIBISO_FREE_MEM(tmp);
|
||||
LIBISO_FREE_MEM(full_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -683,8 +688,9 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
|
||||
: (uint8_t*)node->name;
|
||||
|
||||
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
||||
IsoNode *iso;
|
||||
|
||||
len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1);
|
||||
len_dr = 33 + len_fi + ((len_fi % 2) ? 0 : 1);
|
||||
|
||||
memcpy(rec->file_id, name, len_fi);
|
||||
|
||||
@ -714,7 +720,15 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
|
||||
rec->len_dr[0] = len_dr;
|
||||
iso_bb(rec->block, block, 4);
|
||||
iso_bb(rec->length, len, 4);
|
||||
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||
|
||||
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||
*/
|
||||
iso= node->node;
|
||||
iso_datetime_7(rec->recording_time,
|
||||
(t->dir_rec_mtime & 4) ? ( t->replace_timestamps ?
|
||||
t->timestamp : iso->mtime )
|
||||
: t->now, t->always_gmt);
|
||||
|
||||
rec->flags[0] = ((node->type == ISO1999_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
||||
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
|
||||
rec->len_fi[0] = len_fi;
|
||||
@ -810,15 +824,15 @@ static
|
||||
int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
|
||||
{
|
||||
int ret;
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
uint8_t *buffer = NULL;
|
||||
size_t i;
|
||||
size_t fi_len, len;
|
||||
|
||||
/* buf will point to current write position on buffer */
|
||||
uint8_t *buf = buffer;
|
||||
uint8_t *buf;
|
||||
|
||||
/* initialize buffer with 0s */
|
||||
memset(buffer, 0, BLOCK_SIZE);
|
||||
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||
buf = buffer;
|
||||
|
||||
/* write the "." and ".." entries first */
|
||||
write_one_dir_record(t, dir, 0, buf, 1, 0);
|
||||
@ -832,7 +846,7 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
|
||||
|
||||
/* compute len of directory entry */
|
||||
fi_len = strlen(child->name);
|
||||
len = fi_len + 33 + (fi_len % 2 ? 0 : 1);
|
||||
len = fi_len + 33 + ((fi_len % 2) ? 0 : 1);
|
||||
|
||||
nsections = (child->type == ISO1999_FILE) ? child->info.file->nsections : 1;
|
||||
for (section = 0; section < nsections; ++section) {
|
||||
@ -840,7 +854,7 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
|
||||
/* dir doesn't fit in current block */
|
||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
memset(buffer, 0, BLOCK_SIZE);
|
||||
buf = buffer;
|
||||
@ -853,6 +867,8 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
|
||||
|
||||
/* write the last block */
|
||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -885,13 +901,17 @@ static
|
||||
int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
|
||||
{
|
||||
size_t i, len;
|
||||
uint8_t buf[256]; /* 256 is just a convenient size larger enought */
|
||||
uint8_t *buf = NULL;
|
||||
struct ecma119_path_table_record *rec;
|
||||
void (*write_int)(uint8_t*, uint32_t, int);
|
||||
Iso1999Node *dir;
|
||||
uint32_t path_table_size;
|
||||
int parent = 0;
|
||||
int ret= ISO_SUCCESS;
|
||||
uint8_t *zeros = NULL;
|
||||
|
||||
/* 256 is just a convenient size large enought */
|
||||
LIBISO_ALLOC_MEM(buf, uint8_t, 256);
|
||||
|
||||
path_table_size = 0;
|
||||
write_int = l_type ? iso_lsb : iso_msb;
|
||||
@ -918,7 +938,7 @@ int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
|
||||
ret = iso_write(t, buf, len);
|
||||
if (ret < 0) {
|
||||
/* error */
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
path_table_size += len;
|
||||
}
|
||||
@ -926,11 +946,14 @@ int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
|
||||
/* we need to fill the last block with zeros */
|
||||
path_table_size %= BLOCK_SIZE;
|
||||
if (path_table_size) {
|
||||
uint8_t zeros[BLOCK_SIZE];
|
||||
LIBISO_ALLOC_MEM(zeros, uint8_t, BLOCK_SIZE);
|
||||
len = BLOCK_SIZE - path_table_size;
|
||||
memset(zeros, 0, len);
|
||||
ret = iso_write(t, zeros, len);
|
||||
}
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(zeros);
|
||||
LIBISO_FREE_MEM(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2011-2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -69,7 +70,7 @@ void joliet_node_free(JolietNode *node)
|
||||
return;
|
||||
}
|
||||
if (node->type == JOLIET_DIR) {
|
||||
int i;
|
||||
size_t i;
|
||||
for (i = 0; i < node->info.dir->nchildren; i++) {
|
||||
joliet_node_free(node->info.dir->children[i]);
|
||||
}
|
||||
@ -348,7 +349,11 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
JolietNode **children;
|
||||
IsoHTable *table;
|
||||
int need_sort = 0;
|
||||
uint16_t *full_name = NULL;
|
||||
uint16_t *tmp = NULL;
|
||||
|
||||
LIBISO_ALLOC_MEM(full_name, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
LIBISO_ALLOC_MEM(tmp, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
nchildren = dir->info.dir->nchildren;
|
||||
children = dir->info.dir->children;
|
||||
|
||||
@ -359,7 +364,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
|
||||
(compare_function_t)ucscmp, &table);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
for (i = 0; i < nchildren; ++i) {
|
||||
uint16_t *name = children[i]->name;
|
||||
@ -371,7 +376,6 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
|
||||
for (i = 0; i < nchildren; ++i) {
|
||||
uint16_t *name, *ext;
|
||||
uint16_t full_name[LIBISO_JOLIET_NAME_MAX];
|
||||
int max; /* computed max len for name, without extension */
|
||||
int j = i;
|
||||
int digits = 1; /* characters to change per name */
|
||||
@ -446,7 +450,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
max = maxchar + 1 - digits;
|
||||
}
|
||||
name = full_name;
|
||||
if (max < ucslen(name)) {
|
||||
if ((size_t) max < ucslen(name)) {
|
||||
name[max] = 0;
|
||||
}
|
||||
/* let ext be an empty string */
|
||||
@ -456,7 +460,6 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
ok = 1;
|
||||
/* change name of each file */
|
||||
for (k = i; k <= j; ++k) {
|
||||
uint16_t tmp[LIBISO_JOLIET_NAME_MAX];
|
||||
while (1) {
|
||||
ret = joliet_create_mangled_name(tmp, name, digits,
|
||||
change, ext);
|
||||
@ -518,7 +521,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
ret = ISO_SUCCESS;
|
||||
|
||||
mangle_cleanup : ;
|
||||
ex:;
|
||||
iso_htable_destroy(table, NULL);
|
||||
LIBISO_FREE_MEM(tmp);
|
||||
LIBISO_FREE_MEM(full_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -752,8 +758,9 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
||||
: (uint8_t*)node->name;
|
||||
|
||||
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
||||
IsoNode *iso;
|
||||
|
||||
len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1);
|
||||
len_dr = 33 + len_fi + ((len_fi % 2) ? 0 : 1);
|
||||
|
||||
memcpy(rec->file_id, name, len_fi);
|
||||
|
||||
@ -791,7 +798,15 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
||||
rec->len_dr[0] = len_dr;
|
||||
iso_bb(rec->block, block - t->eff_partition_offset, 4);
|
||||
iso_bb(rec->length, len, 4);
|
||||
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||
|
||||
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||
*/
|
||||
iso= node->node;
|
||||
iso_datetime_7(rec->recording_time,
|
||||
(t->dir_rec_mtime & 2) ? ( t->replace_timestamps ?
|
||||
t->timestamp : iso->mtime )
|
||||
: t->now, t->always_gmt);
|
||||
|
||||
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
||||
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
|
||||
rec->len_fi[0] = len_fi;
|
||||
@ -919,15 +934,16 @@ static
|
||||
int write_one_dir(Ecma119Image *t, JolietNode *dir)
|
||||
{
|
||||
int ret;
|
||||
uint8_t buffer[BLOCK_SIZE];
|
||||
uint8_t *buffer = NULL;
|
||||
size_t i;
|
||||
size_t fi_len, len;
|
||||
|
||||
/* buf will point to current write position on buffer */
|
||||
uint8_t *buf = buffer;
|
||||
uint8_t *buf;
|
||||
|
||||
/* initialize buffer with 0s */
|
||||
memset(buffer, 0, BLOCK_SIZE);
|
||||
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
|
||||
buf = buffer;
|
||||
|
||||
/* write the "." and ".." entries first */
|
||||
write_one_dir_record(t, dir, 0, buf, 1, 0);
|
||||
@ -954,7 +970,7 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
|
||||
/* dir doesn't fit in current block */
|
||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
memset(buffer, 0, BLOCK_SIZE);
|
||||
buf = buffer;
|
||||
@ -967,6 +983,8 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
|
||||
|
||||
/* write the last block */
|
||||
ret = iso_write(t, buffer, BLOCK_SIZE);
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -999,14 +1017,18 @@ static
|
||||
int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
|
||||
{
|
||||
size_t i, len;
|
||||
uint8_t buf[256]; /* 256 is just a convenient size larger enought */
|
||||
uint8_t *buf = NULL;
|
||||
struct ecma119_path_table_record *rec;
|
||||
void (*write_int)(uint8_t*, uint32_t, int);
|
||||
JolietNode *dir;
|
||||
uint32_t path_table_size;
|
||||
int parent = 0;
|
||||
int ret= ISO_SUCCESS;
|
||||
uint8_t *zeros = NULL;
|
||||
|
||||
/* 256 is just a convenient size large enought */
|
||||
LIBISO_ALLOC_MEM(buf, uint8_t, 256);
|
||||
LIBISO_ALLOC_MEM(zeros, uint8_t, BLOCK_SIZE);
|
||||
path_table_size = 0;
|
||||
write_int = l_type ? iso_lsb : iso_msb;
|
||||
|
||||
@ -1033,7 +1055,7 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
|
||||
ret = iso_write(t, buf, len);
|
||||
if (ret < 0) {
|
||||
/* error */
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
path_table_size += len;
|
||||
}
|
||||
@ -1041,11 +1063,13 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
|
||||
/* we need to fill the last block with zeros */
|
||||
path_table_size %= BLOCK_SIZE;
|
||||
if (path_table_size) {
|
||||
uint8_t zeros[BLOCK_SIZE];
|
||||
len = BLOCK_SIZE - path_table_size;
|
||||
memset(zeros, 0, len);
|
||||
ret = iso_write(t, zeros, len);
|
||||
}
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(zeros);
|
||||
LIBISO_FREE_MEM(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
||||
* Copyright (c) 2009-2011 Thomas Schmitt
|
||||
* Copyright (c) 2009-2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -18,15 +18,32 @@
|
||||
|
||||
/*
|
||||
*
|
||||
* Applications must use 64 bit off_t, e.g. on 32-bit GNU/Linux by defining
|
||||
* Applications must use 64 bit off_t.
|
||||
* E.g. on 32-bit GNU/Linux by defining
|
||||
* #define _LARGEFILE_SOURCE
|
||||
* #define _FILE_OFFSET_BITS 64
|
||||
* or take special precautions to interface with the library by 64 bit integers
|
||||
* where this .h files prescribe off_t. Not to use 64 bit file i/o will keep
|
||||
* the application from producing and processing ISO images of more than 2 GB
|
||||
* size.
|
||||
* The minimum requirement is to interface with the library by 64 bit signed
|
||||
* integers where libisofs.h or libisoburn.h prescribe off_t.
|
||||
* Failure to do so may result in surprising malfunction or memory faults.
|
||||
*
|
||||
* Application files which include libisofs/libisofs.h must provide
|
||||
* definitions for uint32_t and uint8_t.
|
||||
* This can be achieved either:
|
||||
* - by using autotools which will define HAVE_STDINT_H or HAVE_INTTYPES_H
|
||||
* according to its ./configure tests,
|
||||
* - or by defining the macros HAVE_STDINT_H resp. HAVE_INTTYPES_H according
|
||||
* to the local situation,
|
||||
* - or by appropriately defining uint32_t and uint8_t by other means,
|
||||
* e.g. by including inttypes.h before including libisofs.h
|
||||
*/
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Normally this API is operated via public functions and opaque object
|
||||
@ -42,16 +59,90 @@
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
/**
|
||||
* The following two functions and three macros are utilities to help ensuring
|
||||
* version match of application, compile time header, and runtime library.
|
||||
*/
|
||||
/**
|
||||
* These three release version numbers tell the revision of this header file
|
||||
* and of the API it describes. They are memorized by applications at
|
||||
* compile time.
|
||||
* They must show the same values as these symbols in ./configure.ac
|
||||
* LIBISOFS_MAJOR_VERSION=...
|
||||
* LIBISOFS_MINOR_VERSION=...
|
||||
* LIBISOFS_MICRO_VERSION=...
|
||||
* Note to anybody who does own work inside libisofs:
|
||||
* Any change of configure.ac or libisofs.h has to keep up this equality !
|
||||
*
|
||||
* Before usage of these macros on your code, please read the usage discussion
|
||||
* below.
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
#define iso_lib_header_version_major 1
|
||||
#define iso_lib_header_version_minor 2
|
||||
#define iso_lib_header_version_micro 2
|
||||
|
||||
/**
|
||||
* Get version of the libisofs library at runtime.
|
||||
* NOTE: This function may be called before iso_init().
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
void iso_lib_version(int *major, int *minor, int *micro);
|
||||
|
||||
/**
|
||||
* Check at runtime if the library is ABI compatible with the given version.
|
||||
* NOTE: This function may be called before iso_init().
|
||||
*
|
||||
* @return
|
||||
* 1 lib is compatible, 0 is not.
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
int iso_lib_is_compatible(int major, int minor, int micro);
|
||||
|
||||
/**
|
||||
* Usage discussion:
|
||||
*
|
||||
* Some developers of the libburnia project have differing opinions how to
|
||||
* ensure the compatibility of libaries and applications.
|
||||
*
|
||||
* It is about whether to use at compile time and at runtime the version
|
||||
* numbers provided here. Thomas Schmitt advises to use them. Vreixo Formoso
|
||||
* advises to use other means.
|
||||
*
|
||||
* At compile time:
|
||||
*
|
||||
* Vreixo Formoso advises to leave proper version matching to properly
|
||||
* programmed checks in the the application's build system, which will
|
||||
* eventually refuse compilation.
|
||||
*
|
||||
* Thomas Schmitt advises to use the macros defined here for comparison with
|
||||
* the application's requirements of library revisions and to eventually
|
||||
* break compilation.
|
||||
*
|
||||
* Both advises are combinable. I.e. be master of your build system and have
|
||||
* #if checks in the source code of your application, nevertheless.
|
||||
*
|
||||
* At runtime (via iso_lib_is_compatible()):
|
||||
*
|
||||
* Vreixo Formoso advises to compare the application's requirements of
|
||||
* library revisions with the runtime library. This is to allow runtime
|
||||
* libraries which are young enough for the application but too old for
|
||||
* the lib*.h files seen at compile time.
|
||||
*
|
||||
* Thomas Schmitt advises to compare the header revisions defined here with
|
||||
* the runtime library. This is to enforce a strictly monotonous chain of
|
||||
* revisions from app to header to library, at the cost of excluding some older
|
||||
* libraries.
|
||||
*
|
||||
* These two advises are mutually exclusive.
|
||||
*/
|
||||
|
||||
struct burn_source;
|
||||
|
||||
/**
|
||||
@ -158,6 +249,15 @@ struct iso_file_section
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
/* If you get here because of a compilation error like
|
||||
|
||||
/usr/include/libisofs/libisofs.h:166: error:
|
||||
expected specifier-qualifier-list before 'uint32_t'
|
||||
|
||||
then see the paragraph above about the definition of uint32_t.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Context for iterate on directory children.
|
||||
* @see iso_dir_get_children()
|
||||
@ -860,15 +960,17 @@ extern ino_t serial_id;
|
||||
struct IsoStream_Iface
|
||||
{
|
||||
/*
|
||||
* Current version of the interface, set to 1 or 2.
|
||||
* Current version of the interface.
|
||||
* Version 0 (since 0.6.4)
|
||||
* deprecated but still valid.
|
||||
* Version 1 (since 0.6.8)
|
||||
* update_size() added.
|
||||
* Version 2 (since 0.6.18)
|
||||
* get_input_stream() added. A filter stream must have version 2.
|
||||
* get_input_stream() added.
|
||||
* A filter stream must have version 2 at least.
|
||||
* Version 3 (since 0.6.20)
|
||||
* compare() added. A filter stream should have version 3.
|
||||
* compare() added.
|
||||
* A filter stream should have version 3 at least.
|
||||
* Version 4 (since 1.0.2)
|
||||
* clone_stream() added.
|
||||
*/
|
||||
@ -995,8 +1097,8 @@ struct IsoStream_Iface
|
||||
* This is also appropriate if one has reason to implement stream.cmp_ino()
|
||||
* without having an own special comparison algorithm.
|
||||
*
|
||||
* With filter streams the decision whether the underlying chains of
|
||||
* streams match should be delegated to
|
||||
* With filter streams, the decision whether the underlying chains of
|
||||
* streams match, should be delegated to
|
||||
* iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
||||
* iso_stream_get_input_stream(s2, 0), 0);
|
||||
*
|
||||
@ -1168,89 +1270,6 @@ int iso_image_new(const char *name, IsoImage **image);
|
||||
void iso_image_set_ignore_aclea(IsoImage *image, int what);
|
||||
|
||||
|
||||
/**
|
||||
* The following two functions three macros are utilities to help ensuring
|
||||
* version match of application, compile time header, and runtime library.
|
||||
*/
|
||||
/**
|
||||
* Get version of the libisofs library at runtime.
|
||||
* NOTE: This function may be called before iso_init().
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
void iso_lib_version(int *major, int *minor, int *micro);
|
||||
|
||||
/**
|
||||
* Check at runtime if the library is ABI compatible with the given version.
|
||||
* NOTE: This function may be called before iso_init().
|
||||
*
|
||||
* @return
|
||||
* 1 lib is compatible, 0 is not.
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
int iso_lib_is_compatible(int major, int minor, int micro);
|
||||
|
||||
|
||||
/**
|
||||
* These three release version numbers tell the revision of this header file
|
||||
* and of the API it describes. They are memorized by applications at
|
||||
* compile time.
|
||||
* They must show the same values as these symbols in ./configure.ac
|
||||
* LIBISOFS_MAJOR_VERSION=...
|
||||
* LIBISOFS_MINOR_VERSION=...
|
||||
* LIBISOFS_MICRO_VERSION=...
|
||||
* Note to anybody who does own work inside libisofs:
|
||||
* Any change of configure.ac or libisofs.h has to keep up this equality !
|
||||
*
|
||||
* Before usage of these macros on your code, please read the usage discussion
|
||||
* below.
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
#define iso_lib_header_version_major 1
|
||||
#define iso_lib_header_version_minor 0
|
||||
#define iso_lib_header_version_micro 8
|
||||
|
||||
/**
|
||||
* Usage discussion:
|
||||
*
|
||||
* Some developers of the libburnia project have differing opinions how to
|
||||
* ensure the compatibility of libaries and applications.
|
||||
*
|
||||
* It is about whether to use at compile time and at runtime the version
|
||||
* numbers provided here. Thomas Schmitt advises to use them. Vreixo Formoso
|
||||
* advises to use other means.
|
||||
*
|
||||
* At compile time:
|
||||
*
|
||||
* Vreixo Formoso advises to leave proper version matching to properly
|
||||
* programmed checks in the the application's build system, which will
|
||||
* eventually refuse compilation.
|
||||
*
|
||||
* Thomas Schmitt advises to use the macros defined here for comparison with
|
||||
* the application's requirements of library revisions and to eventually
|
||||
* break compilation.
|
||||
*
|
||||
* Both advises are combinable. I.e. be master of your build system and have
|
||||
* #if checks in the source code of your application, nevertheless.
|
||||
*
|
||||
* At runtime (via iso_lib_is_compatible()):
|
||||
*
|
||||
* Vreixo Formoso advises to compare the application's requirements of
|
||||
* library revisions with the runtime library. This is to allow runtime
|
||||
* libraries which are young enough for the application but too old for
|
||||
* the lib*.h files seen at compile time.
|
||||
*
|
||||
* Thomas Schmitt advises to compare the header revisions defined here with
|
||||
* the runtime library. This is to enforce a strictly monotonous chain of
|
||||
* revisions from app to header to library, at the cost of excluding some older
|
||||
* libraries.
|
||||
*
|
||||
* These two advises are mutually exclusive.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Creates an IsoWriteOpts for writing an image. You should set the options
|
||||
* desired with the correspondent setters.
|
||||
@ -1517,6 +1536,45 @@ int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit);
|
||||
*/
|
||||
int iso_write_opts_set_allow_deep_paths(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* This call describes the directory where to store Rock Ridge relocated
|
||||
* directories.
|
||||
* If not iso_write_opts_set_allow_deep_paths(,1) is in effect, then it may
|
||||
* become necessary to relocate directories so that no ECMA-119 file path
|
||||
* has more than 8 components. These directories are grafted into either
|
||||
* the root directory of the ISO image or into a dedicated relocation
|
||||
* directory.
|
||||
* For Rock Ridge, the relocated directories are linked forth and back to
|
||||
* placeholders at their original positions in path level 8. Directories
|
||||
* marked by Rock Ridge entry RE are to be considered artefacts of relocation
|
||||
* and shall not be read into a Rock Ridge tree. Instead they are to be read
|
||||
* via their placeholders and their links.
|
||||
* For plain ECMA-119, the relocation directory and the relocated directories
|
||||
* are just normal directories which contain normal files and directories.
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param name
|
||||
* The name of the relocation directory in the root directory. Do not
|
||||
* prepend "/". An empty name or NULL will direct relocated directories
|
||||
* into the root directory. This is the default.
|
||||
* If the given name does not exist in the root directory when
|
||||
* iso_image_create_burn_source() is called, and if there are directories
|
||||
* at path level 8, then directory /name will be created automatically.
|
||||
* The name given by this call will be compared with iso_node_get_name()
|
||||
* of the directories in the root directory, not with the final ECMA-119
|
||||
* names of those directories.
|
||||
* @parm flags
|
||||
* Bitfield for control purposes.
|
||||
* bit0= Mark the relocation directory by a Rock Ridge RE entry, if it
|
||||
* gets created during iso_image_create_burn_source(). This will
|
||||
* make it invisible for most Rock Ridge readers.
|
||||
* bit1= not settable via API (used internally)
|
||||
* @return
|
||||
* 1 success, < 0 error
|
||||
* @since 1.2.2
|
||||
*/
|
||||
int iso_write_opts_set_rr_reloc(IsoWriteOpts *opts, char *name, int flags);
|
||||
|
||||
/**
|
||||
* Allow path in the ISO-9660 tree to have more than 255 characters.
|
||||
* This breaks ECMA-119 specification. Use with caution.
|
||||
@ -1526,7 +1584,7 @@ int iso_write_opts_set_allow_deep_paths(IsoWriteOpts *opts, int allow);
|
||||
int iso_write_opts_set_allow_longer_paths(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* Allow a single file or directory hierarchy to have up to 37 characters.
|
||||
* Allow a single file or directory identifier to have up to 37 characters.
|
||||
* This is larger than the 31 characters allowed by ISO level 2, and the
|
||||
* extra space is taken from the version number, so this also forces
|
||||
* omit_version_numbers.
|
||||
@ -1557,13 +1615,15 @@ int iso_write_opts_set_no_force_dots(IsoWriteOpts *opts, int no);
|
||||
* Allow lowercase characters in ISO-9660 filenames. By default, only
|
||||
* uppercase characters, numbers and a few other characters are allowed.
|
||||
* This breaks ECMA-119 specification. Use with caution.
|
||||
* If lowercase is not allowed then those letters get mapped to uppercase
|
||||
* letters.
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
int iso_write_opts_set_allow_lowercase(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* Allow all ASCII characters to be appear on an ISO-9660 filename. Note
|
||||
* Allow all 8-bit characters to appear on an ISO-9660 filename. Note
|
||||
* that "/" and 0x0 characters are never allowed, even in RR names.
|
||||
* This breaks ECMA-119 specification. Use with caution.
|
||||
*
|
||||
@ -1571,6 +1631,20 @@ int iso_write_opts_set_allow_lowercase(IsoWriteOpts *opts, int allow);
|
||||
*/
|
||||
int iso_write_opts_set_allow_full_ascii(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* If not iso_write_opts_set_allow_full_ascii() is set to 1:
|
||||
* Allow all 7-bit characters that would be allowed by allow_full_ascii, but
|
||||
* map lowercase to uppercase if iso_write_opts_set_allow_lowercase()
|
||||
* is not set to 1.
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param allow
|
||||
* If not zero, then allow what is described above.
|
||||
*
|
||||
* @since 1.2.2
|
||||
*/
|
||||
int iso_write_opts_set_allow_7bit_ascii(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* Allow all characters to be part of Volume and Volset identifiers on
|
||||
* the Primary Volume Descriptor. This breaks ISO-9660 contraints, but
|
||||
@ -1634,9 +1708,35 @@ int iso_write_opts_set_rrip_1_10_px_ino(IsoWriteOpts *opts, int enable);
|
||||
int iso_write_opts_set_aaip_susp_1_10(IsoWriteOpts *opts, int oldvers);
|
||||
|
||||
/**
|
||||
* Store as ECMA-119 Directory Record timestamp the mtime of the source
|
||||
* Store as ECMA-119 Directory Record timestamp the mtime of the source node
|
||||
* rather than the image creation time.
|
||||
* If storing of mtime is enabled, then the settings of
|
||||
* iso_write_opts_set_replace_timestamps() apply. (replace==1 will revoke,
|
||||
* replace==2 will override mtime by iso_write_opts_set_default_timestamp().
|
||||
*
|
||||
* Since version 1.2.0 this may apply also to Joliet and ISO 9660:1999. To
|
||||
* reduce the probability of unwanted behavior changes between pre-1.2.0 and
|
||||
* post-1.2.0, the bits for Joliet and ISO 9660:1999 also enable ECMA-119.
|
||||
* The hopefully unlikely bit14 may then be used to disable mtime for ECMA-119.
|
||||
*
|
||||
* To enable mtime for all three directory trees, submit 7.
|
||||
* To disable this feature completely, submit 0.
|
||||
*
|
||||
* @param opts
|
||||
* The option set to be manipulated.
|
||||
* @param allow
|
||||
* If this parameter is negative, then mtime is enabled only for ECMA-119.
|
||||
* With positive numbers, the parameter is interpreted as bit field :
|
||||
* bit0= enable mtime for ECMA-119
|
||||
* bit1= enable mtime for Joliet and ECMA-119
|
||||
* bit2= enable mtime for ISO 9660:1999 and ECMA-119
|
||||
* bit14= disable mtime for ECMA-119 although some of the other bits
|
||||
* would enable it
|
||||
* @since 1.2.0
|
||||
* Before version 1.2.0 this applied only to ECMA-119 :
|
||||
* 0 stored image creation time in ECMA-119 tree.
|
||||
* Any other value caused storing of mtime.
|
||||
* Joliet and ISO 9660:1999 always stored the image creation time.
|
||||
* @since 0.6.12
|
||||
*/
|
||||
int iso_write_opts_set_dir_rec_mtime(IsoWriteOpts *opts, int allow);
|
||||
@ -1764,8 +1864,10 @@ int iso_write_opts_set_default_gid(IsoWriteOpts *opts, gid_t gid);
|
||||
|
||||
/**
|
||||
* 0 to use IsoNode timestamps, 1 to use recording time, 2 to use
|
||||
* values from timestamp field. This has only meaning if RR extensions
|
||||
* are enabled.
|
||||
* values from timestamp field. This applies to the timestamps of Rock Ridge
|
||||
* and if the use of mtime is enabled by iso_write_opts_set_dir_rec_mtime().
|
||||
* In the latter case, value 1 will revoke the recording of mtime, value
|
||||
* 2 will override mtime by iso_write_opts_set_default_timestamp().
|
||||
*
|
||||
* @see iso_write_opts_set_default_timestamp
|
||||
* @since 0.6.2
|
||||
@ -2858,6 +2960,35 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
|
||||
int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
|
||||
IsoFile **imgnode, IsoBoot **catnode);
|
||||
|
||||
/**
|
||||
* Get detailed information about the boot catalog that was loaded from
|
||||
* an ISO image.
|
||||
* The boot catalog links the El Torito boot record at LBA 17 with the
|
||||
* boot images which are IsoFile objects in the image. The boot catalog
|
||||
* itself is not a regular file and thus will not deliver an IsoStream.
|
||||
* Its content is usually quite short and can be obtained by this call.
|
||||
*
|
||||
* @param image
|
||||
* The image to inquire.
|
||||
* @param catnode
|
||||
* Will return the boot catalog tree node. No extra ref is taken.
|
||||
* @param lba
|
||||
* Will return the block address of the boot catalog in the image.
|
||||
* @param content
|
||||
* Will return either NULL or an allocated memory buffer with the
|
||||
* content bytes of the boot catalog.
|
||||
* Dispose it by free() when no longer needed.
|
||||
* @param size
|
||||
* Will return the number of bytes in content.
|
||||
* @return
|
||||
* 1 if reply is valid, 0 if not boot catalog was loaded, < 0 on error.
|
||||
*
|
||||
* @since 1.1.2
|
||||
*/
|
||||
int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
|
||||
char **content, off_t *size);
|
||||
|
||||
|
||||
/**
|
||||
* Get all El-Torito boot images of an ISO image.
|
||||
*
|
||||
@ -5742,6 +5873,30 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
|
||||
* from local files.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Inquire whether local filesystem operations with ACL or xattr are enabled
|
||||
* inside libisofs. They may be disabled because of compile time decisions.
|
||||
* E.g. because the operating system does not support these features or
|
||||
* because libisofs has not yet an adapter to use them.
|
||||
*
|
||||
* @param flag
|
||||
* Bitfield for control purposes
|
||||
* bit0= inquire availability of ACL
|
||||
* bit1= inquire availability of xattr
|
||||
* bit2 - bit7= Reserved for future types.
|
||||
* It is permissibile to set them to 1 already now.
|
||||
* bit8 and higher: reserved, submit 0
|
||||
* @return
|
||||
* Bitfield corresponding to flag. If bits are set, th
|
||||
* bit0= ACL adapter is enabled
|
||||
* bit1= xattr adapter is enabled
|
||||
* bit2 - bit7= Reserved for future types.
|
||||
* bit8 and higher: reserved, do not interpret these
|
||||
*
|
||||
* @since 1.1.6
|
||||
*/
|
||||
int iso_local_attr_support(int flag);
|
||||
|
||||
/**
|
||||
* Get an ACL of the given file in the local filesystem in long text form.
|
||||
*
|
||||
@ -5785,7 +5940,7 @@ int iso_local_get_acl_text(char *disk_path, char **text, int flag);
|
||||
* bit5= in case of symbolic link: manipulate link target
|
||||
* @return
|
||||
* > 0 ok
|
||||
* 0 no ACL manipulation adapter available
|
||||
* 0 no ACL manipulation adapter available for desired ACL type
|
||||
* -1 failure of system ACL service (see errno)
|
||||
* -2 attempt to manipulate ACL of a symbolic link without bit5
|
||||
* resp. with no suitable link target
|
||||
@ -5874,6 +6029,9 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
|
||||
* bit3= do not ignore eventual non-user attributes.
|
||||
* I.e. those with a name which does not begin by "user."
|
||||
* bit5= in case of symbolic link: manipulate link target
|
||||
* bit6= @since 1.1.6
|
||||
tolerate inappropriate presence or absence of
|
||||
* directory "default" ACL
|
||||
* @return
|
||||
* 1 = ok
|
||||
* < 0 = error
|
||||
@ -6842,6 +7000,13 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
||||
/** Rock Ridge path too long (FAILURE, HIGH, -379) */
|
||||
#define ISO_RR_PATH_TOO_LONG 0xE830FE85
|
||||
|
||||
/** Attribute name cannot be represented (FAILURE, HIGH, -380) */
|
||||
#define ISO_AAIP_BAD_ATTR_NAME 0xE830FE84
|
||||
|
||||
/** ACL text contains multiple entries of user::, group::, other::
|
||||
(FAILURE, HIGH, -379) */
|
||||
#define ISO_AAIP_ACL_MULT_OBJ 0xE830FE83
|
||||
|
||||
|
||||
|
||||
/* Internal developer note:
|
||||
@ -7060,6 +7225,11 @@ struct burn_source {
|
||||
/* currently none being tested */
|
||||
|
||||
|
||||
/* Perform the operations promised by iso_write_opts_set_rr_reloc() */
|
||||
#define Libisofs_with_rr_reloc_diR yes
|
||||
|
||||
|
||||
|
||||
/* ---------------------------- Experiments ---------------------------- */
|
||||
|
||||
|
||||
|
@ -88,6 +88,7 @@ iso_image_get_all_boot_imgs;
|
||||
iso_image_get_application_id;
|
||||
iso_image_get_attached_data;
|
||||
iso_image_get_biblio_file_id;
|
||||
iso_image_get_bootcat;
|
||||
iso_image_get_boot_image;
|
||||
iso_image_get_copyright_file_id;
|
||||
iso_image_get_data_preparer_id;
|
||||
@ -124,6 +125,7 @@ iso_init;
|
||||
iso_init_with_flag;
|
||||
iso_lib_is_compatible;
|
||||
iso_lib_version;
|
||||
iso_local_attr_support;
|
||||
iso_local_get_acl_text;
|
||||
iso_local_get_attrs;
|
||||
iso_local_get_perms_wo_acl;
|
||||
@ -263,6 +265,7 @@ iso_write_opts_get_data_start;
|
||||
iso_write_opts_new;
|
||||
iso_write_opts_set_aaip;
|
||||
iso_write_opts_set_aaip_susp_1_10;
|
||||
iso_write_opts_set_allow_7bit_ascii;
|
||||
iso_write_opts_set_allow_deep_paths;
|
||||
iso_write_opts_set_allow_dir_id_ext;
|
||||
iso_write_opts_set_allow_full_ascii;
|
||||
@ -299,6 +302,7 @@ iso_write_opts_set_relaxed_vol_atts;
|
||||
iso_write_opts_set_replace_mode;
|
||||
iso_write_opts_set_replace_timestamps;
|
||||
iso_write_opts_set_rockridge;
|
||||
iso_write_opts_set_rr_reloc;
|
||||
iso_write_opts_set_rrip_1_10_px_ino;
|
||||
iso_write_opts_set_rrip_version_1_10;
|
||||
iso_write_opts_set_scdbackup_tag;
|
||||
@ -310,5 +314,6 @@ iso_write_opts_set_will_cancel;
|
||||
iso_zisofs_get_params;
|
||||
iso_zisofs_get_refcounts;
|
||||
iso_zisofs_set_params;
|
||||
serial_id;
|
||||
local: *;
|
||||
};
|
||||
|
@ -135,7 +135,7 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
|
||||
|
||||
static int h = 64, s = 32;
|
||||
|
||||
int i, warn_size = 0, id;
|
||||
int i, id;
|
||||
char *wpt;
|
||||
off_t imgsize, cylsize, frac, padding, c, cc;
|
||||
|
||||
@ -164,7 +164,6 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
|
||||
*img_blocks = imgsize / (off_t) 2048;
|
||||
c = imgsize / cylsize;
|
||||
if (c > 1024) {
|
||||
warn_size = 1;
|
||||
cc = 1024;
|
||||
} else
|
||||
cc = c;
|
||||
@ -424,7 +423,7 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
||||
/* # Offset 446
|
||||
*/
|
||||
for (part = 1 ; part <= 4; part++) {
|
||||
if (part != part_number) {
|
||||
if ((int) part != part_number) {
|
||||
/* if this_partition != partition_number: write 16 zero bytes */
|
||||
memset(wpt, 0, 16);
|
||||
wpt+= 16;
|
||||
|
@ -229,10 +229,10 @@ static int md5_init(libisofs_md5_ctx *ctx, int flag)
|
||||
static int md5_update(libisofs_md5_ctx *ctx, unsigned char *data,
|
||||
int datalen, int flag)
|
||||
{
|
||||
unsigned int i, index, partlen;
|
||||
int i, index, partlen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (unsigned int)((ctx->count[0] >> 3) & 0x3F);
|
||||
index = ((ctx->count[0] >> 3) & 0x3F);
|
||||
/* Update number of bits */
|
||||
if ((ctx->count[0] += ((uint32_t) datalen << 3)) <
|
||||
((uint32_t) datalen << 3))
|
||||
@ -621,11 +621,6 @@ int checksum_writer_write_data(IsoImageWriter *writer)
|
||||
void *ctx = NULL;
|
||||
char md5[16];
|
||||
|
||||
#ifdef NIX
|
||||
char tag_block[2048];
|
||||
int l;
|
||||
#endif
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
@ -724,15 +719,16 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
||||
{
|
||||
void *ctx = NULL;
|
||||
off_t pos = 0, line_start;
|
||||
int record_len, block_len, res, i;
|
||||
char postext[40], md5[16], record[160];
|
||||
int record_len, block_len, ret, i;
|
||||
char postext[40], md5[16], *record = NULL;
|
||||
|
||||
LIBISO_ALLOC_MEM(record, char, 160);
|
||||
line_start = strlen(tag_block);
|
||||
iso_md5_compute(t->checksum_ctx, tag_block, line_start);
|
||||
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||
if (res < 0)
|
||||
ret = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
res = iso_md5_end(&ctx, md5);
|
||||
ret = iso_md5_end(&ctx, md5);
|
||||
|
||||
pos = (off_t) t->checksum_tag_pos * (off_t) 2048 + line_start;
|
||||
if(pos >= 1000000000)
|
||||
@ -747,8 +743,8 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
||||
"%2.2x", ((unsigned char *) md5)[i]);
|
||||
record_len += 32;
|
||||
|
||||
res = iso_md5_start(&ctx);
|
||||
if (res < 0)
|
||||
ret = iso_md5_start(&ctx);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
iso_md5_compute(ctx, record, record_len);
|
||||
iso_md5_end(&ctx, md5);
|
||||
@ -765,11 +761,12 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
||||
if (t->scdbackup_tag_written != NULL)
|
||||
strncpy(t->scdbackup_tag_written, tag_block + line_start,
|
||||
block_len - line_start);
|
||||
res = ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (ctx != NULL)
|
||||
iso_md5_end(&ctx, md5);
|
||||
return res;
|
||||
LIBISO_FREE_MEM(record);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -783,20 +780,20 @@ ex:;
|
||||
*/
|
||||
int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
{
|
||||
int res, mode, l, i, wres, tag_id_len;
|
||||
int ret, mode, l, i, wres, tag_id_len;
|
||||
void *ctx = NULL;
|
||||
char md5[16], tag_block[2048], *tag_id;
|
||||
char md5[16], *tag_block = NULL, *tag_id;
|
||||
uint32_t size = 0, pos = 0, start;
|
||||
|
||||
LIBISO_ALLOC_MEM(tag_block, char, 2048);
|
||||
start = t->checksum_range_start;
|
||||
memset(tag_block, 0, 2048);
|
||||
mode = flag & 255;
|
||||
if (mode < 1 || mode > 4)
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||
if (res < 0)
|
||||
return res;
|
||||
res = iso_md5_end(&ctx, md5);
|
||||
{ret = ISO_WRONG_ARG_VALUE; goto ex;}
|
||||
ret = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
ret = iso_md5_end(&ctx, md5);
|
||||
if (mode == 1) {
|
||||
size = t->checksum_range_size;
|
||||
pos = t->checksum_tag_pos;
|
||||
@ -811,7 +808,7 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
}
|
||||
size = pos - start;
|
||||
}
|
||||
if (res < 0)
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
|
||||
iso_util_tag_magic(mode, &tag_id, &tag_id_len, 0);
|
||||
@ -833,8 +830,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
((unsigned char *) md5)[i]);
|
||||
l+= 32;
|
||||
|
||||
res = iso_md5_start(&ctx);
|
||||
if (res > 0) {
|
||||
ret = iso_md5_start(&ctx);
|
||||
if (ret > 0) {
|
||||
iso_md5_compute(ctx, tag_block, l);
|
||||
iso_md5_end(&ctx, md5);
|
||||
strcpy(tag_block + l, " self=");
|
||||
@ -849,8 +846,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
if (t->ms_block > 0) {
|
||||
iso_msg_submit(t->image->id, ISO_SCDBACKUP_TAG_NOT_0, 0, NULL);
|
||||
} else {
|
||||
res = iso_md5_write_scdbackup_tag(t, tag_block, 0);
|
||||
if (res < 0)
|
||||
ret = iso_md5_write_scdbackup_tag(t, tag_block, 0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
@ -861,16 +858,17 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
} else {
|
||||
wres = iso_write(t, tag_block, 2048);
|
||||
if (wres < 0) {
|
||||
res = wres;
|
||||
ret = wres;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
res = ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (ctx != NULL)
|
||||
iso_md5_end(&ctx, md5);
|
||||
return res;
|
||||
LIBISO_FREE_MEM(tag_block);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -245,15 +245,18 @@ int iso_set_abort_severity(char *severity)
|
||||
|
||||
void iso_msg_debug(int imgid, const char *fmt, ...)
|
||||
{
|
||||
char msg[MAX_MSG_LEN];
|
||||
char *msg = NULL;
|
||||
va_list ap;
|
||||
|
||||
LIBISO_ALLOC_MEM_VOID(msg, char, MAX_MSG_LEN);
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
libiso_msgs_submit(libiso_msgr, imgid, 0x00000002, LIBISO_MSGS_SEV_DEBUG,
|
||||
LIBISO_MSGS_PRIO_ZERO, msg, 0, 0);
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(msg);
|
||||
}
|
||||
|
||||
const char *iso_error_to_msg(int errcode)
|
||||
@ -461,6 +464,10 @@ const char *iso_error_to_msg(int errcode)
|
||||
return "Reserved Rock Ridge leaf name";
|
||||
case ISO_RR_PATH_TOO_LONG:
|
||||
return "Rock Ridge path too long";
|
||||
case ISO_AAIP_BAD_ATTR_NAME:
|
||||
return "Attribute name cannot be represented";
|
||||
case ISO_AAIP_ACL_MULT_OBJ:
|
||||
return "ACL text contains multiple entries of user::, group::, other::";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
@ -480,7 +487,7 @@ int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
/* when called with ISO_CANCELED, we don't need to submit any message */
|
||||
if (errcode == ISO_CANCELED && fmt == NULL) {
|
||||
if (errcode == (int) ISO_CANCELED && fmt == NULL) {
|
||||
return ISO_CANCELED;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "aaip_0_2.h"
|
||||
#include "messages.h"
|
||||
#include "util.h"
|
||||
#include "eltorito.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -78,6 +79,14 @@ void iso_node_unref(IsoNode *node)
|
||||
IsoSymlink *link = (IsoSymlink*) node;
|
||||
free(link->dest);
|
||||
}
|
||||
break;
|
||||
case LIBISO_BOOT:
|
||||
{
|
||||
IsoBoot *bootcat = (IsoBoot *) node;
|
||||
if (bootcat->content != NULL)
|
||||
free(bootcat->content);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* other kind of nodes does not need to delete anything here */
|
||||
break;
|
||||
@ -1573,7 +1582,7 @@ int iso_aa_get_attrs(unsigned char *aa_string, size_t *num_attrs,
|
||||
goto ex;
|
||||
}
|
||||
|
||||
if (rpt - aa_string != len) {
|
||||
if ((size_t) (rpt - aa_string) != len) {
|
||||
/* aaip_decode_attrs() returns 2 but still bytes are left */
|
||||
ret = ISO_AAIP_BAD_AASTRING;
|
||||
goto ex;
|
||||
@ -1615,7 +1624,9 @@ int iso_aa_lookup_attr(unsigned char *aa_string, char *name,
|
||||
|
||||
ret = iso_aa_get_attrs(aa_string, &num_attrs, &names,
|
||||
&value_lengths, &values, 0);
|
||||
for (i = 0; i < num_attrs; i++) {
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
for (i = 0; i < (int) num_attrs; i++) {
|
||||
if (strcmp(names[i], name))
|
||||
continue;
|
||||
*value_length = value_lengths[i];
|
||||
@ -2138,10 +2149,12 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
||||
ret = aaip_encode_both_acl(access_text, default_text, st_mode,
|
||||
&acl_len, &acl, 2 | 8);
|
||||
}
|
||||
if (ret <= 0) {
|
||||
if (ret == -1)
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
else if (ret <= 0 && ret >= -3)
|
||||
ret = ISO_AAIP_BAD_ACL_TEXT;
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
|
||||
if(acl == NULL) { /* Delete whole ACL attribute */
|
||||
/* Update S_IRWXG by eventual "group::" ACL entry.
|
||||
@ -2194,6 +2207,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
|
||||
}
|
||||
ret = aaip_encode_both_acl(access_text, default_text,
|
||||
st_mode, &acl_len, &acl, 2 | 8);
|
||||
if (ret < -3)
|
||||
goto ex;
|
||||
if (ret <= 0) {
|
||||
ret = ISO_AAIP_BAD_ACL_TEXT;
|
||||
goto ex;
|
||||
@ -2850,7 +2865,7 @@ int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag)
|
||||
ret = 0;
|
||||
goto ex;
|
||||
}
|
||||
for (i = 0; i < value_len; i++)
|
||||
for (i = 0; i < (int) value_len; i++)
|
||||
idx = (idx << 8) | ((unsigned char *) value)[i];
|
||||
if (idx == 0 || idx > image->checksum_idx_count - 1) {
|
||||
/* (last index is not MD5 of a file) */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -406,12 +406,15 @@ int rrip_SL_append_comp(size_t *n, uint8_t ***comps, char *s, int size, char fl)
|
||||
#ifdef Libisofs_with_rrip_rR
|
||||
|
||||
/**
|
||||
* Add to the given tree node a RR System Use Entry. This is an obsolete
|
||||
* entry from before RRIP-1.10. Nevertheless mkisofs produces it and there
|
||||
* is the suspicion that Solaris takes it as indication for Rock Ridge.
|
||||
* Add a RR System Use Entry to the given tree node. This is an obsolete
|
||||
* entry from before RRIP-1.10. Nevertheless mkisofs produces it. There
|
||||
* is the suspicion that some operating systems could take it as indication
|
||||
* for Rock Ridge.
|
||||
*
|
||||
* I once saw a copy of a RRIP spec which mentioned RR. Here i just use
|
||||
* the same constant 5 bytes as produced by mkisofs.
|
||||
* The meaning of the payload byte is documented e.g. in
|
||||
* /usr/src/linux/fs/isofs/rock.h
|
||||
* It announces the presence of entries PX, PN, SL, NM, CL, PL, RE, TF
|
||||
* by payload byte bits 0 to 7.
|
||||
*/
|
||||
static
|
||||
int rrip_add_RR(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
@ -426,7 +429,14 @@ int rrip_add_RR(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
|
||||
RR[1] = 'R';
|
||||
RR[2] = 5;
|
||||
RR[3] = 1;
|
||||
RR[4] = 0201;
|
||||
|
||||
/* <<< ts B20307 : Not all directories have NM, many files have more entries */
|
||||
RR[4] = 0x89; /* TF, NM , PX */
|
||||
|
||||
/* >>> ts B20307 : find out whether n carries
|
||||
PX, PN, SL, NM, CL, PL, RE, TF and mark by bit0 to bit7 in RR[4]
|
||||
*/
|
||||
|
||||
return susp_append(t, susp, RR);
|
||||
}
|
||||
|
||||
@ -450,8 +460,8 @@ static
|
||||
int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
|
||||
size_t n, int ce)
|
||||
{
|
||||
int ret, i, j;
|
||||
|
||||
int ret;
|
||||
size_t i, j;
|
||||
int total_comp_len = 0;
|
||||
size_t pos, written = 0;
|
||||
|
||||
@ -988,7 +998,10 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
goto unannounced_ca;
|
||||
namelen = namelen - (space - *su_size - 5);
|
||||
|
||||
/* >>> Need to handle lengths > 250 */;
|
||||
/* >>> SUPER_LONG_RR: Need to handle CA part lengths > 250
|
||||
(This cannot happen with name lengths <= 256, as a part
|
||||
of the name will always fit into the directory entry.)
|
||||
*/;
|
||||
|
||||
*ce = 5 + namelen;
|
||||
*su_size = space;
|
||||
@ -1054,8 +1067,8 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
* First, we check how many bytes fit in current
|
||||
* SL field
|
||||
*/
|
||||
int fit = 255 - sl_len - 2;
|
||||
if (clen - 250 <= fit) {
|
||||
ssize_t fit = 255 - sl_len - 2;
|
||||
if ((ssize_t) (clen - 250) <= fit) {
|
||||
/*
|
||||
* the component can be divided between this
|
||||
* and another SL entry
|
||||
@ -1233,7 +1246,17 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
/* we need to add a RE entry */
|
||||
su_size += 4;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
|
||||
(t->rr_reloc_flags & 1)) {
|
||||
/* The dedicated relocation directory shall be marked by RE */
|
||||
su_size += 4;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
} else if (n->type == ECMA119_SPECIAL) {
|
||||
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
|
||||
/* block or char device, we need a PN entry */
|
||||
@ -1257,6 +1280,7 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
|
||||
/* "." or ".." entry */
|
||||
|
||||
if (!t->rrip_version_1_10)
|
||||
su_size += 5; /* NM field */
|
||||
|
||||
if (type == 1 && n->parent == NULL) {
|
||||
@ -1342,7 +1366,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
|
||||
int ce_is_predicted = 0;
|
||||
size_t aaip_sua_free= 0, aaip_len= 0;
|
||||
size_t space;
|
||||
int space;
|
||||
|
||||
if (t == NULL || n == NULL || info == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -1354,7 +1378,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
if (type < 0 || type > 2 || space < ISO_ROCKRIDGE_IN_DIR_REC) {
|
||||
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||
"Unknown node type %d or short RR space %d < %d in directory record",
|
||||
type, (int) space, ISO_ROCKRIDGE_IN_DIR_REC);
|
||||
type, space, ISO_ROCKRIDGE_IN_DIR_REC);
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
|
||||
@ -1418,6 +1442,18 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
goto add_susp_cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_rr_reloc_diR
|
||||
|
||||
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
|
||||
(t->rr_reloc_flags & 1)) {
|
||||
/* The dedicated relocation directory shall be marked by RE */
|
||||
ret = rrip_add_RE(t, node, info);
|
||||
if (ret < 0)
|
||||
goto add_susp_cleanup;
|
||||
|
||||
#endif /* Libisofs_with_rr_reloc_diR */
|
||||
|
||||
}
|
||||
} else if (n->type == ECMA119_SPECIAL) {
|
||||
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
|
||||
@ -1438,7 +1474,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
if (info->suf_len + 28 > space) {
|
||||
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
|
||||
"Directory Record overflow. name='%s' , suf_len=%d > space=%d - 28\n",
|
||||
node->iso_name, (int) info->suf_len, (int) space);
|
||||
node->iso_name, (int) info->suf_len, space);
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
|
||||
@ -1460,9 +1496,11 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
/* Try whether NM, SL, AL will fit into SUA */
|
||||
su_size_pd = info->suf_len;
|
||||
ce_len_pd = ce_len;
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 0);
|
||||
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
|
||||
&su_size_pd, &ce_len_pd, 0);
|
||||
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 1);
|
||||
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
|
||||
&su_size_pd, &ce_len_pd, 1);
|
||||
sua_free -= 28;
|
||||
ce_is_predicted = 1;
|
||||
}
|
||||
@ -1554,8 +1592,8 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
* First, we check how many bytes fit in current
|
||||
* SL field
|
||||
*/
|
||||
int fit = 255 - sl_len - 2;
|
||||
if (clen - 250 <= fit) {
|
||||
ssize_t fit = 255 - sl_len - 2;
|
||||
if ((ssize_t) (clen - 250) <= fit) {
|
||||
/*
|
||||
* the component can be divided between this
|
||||
* and another SL entry
|
||||
@ -1668,7 +1706,10 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
* ..and the part that goes to continuation area.
|
||||
*/
|
||||
|
||||
/* >>> Need a loop to handle lengths > 250 */;
|
||||
/* >>> SUPER_LONG_RR : Need a loop to handle CA lengths > 250
|
||||
(This cannot happen with name lengths <= 256, as a part
|
||||
of the name will always fit into the directory entry.)
|
||||
*/;
|
||||
|
||||
ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen),
|
||||
0, 1);
|
||||
@ -1711,8 +1752,35 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
/* "." or ".." entry */
|
||||
|
||||
/* write the NM entry */
|
||||
if (t->rrip_version_1_10) {
|
||||
/* RRIP-1.10:
|
||||
"NM" System Use Fields recorded for the ISO 9660 directory
|
||||
records with names (00) and (01), used to designate the
|
||||
current and parent directories, respectively, should be
|
||||
ignored. Instead, the receiving system should convert these
|
||||
names to the appropriate receiving system-dependent
|
||||
designations for the current and parent directories.
|
||||
*/
|
||||
/* mkisofs obviously writes no NM for '.' and '..' .
|
||||
Program isoinfo shows empty names with records as of RRIP-1.12
|
||||
*/
|
||||
/* no op */;
|
||||
} else {
|
||||
/* RRIP-1.12:
|
||||
If the ISO 9660 Directory Record File Identifier is (00), then
|
||||
the CURRENT bit of the "NM" Flags field [...], if present, shall
|
||||
be set to ONE. If the ISO 9660 Directory Record File Identifier
|
||||
is (01), then the PARENT bit of the "NM" Flags field [...],
|
||||
if present, shall be set to ONE.
|
||||
[...]
|
||||
"BP 3 - Length (LEN_NM)" shall specify as an 8-bit number the
|
||||
length in bytes [...]. If bit position 1, 2, or 5 of the "NM"
|
||||
Flags is set to ONE, the value of this field shall be 5 and no
|
||||
Name Content shall be recorded.
|
||||
[The CURRENT bit has position 1. The PARENT bit has position 2.]
|
||||
*/
|
||||
ret = rrip_add_NM(t, info, NULL, 0, 1 << type, 0);
|
||||
if (ret < 0) {
|
||||
if (ret < 0)
|
||||
goto add_susp_cleanup;
|
||||
}
|
||||
|
||||
@ -1821,12 +1889,13 @@ void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
|
||||
int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
{
|
||||
size_t i;
|
||||
uint8_t padding[BLOCK_SIZE];
|
||||
uint8_t *padding = NULL;
|
||||
int ret= ISO_SUCCESS;
|
||||
|
||||
if (info->n_ce_susp_fields == 0) {
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
LIBISO_ALLOC_MEM(padding, uint8_t, BLOCK_SIZE);
|
||||
|
||||
for (i = 0; i < info->n_ce_susp_fields; i++) {
|
||||
ret = iso_write(t, info->ce_susp_fields[i],
|
||||
@ -1852,6 +1921,8 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
info->ce_susp_fields = NULL;
|
||||
info->n_ce_susp_fields = 0;
|
||||
info->ce_len = 0;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(padding);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -81,8 +81,7 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
|
||||
* (IEEE 1281, SUSP. section 4)
|
||||
*/
|
||||
if (iter->ce_len) {
|
||||
uint32_t block;
|
||||
int nblocks;
|
||||
uint32_t block, nblocks;
|
||||
|
||||
/* A CE has found, there is another continuation area */
|
||||
nblocks = DIV_UP(iter->ce_off + iter->ce_len, BLOCK_SIZE);
|
||||
|
@ -214,6 +214,7 @@ int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
IsoStreamIface fsrc_stream_class = {
|
||||
4, /* version */
|
||||
"fsrc",
|
||||
@ -398,7 +399,7 @@ static
|
||||
int cut_out_read(IsoStream *stream, void *buf, size_t count)
|
||||
{
|
||||
struct cut_out_stream *data = stream->data;
|
||||
count = (size_t)MIN(data->size - data->pos, count);
|
||||
count = (size_t) MIN((size_t) (data->size - data->pos), count);
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -503,6 +504,7 @@ int cut_out_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||
/*
|
||||
* TODO update cut out streams to deal with update_size(). Seems hard.
|
||||
*/
|
||||
static
|
||||
IsoStreamIface cut_out_stream_class = {
|
||||
4, /* version */
|
||||
"cout",
|
||||
@ -647,7 +649,7 @@ int mem_read(IsoStream *stream, void *buf, size_t count)
|
||||
return ISO_FILE_NOT_OPENED;
|
||||
}
|
||||
|
||||
if (data->offset >= data->size) {
|
||||
if (data->offset >= (ssize_t) data->size) {
|
||||
return 0; /* EOF */
|
||||
}
|
||||
|
||||
@ -748,6 +750,7 @@ int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
IsoStreamIface mem_stream_class = {
|
||||
4, /* version */
|
||||
"mem ",
|
||||
@ -869,6 +872,10 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
|
||||
if (!strncmp(type, "fsrc", 4)) {
|
||||
FSrcStreamData *data = stream->data;
|
||||
char *path = iso_file_source_get_path(data->src);
|
||||
if (path == NULL) {
|
||||
name[0] = 0;
|
||||
return;
|
||||
}
|
||||
strncpy(name, path, PATH_MAX - 1);
|
||||
name[PATH_MAX - 1] = 0;
|
||||
free(path);
|
||||
@ -1076,14 +1083,15 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
|
||||
*/
|
||||
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag)
|
||||
{
|
||||
int res, is_open = 0;
|
||||
char buffer[2048];
|
||||
int ret, is_open = 0;
|
||||
char * buffer = NULL;
|
||||
void *ctx= NULL;
|
||||
off_t file_size;
|
||||
uint32_t b, nblocks;
|
||||
size_t got_bytes;
|
||||
IsoStream *input_stream;
|
||||
|
||||
LIBISO_ALLOC_MEM(buffer, char, 2048);
|
||||
if (flag & 1) {
|
||||
while(1) {
|
||||
input_stream = iso_stream_get_input_stream(stream, 0);
|
||||
@ -1094,36 +1102,37 @@ int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag)
|
||||
}
|
||||
|
||||
if (! iso_stream_is_repeatable(stream))
|
||||
return 0;
|
||||
res = iso_md5_start(&ctx);
|
||||
if (res < 0)
|
||||
return res;
|
||||
res = iso_stream_open(stream);
|
||||
if (res < 0)
|
||||
return 0;
|
||||
{ret = 0; goto ex;}
|
||||
ret = iso_md5_start(&ctx);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
ret = iso_stream_open(stream);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
is_open = 1;
|
||||
file_size = iso_stream_get_size(stream);
|
||||
nblocks = DIV_UP(file_size, 2048);
|
||||
for (b = 0; b < nblocks; ++b) {
|
||||
res = iso_stream_read_buffer(stream, buffer, 2048, &got_bytes);
|
||||
if (res < 0) {
|
||||
res = 0;
|
||||
ret = iso_stream_read_buffer(stream, buffer, 2048, &got_bytes);
|
||||
if (ret < 0) {
|
||||
ret = 0;
|
||||
goto ex;
|
||||
}
|
||||
/* Do not use got_bytes to stay closer to IsoFileSrc processing */
|
||||
if (file_size - b * 2048 > 2048)
|
||||
res = 2048;
|
||||
ret = 2048;
|
||||
else
|
||||
res = file_size - b * 2048;
|
||||
iso_md5_compute(ctx, buffer, res);
|
||||
ret = file_size - b * 2048;
|
||||
iso_md5_compute(ctx, buffer, ret);
|
||||
}
|
||||
res = 1;
|
||||
ret = 1;
|
||||
ex:;
|
||||
if (is_open)
|
||||
iso_stream_close(stream);
|
||||
if (ctx != NULL)
|
||||
iso_md5_end(&ctx, md5);
|
||||
return res;
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* API */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Vreixo Formoso
|
||||
* Copyright (c) 2010 Thomas Schmitt
|
||||
* Copyright (c) 2010 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -387,7 +387,7 @@ static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
|
||||
/* 84 - 87 | boot_bytes | File length in bytes */
|
||||
/* 88 - 311 | 0 | Volume Directory Entries 2 to 15 */
|
||||
|
||||
for (idx = 0; idx < t->image->num_mips_boot_files; idx++) {
|
||||
for (idx = 0; (int) idx < t->image->num_mips_boot_files; idx++) {
|
||||
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[idx],
|
||||
&node, &ecma_node, "MIPS boot file", 0);
|
||||
if (ret < 0)
|
||||
@ -457,18 +457,19 @@ int iso_read_mipsel_elf(Ecma119Image *t, int flag)
|
||||
{
|
||||
uint32_t phdr_adr, todo, count;
|
||||
int ret;
|
||||
uint8_t elf_buf[2048];
|
||||
uint8_t *elf_buf = NULL;
|
||||
IsoNode *iso_node;
|
||||
Ecma119Node *ecma_node;
|
||||
IsoStream *stream;
|
||||
|
||||
if (t->image->num_mips_boot_files <= 0)
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
|
||||
LIBISO_ALLOC_MEM(elf_buf, uint8_t, 2048);
|
||||
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
|
||||
&iso_node, &ecma_node, "MIPS boot file", 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
stream = iso_file_get_stream((IsoFile *) iso_node);
|
||||
|
||||
ret = iso_stream_open(stream);
|
||||
@ -476,7 +477,7 @@ int iso_read_mipsel_elf(Ecma119Image *t, int flag)
|
||||
iso_msg_submit(t->image->id, ret, 0,
|
||||
"Cannot open designated MIPS boot file '%s'",
|
||||
t->image->mips_boot_file_paths[0]);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
ret = iso_stream_read(stream, elf_buf, 32);
|
||||
if (ret != 32) {
|
||||
@ -485,7 +486,7 @@ cannot_read:;
|
||||
iso_msg_submit(t->image->id, ret, 0,
|
||||
"Cannot read from designated MIPS boot file '%s'",
|
||||
t->image->mips_boot_file_paths[0]);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
|
||||
@ -504,7 +505,7 @@ cannot_read:;
|
||||
count = todo;
|
||||
todo -= count;
|
||||
ret = iso_stream_read(stream, elf_buf, count);
|
||||
if (ret != count)
|
||||
if (ret != (int) count)
|
||||
goto cannot_read;
|
||||
}
|
||||
ret = iso_stream_read(stream, elf_buf, 20);
|
||||
@ -521,7 +522,10 @@ cannot_read:;
|
||||
t->mipsel_p_filesz = iso_read_lsb(elf_buf + 16, 4);
|
||||
|
||||
iso_stream_close(stream);
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(elf_buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -679,7 +683,8 @@ static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag)
|
||||
ret = write_sun_partition_entry(1, t->appended_partitions,
|
||||
t->appended_part_start, t->appended_part_size,
|
||||
ISO_SUN_CYL_SIZE, buf, 0);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -844,14 +849,15 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
|
||||
int sa_type, ret, always_align;
|
||||
uint32_t img_blocks;
|
||||
off_t imgsize, cylsize = 0, frac;
|
||||
char msg[160];
|
||||
char *msg = NULL;
|
||||
|
||||
LIBISO_ALLOC_MEM(msg, char, 160);
|
||||
sa_type = (t->system_area_options >> 2) & 0x3f;
|
||||
if (sa_type != 0)
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
always_align = (t->system_area_options >> 8) & 3;
|
||||
|
||||
img_blocks = t->curblock;
|
||||
img_blocks = t->curblock + t->tail_blocks;
|
||||
imgsize = ((off_t) img_blocks) * (off_t) 2048;
|
||||
if (((t->system_area_options & 3) || always_align)
|
||||
&& (off_t) (t->partition_heads_per_cyl * t->partition_secs_per_head
|
||||
@ -877,7 +883,7 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
|
||||
}
|
||||
|
||||
if (always_align >= 2)
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
|
||||
cylsize = 0;
|
||||
if (t->catalog != NULL &&
|
||||
@ -886,7 +892,7 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
|
||||
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
|
||||
*/
|
||||
if (img_blocks >= 0x40000000)
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
cylsize = 64 * 32 * 512;
|
||||
} else if ((t->system_area_options & 2) || always_align) {
|
||||
/* Patch externally provided system area as isohybrid MBR */
|
||||
@ -894,18 +900,18 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
|
||||
/* isohybrid makes only sense together with ISOLINUX boot image
|
||||
and externally provided System Area.
|
||||
*/
|
||||
return ISO_ISOLINUX_CANT_PATCH;
|
||||
{ret = ISO_ISOLINUX_CANT_PATCH; goto ex;}
|
||||
}
|
||||
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head
|
||||
* 512;
|
||||
}
|
||||
if (cylsize == 0)
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
if (((double) imgsize) / (double) cylsize > 1024.0) {
|
||||
iso_msgs_submit(0,
|
||||
"Image size exceeds 1024 cylinders. Cannot align partition.",
|
||||
0, "WARNING", 0);
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
}
|
||||
|
||||
frac = imgsize % cylsize;
|
||||
@ -913,7 +919,7 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
|
||||
|
||||
frac = imgsize - ((off_t) img_blocks) * (off_t) 2048;
|
||||
if (frac == 0)
|
||||
return ISO_SUCCESS;
|
||||
{ret = ISO_SUCCESS; goto ex;}
|
||||
if (frac % 2048) {
|
||||
sprintf(msg,
|
||||
"Cylinder size %d not divisible by 2048. Cannot align partition.",
|
||||
@ -922,5 +928,8 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
|
||||
} else {
|
||||
t->tail_blocks += frac / 2048;
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(msg);
|
||||
return ret;
|
||||
}
|
||||
|
@ -478,12 +478,12 @@ int iso_tree_remove_exclude(IsoImage *image, const char *path)
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
for (i = 0; i < image->nexcludes; ++i) {
|
||||
for (i = 0; (int) i < image->nexcludes; ++i) {
|
||||
if (strcmp(image->excludes[i], path) == 0) {
|
||||
/* exclude found */
|
||||
free(image->excludes[i]);
|
||||
--image->nexcludes;
|
||||
for (j = i; j < image->nexcludes; ++j) {
|
||||
for (j = i; (int) j < image->nexcludes; ++j) {
|
||||
image->excludes[j] = image->excludes[j+1];
|
||||
}
|
||||
image->excludes = realloc(image->excludes, image->nexcludes *
|
||||
@ -761,11 +761,16 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
|
||||
ret = iso_file_source_open(dir);
|
||||
if (ret < 0) {
|
||||
char *path = iso_file_source_get_path(dir);
|
||||
path = iso_file_source_get_path(dir);
|
||||
/* instead of the probable error, we throw a sorry event */
|
||||
if (path != NULL) {
|
||||
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
|
||||
"Can't open dir %s", path);
|
||||
free(path);
|
||||
} else {
|
||||
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
|
||||
"Can't open dir. NULL pointer caught as dir name");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -785,6 +790,11 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
}
|
||||
|
||||
path = iso_file_source_get_path(file);
|
||||
if (path == NULL) {
|
||||
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
|
||||
"NULL pointer caught as file path");
|
||||
return ret;
|
||||
}
|
||||
name = strrchr(path, '/') + 1;
|
||||
|
||||
if (image->follow_symlinks) {
|
||||
@ -847,7 +857,7 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||
ret = iso_dir_insert(parent, new, pos, replace);
|
||||
if (ret < 0) {
|
||||
iso_node_unref(new);
|
||||
if (ret != ISO_NODE_NAME_NOT_UNIQUE) {
|
||||
if (ret != (int) ISO_NODE_NAME_NOT_UNIQUE) {
|
||||
/* error */
|
||||
goto dir_rec_continue;
|
||||
} else {
|
||||
|
279
libisofs/util.c
279
libisofs/util.c
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -219,7 +219,7 @@ int strconv(const char *str, const char *icharset, const char *ocharset,
|
||||
src = (char *)str;
|
||||
ret = (char *)out;
|
||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||
if (n == -1) {
|
||||
if (n == (size_t) -1) {
|
||||
/* error */
|
||||
iso_iconv_close(&conv, 0);
|
||||
retval = ISO_CHARSET_CONV_ERROR;
|
||||
@ -269,7 +269,7 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
|
||||
src = (char *)str;
|
||||
ret = (char *)out;
|
||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||
if (n == -1) {
|
||||
if (n == (size_t) -1) {
|
||||
/* error */
|
||||
iso_iconv_close(&conv, 0);
|
||||
retval = ISO_CHARSET_CONV_ERROR;
|
||||
@ -336,7 +336,7 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output)
|
||||
src = (char *)input;
|
||||
|
||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||
while (n == -1) {
|
||||
while (n == (size_t) -1) {
|
||||
|
||||
if (errno == E2BIG) {
|
||||
/* error, should never occur */
|
||||
@ -382,12 +382,13 @@ conv_error:;
|
||||
int str2ascii(const char *icharset, const char *input, char **output)
|
||||
{
|
||||
int result;
|
||||
wchar_t *wsrc_;
|
||||
char *ret;
|
||||
char *ret_;
|
||||
wchar_t *wsrc_ = NULL;
|
||||
char *ret = NULL;
|
||||
char *ret_ = NULL;
|
||||
char *src;
|
||||
struct iso_iconv_handle conv;
|
||||
int conv_ret;
|
||||
int direct_conv = 0;
|
||||
|
||||
/* That while loop smells like a potential show stopper */
|
||||
size_t loop_counter = 0, loop_limit = 3;
|
||||
@ -405,14 +406,17 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* First try the traditional way via intermediate character set WCHAR_T.
|
||||
* Up to August 2011 this was the only way. But it will not work if
|
||||
* there is no character set "WCHAR_T". E.g. on Solaris.
|
||||
*/
|
||||
/* convert the string to a wide character string. Note: outbytes
|
||||
* is in fact the number of characters in the string and doesn't
|
||||
* include the last NULL character.
|
||||
*/
|
||||
conv_ret = 0;
|
||||
result = str2wchar(icharset, input, &wsrc_);
|
||||
if (result < 0) {
|
||||
goto fallback;
|
||||
}
|
||||
if (result == (int) ISO_SUCCESS) {
|
||||
src = (char *)wsrc_;
|
||||
numchars = wcslen(wsrc_);
|
||||
|
||||
@ -431,11 +435,29 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
||||
if (conv_ret <= 0) {
|
||||
free(wsrc_);
|
||||
free(ret_);
|
||||
}
|
||||
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
|
||||
return result;
|
||||
|
||||
/* If this did not succeed : Try the untraditional direct conversion.
|
||||
*/
|
||||
if (conv_ret <= 0) {
|
||||
conv_ret = iso_iconv_open(&conv, "ASCII", (char *) icharset, 0);
|
||||
if (conv_ret <= 0)
|
||||
goto fallback;
|
||||
direct_conv = 1;
|
||||
src = (char *) input;
|
||||
inbytes = strlen(input);
|
||||
loop_limit = inbytes + 3;
|
||||
outbytes = (inbytes + 1) * sizeof(uint16_t);
|
||||
ret_ = malloc(outbytes);
|
||||
if (ret_ == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
ret = ret_;
|
||||
}
|
||||
|
||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||
while (n == -1) {
|
||||
while (n == (size_t) -1) {
|
||||
/* The destination buffer is too small. Stops here. */
|
||||
if (errno == E2BIG)
|
||||
break;
|
||||
@ -458,8 +480,13 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
||||
/* There was an error with one character but some other remain
|
||||
* to be converted. That's probably a multibyte character.
|
||||
* See above comment. */
|
||||
if (direct_conv) {
|
||||
src++;
|
||||
inbytes--;
|
||||
} else {
|
||||
src += sizeof(wchar_t);
|
||||
inbytes -= sizeof(wchar_t);
|
||||
}
|
||||
|
||||
if (!inbytes)
|
||||
break;
|
||||
@ -471,7 +498,8 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||
}
|
||||
iso_iconv_close(&conv, 0);
|
||||
*ret='\0';
|
||||
*ret = 0;
|
||||
if (wsrc_ != NULL)
|
||||
free(wsrc_);
|
||||
|
||||
*output = ret_;
|
||||
@ -517,12 +545,13 @@ int cmp_ucsbe(const uint16_t *ucs, char c)
|
||||
int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
||||
{
|
||||
int result;
|
||||
wchar_t *wsrc_;
|
||||
wchar_t *wsrc_ = NULL;
|
||||
char *src;
|
||||
char *ret;
|
||||
char *ret_;
|
||||
char *ret = NULL;
|
||||
char *ret_ = NULL;
|
||||
struct iso_iconv_handle conv;
|
||||
int conv_ret;
|
||||
int conv_ret = 0;
|
||||
int direct_conv = 0;
|
||||
|
||||
/* That while loop smells like a potential show stopper */
|
||||
size_t loop_counter = 0, loop_limit = 3;
|
||||
@ -540,10 +569,13 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
||||
* is in fact the number of characters in the string and doesn't
|
||||
* include the last NULL character.
|
||||
*/
|
||||
/* First try the traditional way via intermediate character set WCHAR_T.
|
||||
* Up to August 2011 this was the only way. But it will not work if
|
||||
* there is no character set "WCHAR_T". E.g. on Solaris.
|
||||
*/
|
||||
conv_ret = 0;
|
||||
result = str2wchar(icharset, input, &wsrc_);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
if (result == (int) ISO_SUCCESS) {
|
||||
src = (char *)wsrc_;
|
||||
numchars = wcslen(wsrc_);
|
||||
|
||||
@ -551,9 +583,8 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
||||
loop_limit = inbytes + 3;
|
||||
|
||||
ret_ = malloc((numchars+1) * sizeof(uint16_t));
|
||||
if (ret_ == NULL) {
|
||||
if (ret_ == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
outbytes = numchars * sizeof(uint16_t);
|
||||
ret = ret_;
|
||||
|
||||
@ -562,11 +593,30 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
||||
if (conv_ret <= 0) {
|
||||
free(wsrc_);
|
||||
free(ret_);
|
||||
}
|
||||
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
|
||||
return result;
|
||||
|
||||
/* If this did not succeed : Try the untraditional direct conversion.
|
||||
*/
|
||||
if (conv_ret <= 0) {
|
||||
conv_ret = iso_iconv_open(&conv, "UCS-2BE", (char *) icharset, 0);
|
||||
if (conv_ret <= 0) {
|
||||
return ISO_CHARSET_CONV_ERROR;
|
||||
}
|
||||
direct_conv = 1;
|
||||
src = (char *) input;
|
||||
inbytes = strlen(input);
|
||||
loop_limit = inbytes + 3;
|
||||
outbytes = (inbytes + 1) * sizeof(uint16_t);
|
||||
ret_ = malloc(outbytes);
|
||||
if (ret_ == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
ret = ret_;
|
||||
}
|
||||
|
||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||
while (n == -1) {
|
||||
while (n == (size_t) -1) {
|
||||
/* The destination buffer is too small. Stops here. */
|
||||
if (errno == E2BIG)
|
||||
break;
|
||||
@ -589,8 +639,13 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
||||
/* There was an error with one character but some other remain
|
||||
* to be converted. That's probably a multibyte character.
|
||||
* See above comment. */
|
||||
if (direct_conv) {
|
||||
src++;
|
||||
inbytes--;
|
||||
} else {
|
||||
src += sizeof(wchar_t);
|
||||
inbytes -= sizeof(wchar_t);
|
||||
}
|
||||
|
||||
if (!inbytes)
|
||||
break;
|
||||
@ -605,6 +660,7 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
||||
|
||||
/* close the ucs string */
|
||||
set_ucsbe((uint16_t*) ret, '\0');
|
||||
if (wsrc_ != NULL)
|
||||
free(wsrc_);
|
||||
|
||||
*output = (uint16_t*)ret_;
|
||||
@ -629,36 +685,75 @@ static int valid_j_char(uint16_t c)
|
||||
&& cmp_ucsbe(&c, '\\');
|
||||
}
|
||||
|
||||
/* @param relaxed bit0+1 0= strict ECMA-119
|
||||
1= additionally allow lowercase (else map to upper)
|
||||
2= allow all 8-bit characters
|
||||
bit2 allow all 7-bit characters (but map to upper if
|
||||
not bit0+1 == 2)
|
||||
*/
|
||||
static char map_fileid_char(char c, int relaxed)
|
||||
{
|
||||
char upper;
|
||||
|
||||
if (c == '/') /* Allowing slashes would cause lots of confusion */
|
||||
return '_';
|
||||
if ((relaxed & 3) == 2)
|
||||
return c;
|
||||
if (valid_d_char(c))
|
||||
return c;
|
||||
if ((relaxed & 4) && (c & 0x7f) == c && (c < 'a' || c > 'z'))
|
||||
return c;
|
||||
upper= toupper(c);
|
||||
if (valid_d_char(upper)) {
|
||||
if (relaxed & 3) {
|
||||
/* lower chars are allowed */
|
||||
return c;
|
||||
}
|
||||
return upper;
|
||||
}
|
||||
return '_';
|
||||
}
|
||||
|
||||
static
|
||||
char *iso_dirid(const char *src, int size)
|
||||
char *iso_dirid(const char *src, int size, int relaxed)
|
||||
{
|
||||
size_t len, i;
|
||||
char name[32];
|
||||
|
||||
len = strlen(src);
|
||||
if (len > size) {
|
||||
if ((int) len > size) {
|
||||
len = size;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
|
||||
#ifdef Libisofs_old_ecma119_nameS
|
||||
|
||||
char c= toupper(src[i]);
|
||||
name[i] = valid_d_char(c) ? c : '_';
|
||||
|
||||
#else /* Libisofs_old_ecma119_nameS */
|
||||
|
||||
name[i] = map_fileid_char(src[i], relaxed);
|
||||
|
||||
#endif /* ! Libisofs_old_ecma119_nameS */
|
||||
|
||||
}
|
||||
|
||||
name[len] = '\0';
|
||||
return strdup(name);
|
||||
}
|
||||
|
||||
char *iso_1_dirid(const char *src)
|
||||
char *iso_1_dirid(const char *src, int relaxed)
|
||||
{
|
||||
return iso_dirid(src, 8);
|
||||
return iso_dirid(src, 8, relaxed);
|
||||
}
|
||||
|
||||
char *iso_2_dirid(const char *src)
|
||||
{
|
||||
return iso_dirid(src, 31);
|
||||
return iso_dirid(src, 31, 0);
|
||||
}
|
||||
|
||||
char *iso_1_fileid(const char *src)
|
||||
char *iso_1_fileid(const char *src, int relaxed, int force_dots)
|
||||
{
|
||||
char *dot; /* Position of the last dot in the filename, will be used
|
||||
* to calculate lname and lext. */
|
||||
@ -669,7 +764,8 @@ char *iso_1_fileid(const char *src)
|
||||
return NULL;
|
||||
}
|
||||
dot = strrchr(src, '.');
|
||||
|
||||
if (dot == src && strlen(src) > 4)
|
||||
dot = NULL; /* Use the long extension instead of the empty name */
|
||||
lext = dot ? strlen(dot + 1) : 0;
|
||||
lname = strlen(src) - lext - (dot ? 1 : 0);
|
||||
|
||||
@ -682,19 +778,43 @@ char *iso_1_fileid(const char *src)
|
||||
|
||||
/* Convert up to 8 characters of the filename. */
|
||||
for (i = 0; i < lname && i < 8; i++) {
|
||||
|
||||
#ifdef Libisofs_old_ecma119_nameS
|
||||
|
||||
char c= toupper(src[i]);
|
||||
|
||||
dest[pos++] = valid_d_char(c) ? c : '_';
|
||||
|
||||
#else /* Libisofs_old_ecma119_nameS */
|
||||
|
||||
if (dot == NULL && src[i] == '.')
|
||||
dest[pos++] = '_'; /* make sure that ignored dots do not appear */
|
||||
else
|
||||
dest[pos++] = map_fileid_char(src[i], relaxed);
|
||||
|
||||
#endif /* ! Libisofs_old_ecma119_nameS */
|
||||
|
||||
}
|
||||
|
||||
/* This dot is mandatory, even if there is no extension. */
|
||||
if (force_dots || lext > 0)
|
||||
dest[pos++] = '.';
|
||||
|
||||
/* Convert up to 3 characters of the extension, if any. */
|
||||
for (i = 0; i < lext && i < 3; i++) {
|
||||
|
||||
#ifdef Libisofs_old_ecma119_nameS
|
||||
|
||||
char c= toupper(src[lname + 1 + i]);
|
||||
|
||||
dest[pos++] = valid_d_char(c) ? c : '_';
|
||||
|
||||
#else /* Libisofs_old_ecma119_nameS */
|
||||
|
||||
dest[pos++] = map_fileid_char(src[lname + 1 + i], relaxed);
|
||||
|
||||
#endif /* ! Libisofs_old_ecma119_nameS */
|
||||
|
||||
}
|
||||
|
||||
dest[pos] = '\0';
|
||||
@ -761,8 +881,11 @@ char *iso_2_fileid(const char *src)
|
||||
* @param size
|
||||
* Max len for the name
|
||||
* @param relaxed
|
||||
* 0 only allow d-characters, 1 allow also lowe case chars,
|
||||
* 2 allow all characters
|
||||
* bit0+1: 0 only allow d-characters,
|
||||
* 1 allow also lowe case chars,
|
||||
* 2 allow all 8-bit characters,
|
||||
* bit2: allow 7-bit characters (but map lowercase to uppercase if
|
||||
* not bit0+1 == 2)
|
||||
*/
|
||||
char *iso_r_dirid(const char *src, int size, int relaxed)
|
||||
{
|
||||
@ -770,13 +893,16 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
|
||||
char *dest;
|
||||
|
||||
len = strlen(src);
|
||||
if (len > size) {
|
||||
if ((int) len > size) {
|
||||
len = size;
|
||||
}
|
||||
dest = malloc(len + 1);
|
||||
if (dest == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < len; i++) {
|
||||
|
||||
#ifdef Libisofs_old_ecma119_nameS
|
||||
|
||||
char c= src[i];
|
||||
if (relaxed == 2) {
|
||||
/* all chars are allowed */
|
||||
@ -797,6 +923,13 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
|
||||
dest[i] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
#else /* Libisofs_old_ecma119_nameS */
|
||||
|
||||
dest[i] = map_fileid_char(src[i], relaxed);
|
||||
|
||||
#endif /* ! Libisofs_old_ecma119_nameS */
|
||||
|
||||
}
|
||||
|
||||
dest[len] = '\0';
|
||||
@ -804,13 +937,17 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a file name suitable for an ISO image with relaxed constraints.
|
||||
* Create a file name suitable for an ISO image with level > 1 and
|
||||
* with relaxed constraints.
|
||||
*
|
||||
* @param len
|
||||
* Max len for the name, without taken the "." into account.
|
||||
* @param relaxed
|
||||
* 0 only allow d-characters, 1 allow also lowe case chars,
|
||||
* 2 allow all characters
|
||||
* bit0+1: 0 only allow d-characters,
|
||||
* 1 allow also lowe case chars,
|
||||
* 2 allow all 8-bit characters,
|
||||
* bit2: allow 7-bit characters (but map lowercase to uppercase if
|
||||
* not bit0+1 == 2)
|
||||
* @param forcedot
|
||||
* Whether to ensure that "." is added
|
||||
*/
|
||||
@ -838,15 +975,15 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
|
||||
*/
|
||||
if (dot == NULL || *(dot + 1) == '\0') {
|
||||
lname = strlen(src);
|
||||
lnname = (lname > len) ? len : lname;
|
||||
lnname = (lname > (int) len) ? (int) len : lname;
|
||||
lext = lnext = 0;
|
||||
} else {
|
||||
lext = strlen(dot + 1);
|
||||
lname = strlen(src) - lext - 1;
|
||||
lnext = (strlen(src) > len + 1 && lext > 3) ?
|
||||
(lname < len - 3 ? len - lname : 3)
|
||||
(lname < (int) len - 3 ? (int) len - lname : 3)
|
||||
: lext;
|
||||
lnname = (strlen(src) > len + 1) ? len - lnext : lname;
|
||||
lnname = (strlen(src) > len + 1) ? (int) len - lnext : lname;
|
||||
}
|
||||
|
||||
if (lnname == 0 && lnext == 0) {
|
||||
@ -857,6 +994,9 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
|
||||
|
||||
/* Convert up to lnname characters of the filename. */
|
||||
for (i = 0; i < lnname; i++) {
|
||||
|
||||
#ifdef Libisofs_old_ecma119_nameS
|
||||
|
||||
char c= src[i];
|
||||
if (relaxed == 2) {
|
||||
/* all chars are allowed */
|
||||
@ -877,6 +1017,13 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
|
||||
dest[pos++] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
#else /* Libisofs_old_ecma119_nameS */
|
||||
|
||||
dest[pos++] = map_fileid_char(src[i], relaxed);
|
||||
|
||||
#endif /* ! Libisofs_old_ecma119_nameS */
|
||||
|
||||
}
|
||||
if (lnext > 0 || forcedot) {
|
||||
dest[pos++] = '.';
|
||||
@ -884,6 +1031,9 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
|
||||
|
||||
/* Convert up to lnext characters of the extension, if any. */
|
||||
for (i = lname + 1; i < lname + 1 + lnext; i++) {
|
||||
|
||||
#ifdef Libisofs_old_ecma119_nameS
|
||||
|
||||
char c= src[i];
|
||||
if (relaxed == 2) {
|
||||
/* all chars are allowed */
|
||||
@ -904,6 +1054,13 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
|
||||
dest[pos++] = '_';
|
||||
}
|
||||
}
|
||||
|
||||
#else /* Libisofs_old_ecma119_nameS */
|
||||
|
||||
dest[pos++] = map_fileid_char(src[i], relaxed);
|
||||
|
||||
#endif /* ! Libisofs_old_ecma119_nameS */
|
||||
|
||||
}
|
||||
dest[pos] = '\0';
|
||||
|
||||
@ -921,13 +1078,15 @@ ex:;
|
||||
*/
|
||||
uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
{
|
||||
uint16_t *dot;
|
||||
uint16_t *dot, *retval = NULL;
|
||||
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
|
||||
uint16_t dest[LIBISO_JOLIET_NAME_MAX];
|
||||
uint16_t *dest = NULL;
|
||||
|
||||
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
|
||||
|
||||
if (src == NULL) {
|
||||
return NULL;
|
||||
goto ex;
|
||||
}
|
||||
if (flag & 2)
|
||||
maxchar = 103;
|
||||
@ -954,7 +1113,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
}
|
||||
|
||||
if (lnname == 0 && lnext == 0) {
|
||||
return NULL;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
@ -989,7 +1148,10 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
|
||||
is_done:;
|
||||
set_ucsbe(dest + pos, '\0');
|
||||
return ucsdup(dest);
|
||||
retval = ucsdup(dest);
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(dest);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* @param flag bit1= allow 103 characters rather than 64
|
||||
@ -997,10 +1159,12 @@ is_done:;
|
||||
uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
|
||||
{
|
||||
size_t len, i, maxchar = 64;
|
||||
uint16_t dest[LIBISO_JOLIET_NAME_MAX]; /* was: 65 = 64 + 1 (\0) */
|
||||
uint16_t *dest = NULL, *retval = NULL;
|
||||
/* was: 65 = 64 + 1 (\0) */
|
||||
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
|
||||
if (src == NULL) {
|
||||
return NULL;
|
||||
goto ex;
|
||||
}
|
||||
if (flag & 2)
|
||||
maxchar = 103;
|
||||
@ -1018,7 +1182,10 @@ uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
|
||||
}
|
||||
}
|
||||
set_ucsbe(dest + len, '\0');
|
||||
return ucsdup(dest);
|
||||
retval = ucsdup(dest);
|
||||
ex:
|
||||
LIBISO_FREE_MEM(dest);
|
||||
return retval;
|
||||
}
|
||||
|
||||
size_t ucslen(const uint16_t *str)
|
||||
@ -1564,12 +1731,12 @@ void strncpy_pad(char *dest, const char *src, size_t max)
|
||||
|
||||
if (src != NULL) {
|
||||
len = MIN(strlen(src), max);
|
||||
for (i = 0; i < len; ++i)
|
||||
dest[i] = src[i];
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
dest[i] = src[i];
|
||||
for (i = len; i < max; ++i)
|
||||
dest[i] = ' ';
|
||||
}
|
||||
@ -1601,7 +1768,7 @@ char *ucs2str(const char *buf, size_t len)
|
||||
|
||||
n = iso_iconv(&conv, &src, &inbytes, &str, &outbytes, 0);
|
||||
iso_iconv_close(&conv, 0);
|
||||
if (n == -1) {
|
||||
if (n == (size_t) -1) {
|
||||
/* error */
|
||||
goto ex;
|
||||
}
|
||||
@ -1838,12 +2005,12 @@ int iso_util_eval_md5_tag(char *block, int desired, uint32_t lba,
|
||||
*tag_type = 0;
|
||||
decode_ret = iso_util_decode_md5_tag(block, tag_type, &pos,
|
||||
&range_start, &range_size, next_tag, md5, 0);
|
||||
if (decode_ret != 1 && decode_ret != ISO_MD5_AREA_CORRUPTED)
|
||||
if (decode_ret != 1 && decode_ret != (int) ISO_MD5_AREA_CORRUPTED)
|
||||
return 0;
|
||||
if (*tag_type > 30)
|
||||
goto unexpected_type;
|
||||
|
||||
if (decode_ret == ISO_MD5_AREA_CORRUPTED) {
|
||||
if (decode_ret == (int) ISO_MD5_AREA_CORRUPTED) {
|
||||
ret = decode_ret;
|
||||
goto ex;
|
||||
} else if (!((1 << *tag_type) & desired)) {
|
||||
@ -1887,3 +2054,13 @@ ex:;
|
||||
}
|
||||
|
||||
|
||||
void *iso_alloc_mem(size_t size, size_t count, int flag)
|
||||
{
|
||||
void *pt;
|
||||
|
||||
pt = calloc(size, count);
|
||||
if(pt == NULL)
|
||||
iso_msg_submit(-1, ISO_OUT_OF_MEM, 0, "Out of virtual memory");
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -93,8 +93,11 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output);
|
||||
*
|
||||
* @param src
|
||||
* The identifier, in ASCII encoding.
|
||||
* @param relaxed
|
||||
* 0 only allow d-characters, 1 allow also lowe case chars,
|
||||
* 2 allow all characters
|
||||
*/
|
||||
char *iso_1_dirid(const char *src);
|
||||
char *iso_1_dirid(const char *src, int relaxed);
|
||||
|
||||
/**
|
||||
* Create a level 2 directory identifier.
|
||||
@ -124,8 +127,13 @@ char *iso_r_dirid(const char *src, int size, int relaxed);
|
||||
*
|
||||
* @param src
|
||||
* The identifier, in ASCII encoding.
|
||||
* @param relaxed
|
||||
* 0 only allow d-characters, 1 allow also lowe case chars,
|
||||
* 2 allow all characters
|
||||
* @param force_dots
|
||||
* If 1 then prepend empty extension by SEPARATOR1 = '.'
|
||||
*/
|
||||
char *iso_1_fileid(const char *src);
|
||||
char *iso_1_fileid(const char *src, int relaxed, int force_dots);
|
||||
|
||||
/**
|
||||
* Create a level 2 file identifier.
|
||||
@ -539,4 +547,24 @@ int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
void *iso_alloc_mem(size_t size, size_t count, int flag);
|
||||
|
||||
#define LIBISO_ALLOC_MEM(pt, typ, count) { \
|
||||
pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \
|
||||
if(pt == NULL) { \
|
||||
ret= ISO_OUT_OF_MEM; goto ex; \
|
||||
} }
|
||||
|
||||
#define LIBISO_ALLOC_MEM_VOID(pt, typ, count) { \
|
||||
pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \
|
||||
if(pt == NULL) { \
|
||||
goto ex; \
|
||||
} }
|
||||
|
||||
#define LIBISO_FREE_MEM(pt) { \
|
||||
if(pt != NULL) \
|
||||
free((char *) pt); \
|
||||
}
|
||||
|
||||
|
||||
#endif /*LIBISO_UTIL_H_*/
|
||||
|
@ -164,7 +164,7 @@ int iso_rbtree_insert(IsoRBTree *tree, void *data, void **item)
|
||||
new = data;
|
||||
added = 1;
|
||||
} else {
|
||||
struct iso_rbnode head = { 0 }; /* False tree root */
|
||||
struct iso_rbnode head = { 0, {NULL, NULL}, 0 }; /* False tree root */
|
||||
|
||||
struct iso_rbnode *g, *t; /* Grandparent & parent */
|
||||
struct iso_rbnode *p, *q; /* Iterator & parent */
|
||||
|
Reference in New Issue
Block a user