Compare commits
72 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 |
34
ChangeLog
34
ChangeLog
@ -1,3 +1,37 @@
|
||||
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
|
||||
===============================================================================
|
||||
|
@ -220,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)
|
||||
@ -250,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 \
|
||||
|
28
configure.ac
28
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libisofs], [1.1.0], [http://libburnia-project.org])
|
||||
AC_INIT([libisofs], [1.2.2], [http://libburnia-project.org])
|
||||
AC_PREREQ([2.50])
|
||||
dnl AC_CONFIG_HEADER([config.h])
|
||||
|
||||
@ -40,8 +40,8 @@ dnl
|
||||
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||
dnl
|
||||
LIBISOFS_MAJOR_VERSION=1
|
||||
LIBISOFS_MINOR_VERSION=1
|
||||
LIBISOFS_MICRO_VERSION=0
|
||||
LIBISOFS_MINOR_VERSION=2
|
||||
LIBISOFS_MICRO_VERSION=2
|
||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||
|
||||
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
||||
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
|
||||
|
||||
dnl Libtool versioning
|
||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||
# 2011.06.18 development jump has not yet happened
|
||||
# SONAME = 54 - 48 = 6 . Library name = libisofs.6.48.0
|
||||
LT_CURRENT=54
|
||||
LT_AGE=48
|
||||
# 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`
|
||||
|
||||
@ -160,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
|
||||
@ -183,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,21 +598,22 @@ 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) {
|
||||
@ -242,14 +630,14 @@ ex:;
|
||||
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,7 +259,10 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||
(*values)[i]= NULL;
|
||||
(*value_lengths)[i]= 0;
|
||||
}
|
||||
if(!(flag & 4)) {
|
||||
|
||||
#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))
|
||||
@ -229,11 +272,6 @@ 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; (size_t) i < *num_attrs; i++) {
|
||||
if(!(flag & 8))
|
||||
if(strncmp((*names)[i], "user.", 5))
|
||||
@ -291,12 +329,19 @@ 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; (size_t) i < *num_attrs; i++)
|
||||
@ -312,8 +357,6 @@ ex:;
|
||||
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)
|
||||
@ -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:;
|
||||
|
@ -95,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;
|
||||
@ -106,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;
|
||||
@ -159,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 */
|
||||
|
||||
@ -269,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)
|
||||
@ -280,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);
|
||||
@ -293,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 < -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);
|
||||
}
|
||||
@ -342,6 +351,9 @@ 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)
|
||||
@ -387,6 +399,13 @@ 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) >= name_size)
|
||||
@ -399,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;
|
||||
@ -408,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) >= 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;
|
||||
@ -440,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;
|
||||
@ -1702,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;
|
||||
@ -1791,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 */
|
||||
|
||||
@ -2124,8 +2166,9 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
}
|
||||
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);
|
||||
}
|
||||
@ -2143,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);
|
||||
|
@ -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,
|
||||
@ -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;
|
||||
}
|
||||
@ -1666,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;
|
||||
@ -1673,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;
|
||||
@ -2310,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)
|
||||
{
|
||||
@ -2326,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);
|
||||
@ -2434,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;
|
||||
@ -2470,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++)
|
||||
@ -2642,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) {
|
||||
@ -2701,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)
|
||||
{
|
||||
@ -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;
|
||||
@ -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);
|
||||
@ -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;
|
||||
@ -1160,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) {
|
||||
@ -1168,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
|
||||
|
||||
@ -345,6 +347,7 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
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
|
||||
@ -381,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
|
||||
|
@ -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 ;
|
||||
@ -520,18 +522,30 @@ int read_dir(ImageFileSourceData *data)
|
||||
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)) {
|
||||
|
||||
@ -542,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.
|
||||
@ -1930,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;
|
||||
|
||||
@ -1943,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) {
|
||||
@ -2052,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 */
|
||||
@ -2078,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);
|
||||
}
|
||||
|
||||
@ -2328,14 +2343,15 @@ ex:;
|
||||
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 = NULL;
|
||||
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) {
|
||||
goto ex;
|
||||
@ -2367,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);
|
||||
@ -2385,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;
|
||||
@ -2410,6 +2438,27 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
|
||||
}
|
||||
}
|
||||
after_bootblocks:;
|
||||
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);
|
||||
@ -2531,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;
|
||||
|
||||
@ -2802,9 +2853,10 @@ 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;
|
||||
@ -2861,9 +2913,28 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
free(name);
|
||||
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 {
|
||||
@ -3276,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;
|
||||
@ -3328,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;
|
||||
|
||||
@ -3463,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;
|
||||
@ -3572,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,13 +95,11 @@ 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;
|
||||
@ -140,13 +138,11 @@ 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;
|
||||
@ -186,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);
|
||||
@ -419,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) {
|
||||
@ -430,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);
|
||||
|
||||
/*
|
||||
@ -503,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;
|
||||
|
||||
@ -525,6 +514,9 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
||||
&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;
|
||||
}
|
||||
@ -827,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;
|
||||
@ -867,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,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2011 Thomas Schmitt
|
||||
* 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
|
||||
@ -688,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);
|
||||
|
||||
@ -719,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;
|
||||
@ -837,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) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2011 Thomas Schmitt
|
||||
* 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
|
||||
@ -758,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);
|
||||
|
||||
@ -797,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;
|
||||
|
@ -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
|
||||
@ -61,6 +61,88 @@
|
||||
|
||||
#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;
|
||||
|
||||
/**
|
||||
@ -878,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.
|
||||
*/
|
||||
@ -1013,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);
|
||||
*
|
||||
@ -1186,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 1
|
||||
#define iso_lib_header_version_micro 0
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -1535,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.
|
||||
@ -1544,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.
|
||||
@ -1575,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.
|
||||
*
|
||||
@ -1589,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
|
||||
@ -1652,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);
|
||||
@ -1782,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
|
||||
@ -2876,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.
|
||||
*
|
||||
@ -5760,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.
|
||||
*
|
||||
@ -5803,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
|
||||
@ -5892,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
|
||||
@ -6860,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:
|
||||
@ -7078,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;
|
||||
|
@ -247,9 +247,8 @@ void iso_msg_debug(int imgid, const char *fmt, ...)
|
||||
{
|
||||
char *msg = NULL;
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
LIBISO_ALLOC_MEM(msg, char, MAX_MSG_LEN);
|
||||
LIBISO_ALLOC_MEM_VOID(msg, char, MAX_MSG_LEN);
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
|
||||
va_end(ap);
|
||||
@ -465,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";
|
||||
}
|
||||
|
@ -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;
|
||||
@ -1615,6 +1624,8 @@ 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);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
for (i = 0; i < (int) num_attrs; i++) {
|
||||
if (strcmp(names[i], name))
|
||||
continue;
|
||||
@ -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;
|
||||
|
@ -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
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -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 */
|
||||
@ -1419,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)) {
|
||||
@ -1671,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);
|
||||
|
@ -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",
|
||||
@ -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",
|
||||
@ -748,6 +750,7 @@ int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
IsoStreamIface mem_stream_class = {
|
||||
4, /* version */
|
||||
"mem ",
|
||||
|
@ -683,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;
|
||||
}
|
||||
|
||||
|
223
libisofs/util.c
223
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
|
||||
@ -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,7 +435,25 @@ 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);
|
||||
@ -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,8 +593,27 @@ 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 == (size_t) -1) {
|
||||
@ -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,8 +685,37 @@ 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];
|
||||
@ -640,25 +725,35 @@ char *iso_dirid(const char *src, int 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)
|
||||
{
|
||||
@ -777,6 +900,9 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
|
||||
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
|
||||
*/
|
||||
@ -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';
|
||||
|
||||
@ -924,9 +1081,8 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
uint16_t *dot, *retval = NULL;
|
||||
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
|
||||
uint16_t *dest = NULL;
|
||||
int ret;
|
||||
|
||||
LIBISO_ALLOC_MEM(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
|
||||
|
||||
if (src == NULL) {
|
||||
@ -1004,9 +1160,8 @@ uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
|
||||
{
|
||||
size_t len, i, maxchar = 64;
|
||||
uint16_t *dest = NULL, *retval = NULL;
|
||||
int ret;
|
||||
/* was: 65 = 64 + 1 (\0) */
|
||||
LIBISO_ALLOC_MEM(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
|
||||
|
||||
if (src == NULL) {
|
||||
goto ex;
|
||||
@ -1576,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] = ' ';
|
||||
}
|
||||
|
@ -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.
|
||||
@ -547,6 +555,12 @@ void *iso_alloc_mem(size_t size, size_t count, int flag);
|
||||
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); \
|
||||
|
Reference in New Issue
Block a user