Compare commits

...

123 Commits

Author SHA1 Message Date
125789feef Version leap to 1.2.2 2012-04-02 19:00:27 +02:00
37efffcf26 Removed obsolete development comments 2012-04-02 11:36:16 +02:00
b2c281d0c6 Updated ChangeLog 2012-03-27 13:51:52 +02:00
8a2fa9fe2e New API call iso_write_opts_set_allow_7bit_ascii(). 2012-03-22 11:18:44 +01:00
1247edff95 Reacted on warnings of cppcheck. 2012-03-21 20:28:15 +01:00
a2fe1a4100 Corrected flaws of revision 926. 2012-03-14 13:50:46 +01:00
4eb4146474 Improved standards compliance for ISO level 1 names with partly relaxed
constraints.
2012-03-14 09:07:59 +01:00
ce35aefb32 Bug fix: Directory name mapping to ISO level 1 was too liberal if
iso_write_opts_set_allow_dir_id_ext() was enabled.
2012-03-13 09:38:29 +01:00
269e0b19a5 Improved the ISO level 1 mapping of file names which begin by a dot. 2012-03-13 09:20:20 +01:00
0a8bb0e9b8 Made sure that empty relocation directory name leads to root directory. 2012-03-10 11:29:03 +01:00
76f2a5f4d3 New API call iso_write_opts_set_rr_reloc() 2012-03-09 19:59:51 +01:00
e49f9672bc Disabled skipping of ECMA-119 directory /RR_MOVED by name. 2012-03-06 16:18:05 +01:00
37f880797d Small comment change in libisofs/libisofs.h 2012-03-06 15:14:45 +01:00
475eb36978 Small change in doc/iso_hybrid_fs.txt 2012-03-06 15:13:45 +01:00
ac9116c64e Fixed a typo in doc/iso_hybrid_fs.txt 2012-02-22 18:06:23 +01:00
b1c218c280 Described the opportunities and constraints of ISO 9660 hybrid fileystems,
and the libisofs implementation needs when adding further filesystem types.
2012-02-21 22:30:29 +01:00
ebea7c29ef Reporting name of base file with error message for filtered streams 2012-02-11 19:09:40 +01:00
09c49f777a Version leap to 1.2.1 2012-01-27 15:57:45 +01:00
5f76be9d76 Version leap to 1.2.0 2012-01-27 10:59:50 +01:00
305fe3f496 Updated changelog 2012-01-27 10:56:50 +01:00
191c3245af Corrected libburnia domain name in AAIP documentation 2012-01-24 14:48:42 +01:00
b5b30b1c75 Updated ChangeLog 2012-01-24 14:00:27 +01:00
6a1bbaa902 Extended influence of iso_write_opts_set_dir_rec_mtime() to Joliet and
ISO 9660:1999.
2012-01-14 15:54:25 +01:00
bddc44d1ca Added ./bootstrap script to release tarball 2011-12-03 15:58:38 +01:00
9b61ff377c Removing demo/.libs with make clean 2011-12-03 15:43:18 +01:00
22fed6bedb Reacted on warning of cppcheck 2011-10-09 18:26:13 +02:00
3433592f69 Version leap to 1.1.7 2011-09-27 14:33:07 +02:00
d787ecbcd9 Version leap to 1.1.6 2011-09-27 14:29:18 +02:00
182edb3a00 Updated changelog 2011-09-26 19:10:13 +02:00
cb25d4d4e5 Clarified a remark about maximum length of RR name parts in CA. 2011-09-26 18:23:24 +02:00
afdef92343 Moved version number macros higher in libisofs/libisofs.h 2011-09-24 16:38:20 +02:00
2bc7084315 Adaptions and remarks about GNU/Hurd 2011-08-30 19:20:18 +02:00
6d10908a58 Detecting and rejecting multiple entries of user::, group::, other:: in ACL text 2011-08-24 09:23:02 +02:00
2ba54fafe7 New optional tolerance towards failure to restore "default" ACLS on FreeBSD. 2011-08-23 12:40:09 +02:00
ca63dac7e3 Enabled recording and restoring of extattr on FreeBSD.
Gave up unconditional ACL support in favor of configure control.
2011-08-22 17:10:13 +02:00
f885da8087 Avoided to restore xattr of namespace "isofs" if non-"user" restoring is
enabled.
2011-08-22 15:57:16 +02:00
8438db02cf Avoided to call calloc() for 0 bytes when reading Linux xattr. 2011-08-22 12:37:11 +02:00
ce19db5e19 Bug fix: On Solaris: False out-of-memory errors when writing images. 2011-08-19 12:40:45 +02:00
aeb5258ae2 Removed rogue comma from FreeBSD ACL adapter 2011-08-18 16:06:33 +02:00
f10c2d7779 New API call iso_local_attr_support() 2011-08-18 15:07:31 +02:00
82bfcf429a Bug fix: No ACLs were recorded on FreeBSD. 2011-08-18 10:29:34 +02:00
8fb8c01a0f Corrected a theoretical flaw in a code path which is not yet used. 2011-08-18 10:28:41 +02:00
73910e2f3c Bug fix: ACL entries of groups and of user id 0 were not properly recorded
and cannot be restored.
2011-08-18 10:26:09 +02:00
9c5fc21679 Small change in a comment 2011-08-18 10:24:47 +02:00
3a82f213e0 Implemented direct iconv conversion for the case that the traditional
two-step conversion via character set "WCHAR_T" fails. E.g. on Solaris.
2011-08-11 18:22:49 +02:00
6892c734e2 Bug fix: The function for restoring ACLs and xattr returned error on
FreeBSD, even if no xattr were to be restored.
2011-08-09 19:00:03 +02:00
66f6937c17 Clarified stream version prescription and made internal stream data
instances static.
2011-08-09 14:59:19 +02:00
baa5b7cd42 Added missing symbol serial_id to libisofs.ver 2011-08-09 14:58:46 +02:00
f2658ef173 Started new development cycle 2011-08-09 12:32:04 +02:00
ecdb3aeb1d Version leap to 1.1.5 2011-08-08 13:58:43 +02:00
745a878884 Version leap to 1.1.4 2011-08-08 09:35:46 +02:00
6ae8386c23 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.
2011-08-08 08:25:18 +02:00
b90e613246 Reacted on warnings of cppcheck 2011-07-11 12:44:12 +02:00
bbc3caf86b Reacted on warnings of cppcheck 2011-07-11 12:43:12 +02:00
b086d53274 Reacted on warnings of cppcheck 2011-07-11 12:41:30 +02:00
17b36623a6 Version leap to 1.1.3 2011-07-08 14:42:09 +02:00
286648574d Version leap to 1.1.2 2011-07-08 10:28:12 +02:00
317bba395e Updated changelog 2011-07-08 10:25:24 +02:00
541b41b6a1 Clarified a comment about retrieving content of boot catalog. 2011-07-07 14:11:30 +02:00
91a8be5262 Silenced a warning of cppcheck about possible null pointer dereference. 2011-07-06 12:31:37 +02:00
91e99703b4 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 18:54:11 +02:00
dd7dac3397 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:07:35 +02:00
43d4833dd6 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:06:16 +02:00
dd1629b5ca Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:04:05 +02:00
bc8138ce78 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:00:29 +02:00
2d568c1dbb Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:56:26 +02:00
842b62d111 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:50:52 +02:00
4f3357e3ec Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:39:38 +02:00
9ffe91c372 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:37:55 +02:00
7e2add413a Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:35:43 +02:00
004aefd0b7 New API call iso_image_get_bootcat() 2011-07-03 21:02:19 +02:00
00955ba85c Version leap to 1.1.1 2011-06-18 19:22:11 +02:00
4a79812d15 Version leap to 1.1.0 2011-06-18 14:23:02 +02:00
9b2f97e4b7 Updated changelog 2011-06-18 14:06:38 +02:00
35cfb756be Bug fix: Padding as of iso_write_opts_set_tail_blocks() was added only
after cylinder alignment as of iso_write_opts_set_system_area()
         and thus spoiled this alignment.
2011-06-15 17:09:48 +02:00
2835fccfa4 Replaced some large local variables by other means in libisofs/util.c 2011-06-12 12:46:52 +02:00
31c7f68990 Replaced some large local variables by other means in libisofs/system_area.c 2011-06-12 12:28:38 +02:00
4e0ca258de Replaced some large local variables by other means in libisofs/stream.c 2011-06-12 09:59:53 +02:00
9653854462 Replaced some large local variables by other means in libisofs/rockridge.c 2011-06-12 09:51:08 +02:00
6e95f8bbcb Replaced some large local variables by other means in libisofs/messages.c 2011-06-11 22:23:44 +02:00
ce3aa0d5c7 Replaced some large local variables by other means in libisofs/md5.c 2011-06-11 19:23:32 +02:00
d5bfc552c4 Replaced some large local variables by other means in libisofs/joliet.c 2011-06-11 16:33:57 +02:00
bad54a5967 Replaced some large local variables by other means in libisofs/iso1999.c 2011-06-11 13:42:55 +02:00
49b0a89bfe Replaced some large local variables by other means in libisofs/fs_image.c 2011-06-11 12:40:33 +02:00
265df5fbe3 Replaced some large local variables by other means in libisofs/filesrc.c 2011-06-11 11:08:20 +02:00
f089bcf66a Replaced some large local variables by other means in libisofs/ecma119.c 2011-06-10 14:55:57 +02:00
062e5f0bf0 Changed error code of libisofs/util.h from -1 to ISO_OUT_OF_MEM 2011-06-10 14:55:34 +02:00
d932bfcdea Replaced some large local variables by other means in libisofs/builder.c 2011-06-09 16:51:00 +02:00
3ef67cb49d Replaced some large local variables by other means in libisofs/aaip_0_2.c 2011-06-09 14:27:41 +02:00
f08ae22dbe Macros LIBISO_ALLOC_MEM, LIBISO_FREE_MEM for replaceing local variables 2011-06-09 14:23:21 +02:00
45d316d1ca Added option -I . to aclocal in bootstrap script on advise of George Danchev 2011-06-09 14:21:20 +02:00
4d8fc6ffee Introduced AC_CONFIG_MACRO_DIR() and ACLOCAL_AMFLAGS on advise of George Danchev 2011-06-08 21:27:53 +02:00
023e413624 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for
libisofs/aaip-os-freebsd.c
2011-06-02 10:28:52 +02:00
d361186bca Made callers of iso_file_source_get_path() aware that NULL might be returned. 2011-06-01 11:37:30 +02:00
e7d9559d16 Avoiding to produce NM field for "." and ".." entries if Rock Ridge
version 1.10 is chosen by iso_write_opts_set_rrip_version_1_10()
2011-06-01 11:34:45 +02:00
94eecbb123 Reacted on static code checker warning reported by George Danchev 2011-05-22 20:23:48 +02:00
777f74ea0b Added options -Wextra -Wno-unused-parameter for gcc 2011-05-22 16:35:22 +02:00
2b8d47ddd8 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for util_rbtree.c 2011-05-21 23:21:14 +02:00
e839b7b368 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for util.c 2011-05-21 23:20:44 +02:00
1334027a83 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for tree.c 2011-05-21 23:19:34 +02:00
8d3a0a6a9e Reacted on -Wextra -Wno-unused-parameter warnings of gcc for system_area.c 2011-05-21 23:19:06 +02:00
7b7ea41f12 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for stream.c 2011-05-21 23:18:35 +02:00
bb5886094e Reacted on -Wextra -Wno-unused-parameter warnings of gcc for rockridge_read.c 2011-05-21 23:18:00 +02:00
b076ce9b44 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for rockridge.c 2011-05-21 23:17:38 +02:00
05f26898f3 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for node.c 2011-05-21 23:16:35 +02:00
a698f0ee22 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for messages.c 2011-05-21 23:16:10 +02:00
e69854b35f Reacted on -Wextra -Wno-unused-parameter warnings of gcc for md5.c 2011-05-21 23:15:48 +02:00
228995c148 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for make_isohybrid_mbr.c 2011-05-21 23:15:19 +02:00
071e14f9b0 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for joliet.c 2011-05-21 23:14:49 +02:00
b08d6271ab Reacted on -Wextra -Wno-unused-parameter warnings of gcc for iso1999.c 2011-05-21 23:14:16 +02:00
431d31fff6 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for fs_local.c 2011-05-21 23:13:40 +02:00
a37571c6c5 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for fs_image.c 2011-05-21 23:13:16 +02:00
6e98006640 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for filters/zisofs.c 2011-05-21 23:12:29 +02:00
d264e818c3 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for filters/gzip.c 2011-05-21 23:11:48 +02:00
d0f740facf Reacted on -Wextra -Wno-unused-parameter warnings of gcc for eltorito.c 2011-05-21 23:11:18 +02:00
944b5a6152 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for ecma119_tree.c 2011-05-21 23:10:21 +02:00
b51232fef4 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for ecma119.c 2011-05-21 23:09:44 +02:00
99f037e210 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for buffer.c 2011-05-21 23:08:53 +02:00
c794a48a06 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for aaip_0_2.c 2011-05-21 23:08:14 +02:00
47d599e8c3 Reacted on -Wextra -Wno-unused-parameter warnings of gcc for aaip-os-linux.c 2011-05-21 23:05:17 +02:00
0a87e838df Mentioned the need to define uint32_t when including libisofs.h 2011-05-19 15:43:44 +02:00
e945e38add Mentioned upcomming version in ChangeLog 2011-05-13 09:01:01 +02:00
6d68abc707 Version leap to 1.0.9 2011-05-12 18:59:38 +02:00
41 changed files with 2785 additions and 757 deletions

View File

@ -1,3 +1,44 @@
bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.2.2.tar.gz)
===============================================================================
* New API call iso_write_opts_set_rr_reloc()
* Bug fix: Directory name mapping to ISO level 1 was too liberal if
iso_write_opts_set_allow_dir_id_ext() was enabled
* New API call iso_write_opts_set_allow_7bit_ascii()
* Improved standards compliance for ISO level 1 names with partly relaxed
constraints.
libisofs-1.2.0.tar.gz Sat Jan 28 2012
===============================================================================
* Extended influence of iso_write_opts_set_dir_rec_mtime() to Joliet and
ISO 9660:1999.
libisofs-1.1.6.tar.gz Tue Sep 27 2011
===============================================================================
* Bug fix: On Solaris: False out-of-memory errors when writing images.
* Bug fix: On FreeBSD: No ACLs were recorded.
* Bug fix: ACL entries of groups and of user id 0 were not properly recorded
and cannot be restored.
* Bug fix: On FreeBSD: The function for restoring ACLs and xattr returned
error, even if no xattr were to be restored.
* New API call iso_local_attr_support()
* Enabled recording and restoring of extattr on FreeBSD.
libisofs-1.1.4.tar.gz Mon Aug 08 2011
===============================================================================
* Bug fix: The function for restoring ACLs and xattr returned error on systems
other than Linux and FreeBSD, even if nothing was to be restored.
libisofs-1.1.2.tar.gz Fri Jul 08 2011
===============================================================================
* New API call iso_image_get_bootcat()
libisofs-1.1.0.tar.gz Sat Jun 18 2011
===============================================================================
* Bug fix: Padding as of iso_write_opts_set_tail_blocks() was added only
after cylinder alignment as of iso_write_opts_set_system_area()
and thus spoiled this alignment.
libisofs-1.0.8.tar.gz Thu May 12 2011
===============================================================================
* Bug fix: iso_write_opts_set_system_area() with system area types

View File

@ -6,6 +6,7 @@ pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
libincludedir=$(includedir)/libisofs
lib_LTLIBRARIES = libisofs/libisofs.la
ACLOCAL_AMFLAGS = -I ./
## ========================================================================= ##
@ -219,6 +220,12 @@ demo_demo_SOURCES = demo/demo.c
# test/mocked_fsrc.h \
# test/mocked_fsrc.c
# "make clean" shall remove a few stubborn .libs directories
# which George Danchev reported Dec 03 2011.
# Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean
clean-local:
-rm -rf demo/.libs
## ========================================================================= ##
## Build documentation (You need Doxygen for this to work)
@ -249,6 +256,7 @@ nodist_pkgconfig_DATA = \
# ts A80114 : added aaip-os*
EXTRA_DIST = \
bootstrap \
libisofs-1.pc.in \
version.h.in \
doc/doxygen.conf.in \

View File

@ -1,10 +1,7 @@
#!/bin/sh -x
aclocal
aclocal -I .
libtoolize --copy --force
autoconf
# ts A61101 : libburn is not prepared for config.h
# autoheader
automake --foreign --add-missing --copy --include-deps

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.0.8], [http://libburnia-project.org])
AC_INIT([libisofs], [1.2.2], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -8,6 +8,7 @@ AC_CANONICAL_TARGET
LIBBURNIA_SET_FLAGS
AM_INIT_AUTOMAKE([subdir-objects])
AC_CONFIG_MACRO_DIR([./])
dnl
dnl if MAJOR or MINOR version changes, be sure to change AC_INIT above to match
@ -39,8 +40,8 @@ dnl
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=0
LIBISOFS_MICRO_VERSION=8
LIBISOFS_MINOR_VERSION=2
LIBISOFS_MICRO_VERSION=2
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -50,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2011.05.12 development jump has not yet happened
# SONAME = 52 - 46 = 6 . Library name = libisofs.6.46.0
LT_CURRENT=52
LT_AGE=46
# 2012.01.28 development jump has not yet happened
# SONAME = 64 - 58 = 6 . Library name = libisofs.6.58.0
LT_CURRENT=64
LT_AGE=58
LT_REVISION=0
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
@ -139,7 +140,7 @@ if test x$enable_debug != xyes; then
CFLAGS="-DNDEBUG $CFLAGS"
else
if test x$GCC = xyes; then
CFLAGS="-g -pedantic -Wall $CFLAGS"
CFLAGS="-g -pedantic -Wall -Wextra -Wno-unused-parameter $CFLAGS"
fi
CFLAGS="-DDEBUG $CFLAGS"
fi
@ -159,14 +160,19 @@ LIBBURNIA_SET_PKGCONFIG
dnl Add compiler-specific flags
AC_ARG_ENABLE(libacl,
[ --enable-libacl Enable use of libacl by libisofs, default=yes],
[ --enable-libacl Enable use of ACL functions by libisofs, default=yes],
, enable_libacl=yes)
if test "x$enable_libacl" = xyes; then
dnl Check whether there is libacl-devel and libacl-runtime.
dnl If not, erase this macro which would enable use of acl_to_text and others
LIBACL_DEF="-DLibisofs_with_aaip_acL"
dnl The empty yes case obviously causes -lacl to be linked
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , LIBACL_DEF= ), LIBACL_DEF= )
has_acl_h_but_no_func=0
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , has_acl_h_but_no_libacl=1 ), LIBACL_DEF= )
if test "$has_acl_h_but_no_libacl" = 1
then
AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= )
fi
else
LIBACL_DEF=
fi
@ -182,6 +188,11 @@ dnl Check whether there is the header for Linux xattr.
dnl If not, erase this macro which would enable use of listxattr and others
XATTR_DEF="-DLibisofs_with_aaip_xattR"
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= , XATTR_DEF= ), XATTR_DEF= )
if test "x$XATTR_DEF" = x
then
XATTR_DEF="-DLibisofs_with_freebsd_extattR"
AC_CHECK_HEADER(sys/extattr.h, AC_CHECK_LIB(c, extattr_list_file, X=, XATTR_DEF= ), XATTR_DEF= )
fi
else
XATTR_DEF=
fi

159
doc/iso_hybrid_fs.txt Normal file
View 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.

View File

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

View File

@ -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,8 +112,12 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
continue;
}
/* Extended Attribute */
if(!(flag & 4))
return(-6);
if(flag & 4)
continue;
if(!(flag & 8))
if(strncmp(names[i], "user.", 5))
continue;
return(-6);
}
if(flag & 2)
return(-6);

View File

@ -7,7 +7,7 @@
To be included by aaip_0_2.c
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
*/
@ -24,15 +24,51 @@
#include <sys/stat.h>
#include <errno.h>
#ifndef Libisofs_with_aaip_acL
/* It seems ACL is fixely integrated in FreeBSD libc. There is no libacl. */
#define Libisofs_with_aaip_acL yes
#endif
#ifdef Libisofs_with_aaip_acL
#include <sys/acl.h>
#endif
#ifdef Libisofs_with_freebsd_extattR
#include <sys/extattr.h>
#endif
/* <<< Use old ACL adapter code that is unable to deal with extattr */
/* # define Libisofs_old_freebsd_acl_adapteR */
/* ------------------------------ Inquiry --------------------------------- */
/* See also API iso_local_attr_support().
@param flag
Bitfield for control purposes
bit0= inquire availability of ACL
bit1= inquire availability of xattr
bit2 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag. If bits are set, th
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these
*/
int aaip_local_attr_support(int flag)
{
int ret= 0;
#ifdef Libisofs_with_aaip_acL
if(flag & 1)
ret|= 1;
#endif
#ifdef Libisofs_with_freebsd_extattR
if(flag & 2)
ret|= 2;
#endif
return(ret);
}
/* ------------------------------ Getters --------------------------------- */
@ -137,6 +173,349 @@ int aaip_get_acl_text(char *path, char **text, int flag)
}
#ifndef Libisofs_old_freebsd_acl_adapteR
#ifdef Libisofs_with_freebsd_extattR
/*
@param flag Bitfield for control purposes
bit5= in case of symbolic link: inquire link target
*/
static int aaip_extattr_make_list(char *path, int attrnamespace,
char **list, ssize_t *list_size, int flag)
{
*list= NULL;
*list_size= 0;
/* man 2 extattr_list_file:
If data is NULL in a call to extattr_get_file() and extattr_list_file()
then the size of defined extended attribute data will be returned,
*/
if(flag & 32) /* follow link */
*list_size= extattr_list_file(path, attrnamespace, NULL, (size_t) 0);
else
*list_size= extattr_list_link(path, attrnamespace, NULL, (size_t) 0);
if(*list_size == -1)
return(0);
if(*list_size == 0)
return(2);
*list= calloc(*list_size, 1);
if(*list == NULL)
return(-1);
if(flag & 32)
*list_size= extattr_list_file(path, attrnamespace, *list,
(size_t) *list_size);
else
*list_size= extattr_list_link(path, attrnamespace, *list,
(size_t) *list_size);
if(*list_size == -1)
return(0);
return(1);
}
/*
@param flag Bitfield for control purposes
bit0= preserve existing namelist content
bit1= ignore names with NUL rather than returning error
*/
static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
char *list, ssize_t list_size,
char **namelist, ssize_t *namelist_size,
ssize_t *num_names, int flag)
{
int i, j, len, new_bytes= 0, space_len;
char *new_list= NULL, *wpt;
if(!(flag & 1)) {
*namelist= NULL;
*namelist_size= 0;
*num_names= 0;
}
if(list_size <= 0)
return(1);
space_len= strlen(attrnamespace);
for(i= 0; i < list_size; i+= len + 1) {
len= *((unsigned char *) (list + i));
if(len == 0)
return ISO_AAIP_BAD_ATTR_NAME; /* empty name is reserved for ACL */
for(j= 0; j < len; j++)
if(list[i + 1 + j] == 0) {
if(flag & 2)
continue;
return ISO_AAIP_BAD_ATTR_NAME; /* names may not contain 0-bytes */
}
new_bytes+= space_len + 1 + len + 1;
}
if((flag & 1) && *namelist_size > 0)
new_bytes+= *namelist_size;
new_list= calloc(new_bytes, 1);
if(new_list == NULL)
return(ISO_OUT_OF_MEM);
wpt= new_list;
if((flag & 1) && *namelist_size > 0) {
memcpy(new_list, *namelist, *namelist_size);
wpt= new_list + *namelist_size;
}
for(i= 0; i < list_size; i+= len + 1) {
len= *((unsigned char *) (list + i));
if(flag & 2) {
for(j= 0; j < len; j++)
if(list[i + j] == 0)
continue;
}
memcpy(wpt, attrnamespace, space_len);
wpt[space_len]= '.';
wpt+= space_len + 1;
memcpy(wpt, list + i + 1, len);
wpt+= len;
*(wpt++)= 0;
(*num_names)++;
}
if((flag & 1) && *namelist != NULL)
free(*namelist);
*namelist= new_list;
*namelist_size= new_bytes;
return(1);
}
#endif /* Libisofs_with_freebsd_extattR */
/* Obtain the Extended Attributes and/or the ACLs of the given file in a form
that is ready for aaip_encode().
@param path Path to the file
@param num_attrs Will return the number of name-value pairs
@param names Will return an array of pointers to 0-terminated names
@param value_lengths Will return an arry with the lenghts of values
@param values Will return an array of pointers to 8-bit values
@param flag Bitfield for control purposes
bit0= obtain ACL (access and eventually default)
bit1= use numeric ACL qualifiers rather than names
bit2= do not obtain attributes other than ACL
bit3= do not ignore eventual non-user attributes
I.e. those with a name which does not begin
by "user."
bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target
bit15= free memory of names, value_lengths, values
@return >0 ok
<=0 error
-1= out of memory
-2= program error with prediction of result size
-3= error with conversion of name to uid or gid
*/
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag)
{
int ret;
ssize_t i, num_names= 0, acl_names= 0;
#ifdef Libisofs_with_aaip_acL
unsigned char *a_acl= NULL;
char *a_acl_text= NULL;
size_t a_acl_len= 0;
#endif
#ifdef Libisofs_with_freebsd_extattR
char *list= NULL, *user_list= NULL, *sys_list= NULL, *namept;
ssize_t value_ret, retry= 0, list_size= 0, user_list_size= 0;
ssize_t sys_list_size= 0;
int attrnamespace;
#endif
if(flag & (1 << 15)) { /* Free memory */
{ret= 1; goto ex;}
}
*num_attrs= 0;
*names= NULL;
*value_lengths= NULL;
*values= NULL;
/* Set up arrays */
#ifdef Libisofs_with_freebsd_extattR
if(!(flag & 4)) { /* Get extattr names */
/* Linux : Names are encoded as name NUL
FreeBSD: Names are encoded as length_byte:chars (no NUL)
AAIP demands names not to contain NUL bytes.
*/
/* Obtain lists of names
Must be done separately for namespaces. See man 9 extattr :
EXTATTR_NAMESPACE_USER , EXTATTR_NAMESPACE_SYSTEM
Must then be marked by "user." and "system." for libisofs use.
*/
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_USER,
&user_list, &user_list_size, flag & 32);
if(ret <= 0)
{ret= -1; goto ex;}
if(flag & 8) {
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_SYSTEM,
&sys_list, &sys_list_size, flag & 32);
if(ret <= 0)
{ret= -1; goto ex;}
}
/* Check for NUL in names, convert into a linuxish list of namespace.name */
ret= aaip_extattr_make_namelist(path, "user", user_list, user_list_size,
&list, &list_size, &num_names, 0);
if(ret <= 0)
goto ex;
ret= aaip_extattr_make_namelist(path, "system", sys_list, sys_list_size,
&list, &list_size, &num_names, 1);
if(ret <= 0)
goto ex;
}
#endif /* Libisofs_with_freebsd_extattR */
#ifdef Libisofs_with_aaip_acL
if(flag & 1) {
num_names++;
acl_names= 1;
}
#endif
if(num_names == 0)
{ret= 1; goto ex;}
(*names)= calloc(num_names, sizeof(char *));
(*value_lengths)= calloc(num_names, sizeof(size_t));
(*values)= calloc(num_names, sizeof(char *));
if(*names == NULL || *value_lengths == NULL || *values == NULL)
{ret= -1; goto ex;}
for(i= 0; i < num_names; i++) {
(*names)[i]= NULL;
(*values)[i]= NULL;
(*value_lengths)[i]= 0;
}
#ifdef Libisofs_with_freebsd_extattR
if(!(flag & 4)) { /* Get xattr values */
for(i= 0; i < list_size && (size_t) num_names - acl_names > *num_attrs;
i+= strlen(list + i) + 1) {
if(!(flag & 8))
if(strncmp(list + i, "user.", 5))
continue;
(*names)[(*num_attrs)++]= strdup(list + i);
if((*names)[(*num_attrs) - 1] == NULL)
{ret= -1; goto ex;}
}
for(i= 0; (size_t) i < *num_attrs; i++) {
if(strncmp((*names)[i], "user.", 5) == 0) {
attrnamespace= EXTATTR_NAMESPACE_USER;
namept= (*names)[i] + 5;
} else {
if(!(flag & 8))
continue;
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
namept= (*names)[i] + 7;
}
/* Predict length of value */
if(flag & 32) /* follow link */
value_ret= extattr_get_file(path, attrnamespace, namept,
NULL, (size_t) 0);
else
value_ret= extattr_get_link(path, attrnamespace, namept,
NULL, (size_t) 0);
if(value_ret == -1)
continue;
(*values)[i]= calloc(value_ret + 1, 1);
if((*values)[i] == NULL)
{ret= -1; goto ex;}
/* Obtain value */
if(flag & 32) /* follow link */
value_ret= extattr_get_file(path, attrnamespace, namept,
(*values)[i], (size_t) value_ret);
else
value_ret= extattr_get_link(path, attrnamespace, namept,
(*values)[i], (size_t) value_ret);
if(value_ret == -1) { /* there could be a race condition */
if(retry++ > 5)
{ret= -1; goto ex;}
i--;
continue;
}
(*value_lengths)[i]= value_ret;
retry= 0;
}
}
#endif /* Libisofs_with_freebsd_extattR */
#ifdef Libisofs_with_aaip_acL
if(flag & 1) { /* Obtain ACL */
/* access-ACL */
aaip_get_acl_text(path, &a_acl_text, flag & (16 | 32));
if(a_acl_text == NULL)
{ret= 1; goto ex;} /* empty ACL / only st_mode info was found in ACL */
ret= aaip_encode_acl(a_acl_text, (mode_t) 0, &a_acl_len, &a_acl, flag & 2);
if(ret <= 0)
goto ex;
/* Note: There are no default-ACL in FreeBSD */
/* Set as attribute with empty name */;
(*names)[*num_attrs]= strdup("");
if((*names)[*num_attrs] == NULL)
{ret= -1; goto ex;}
(*values)[*num_attrs]= (char *) a_acl;
a_acl= NULL;
(*value_lengths)[*num_attrs]= a_acl_len;
(*num_attrs)++;
}
#endif /* Libisofs_with_aaip_acL */
ret= 1;
ex:;
#ifdef Libisofs_with_aaip_acL
if(a_acl != NULL)
free(a_acl);
if(a_acl_text != NULL)
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
#endif
#ifdef Libisofs_with_freebsd_extattR
if(list != NULL)
free(list);
if(user_list != NULL)
free(user_list);
if(sys_list != NULL)
free(sys_list);
#endif
if(ret <= 0 || (flag & (1 << 15))) {
if(*names != NULL) {
for(i= 0; (size_t) i < *num_attrs; i++)
free((*names)[i]);
free(*names);
}
*names= NULL;
if(*value_lengths != NULL)
free(*value_lengths);
*value_lengths= NULL;
if(*values != NULL) {
for(i= 0; (size_t) i < *num_attrs; i++)
free((*values)[i]);
free(*values);
}
*values= NULL;
*num_attrs= 0;
}
return(ret);
}
#else /* ! Libisofs_old_freebsd_acl_adapteR */
/* Obtain the Extended Attributes and/or the ACLs of the given file in a form
that is ready for aaip_encode().
@ -152,20 +531,28 @@ int aaip_get_acl_text(char *path, char **text, int flag)
bit0= obtain ACL (access and eventually default)
bit1= use numeric ACL qualifiers rather than names
bit2= do not encode attributes other than ACL
bit3= -reserved-
bit3= do not ignore eventual non-user attributes
I.e. those which are not from name space
EXTATTR_NAMESPACE_USER
bit4= do not return trivial ACL that matches st_mode
bit15= free memory of names, value_lengths, values
@return >0 ok
<=0 error
-1= out of memory
-2= program error with prediction of result size
-3= error with conversion of name to uid or gid
*/
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag)
{
int ret;
ssize_t i, num_names;
size_t a_acl_len= 0, acl_len= 0;
unsigned char *a_acl= NULL, *d_acl= NULL, *acl= NULL;
#ifdef Libisofs_with_aaip_acL
size_t a_acl_len= 0;
unsigned char *a_acl= NULL;
char *acl_text= NULL;
#endif
if(flag & (1 << 15)) { /* Free memory */
{ret= 1; goto ex;}
@ -211,25 +598,26 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
(*names)[*num_attrs]= strdup("");
if((*names)[*num_attrs] == NULL)
{ret= -1; goto ex;}
(*values)[*num_attrs]= (char *) acl;
(*value_lengths)[*num_attrs]= acl_len;
(*values)[*num_attrs]= (char *) a_acl;
a_acl= NULL;
(*value_lengths)[*num_attrs]= a_acl_len;
(*num_attrs)++;
}
#endif /* Libisofs_with_aaip_acL */
#endif /* ! Libisofs_with_aaip_acL */
ret= 1;
ex:;
#ifdef Libisofs_with_aaip_acL
if(a_acl != NULL)
free(a_acl);
if(d_acl != NULL)
free(d_acl);
if(acl_text != NULL)
aaip_get_acl_text("", &acl_text, 1 << 15); /* free */
#endif /* Libisofs_with_aaip_acL */
if(ret <= 0 || (flag & (1 << 15))) {
if(*names != NULL) {
for(i= 0; i < *num_attrs; i++)
for(i= 0; i < (ssize_t) *num_attrs; i++)
free((*names)[i]);
free(*names);
}
@ -238,18 +626,18 @@ ex:;
free(*value_lengths);
*value_lengths= NULL;
if(*values != NULL) {
for(i= 0; i < *num_attrs; i++)
for(i= 0; i < (ssize_t) *num_attrs; i++)
free((*values)[i]);
free(*values);
}
if(acl != NULL)
free(acl);
*values= NULL;
*num_attrs= 0;
}
return(ret);
}
#endif /* Libisofs_old_freebsd_acl_adapteR */
/* ------------------------------ Setters --------------------------------- */
@ -259,9 +647,14 @@ ex:;
@param text The input text (0 terminated, ACL long text form)
@param flag Bitfield for control purposes
bit0= set default ACL rather than access ACL
bit5= in case of symbolic link: manipulate link target
bit6= tolerate inappropriate presence or absence of
directory default ACL
@return > 0 ok
0 no suitable ACL manipulation adapter available
-1 failure of system ACL service (see errno)
-2 ACL support not enabled at compile time
-2 attempt to manipulate ACL of a symbolic link
without bit5 resp. with no suitable link target
*/
int aaip_set_acl_text(char *path, char *text, int flag)
{
@ -302,13 +695,200 @@ ex:
#else /* Libisofs_with_aaip_acL */
return(-2);
return(0);
#endif /* ! Libisofs_with_aaip_acL */
}
#ifndef Libisofs_old_freebsd_acl_adapteR
#ifdef Libisofs_with_freebsd_extattR
/*
@param flag Bitfield for control purposes
bit5= in case of symbolic link: manipulate link target
*/
static int aaip_extattr_delete_names(char *path, int attrnamespace,
char *list, ssize_t list_size, int flag)
{
int len;
char name[256];
ssize_t value_ret, i;
for(i= 0; i < list_size; i+= len + 1) {
len= *((unsigned char *) (list + i));
if(len > 0)
strncpy(name, list + i + 1, len);
name[len]= 0;
if(flag & 32)
value_ret= extattr_delete_file(path, attrnamespace, name);
else
value_ret= extattr_delete_file(path, attrnamespace, name);
if(value_ret == -1)
return(0);
}
return(1);
}
#endif /* Libisofs_with_freebsd_extattR */
/* Bring the given attributes and/or ACLs into effect with the given file.
@param flag Bitfield for control purposes
bit0= decode and set ACLs
bit1= first clear all existing attributes of the file
bit2= do not set attributes other than ACLs
bit3= do not ignore eventual non-user attributes.
I.e. those with a name which does not begin
by "user."
bit5= in case of symbolic link: manipulate link target
bit6= tolerate inappropriate presence or absence of
directory default ACL
@return 1 success
-1 error memory allocation
-2 error with decoding of ACL
-3 error with setting ACL
-4 error with setting attribute
-5 error with deleting attributes
-6 support of xattr not enabled at compile time
-7 support of ACL not enabled at compile time
-8 unsupported xattr namespace
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
{
int ret, has_default_acl= 0;
size_t i, consumed, acl_text_fill, acl_idx= 0;
char *acl_text= NULL;
#ifdef Libisofs_with_freebsd_extattR
char *user_list= NULL, *sys_list= NULL, *namept;
ssize_t user_list_size= 0, sys_list_size= 0;
int attrnamespace;
#endif
#ifdef Libisofs_with_freebsd_extattR
if(flag & 2) { /* Delete all file attributes */
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_USER,
&user_list, &user_list_size, flag & 32);
if(ret <= 0)
{ret= -1; goto ex;}
ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_USER,
user_list, user_list_size, flag & 32);
if(ret <= 0)
{ret= -5; goto ex;}
if(flag & 8) {
ret= aaip_extattr_make_list(path, EXTATTR_NAMESPACE_SYSTEM,
&sys_list, &sys_list_size, flag & 32);
if(ret <= 0)
{ret= -5; goto ex;}
ret= aaip_extattr_delete_names(path, EXTATTR_NAMESPACE_SYSTEM,
sys_list, sys_list_size, flag & 32);
if(ret <= 0)
{ret= -5; goto ex;}
}
}
#endif /* Libisofs_with_freebsd_extattR */
for(i= 0; i < num_attrs; i++) {
if(names[i] == NULL || values[i] == NULL)
continue;
if(names[i][0] == 0) { /* ACLs */
if(flag & 1)
acl_idx= i + 1;
continue;
}
/* Extended Attribute */
if(flag & 4)
continue;
#ifdef Libisofs_with_freebsd_extattR
if(strncmp(names[i], "user.", 5) == 0) {
attrnamespace= EXTATTR_NAMESPACE_USER;
namept= names[i] + 5;
} else if(strncmp(names[i], "isofs.", 6) == 0 || !(flag & 8)) {
continue;
} else if(strncmp(names[i], "system.", 7) == 0) {
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
namept= names[i] + 7;
} else {
{ret= -8; goto ex;}
}
if(flag & 32)
ret= extattr_set_file(path, attrnamespace, namept,
values[i], value_lengths[i]);
else
ret= extattr_set_link(path, attrnamespace, namept,
values[i], value_lengths[i]);
if(ret == -1)
{ret= -4; goto ex;}
#else
if(strncmp(names[i], "user.", 5) == 0)
;
else if(strncmp(names[i], "isofs.", 6) == 0 || !(flag & 8))
continue;
{ret= -6; goto ex;}
#endif /* Libisofs_with_freebsd_extattR */
}
/* Decode ACLs */
if(acl_idx == 0)
{ret= 1; goto ex;}
i= acl_idx - 1;
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
&consumed, NULL, 0, &acl_text_fill, 1);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
acl_text= calloc(acl_text_fill, 1);
if(acl_text == NULL)
{ret= -1; goto ex;}
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
&consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
has_default_acl= (ret == 2);
#ifdef Libisofs_with_aaip_acL
ret= aaip_set_acl_text(path, acl_text, flag & (32 | 64));
if(ret <= 0)
{ret= -3; goto ex;}
#else
{ret= -7; goto ex;}
#endif
if(has_default_acl && !(flag & 64))
{ret= -3; goto ex;}
ret= 1;
ex:;
if(acl_text != NULL)
free(acl_text);
#ifdef Libisofs_with_freebsd_extattR
if(user_list != NULL)
free(user_list);
if(sys_list != NULL)
free(sys_list);
#endif /* Libisofs_with_freebsd_extattR */
return(ret);
}
#else /* ! Libisofs_old_freebsd_acl_adapteR */
/* Bring the given attributes and/or ACLs into effect with the given file.
Note: There are no Extended Attributes in FreeBSD. So only ACL get set.
@ -317,6 +897,9 @@ ex:
bit0= decode and set ACLs
( bit1= first clear all existing attributes of the file )
( bit2= do not set attributes other than ACLs )
( bit3= do not ignore eventual non-user attributes.
I.e. those with a name which does not begin
by "user." )
@return 1 success
-1 error memory allocation
-2 error with decoding of ACL
@ -338,6 +921,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
continue;
if(names[i][0] == 0) { /* Decode ACLs */
/* access ACL */
if(!(flag & 1))
continue;
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
&consumed, NULL, 0, &acl_text_fill, 1);
if(ret <= 0)
@ -379,8 +964,14 @@ 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)
@ -393,4 +984,5 @@ ex:;
return(ret);
}
#endif /* Libisofs_old_freebsd_acl_adapteR */

View File

@ -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,39 +208,42 @@ 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)
{ret= -1; goto ex;}
list= calloc(list_size, 1);
if(list == NULL)
{ret= -1; goto ex;}
if(flag & 32)
list_size= listxattr(path, list, list_size);
else
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 */
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;}
if(flag & 32)
list_size= listxattr(path, list, list_size);
else
list_size= llistxattr(path, list, list_size);
if(list_size == -1)
{ret= -1; goto ex;}
}
for(i= 0; i < list_size; i+= strlen(list + i) + 1)
num_names++;
}
#endif /* ! Libisofs_with_aaip_xattR */
#ifdef Libisofs_with_aaip_acL
if(flag & 1)
num_names++;
#endif
if(num_names == 0)
@ -219,8 +259,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
(*values)[i]= NULL;
(*value_lengths)[i]= 0;
}
if(!(flag & 4)) {
for(i= 0; i < list_size && num_names > *num_attrs;
#ifdef Libisofs_with_aaip_xattR
if(!(flag & 4)) { /* Get xattr values */
for(i= 0; i < list_size && (size_t) num_names > *num_attrs;
i+= strlen(list + i) + 1) {
if(!(flag & 8))
if(strncmp(list + i, "user.", 5))
@ -229,12 +272,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
if((*names)[(*num_attrs) - 1] == NULL)
{ret= -1; goto ex;}
}
}
#ifdef Libisofs_with_aaip_xattR
if(!(flag & 4)) { /* Get xattr values */
for(i= 0; i < *num_attrs; i++) {
for(i= 0; (size_t) i < *num_attrs; i++) {
if(!(flag & 8))
if(strncmp((*names)[i], "user.", 5))
continue;
@ -291,15 +329,22 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
ret= 1;
ex:;
#ifdef Libisofs_with_aaip_acL
if(a_acl_text != NULL)
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
if(d_acl_text != NULL)
aaip_get_acl_text("", &d_acl_text, 1 << 15); /* free */
if(acl != NULL)
free(acl);
#endif
#ifdef Libisofs_with_aaip_xattR
if(list != NULL)
free(list);
#endif
if(ret <= 0 || (flag & (1 << 15))) {
if(*names != NULL) {
for(i= 0; i < *num_attrs; i++)
for(i= 0; (size_t) i < *num_attrs; i++)
free((*names)[i]);
free(*names);
}
@ -308,12 +353,10 @@ ex:;
free(*value_lengths);
*value_lengths= NULL;
if(*values != NULL) {
for(i= 0; i < *num_attrs; i++)
for(i= 0; (size_t) i < *num_attrs; i++)
free((*values)[i]);
free(*values);
}
if(acl != NULL)
free(acl);
*values= NULL;
*num_attrs= 0;
}
@ -384,7 +427,9 @@ ex:
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
bit5= in case of symbolic link: manipulate link target
bit6= tolerate inappropriate presence or absense of
directory default ACL
@return 1 success
-1 error memory allocation
-2 error with decoding of ACL
@ -393,6 +438,8 @@ ex:
-5 error with deleting attributes
-6 support of xattr not enabled at compile time
-7 support of ACL not enabled at compile time
( -8 unsupported xattr namespace )
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
@ -422,7 +469,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
list_size= llistxattr(path, list, list_size);
if(list_size == -1)
{ret= -5; goto ex;}
for(i= 0; i < list_size; i+= strlen(list + i) + 1) {
for(i= 0; i < (size_t) list_size; i+= strlen(list + i) + 1) {
if(!(flag & 8))
if(strncmp(list + i, "user.", 5))
continue;
@ -447,7 +494,11 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
continue;
}
/* Extended Attribute */
if((flag & 1) && !(flag & 8))
if(flag & 4)
continue;
if(strncmp(names[i], "isofs.", 6) == 0)
continue;
if(!(flag & 8))
if(strncmp(names[i], "user.", 5))
continue;
@ -475,6 +526,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
/* "access" ACL */
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
&consumed, NULL, 0, &acl_text_fill, 1);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
acl_text= calloc(acl_text_fill, 1);
@ -482,6 +535,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
{ret= -1; goto ex;}
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
&consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
has_default_acl= (ret == 2);
@ -500,6 +555,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
ret= aaip_decode_acl((unsigned char *) (values[i] + consumed),
value_lengths[i] - consumed, &h_consumed,
NULL, 0, &acl_text_fill, 1);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
acl_text= calloc(acl_text_fill, 1);
@ -508,11 +565,21 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
ret= aaip_decode_acl((unsigned char *) (values[i] + consumed),
value_lengths[i] - consumed, &h_consumed,
acl_text, acl_text_fill, &acl_text_fill, 0);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
if(ret <= 0)
{ret= -3; goto ex;}
} else {
if(!(flag & 64)) {
/* >>> ??? take offense from missing default ACL ?
??? does Linux demand a default ACL for directories with access ACL ?
*/;
}
}
ret= 1;
ex:;

View File

@ -4,10 +4,10 @@
Arbitrary Attribute Interchange Protocol , AAIP versions 0.2 , 1.0 , 2.0.
Implementation of encoding and decoding xattr and ACL.
See test/aaip_0_2.h
See libisofs/aaip_0_2.h
http://libburnia-project.org/wiki/AAIP
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
*/
@ -26,6 +26,7 @@
#include <sys/stat.h>
#include "libisofs.h"
#include "util.h"
/*
#define Aaip_encode_debuG 1
@ -94,8 +95,8 @@ size_t aaip_encode(size_t num_attrs, char **names,
size_t *value_lengths, char **values,
size_t *result_len, unsigned char **result, int flag)
{
size_t mem_size= 0, comp_size;
unsigned int number_of_fields, i, num_recs, total_recs= 0, ret;
size_t mem_size= 0, comp_size, ret;
unsigned int number_of_fields, i, num_recs;
/* Predict memory needs, number of SUSP fields and component records */
*result_len= 0;
@ -105,7 +106,6 @@ size_t aaip_encode(size_t num_attrs, char **names,
if(ret <= 0)
return(ret);
mem_size+= comp_size;
total_recs= num_recs;
}
number_of_fields= mem_size / 250 + !!(mem_size % 250);
mem_size+= number_of_fields * 5;
@ -158,9 +158,9 @@ size_t aaip_encode(size_t num_attrs, char **names,
ret= 0;
for(i= 0; i < *result_len; i+= ((unsigned char *) (*result))[i + 2])
ret++;
if(ret != number_of_fields) {
if(ret != (int) number_of_fields) {
fprintf(stderr, "aaip_encode(): WRONG NUMBER OF FIELDS %d <> %d\n",
number_of_fields, ret);
(int) number_of_fields, ret);
}
#endif /* Aaip_encode_debuG */
@ -187,7 +187,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
aaip_encode_byte(result, result_fill, 0);
return(1);
}
for(rpt= data; rpt - data < l;) {
for(rpt= data; rpt - data < (ssize_t) l;) {
todo= l - (rpt - data) + (prefix > 0);
aaip_encode_byte(result, result_fill, (todo > 255));
if(todo > 255)
@ -198,7 +198,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
todo--;
prefix= 0;
}
for(comp_start= rpt; rpt - comp_start < todo; rpt++)
for(comp_start= rpt; rpt - comp_start < (ssize_t) todo; rpt++)
aaip_encode_byte(result, result_fill, *((unsigned char *) rpt));
}
return(1);
@ -268,7 +268,11 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
bit3= check for completeness of list and eventually
fill up with entries deduced from st_mode
@return >0 means ok
0 means error
<=0 means error
-1= out of memory
-2= program error with prediction of result size
-3= error with conversion of name to uid or gid
ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other::
*/
int aaip_encode_acl(char *acl_text, mode_t st_mode,
size_t *result_len, unsigned char **result, int flag)
@ -279,8 +283,10 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
*result_len= 0;
bytes= aaip_encode_acl_text(acl_text, st_mode,
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8)));
if(bytes < -2)
return(bytes);
if(bytes < 0)
return(0);
return((int) bytes - 1);
if(flag & 1) {
*result_len= bytes;
return(1);
@ -292,9 +298,13 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
*result_len= bytes;
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
(flag & (2 | 4 | 8)));
if(bytes != *result_len) {
if(bytes < -2)
return(bytes);
if(bytes < 0)
return((int) bytes - 1);
if((size_t) bytes != *result_len) {
*result_len= 0;
return(0);
return(-2);
}
return(1);
}
@ -341,26 +351,31 @@ static int aaip_make_aaip_perms(int r, int w, int x)
fill up with entries deduced from st_mode
@return >=0 number of bytes produced resp. counted
<0 means error
-1: result size overflow
-2: conversion errror with user name or group name
ISO_AAIP_ACL_MULT_OBJ: multiple entries of user::, group::, other::
*/
static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
size_t result_size, unsigned char *result, int flag)
{
char *rpt, *npt, *cpt;
int qualifier= 0, perms, type, i, qualifier_len= 0, num_recs, needed= 0;
int qualifier= 0, perms, type, i, qualifier_len= 0, num_recs, needed= 0, ret;
unsigned int has_u= 0, has_g= 0, has_o= 0, has_m= 0, is_trivial= 1;
uid_t uid, huid;
gid_t gid, hgid;
ssize_t count= 0;
struct passwd *pwd;
struct group *grp;
char name[1024];
char *name = NULL;
int name_size= 1024;
double num;
LIBISO_ALLOC_MEM(name, char, name_size);
if(flag & 4) {
/* set SWITCH_MARK to indicate a default ACL */;
if(!(flag & 1)) {
if(count >= result_size)
return(-1);
if((size_t) count >= result_size)
{ret= -1; goto ex;}
result[count]= (Aaip_SWITCH_MARK << 4) | Aaip_EXEC;
}
count++;
@ -384,9 +399,16 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
if(strncmp(rpt, "user:", 5) == 0) {
if(cpt - rpt == 5) {
type= Aaip_ACL_USER_OBJ;
if (has_u) {
/* >>> Duplicate u:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
return((int) ISO_AAIP_ACL_MULT_OBJ);
}
has_u++;
} else {
if(cpt - (rpt + 5) >= sizeof(name))
if(cpt - (rpt + 5) >= name_size)
continue;
is_trivial= 0;
strncpy(name, rpt + 5, cpt - (rpt + 5));
@ -396,8 +418,10 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
pwd= getpwnam(name);
if(pwd == NULL) {
num= aaip_numeric_id(name, 0);
if(num <= 0)
goto user_by_name;
if(num <= 0) {
/* ACL_USER is not part of AAIP 2.0 */
{ret= -2; goto ex;}
}
uid= huid= num;
} else
uid= huid= pwd->pw_uid;
@ -405,31 +429,44 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
for(i= 0; huid != 0; i++)
huid= huid >> 8;
qualifier_len= i;
if(qualifier_len <= 0)
qualifier_len= 1;
for(i= 0; i < qualifier_len ; i++)
name[i]= uid >> (8 * (qualifier_len - i - 1));
} else {
user_by_name:;
type= Aaip_ACL_USER;
qualifier_len= strlen(name);
if(qualifier_len <= 0)
qualifier_len= 1;
}
qualifier= 1;
}
} else if(strncmp(rpt, "group:", 6) == 0) {
if(cpt - rpt == 6) {
type= Aaip_ACL_GROUP_OBJ;
if (has_g) {
/* >>> Duplicate g:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
return((int) ISO_AAIP_ACL_MULT_OBJ);
}
has_g++;
} else {
if(cpt - (rpt + 6) >= sizeof(name))
if(cpt - (rpt + 6) >= name_size)
continue;
is_trivial= 0;
strncpy(name, rpt + 6, cpt - (rpt + 6));
name[cpt - (rpt + 6)]= 0;
if(flag & 2) {
type= Aaip_ACL_GROUP_N;
grp= getgrnam(name);
if(grp == NULL) {
num= aaip_numeric_id(name, 0);
if(num <= 0)
goto group_by_name;
if(num <= 0) {
/* ACL_GROUP is not part of AAIP 2.0 */
{ret= -2; goto ex;}
}
gid= hgid= num;
} else
gid= hgid= grp->gr_gid;
@ -437,18 +474,27 @@ user_by_name:;
for(i= 0; hgid != 0; i++)
hgid= hgid >> 8;
qualifier_len= i;
if(qualifier_len <= 0)
qualifier_len= 1;
for(i= 0; i < qualifier_len ; i++)
name[i]= gid >> (8 * (qualifier_len - i - 1));
} else {
group_by_name:;
type= Aaip_ACL_GROUP;
qualifier_len= strlen(name);
if(qualifier_len <= 0)
qualifier_len= 1;
}
qualifier= 1;
}
} else if(strncmp(rpt, "other:", 6) == 0) {
type= Aaip_ACL_OTHER;
if (has_o) {
/* >>> Duplicate o:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
return((int) ISO_AAIP_ACL_MULT_OBJ);
}
has_o++;
} else if(strncmp(rpt, "mask:", 5) == 0) {
type= Aaip_ACL_MASK;
@ -461,8 +507,8 @@ group_by_name:;
perms= aaip_make_aaip_perms(cpt[1] == 'r', cpt[2] == 'w', cpt[3] == 'x');
if(!(flag & 1)) {
if(count >= result_size)
return(-1);
if((size_t) count >= result_size)
{ret= -1; goto ex;}
result[count]= perms | ((!!qualifier) << 3) | (type << 4);
}
count++;
@ -470,8 +516,8 @@ group_by_name:;
if(qualifier) {
num_recs= (qualifier_len / 127) + !!(qualifier_len % 127);
if(!(flag & 1)) {
if(count + 1 > result_size)
return(-1);
if((size_t) (count + 1) > result_size)
{ret= -1; goto ex;}
for(i= 0; i < num_recs; i++) {
if(i < num_recs - 1)
result[count++]= 255;
@ -480,8 +526,8 @@ group_by_name:;
if(result[count - 1] == 0)
result[count - 1]= 127;
}
if(count + (result[count - 1] & 127) > result_size)
return(-1);
if((size_t) (count + (result[count - 1] & 127)) > result_size)
{ret= -1; goto ex;}
memcpy(result + count, name + i * 127, result[count - 1] & 127);
count+= result[count - 1] & 127;
}
@ -495,8 +541,8 @@ group_by_name:;
if(flag & 1)
count+= needed;
else {
if(count + needed > result_size)
return(-1);
if((size_t) (count + needed) > result_size)
{ret= -1; goto ex;}
}
}
if ((flag & 8) && needed > 0 && !(flag & 1)) {
@ -521,7 +567,10 @@ group_by_name:;
result[count++]= perms | (Aaip_ACL_MASK << 4);
}
}
return(count);
ret= count;
ex:;
LIBISO_FREE_MEM(name);
return(ret);
}
@ -1120,9 +1169,9 @@ static int aaip_consume_rec_head(struct aaip_state *aaip,
size_t todo;
todo= *num_data;
if(todo > aaip->aa_missing)
if(todo > (size_t) aaip->aa_missing)
todo= aaip->aa_missing;
if(todo >= aaip->rec_head_missing)
if(todo >= (size_t) aaip->rec_head_missing)
todo= aaip->rec_head_missing;
if(!aaip->recs_invalid)
aaip_push_to_recs(aaip, *data, todo, 0);
@ -1144,9 +1193,9 @@ static int aaip_consume_rec_data(struct aaip_state *aaip,
size_t todo;
todo= *num_data;
if(todo > aaip->aa_missing)
if(todo > (size_t) aaip->aa_missing)
todo= aaip->aa_missing;
if(todo > aaip->rec_missing)
if(todo > (size_t) aaip->rec_missing)
todo= aaip->rec_missing;
if(!aaip->recs_invalid)
aaip_push_to_recs(aaip, *data, todo, 1);
@ -1178,7 +1227,7 @@ static int aaip_consume_aa_head(struct aaip_state *aaip,
unsigned char aa_head[5];
todo= *num_data;
if(todo >= aaip->aa_head_missing)
if(todo >= (size_t) aaip->aa_head_missing)
todo= aaip->aa_head_missing;
aaip_push_to_recs(aaip, *data, todo, 0);
aaip->aa_head_missing-= todo;
@ -1225,7 +1274,7 @@ static int aaip_consume_aa_data(struct aaip_state *aaip,
aaip_push_to_recs(aaip, zero_char, 1, 0);
} else {
/* fill in missing btes */
for(i= 0; i < aaip->rec_missing; i++)
for(i= 0; (int) i < aaip->rec_missing; i++)
aaip_push_to_recs(aaip, zero_char, 1, 1);
}
aaip->rec_head_missing= 2;
@ -1696,7 +1745,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
unsigned char *data, size_t num_data, size_t *consumed,
int flag)
{
int ret, was_non_aa= 0;
int ret;
struct aaip_state *aaip;
size_t h_num, *h_lengths, i, new_mem, pair_consumed= 0;
char **h_names, **h_values, *hpt;
@ -1785,7 +1834,6 @@ int aaip_decode_attrs(struct aaip_state **handle,
return(ret);
} else if(ret == -1) { /* non-AAIP field detected */
was_non_aa= 1;
if(pair_consumed <= 0)
return(-4); /* interpretation did not advance */
@ -1968,14 +2016,16 @@ static int aaip_read_qualifier(unsigned char *data, size_t num_data,
char *name, size_t name_size, size_t *name_fill,
int flag)
{
int is_done= 0, rec_len= 0;
int is_done= 0;
size_t rec_len= 0;
unsigned char *rpt;
*name_fill= 0;
for(rpt= data; !is_done; rpt+= rec_len) {
rec_len= (*rpt) & 127;
is_done= !((*rpt) & 128);
if(*name_fill + rec_len >= name_size || rpt + 1 + rec_len - data > num_data)
if(*name_fill + rec_len >= name_size ||
(size_t) (rpt + 1 + rec_len - data) > num_data)
return(-1);
memcpy(name + *name_fill, rpt + 1, rec_len);
rpt+= 1 + rec_len;
@ -2013,20 +2063,21 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
size_t *acl_text_fill, int flag)
{
unsigned char *rpt;
char perm_text[4], *wpt, name[1024];
int type, qualifier= 0, perm, ret, i, cnt;
size_t w_size, name_fill= 0;
char perm_text[4], *wpt, *name= NULL;
int type, qualifier= 0, perm, ret, cnt, name_size= 1024;
size_t w_size, name_fill= 0, i;
uid_t uid;
gid_t gid;
struct passwd *pwd;
struct group *grp;
LIBISO_ALLOC_MEM(name, char, name_size);
cnt= flag & 1;
*consumed= 0;
wpt= acl_text;
w_size= acl_text_size;
*acl_text_fill= 0;
for(rpt= data; rpt - data < num_data; ) {
for(rpt= data; (size_t) (rpt - data) < num_data; ) {
perm= *rpt;
strcpy(perm_text, "---");
if(perm & Aaip_READ)
@ -2038,14 +2089,14 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
type= (*rpt) >> 4;
if(type == Aaip_FUTURE_VERSION) /* indicate to caller: version mismatch */
return(-3);
{ret = -3; goto ex;}
qualifier= !!((*rpt) & 8);
if(qualifier) {
ret= aaip_read_qualifier(rpt + 1, num_data - (rpt + 1 - data),
name, sizeof(name), &name_fill, 0);
name, name_size, &name_fill, 0);
if(ret <= 0)
return(-1);
{ret = -1; goto ex;}
}
/* Advance read pointer */
@ -2086,7 +2137,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
pwd= getpwuid(uid);
if(pwd == NULL)
sprintf(name, "%.f", (double) uid);
else if(strlen(pwd->pw_name) >= sizeof(name))
else if(strlen(pwd->pw_name) >= (size_t) name_size)
sprintf(name, "%.f", (double) uid);
else
strcpy(name, pwd->pw_name);
@ -2100,7 +2151,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
grp= getgrgid(gid);
if(grp == NULL)
sprintf(name, "%.f", (double) gid);
else if(strlen(grp->gr_name) >= sizeof(name))
else if(strlen(grp->gr_name) >= (size_t) name_size)
sprintf(name, "%.f", (double) gid);
else
strcpy(name, grp->gr_name);
@ -2108,15 +2159,17 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
ret= aaip_write_acl_line(&wpt, &w_size, "group", name, perm_text, cnt);
} else {
/* indicate to caller: unknown type */
return(-4);
{ret = -4; goto ex;}
}
if(ret <= 0)
return(-2);
{ret = -2; goto ex;}
}
ret= 1;
ex:;
*acl_text_fill= w_size;
if(flag & 1)
*acl_text_fill= w_size + 1;
(*acl_text_fill)++;
LIBISO_FREE_MEM(name);
return(ret);
}
@ -2133,6 +2186,13 @@ ex:;
#include "aaip-os-linux.c"
/* August 2011: aaip-os-linux.c would also work for GNU/Hurd : ifdef __GNU__
Libraries and headers are present on Debian GNU/Hurd but there is no
ACL or xattr support in the filesystems yet.
Further, llistxattr() produces ENOSYS "Function not implemented".
So it makes few sense to enable it here.
*/
#else
#include "aaip-os-dummy.c"

View File

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

View File

@ -150,7 +150,7 @@ void iso_ring_buffer_free(IsoRingBuffer *buf)
int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
{
size_t len;
int bytes_write = 0;
size_t bytes_write = 0;
if (buf == NULL || data == NULL) {
return ISO_NULL_POINTER;
@ -206,7 +206,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
{
size_t len;
int bytes_read = 0;
size_t bytes_read = 0;
if (buf == NULL || dest == NULL) {
return ISO_NULL_POINTER;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -20,6 +20,7 @@
#include "fsource.h"
#include "image.h"
#include "aaip_0_2.h"
#include "util.h"
#include <stdlib.h>
#include <string.h>
@ -104,9 +105,11 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
char *name;
unsigned char *aa_string = NULL;
char *a_text = NULL, *d_text = NULL;
char *dest = NULL;
IsoSymlink *link;
if (builder == NULL || src == NULL || node == NULL) {
return ISO_NULL_POINTER;
{ret = ISO_NULL_POINTER; goto ex;}
}
/* get info about source */
@ -116,7 +119,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_file_source_lstat(src, &info);
}
if (ret < 0) {
return ret;
goto ex;
}
name = iso_file_source_get_name(src);
@ -157,9 +160,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
case S_IFLNK:
{
/* source is a symbolic link */
char dest[LIBISOFS_NODE_PATH_MAX];
IsoSymlink *link;
LIBISO_ALLOC_MEM(dest, char, LIBISOFS_NODE_PATH_MAX);
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
if (ret < 0) {
break;
@ -198,7 +199,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
if (ret < 0) {
free(name);
return ret;
goto ex;
}
/* fill fields */
@ -233,14 +234,17 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
if (ret == 1 && aa_string != NULL) {
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
if (ret < 0)
return ret;
goto ex;
} else if(aa_string != NULL) {
free(aa_string);
}
*node = new;
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(dest);
return ret;
}
static

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2012 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -89,6 +89,14 @@ void ecma119_image_free(Ecma119Image *t)
writer->free_data(writer);
free(writer);
}
#ifdef Libisofs_with_rr_reloc_diR
if (t->rr_reloc_dir != NULL)
free(t->rr_reloc_dir);
#endif /* Libisofs_with_rr_reloc_diR */
if (t->input_charset != NULL)
free(t->input_charset);
if (t->output_charset != NULL)
@ -363,7 +371,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
IsoNode *iso;
len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1);
len_dr = 33 + len_fi + ((len_fi % 2) ? 0 : 1);
memcpy(rec->file_id, name, len_fi);
@ -402,7 +410,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
rec->len_dr[0] = len_dr + (info != NULL ? info->suf_len : 0);
iso_bb(rec->block, block - t->eff_partition_offset, 4);
iso_bb(rec->length, len, 4);
if (t->dir_rec_mtime) {
if (t->dir_rec_mtime & 1) {
iso= node->node;
iso_datetime_7(rec->recording_time,
t->replace_timestamps ? t->timestamp : iso->mtime,
@ -576,16 +584,16 @@ static
int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
{
int ret;
uint8_t buffer[BLOCK_SIZE];
uint8_t *buffer = NULL;
size_t i;
size_t fi_len, len;
struct susp_info info;
/* buf will point to current write position on buffer */
uint8_t *buf = buffer;
uint8_t *buf;
/* initialize buffer with 0s */
memset(buffer, 0, BLOCK_SIZE);
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
buf = buffer;
/*
* set susp_info to 0's, this way code for both plain ECMA-119 and
@ -602,7 +610,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
if (t->rockridge) {
ret = rrip_get_susp_fields(t, dir, 1, 34, &info);
if (ret < 0) {
return ret;
goto ex;
}
}
len = 34 + info.suf_len;
@ -612,7 +620,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
if (t->rockridge) {
ret = rrip_get_susp_fields(t, dir, 2, 34, &info);
if (ret < 0) {
return ret;
goto ex;
}
}
len = 34 + info.suf_len;
@ -629,7 +637,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
for (section = 0; section < nsections; ++section) {
/* compute len of directory entry */
len = fi_len + 33 + (fi_len % 2 ? 0 : 1);
len = fi_len + 33 + ((fi_len % 2) ? 0 : 1);
if (need_version_number(t, child)) {
len += 2;
}
@ -638,7 +646,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
if (t->rockridge) {
ret = rrip_get_susp_fields(t, child, 0, len, &info);
if (ret < 0) {
return ret;
goto ex;
}
len += info.suf_len;
}
@ -647,7 +655,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
/* dir doesn't fit in current block */
ret = iso_write(t, buffer, BLOCK_SIZE);
if (ret < 0) {
return ret;
goto ex;
}
memset(buffer, 0, BLOCK_SIZE);
buf = buffer;
@ -661,7 +669,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
/* write the last block */
ret = iso_write(t, buffer, BLOCK_SIZE);
if (ret < 0) {
return ret;
goto ex;
}
/* write the Continuation Area if needed */
@ -669,6 +677,8 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
ret = rrip_write_ce_fields(t, &info);
}
ex:;
LIBISO_FREE_MEM(buffer);
return ret;
}
@ -708,6 +718,7 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
uint32_t path_table_size;
int parent = 0;
int ret= ISO_SUCCESS;
uint8_t *zeros = NULL;
path_table_size = 0;
write_int = l_type ? iso_lsb : iso_msb;
@ -735,7 +746,7 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
ret = iso_write(t, buf, len);
if (ret < 0) {
/* error */
return ret;
goto ex;
}
path_table_size += len;
}
@ -743,11 +754,12 @@ int write_path_table(Ecma119Image *t, Ecma119Node **pathlist, int l_type)
/* we need to fill the last block with zeros */
path_table_size %= BLOCK_SIZE;
if (path_table_size) {
uint8_t zeros[BLOCK_SIZE];
len = BLOCK_SIZE - path_table_size;
memset(zeros, 0, len);
LIBISO_ALLOC_MEM(zeros, uint8_t, len);
ret = iso_write(t, zeros, len);
}
ex:;
LIBISO_FREE_MEM(zeros);
return ret;
}
@ -878,28 +890,28 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
int ret;
Ecma119Image *t;
uint32_t curblock;
char *msg = NULL;
if (writer == NULL)
{ret = ISO_ASSERT_FAILURE; goto ex;}
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
}
t = writer->target;
ret = ecma119_writer_write_dirs(writer);
if (ret < 0)
return ret;
goto ex;
if (t->partition_offset > 0) {
t->eff_partition_offset = t->partition_offset;
ret = ecma119_writer_write_dirs(writer);
t->eff_partition_offset = 0;
if (ret < 0)
return ret;
goto ex;
}
curblock = (t->bytes_written / 2048) + t->ms_block;
if (curblock != t->tree_end_block) {
char msg[100];
LIBISO_ALLOC_MEM(msg, char, 100);
sprintf(msg,
"Calculated and written ECMA-119 tree end differ: %lu <> %lu",
(unsigned long) t->tree_end_block,
@ -908,8 +920,10 @@ int ecma119_writer_write_data(IsoImageWriter *writer)
t->tree_end_block = 1;/* Mark for harsher reaction at end of writing */
}
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(msg);
return ret;
}
static
@ -990,27 +1004,30 @@ int mspad_writer_write_data(IsoImageWriter *writer)
{
int ret;
Ecma119Image *t;
uint8_t pad[BLOCK_SIZE];
uint8_t *pad = NULL;
size_t i;
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
{ret = ISO_ASSERT_FAILURE; goto ex;}
}
t = writer->target;
if (t->mspad_blocks == 0) {
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
}
memset(pad, 0, BLOCK_SIZE);
LIBISO_ALLOC_MEM(pad, uint8_t, BLOCK_SIZE);
for (i = 0; i < t->mspad_blocks; ++i) {
ret = iso_write(t, pad, BLOCK_SIZE);
if (ret < 0) {
return ret;
goto ex;
}
}
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(pad);
return ret;
}
static
@ -1076,23 +1093,26 @@ int zero_writer_write_data(IsoImageWriter *writer)
int ret;
Ecma119Image *t;
struct iso_zero_writer_data_struct *data;
uint8_t pad[BLOCK_SIZE];
uint8_t *pad = NULL;
size_t i;
if (writer == NULL)
return ISO_ASSERT_FAILURE;
{ret = ISO_ASSERT_FAILURE; goto ex;}
t = writer->target;
data = (struct iso_zero_writer_data_struct *) writer->data;
if (data->num_blocks == 0)
return ISO_SUCCESS;
memset(pad, 0, BLOCK_SIZE);
{ret = ISO_SUCCESS; goto ex;}
LIBISO_ALLOC_MEM(pad, uint8_t, BLOCK_SIZE);
for (i = 0; i < data->num_blocks; ++i) {
ret = iso_write(t, pad, BLOCK_SIZE);
if (ret < 0)
return ret;
goto ex;
}
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(pad);
return ret;
}
static
@ -1113,7 +1133,7 @@ int tail_writer_compute_data_blocks(IsoImageWriter *writer)
int ret;
Ecma119Image *target;
struct iso_zero_writer_data_struct *data;
char msg[160];
char msg[80];
target = writer->target;
ret = iso_align_isohybrid(target, 0);
@ -1185,11 +1205,11 @@ int transplant_checksum_buffer(Ecma119Image *target, int flag)
static
int write_vol_desc_terminator(Ecma119Image *target)
{
int res;
uint8_t buf[BLOCK_SIZE];
int ret;
uint8_t *buf = NULL;
struct ecma119_vol_desc_terminator *vol;
memset(buf, 0, BLOCK_SIZE);
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
vol = (struct ecma119_vol_desc_terminator *) buf;
@ -1197,8 +1217,10 @@ int write_vol_desc_terminator(Ecma119Image *target)
memcpy(vol->std_identifier, "CD001", 5);
vol->vol_desc_version[0] = 1;
res = iso_write(target, buf, BLOCK_SIZE);
return res;
ret = iso_write(target, buf, BLOCK_SIZE);
ex:
LIBISO_FREE_MEM(buf);
return ret;
}
@ -1229,7 +1251,7 @@ int write_head_part1(Ecma119Image *target, int *write_count, int flag)
/* write volume descriptors, one per writer */
iso_msg_debug(target->image->id, "Write volume descriptors");
for (i = 0; i < target->nwriters; ++i) {
for (i = 0; i < (int) target->nwriters; ++i) {
writer = target->writers[i];
res = writer->write_vol_desc(writer);
if (res < 0)
@ -1257,26 +1279,27 @@ write_error:;
static
int write_head_part2(Ecma119Image *target, int *write_count, int flag)
{
int res, i;
uint8_t buf[BLOCK_SIZE];
int ret, i;
uint8_t *buf = NULL;
IsoImageWriter *writer;
if (target->partition_offset <= 0)
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
/* Write multi-session padding up to target->partition_offset + 16 */
memset(buf, 0, BLOCK_SIZE);
for(; *write_count < target->partition_offset + 16; (*write_count)++) {
res = iso_write(target, buf, BLOCK_SIZE);
if (res < 0)
goto write_error;
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
for(; *write_count < (int) target->partition_offset + 16;
(*write_count)++) {
ret = iso_write(target, buf, BLOCK_SIZE);
if (ret < 0)
goto ex;
}
/* Write volume descriptors subtracting
target->partiton_offset from any LBA pointer.
*/
target->eff_partition_offset = target->partition_offset;
for (i = 0; i < target->nwriters; ++i) {
for (i = 0; i < (int) target->nwriters; ++i) {
writer = target->writers[i];
/* Not all writers have an entry in the partion volume descriptor set.
It must be guaranteed that they write exactly one block.
@ -1287,23 +1310,23 @@ int write_head_part2(Ecma119Image *target, int *write_count, int flag)
if(writer->write_vol_desc != ecma119_writer_write_vol_desc &&
writer->write_vol_desc != joliet_writer_write_vol_desc)
continue;
res = writer->write_vol_desc(writer);
if (res < 0)
goto write_error;
ret = writer->write_vol_desc(writer);
if (ret < 0)
goto ex;
(*write_count)++;
}
res = write_vol_desc_terminator(target);
if (res < 0)
goto write_error;
ret = write_vol_desc_terminator(target);
if (ret < 0)
goto ex;
(*write_count)++;
target->eff_partition_offset = 0;
/* >>> TWINTREE: Postponed for now:
Write second superblock checksum tag */;
return ISO_SUCCESS;
write_error:;
return res;
ret = ISO_SUCCESS;
ex:;
return ret;
}
static
@ -1359,19 +1382,19 @@ static int write_mbr_partition_file(Ecma119Image *target, char *path,
{
FILE *fp = NULL;
uint32_t i;
uint8_t buf[BLOCK_SIZE];
uint8_t *buf = NULL;
int ret;
memset(buf, 0, BLOCK_SIZE);
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
for (i = 0; i < prepad; i++) {
ret = iso_write(target, buf, BLOCK_SIZE);
if (ret < 0)
return ret;
goto ex;
}
fp = fopen(path, "rb");
if (fp == NULL)
return ISO_BAD_PARTITION_FILE;
{ret = ISO_BAD_PARTITION_FILE; goto ex;}
for (i = 0; i < blocks; i++) {
memset(buf, 0, BLOCK_SIZE);
@ -1385,12 +1408,15 @@ static int write_mbr_partition_file(Ecma119Image *target, char *path,
ret = iso_write(target, buf, BLOCK_SIZE);
if (ret < 0) {
fclose(fp);
return ret;
goto ex;
}
}
if (fp != NULL)
fclose(fp);
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(buf);
return ret;
}
@ -1412,7 +1438,7 @@ void *write_function(void *arg)
goto write_error;
/* write data for each writer */
for (i = 0; i < target->nwriters; ++i) {
for (i = 0; i < (int) target->nwriters; ++i) {
writer = target->writers[i];
res = writer->write_data(writer);
if (res < 0) {
@ -1469,10 +1495,10 @@ void *write_function(void *arg)
#endif
write_error: ;
if (res != ISO_LIBJTE_END_FAILED)
if (res != (int) ISO_LIBJTE_END_FAILED)
finish_libjte(target);
target->eff_partition_offset = 0;
if (res == ISO_CANCELED) {
if (res == (int) ISO_CANCELED) {
/* canceled */
if (!target->will_cancel)
iso_msg_submit(target->image->id, ISO_IMAGE_WRITE_CANCELED,
@ -1648,6 +1674,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->no_force_dots = opts->no_force_dots;
target->allow_lowercase = opts->allow_lowercase;
target->allow_full_ascii = opts->allow_full_ascii;
target->allow_7bit_ascii = opts->allow_7bit_ascii;
target->relaxed_vol_atts = opts->relaxed_vol_atts;
target->joliet_longer_paths = opts->joliet_longer_paths;
target->joliet_long_names = opts->joliet_long_names;
@ -1655,6 +1682,22 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
target->dir_rec_mtime = opts->dir_rec_mtime;
#ifdef Libisofs_with_rr_reloc_diR
target->rr_reloc_dir = NULL;
if (opts->rr_reloc_dir != NULL) {
target->rr_reloc_dir = strdup(opts->rr_reloc_dir);
if (target->rr_reloc_dir == NULL) {
ret = ISO_OUT_OF_MEM;
goto target_cleanup;
}
}
target->rr_reloc_flags = opts->rr_reloc_flags;
target->rr_reloc_node = NULL;
#endif /* Libisofs_with_rr_reloc_diR */
target->sort_files = opts->sort_files;
target->replace_uid = opts->replace_uid ? 1 : 0;
@ -1949,7 +1992,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->curblock = target->ms_block + target->partition_offset + 16;
/* Account for partition tree volume descriptors */
for (i = 0; i < target->nwriters; ++i) {
for (i = 0; i < (int) target->nwriters; ++i) {
/* Not all writers have an entry in the partition
volume descriptor set.
*/
@ -1975,7 +2018,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
* That function computes the size needed by its structures and
* increments image current block propertly.
*/
for (i = 0; i < target->nwriters; ++i) {
for (i = 0; i < (int) target->nwriters; ++i) {
IsoImageWriter *writer = target->writers[i];
/* Delaying boot image patching until new LBA is known */
@ -2292,6 +2335,69 @@ int bs_set_size(struct burn_source *bs, off_t size)
return 1;
}
#ifdef Libisofs_with_rr_reloc_diR
static
int dive_to_depth_8(IsoDir *dir, int depth)
{
int ret;
IsoNode *pos;
if (depth >= 8)
return 1;
pos = dir->children;
for (pos = dir->children; pos != NULL; pos = pos->next) {
if (pos->type != LIBISO_DIR)
continue;
ret = dive_to_depth_8((IsoDir *) pos, depth + 1);
if (ret != 0)
return ret;
}
return 0;
}
static
int make_reloc_dir_if_needed(IsoImage *img, IsoWriteOpts *opts, int flag)
{
int ret;
IsoDir *dir;
/* Two forms to express the root directory */
if (opts->rr_reloc_dir == NULL)
return 1;
if (opts->rr_reloc_dir[0] == 0)
return 1;
if (strchr(opts->rr_reloc_dir, '/') != NULL)
return 0;
/* Check existence of opts->rr_reloc_dir */
ret = iso_dir_get_node(img->root, opts->rr_reloc_dir, NULL);
if (ret > 0)
return 1;
if (ret < 0)
return ret;
/* Check whether there is a directory of depth 8 (root is depth 1) */
ret = dive_to_depth_8(img->root, 1);
if (ret < 0)
return ret;
if (ret == 0)
return 1;
/* Make IsoDir with same permissions as root directory */
ret = iso_tree_add_new_dir(img->root, opts->rr_reloc_dir, &dir);
if (ret < 0)
return ret;
opts->rr_reloc_flags |= 2; /* Auto-created relocation directory */
return 1;
}
#endif /* Libisofs_with_rr_reloc_diR */
int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
struct burn_source **burn_src)
{
@ -2308,6 +2414,18 @@ int iso_image_create_burn_source(IsoImage *image, IsoWriteOpts *opts,
return ISO_OUT_OF_MEM;
}
#ifdef Libisofs_with_rr_reloc_diR
if (!opts->allow_deep_paths) {
ret = make_reloc_dir_if_needed(image, opts, 0);
if (ret < 0) {
free(source);
return ret;
}
}
#endif /* Libisofs_with_rr_reloc_diR */
ret = ecma119_image_new(image, opts, &target);
if (ret < 0) {
free(source);
@ -2416,6 +2534,13 @@ int iso_write_opts_new(IsoWriteOpts **opts, int profile)
wopts->fifo_size = 1024; /* 2 MB buffer */
wopts->sort_files = 1; /* file sorting is always good */
#ifdef Libisofs_with_rr_reloc_diR
wopts->rr_reloc_dir = NULL;
wopts->rr_reloc_flags = 0;
#endif /* Libisofs_with_rr_reloc_diR */
wopts->system_area_data = NULL;
wopts->system_area_options = 0;
wopts->vol_creation_time = 0;
@ -2452,6 +2577,14 @@ void iso_write_opts_free(IsoWriteOpts *opts)
return;
}
free(opts->output_charset);
#ifdef Libisofs_with_rr_reloc_diR
if (opts->rr_reloc_dir != NULL)
free(opts->rr_reloc_dir);
#endif /* Libisofs_with_rr_reloc_diR */
if (opts->system_area_data != NULL)
free(opts->system_area_data);
for (i = 0; i < ISO_MAX_PARTITIONS; i++)
@ -2624,6 +2757,16 @@ int iso_write_opts_set_allow_full_ascii(IsoWriteOpts *opts, int allow)
return ISO_SUCCESS;
}
int iso_write_opts_set_allow_7bit_ascii(IsoWriteOpts *opts, int allow)
{
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->allow_7bit_ascii = allow ? 1 : 0;
return ISO_SUCCESS;
}
int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow)
{
if (opts == NULL) {
@ -2683,7 +2826,29 @@ int iso_write_opts_set_dir_rec_mtime(IsoWriteOpts *opts, int allow)
if (opts == NULL) {
return ISO_NULL_POINTER;
}
opts->dir_rec_mtime = allow ? 1 : 0;
if (allow < 0)
allow = 1;
else if (allow & (1 << 14))
allow &= ~1;
else if (allow & 6)
allow |= 1;
opts->dir_rec_mtime = allow & 7;
return ISO_SUCCESS;
}
int iso_write_opts_set_rr_reloc(IsoWriteOpts *opts, char *name, int flags)
{
if (opts->rr_reloc_dir != name) {
if (opts->rr_reloc_dir != NULL)
free(opts->rr_reloc_dir);
opts->rr_reloc_dir = NULL;
if (name != NULL) {
opts->rr_reloc_dir = strdup(name);
if (opts->rr_reloc_dir == NULL)
return ISO_OUT_OF_MEM;
}
}
opts->rr_reloc_flags = flags & 1;
return ISO_SUCCESS;
}

View File

@ -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 :1;
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)
*/
/**
* 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;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2012 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -32,7 +32,7 @@
static
int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
{
int ret, relaxed, free_ascii_name= 0, force_dots = 0, max_len;
int ret, relaxed, free_ascii_name= 0, force_dots = 0;
char *ascii_name;
char *isoname= NULL;
@ -59,6 +59,8 @@ int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
} else {
relaxed = (int)img->allow_lowercase;
}
if (img->allow_7bit_ascii)
relaxed |= 4;
if (iso->type == LIBISO_DIR && !(img->allow_dir_id_ext)) {
if (img->untranslated_name_len > 0) {
if (strlen(ascii_name) > img->untranslated_name_len) {
@ -73,11 +75,22 @@ needs_transl:;
} else if (img->max_37_char_filenames) {
isoname = iso_r_dirid(ascii_name, 37, relaxed);
} else if (img->iso_level == 1) {
#ifdef Libisofs_old_ecma119_nameS
if (relaxed) {
isoname = iso_r_dirid(ascii_name, 8, relaxed);
} else {
isoname = iso_1_dirid(ascii_name);
isoname = iso_1_dirid(ascii_name, 0);
}
#else /* Libisofs_old_ecma119_nameS */
isoname = iso_1_dirid(ascii_name, relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
} else {
if (relaxed) {
isoname = iso_r_dirid(ascii_name, 31, relaxed);
@ -94,7 +107,12 @@ needs_transl:;
} else if (img->max_37_char_filenames) {
isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots);
} else if (img->iso_level == 1) {
if (relaxed || !force_dots) {
#ifdef Libisofs_old_ecma119_nameS
int max_len;
if (relaxed) {
if (strchr(ascii_name, '.') == NULL)
max_len = 8;
else
@ -102,8 +120,15 @@ needs_transl:;
isoname = iso_r_fileid(ascii_name, max_len, relaxed,
force_dots);
} else {
isoname = iso_1_fileid(ascii_name);
isoname = iso_1_fileid(ascii_name, 0, force_dots);
}
#else /* Libisofs_old_ecma119_nameS */
isoname = iso_1_fileid(ascii_name, relaxed, force_dots);
#endif /* ! Libisofs_old_ecma119_nameS */
} else {
if (relaxed || !force_dots) {
isoname = iso_r_fileid(ascii_name, 30, relaxed, force_dots);
@ -126,6 +151,21 @@ needs_transl:;
}
}
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
{
#ifdef Libisofs_with_rr_reloc_diR
if (img->rr_reloc_node == node &&
node != img->root && node != img->partition_root &&
(img->rr_reloc_flags & 2))
return 1;
#endif /* Libisofs_with_rr_reloc_diR */
return 0;
}
static
int create_ecma119_node(Ecma119Image *img, IsoNode *iso, Ecma119Node **node)
{
@ -299,7 +339,7 @@ void ecma119_node_free(Ecma119Node *node)
return;
}
if (node->type == ECMA119_DIR) {
int i;
size_t i;
for (i = 0; i < node->info.dir->nchildren; i++) {
ecma119_node_free(node->info.dir->children[i]);
}
@ -434,6 +474,22 @@ int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
if (ret < 0) {
goto ex;
}
#ifdef Libisofs_with_rr_reloc_diR
if (depth == 1) { /* root is default */
image->rr_reloc_node = node;
} else if (depth == 2) {
/* Directories in root may be used as relocation dir */
if (image->rr_reloc_dir != NULL)
if (image->rr_reloc_dir[0] != 0 &&
strcmp(iso->name, image->rr_reloc_dir) == 0)
image->rr_reloc_node = node;
}
#endif /* Libisofs_with_rr_reloc_diR */
}
ret = ISO_SUCCESS;
pos = dir->children;
@ -643,7 +699,7 @@ int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
max = max_file_len - digits;
}
name = full_name;
if (max < strlen(name)) {
if ((size_t) max < strlen(name)) {
name[max] = '\0';
}
/* let ext be an empty string */
@ -750,7 +806,7 @@ int mangle_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
}
static
int mangle_tree(Ecma119Image *img, int recurse)
int mangle_tree(Ecma119Image *img, Ecma119Node *dir, int recurse)
{
int max_file, max_dir;
Ecma119Node *root;
@ -765,7 +821,9 @@ int mangle_tree(Ecma119Image *img, int recurse)
} else {
max_file = max_dir = 31;
}
if (img->eff_partition_offset > 0) {
if (dir != NULL) {
root = dir;
} else if (img->eff_partition_offset > 0) {
root = img->partition_root;
} else {
root = img->root;
@ -887,41 +945,75 @@ 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) {
if (img->eff_partition_offset > 0) {
root = img->partition_root;
} else {
root = img->root;
#ifdef Libisofs_with_rr_reloc_diR
reloc = img->rr_reloc_node;
if (reloc == NULL) {
if (img->eff_partition_offset > 0) {
reloc = img->partition_root;
} else {
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;
}
/*
* 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;
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)
*/
return ISO_SUCCESS;
}
for (i = 0; i < dir->info.dir->nchildren; i++) {
Ecma119Node *child = dir->info.dir->children[i];
if (child->type == ECMA119_DIR) {
int newpathlen = pathlen + 1 + strlen(child->iso_name);
ret = reorder_tree(img, child, level + 1, newpathlen);
if (ret < 0) {
return ret;
}
}
/* 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++) {
child = dir->info.dir->children[i];
if (child->type == ECMA119_DIR) {
newpathlen = pathlen + 1 + strlen(child->iso_name);
ret = reorder_tree(img, child, level + 1, newpathlen);
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;
}

View File

@ -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_*/

View File

@ -275,6 +275,9 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
free(node);
return ISO_OUT_OF_MEM;
}
node->lba = 0;
node->size = 0;
node->content = NULL;
/* atributes from parent */
node->node.mode = S_IFREG | (parent->node.mode & 0444);
@ -384,14 +387,14 @@ int create_image(IsoImage *image, const char *image_path,
if (ret != sizeof(mbr)) {
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Can't read MBR from image file.");
return ret < 0 ? ret : ISO_FILE_READ_ERROR;
return ret < 0 ? ret : (int) ISO_FILE_READ_ERROR;
}
/* check valid MBR signature */
if ( mbr.sign1 != 0x55 || mbr.sign2 != 0xAA ) {
iso_msg_submit(image->id, ISO_BOOT_IMAGE_NOT_VALID, 0,
"Invalid MBR. Wrong signature.");
return ISO_BOOT_IMAGE_NOT_VALID;
return (int) ISO_BOOT_IMAGE_NOT_VALID;
}
/* ensure single partition */
@ -487,7 +490,7 @@ int iso_image_set_boot_image(IsoImage *image, const char *image_path,
"Cannot find directory for El Torito boot catalog in ISO image: '%s'",
catdir);
free(catdir);
return ret < 0 ? ret : ISO_NODE_DOESNT_EXIST;
return ret < 0 ? ret : (int) ISO_NODE_DOESNT_EXIST;
}
if (p->type != LIBISO_DIR) {
free(catdir);
@ -598,6 +601,30 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
return ISO_SUCCESS;
}
int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
char **content, off_t *size)
{
IsoBoot *bootcat;
*catnode = NULL;
*lba = 0;
*content = NULL;
*size = 0;
bootcat = image->bootcat->node;
if (bootcat == NULL)
return 0;
*catnode = bootcat;
*lba = bootcat->lba;
*size = bootcat->size;
if (bootcat->size > 0 && bootcat->content != NULL) {
*content = calloc(1, bootcat->size);
if (*content == NULL)
return ISO_OUT_OF_MEM;
memcpy(*content, bootcat->content, bootcat->size);
}
return 1;
}
int iso_image_get_all_boot_imgs(IsoImage *image, int *num_boots,
ElToritoBootImage ***boots, IsoFile ***bootnodes, int flag)
{
@ -760,7 +787,6 @@ write_validation_entry(uint8_t *buf, uint8_t platform_id,
static void
write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
{
int pi;
char *id_string;
struct el_torito_section_header *e =
@ -768,7 +794,7 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
/* 0x90 = more section headers follow , 0x91 = final section */
e->header_indicator[0] = 0x90 + (idx == t->catalog->num_bootimages - 1);
pi= e->platform_id[0] = t->catalog->bootimages[idx]->platform_id;
e->platform_id[0] = t->catalog->bootimages[idx]->platform_id;
e->num_entries[0] = num_entries & 0xff;
e->num_entries[1] = (num_entries >> 8) & 0xff;;
id_string = (char *) e->id_string;
@ -837,10 +863,10 @@ int catalog_open(IsoStream *stream)
for (j = i + 1; j < cat->num_bootimages; j++) {
if (boots[i]->platform_id != boots[j]->platform_id)
break;
for (k = 0; k < sizeof(boots[i]->id_string); k++)
for (k = 0; k < (int) sizeof(boots[i]->id_string); k++)
if (boots[i]->id_string[k] != boots[j]->id_string[k])
break;
if (k < sizeof(boots[i]->id_string))
if (k < (int) sizeof(boots[i]->id_string))
break;
}
num_entries = j - i;
@ -896,7 +922,7 @@ int catalog_read(IsoStream *stream, void *buf, size_t count)
return ISO_FILE_NOT_OPENED;
}
len = MIN(count, BLOCK_SIZE - data->offset);
len = MIN(count, (size_t) (BLOCK_SIZE - data->offset));
memcpy(buf, data->buffer + data->offset, len);
return len;
}
@ -936,7 +962,11 @@ IsoStreamIface catalog_stream_class = {
catalog_read,
catalog_is_repeatable,
catalog_get_id,
catalog_free
catalog_free,
NULL,
NULL,
NULL,
NULL
};
/**
@ -1127,8 +1157,8 @@ int eltorito_writer_compute_data_blocks(IsoImageWriter *writer)
}
ret = iso_stream_read(original, buf, size);
iso_stream_close(original);
if (ret != size) {
return (ret < 0) ? ret : ISO_FILE_READ_ERROR;
if (ret != (int) size) {
return (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR;
}
/* ok, patch the read buffer */
@ -1156,7 +1186,6 @@ static
int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
{
Ecma119Image *t;
struct el_torito_boot_catalog *cat;
struct ecma119_boot_rec_vol_desc vol;
if (writer == NULL) {
@ -1164,7 +1193,6 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
}
t = writer->target;
cat = t->catalog;
iso_msg_debug(t->image->id, "Write El-Torito boot record");
memset(&vol, 0, sizeof(struct ecma119_boot_rec_vol_desc));

View File

@ -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 */

View File

@ -26,6 +26,8 @@
#include <string.h>
#include <limits.h>
/* <<< */
#include <stdio.h>
#ifdef Xorriso_standalonE
@ -335,25 +337,27 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
{
int res, ret, was_error;
size_t i, b;
Ecma119Image *t;
Ecma119Image *t = NULL;
IsoFileSrc *file;
IsoFileSrc **filelist;
char name[PATH_MAX];
char buffer[BLOCK_SIZE];
char *name = NULL;
char *buffer = NULL;
off_t file_size;
uint32_t nblocks;
void *ctx= NULL;
char md5[16], pre_md5[16];
int pre_md5_valid = 0;
IsoStream *stream, *inp;
#ifdef Libisofs_with_libjtE
int jte_begun = 0;
#endif
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
ret = ISO_ASSERT_FAILURE; goto ex;
}
memset(buffer, 0, BLOCK_SIZE);
LIBISO_ALLOC_MEM(name, char, PATH_MAX);
LIBISO_ALLOC_MEM(buffer, char, BLOCK_SIZE);
t = writer->target;
filelist = writer->data;
@ -380,7 +384,14 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
pre_md5_valid = filesrc_make_md5(t, file, pre_md5, 0);
}
res = filesrc_open(file);
iso_stream_get_file_name(file->stream, name);
/* Get file name from end of filter chain */
for (stream = file->stream; ; stream = inp) {
inp = iso_stream_get_input_stream(stream, 0);
if (inp == NULL)
break;
}
iso_stream_get_file_name(stream, name);
if (res < 0) {
/*
* UPS, very ugly error, the best we can do is just to write
@ -562,13 +573,15 @@ ex:;
iso_md5_end(&ctx, md5);
#ifdef Libisofs_with_libjtE
if (jte_begun) {
if (jte_begun && t != NULL) {
libjte_end_data_file(t->libjte_handle);
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
ISO_LIBJTE_END_FAILED, 0);
}
#endif /* Libisofs_with_libjtE */
LIBISO_FREE_MEM(buffer);
LIBISO_FREE_MEM(name);
return ret;
}

View File

@ -394,7 +394,7 @@ int gzip_stream_convert(IsoStream *stream, void *buf, size_t desired, int flag)
if (cnv_ret == Z_STREAM_ERROR || cnv_ret == Z_BUF_ERROR) {
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
}
if (strm->avail_out < rng->out_buffer_size)
if ((int) strm->avail_out < rng->out_buffer_size)
break; /* output is available */
if (strm->avail_in == 0) /* all pending input consumed */
break;

View File

@ -576,7 +576,8 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
rng->block_pointers[i] =
iso_read_lsb((uint8_t *) (rng->block_pointers + i), 4);
if (i > 0)
if (rng->block_pointers[i] - rng->block_pointers[i - 1]
if ((int) (rng->block_pointers[i] -
rng->block_pointers[i - 1])
> block_max)
block_max = rng->block_pointers[i]
- rng->block_pointers[i - 1];
@ -619,7 +620,7 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
if (ret != Z_OK)
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
rng->buffer_fill = buf_len;
if (buf_len < rng->block_size &&
if ((int) buf_len < rng->block_size &&
i != rng->block_pointer_fill - 1)
return (rng->error_ret = ISO_ZISOFS_WRONG_INPUT);
} else if(ret == 0) {

View File

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

View File

@ -293,6 +293,8 @@ typedef struct
uint32_t bootblocks[Libisofs_max_boot_imageS];
uint32_t catblock; /**< Block for El-Torito catalog */
off_t catsize; /* Size of boot catalog in bytes */
char *catcontent;
/* Whether inode numbers from PX entries shall be discarded */
unsigned int make_new_ino : 1 ;
@ -392,6 +394,8 @@ char* ifs_get_path(IsoFileSource *src)
char *path, *new_path;
int pathlen;
if (data->name == NULL)
return NULL;
path = ifs_get_path(data->parent);
if (path == NULL)
return NULL;
@ -470,15 +474,16 @@ int read_dir(ImageFileSourceData *data)
IsoImageFilesystem *fs;
_ImageFsData *fsdata;
struct ecma119_dir_record *record;
uint8_t buffer[BLOCK_SIZE];
uint8_t *buffer = NULL;
IsoFileSource *child = NULL;
uint32_t pos = 0;
uint32_t tlen = 0;
if (data == NULL) {
return ISO_NULL_POINTER;
ret = ISO_NULL_POINTER; goto ex;
}
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
fs = data->fs;
fsdata = fs->data;
@ -486,7 +491,7 @@ int read_dir(ImageFileSourceData *data)
block = data->sections[0].block;
ret = fsdata->src->read_block(fsdata->src, block, buffer);
if (ret < 0) {
return ret;
goto ex;
}
/* "." entry, get size of the dir and skip */
@ -510,25 +515,37 @@ int read_dir(ImageFileSourceData *data)
*/
ret = fsdata->src->read_block(fsdata->src, ++block, buffer);
if (ret < 0) {
return ret;
goto ex;
}
tlen += 2048 - pos;
pos = 0;
continue;
}
/*
/* (Vreixo:)
* What about ignoring files with existence flag?
* if (record->flags[0] & 0x01)
* continue;
* ts B20306 : >>> One should rather record that flag and write it
* >>> to the new image.
*/
/*
#ifdef Libisofs_wrongly_skip_rr_moveD
/* ts B20306 :
This skipping by name is wrong resp. redundant:
If no rr reading is enabled, then it is the only access point for
the content of relocated directories. So one should not ignore it.
If rr reading is enabled, then the RE entry of mkisofs' RR_MOVED
will cause it to be skipped.
*/
/* (Vreixo:)
* For a extrange reason, mkisofs relocates directories under
* a RR_MOVED dir. It seems that it is only used for that purposes,
* and thus it should be removed from the iso tree before
* generating a new image with libisofs, that don't uses it.
*/
if (data->parent == NULL && record->len_fi[0] == 8
&& !strncmp((char*)record->file_id, "RR_MOVED", 8)) {
@ -539,6 +556,8 @@ int read_dir(ImageFileSourceData *data)
continue;
}
#endif /* Libisofs_wrongly_skip_rr_moveD */
/*
* We pass a NULL parent instead of dir, to prevent the circular
* reference from child to parent.
@ -555,7 +574,7 @@ int read_dir(ImageFileSourceData *data)
free(ifsdata);
free(child);
}
return ret;
goto ex;
}
/* add to the child list */
@ -564,7 +583,7 @@ int read_dir(ImageFileSourceData *data)
node = malloc(sizeof(struct child_list));
if (node == NULL) {
iso_file_source_unref(child);
return ISO_OUT_OF_MEM;
{ret = ISO_OUT_OF_MEM; goto ex;}
}
/*
* Note that we insert in reverse order. This leads to faster
@ -581,7 +600,10 @@ int read_dir(ImageFileSourceData *data)
pos += record->len_dr[0];
}
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(buffer);
return ret;
}
static
@ -1245,7 +1267,8 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
int aa_done = 0;
char *cs_value = NULL;
size_t cs_value_length = 0;
char msg[160];
char *msg = NULL;
uint8_t *buffer = NULL;
int has_px = 0;
@ -1255,7 +1278,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
#endif
if (fs == NULL || fs->data == NULL || record == NULL || src == NULL) {
return ISO_NULL_POINTER;
ret = ISO_NULL_POINTER; goto ex;
}
fsdata = (_ImageFsData*)fs->data;
@ -1274,7 +1297,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
"in interleaved mode. We do not support this mode, as we think "
"it is not used. If you are reading this, then we are wrong :) "
"Please contact libisofs developers, so we can fix this.");
return ISO_UNSUPPORTED_ECMA119;
{ret = ISO_UNSUPPORTED_ECMA119; goto ex;}
}
/*
@ -1285,7 +1308,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
iso_msg_submit(fsdata->msgid, ISO_UNSUPPORTED_ECMA119, 0,
"Unsupported image. This image has at least one file with "
"ECMA-119 Extended Attributes, that are not supported");
return ISO_UNSUPPORTED_ECMA119;
{ret = ISO_UNSUPPORTED_ECMA119; goto ex;}
}
/* TODO #00013 : check for unsupported flags when reading a dir record */
@ -1300,13 +1323,13 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
if (new_name == NULL) {
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
"Cannot retrieve file name");
return ISO_WRONG_ECMA119;
{ret = ISO_WRONG_ECMA119; goto ex;}
}
if (strcmp(new_name, data->name)) {
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
"Multi-extent file lacks last entry.");
free(new_name);
return ISO_WRONG_ECMA119;
{ret = ISO_WRONG_ECMA119; goto ex;}
}
free(new_name);
}
@ -1321,7 +1344,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
if (record->flags[0] & 0x02) {
iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
"Directories with more than one section are not allowed.");
return ISO_WRONG_ECMA119;
{ret = ISO_WRONG_ECMA119; goto ex;}
}
if (*src == NULL) {
@ -1362,7 +1385,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ifsdata->info.st_size += (off_t) ifsdata->sections[ifsdata->nsections].size;
ifsdata->nsections++;
return 2;
{ret = 2; goto ex;}
}
/*
@ -1380,7 +1403,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
iter = susp_iter_new(fsdata->src, record, fsdata->len_skp,
fsdata->msgid);
if (iter == NULL) {
return ISO_OUT_OF_MEM;
{ret = ISO_OUT_OF_MEM; goto ex;}
}
while ((ret = susp_iter_next(iter, &sue)) > 0) {
@ -1449,7 +1472,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
*/
susp_iter_free(iter);
free(name);
return 0; /* it's not an error */
{ret = 0; goto ex;} /* it's not an error */
} else if (SUSP_SIG(sue, 'C', 'L')) {
/*
* This entry is a placeholder for a relocated dir.
@ -1581,13 +1604,14 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
if (ret < 0) {
free(name);
return ret;
goto ex;
}
if ((flag & 1) && aa_string != NULL) {
ret = iso_aa_lookup_attr(aa_string, "isofs.cs",
&cs_value_length, &cs_value, 0);
if (ret == 1) {
LIBISO_ALLOC_MEM(msg, char, 160);
if (fsdata->auto_input_charset & 1) {
if (fsdata->input_charset != NULL)
free(fsdata->input_charset);
@ -1621,7 +1645,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
free(newname);
if (ret < 0) {
free(name);
return ret;
goto ex;
}
} else {
free(name);
@ -1643,7 +1667,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
free(newlinkdest);
if (ret < 0) {
free(name);
return ret;
goto ex;
}
} else {
free(linkdest);
@ -1676,15 +1700,17 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
if (record->len_fi[0] == 1 && record->file_id[0] == 0) {
/* "." entry, we can call this for root node, so... */
if (!(atts.st_mode & S_IFDIR)) {
return iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
"Wrong ISO file name. \".\" not dir");
goto ex;
}
} else {
name = get_name(fsdata, (char*)record->file_id, record->len_fi[0]);
if (name == NULL) {
return iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_ECMA119, 0,
"Cannot retrieve file name");
goto ex;
}
/* remove trailing version number */
@ -1710,24 +1736,24 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
* Thus, we need to read attributes for this directory from the "."
* entry of the relocated dir.
*/
uint8_t buffer[BLOCK_SIZE];
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
ret = fsdata->src->read_block(fsdata->src, relocated_dir, buffer);
if (ret < 0) {
return ret;
goto ex;
}
ret = iso_file_source_new_ifs(fs, parent, (struct ecma119_dir_record*)
buffer, src, 0);
if (ret <= 0) {
return ret;
goto ex;
}
/* but the real name is the name of the placeholder */
ifsdata = (ImageFileSourceData*) (*src)->data;
ifsdata->name = name;
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
}
/* Production of missing inode numbers is delayed until the image is
@ -1763,7 +1789,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ret = iso_msg_submit(fsdata->msgid, ISO_WRONG_RR, 0,
"Link without destination.");
free(name);
return ret;
goto ex;
}
/* ok, we can now create the file source */
@ -1831,13 +1857,17 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
ifsrc->refcount = 1;
*src = ifsrc;
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
ifs_cleanup: ;
free(name);
free(linkdest);
free(ifsdata);
free(ifsrc);
ex:;
LIBISO_FREE_MEM(msg);
LIBISO_FREE_MEM(buffer);
return ret;
}
@ -1846,25 +1876,26 @@ int ifs_get_root(IsoFilesystem *fs, IsoFileSource **root)
{
int ret;
_ImageFsData *data;
uint8_t buffer[BLOCK_SIZE];
uint8_t *buffer = NULL;
if (fs == NULL || fs->data == NULL || root == NULL) {
return ISO_NULL_POINTER;
ret = ISO_NULL_POINTER; goto ex;
}
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
data = (_ImageFsData*)fs->data;
/* open the filesystem */
ret = ifs_fs_open((IsoImageFilesystem*)fs);
if (ret < 0) {
return ret;
goto ex;
}
/* read extend for root record */
ret = data->src->read_block(data->src, data->iso_root_block, buffer);
if (ret < 0) {
ifs_fs_close((IsoImageFilesystem*)fs);
return ret;
goto ex;
}
/* get root attributes from "." entry */
@ -1873,6 +1904,8 @@ int ifs_get_root(IsoFilesystem *fs, IsoFileSource **root)
(struct ecma119_dir_record*) buffer, root, 1);
ifs_fs_close((IsoImageFilesystem*)fs);
ex:;
LIBISO_FREE_MEM(buffer);
return ret;
}
@ -1913,7 +1946,6 @@ static
int ifs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file)
{
int ret;
_ImageFsData *data;
IsoFileSource *src;
char *ptr, *brk_info, *component;
@ -1926,8 +1958,6 @@ int ifs_get_by_path(IsoFilesystem *fs, const char *path, IsoFileSource **file)
return ISO_FILE_BAD_PATH;
}
data = (_ImageFsData*)fs->data;
/* open the filesystem */
ret = ifs_fs_open((IsoImageFilesystem*)fs);
if (ret < 0) {
@ -2035,10 +2065,8 @@ int ifs_fs_close(IsoImageFilesystem *fs)
static
void ifs_fs_free(IsoFilesystem *fs)
{
IsoImageFilesystem *ifs;
_ImageFsData *data;
ifs = (IsoImageFilesystem*)fs;
data = (_ImageFsData*) fs->data;
/* close data source if already openned */
@ -2061,6 +2089,10 @@ void ifs_fs_free(IsoFilesystem *fs)
free(data->biblio_file_id);
free(data->input_charset);
free(data->local_charset);
if(data->catcontent != NULL)
free(data->catcontent);
free(data);
}
@ -2075,14 +2107,15 @@ static
int read_root_susp_entries(_ImageFsData *data, uint32_t block)
{
int ret;
unsigned char buffer[2048];
unsigned char *buffer = NULL;
struct ecma119_dir_record *record;
struct susp_sys_user_entry *sue;
SuspIterator *iter;
LIBISO_ALLOC_MEM(buffer, unsigned char, 2048);
ret = data->src->read_block(data->src, block, buffer);
if (ret < 0) {
return ret;
goto ex;
}
/* record will be the "." directory entry for the root record */
@ -2097,7 +2130,7 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
iter = susp_iter_new(data->src, record, data->len_skp, data->msgid);
if (iter == NULL) {
return ISO_OUT_OF_MEM;
ret = ISO_OUT_OF_MEM; goto ex;
}
/* first entry must be an SP system use entry */
@ -2105,11 +2138,11 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
if (ret < 0) {
/* error */
susp_iter_free(iter);
return ret;
goto ex;
} else if (ret == 0 || !SUSP_SIG(sue, 'S', 'P') ) {
iso_msg_debug(data->msgid, "SUSP/RR is not being used.");
susp_iter_free(iter);
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
}
/* it is a SP system use entry */
@ -2117,9 +2150,10 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
|| sue->data.SP.ef[0] != 0xEF) {
susp_iter_free(iter);
return iso_msg_submit(data->msgid, ISO_UNSUPPORTED_SUSP, 0,
ret = iso_msg_submit(data->msgid, ISO_UNSUPPORTED_SUSP, 0,
"SUSP SP system use entry seems to be wrong. "
"Ignoring Rock Ridge Extensions.");
goto ex;
}
iso_msg_debug(data->msgid, "SUSP/RR is being used.");
@ -2204,10 +2238,13 @@ int read_root_susp_entries(_ImageFsData *data, uint32_t block)
susp_iter_free(iter);
if (ret < 0) {
return ret;
goto ex;
}
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:
LIBISO_FREE_MEM(buffer);
return ret;
}
static
@ -2240,11 +2277,12 @@ int read_pvm(_ImageFsData *data, uint32_t block)
int ret;
struct ecma119_pri_vol_desc *pvm;
struct ecma119_dir_record *rootdr;
uint8_t buffer[BLOCK_SIZE];
uint8_t *buffer = NULL;
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
ret = read_pvd_block(data->src, block, buffer, NULL);
if (ret < 0)
return ret;
goto ex;
/* ok, it is a valid PVD */
pvm = (struct ecma119_pri_vol_desc *)buffer;
@ -2292,7 +2330,10 @@ int read_pvm(_ImageFsData *data, uint32_t block)
* example.
*/
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(buffer);
return ret;
}
/**
@ -2302,16 +2343,18 @@ int read_pvm(_ImageFsData *data, uint32_t block)
static
int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
{
int ret, i, rx, last_done, idx;
int ret, i, rx, last_done, idx, bufsize;
struct el_torito_validation_entry *ve;
struct el_torito_section_header *sh;
struct el_torito_section_entry *entry; /* also usable as default_entry */
unsigned char buffer[BLOCK_SIZE];
unsigned char *buffer = NULL, *rpt;
LIBISO_ALLOC_MEM(buffer, unsigned char, BLOCK_SIZE);
data->num_bootimgs = 0;
data->catsize = 0;
ret = data->src->read_block(data->src, block, buffer);
if (ret < 0) {
return ret;
goto ex;
}
ve = (struct el_torito_validation_entry*)buffer;
@ -2322,7 +2365,7 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
iso_msg_submit(data->msgid, ISO_WRONG_EL_TORITO, 0,
"Wrong or damaged El-Torito Catalog. El-Torito info "
"will be ignored.");
return ISO_WRONG_EL_TORITO;
{ret = ISO_WRONG_EL_TORITO; goto ex;}
}
/* check for a valid platform */
@ -2330,7 +2373,7 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
iso_msg_submit(data->msgid, ISO_UNSUPPORTED_EL_TORITO, 0,
"Unsupported El-Torito platform. Only 80x86 and EFI are "
"supported. El-Torito info will be ignored.");
return ISO_UNSUPPORTED_EL_TORITO;
{ret = ISO_UNSUPPORTED_EL_TORITO; goto ex;}
}
/* ok, once we are here we assume it is a valid catalog */
@ -2340,6 +2383,7 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
data->eltorito = 1;
/* The Default Entry is declared mandatory */
data->catsize = 64;
data->num_bootimgs = 1;
data->platform_ids[0] = ve->platform_id[0];
memcpy(data->id_strings[0], ve->id_string, 24);
@ -2358,10 +2402,21 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
for (rx = 64; (buffer[rx] & 0xfe) == 0x90 && !last_done; rx += 32) {
last_done = buffer[rx] & 1;
/* Read Section Header */
/* >>> ts B10703 : load a new buffer if needed */;
sh = (struct el_torito_section_header *) (buffer + rx);
data->catsize += 32;
for (i = 0; i < sh->num_entries[0]; i++) {
rx += 32;
data->catsize += 32;
/* >>> ts B10703 : load a new buffer if needed */;
if (data->num_bootimgs >= Libisofs_max_boot_imageS) {
/* >>> ts B10703 : need to continue rather than abort */;
ret = iso_msg_submit(data->msgid, ISO_EL_TORITO_WARN, 0,
"Too many boot images found. List truncated.");
goto after_bootblocks;
@ -2383,7 +2438,31 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
}
}
after_bootblocks:;
return ISO_SUCCESS;
if(data->catsize > 0) {
if(data->catcontent != NULL)
free(data->catcontent);
if(data->catsize > 10 * BLOCK_SIZE)
data->catsize = 10 * BLOCK_SIZE;
bufsize = data->catsize;
if (bufsize % BLOCK_SIZE)
bufsize += BLOCK_SIZE - (bufsize % BLOCK_SIZE);
data->catcontent = calloc(bufsize , 1);
if(data->catcontent == NULL) {
data->catsize = 0;
ret = ISO_OUT_OF_MEM;
goto ex;
}
for(rx = 0; rx < bufsize; rx += BLOCK_SIZE) {
rpt = (unsigned char *) (data->catcontent + rx);
ret = data->src->read_block(data->src, block + rx / BLOCK_SIZE, rpt);
if (ret < 0)
goto ex;
}
}
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(buffer);
return ret;
}
@ -2397,11 +2476,12 @@ static
int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
{
int tag_type, ret;
char block[2048], md5[16];
char *block = NULL, md5[16];
int desired = (1 << 2);
void *ctx = NULL;
uint32_t next_tag = 0, i;
LIBISO_ALLOC_MEM(block, char, 2048);
ret = iso_md5_start(&ctx);
if (ret < 0)
goto ex;
@ -2416,11 +2496,12 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
ret = iso_util_eval_md5_tag(block, desired, start_lba + i,
ctx, start_lba, &tag_type, &next_tag, 0);
iso_md5_compute(ctx, block, 2048);
if (ret == ISO_MD5_TAG_COPIED) { /* growing without emulated TOC */
if (ret == (int) ISO_MD5_TAG_COPIED) {/* growing without emulated TOC */
ret = 2;
goto ex;
}
if (ret == ISO_MD5_AREA_CORRUPTED || ret == ISO_MD5_TAG_MISMATCH)
if (ret == (int) ISO_MD5_AREA_CORRUPTED ||
ret == (int) ISO_MD5_TAG_MISMATCH)
ret = ISO_SB_TREE_CORRUPTED;
if (ret < 0)
goto ex;
@ -2454,7 +2535,8 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
}
ret = iso_util_eval_md5_tag(block, (1 << 3), start_lba + i - 1,
ctx, start_lba, &tag_type, &next_tag, 0);
if (ret == ISO_MD5_AREA_CORRUPTED || ret == ISO_MD5_TAG_MISMATCH)
if (ret == (int) ISO_MD5_AREA_CORRUPTED ||
ret == (int) ISO_MD5_TAG_MISMATCH)
ret = ISO_SB_TREE_CORRUPTED;
if (ret < 0)
goto ex;
@ -2463,6 +2545,7 @@ int iso_src_check_sb_tree(IsoDataSource *src, uint32_t start_lba, int flag)
ex:
if (ctx != NULL)
iso_md5_end(&ctx, md5);
LIBISO_FREE_MEM(block);
return ret;
}
@ -2474,21 +2557,22 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
uint32_t block;
IsoImageFilesystem *ifs;
_ImageFsData *data;
uint8_t buffer[BLOCK_SIZE];
uint8_t *buffer = NULL;
if (src == NULL || opts == NULL || fs == NULL) {
return ISO_NULL_POINTER;
ret = ISO_NULL_POINTER; goto ex;
}
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
data = calloc(1, sizeof(_ImageFsData));
if (data == NULL) {
return ISO_OUT_OF_MEM;
ret = ISO_OUT_OF_MEM; goto ex;
}
ifs = calloc(1, sizeof(IsoImageFilesystem));
if (ifs == NULL) {
free(data);
return ISO_OUT_OF_MEM;
{ret = ISO_OUT_OF_MEM; goto ex;}
}
/* get our ref to IsoDataSource */
@ -2496,6 +2580,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
iso_data_source_ref(src);
data->open_count = 0;
data->catcontent = NULL;
/* get an id for the filesystem */
data->id = ++fs_dev_id;
@ -2590,8 +2676,8 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
} else {
data->catblock = iso_read_lsb(vol->boot_catalog, 4);
ret = read_el_torito_boot_catalog(data, data->catblock);
if (ret < 0 && ret != ISO_UNSUPPORTED_EL_TORITO &&
ret != ISO_WRONG_EL_TORITO) {
if (ret < 0 && ret != (int) ISO_UNSUPPORTED_EL_TORITO &&
ret != (int) ISO_WRONG_EL_TORITO) {
goto fs_cleanup;
}
}
@ -2712,11 +2798,14 @@ int iso_image_filesystem_new(IsoDataSource *src, struct iso_read_opts *opts,
/* and finally return. Note that we keep the DataSource opened */
*fs = ifs;
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
fs_cleanup: ;
fs_cleanup: ;
ifs_fs_free(ifs);
free(ifs);
ex:;
LIBISO_FREE_MEM(buffer);
return ret;
}
@ -2764,10 +2853,12 @@ static
int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoFileSource *src, IsoNode **node)
{
int ret, idx;
int ret, idx, to_copy;
struct stat info;
IsoNode *new;
IsoBoot *bootcat;
char *name;
char *dest = NULL;
ImageFileSourceData *data;
_ImageFsData *fsdata;
@ -2780,7 +2871,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
if (builder == NULL || src == NULL || node == NULL || src->data == NULL) {
return ISO_NULL_POINTER;
ret = ISO_NULL_POINTER; goto ex;
}
data = (ImageFileSourceData*)src->data;
@ -2791,7 +2882,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
/* get info about source */
ret = iso_file_source_lstat(src, &info);
if (ret < 0) {
return ret;
goto ex;
}
new = NULL;
@ -2809,7 +2900,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
"We can continue, but that could lead to "
"problems");
if (ret < 0) {
return ret;
goto ex;
}
iso_node_unref((IsoNode*)image->bootcat->node);
}
@ -2820,11 +2911,30 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
if (new == NULL) {
ret = ISO_OUT_OF_MEM;
free(name);
return ret;
goto ex;
}
bootcat = (IsoBoot *) new;
bootcat->lba = data->sections[0].block;
bootcat->size = info.st_size;
if (bootcat->size > 10 * BLOCK_SIZE)
bootcat->size = 10 * BLOCK_SIZE;
bootcat->content = NULL;
if (bootcat->size > 0) {
bootcat->content = calloc(1, bootcat->size);
if (bootcat->content == NULL) {
ret = ISO_OUT_OF_MEM;
free(name);
free(new);
goto ex;
}
to_copy = bootcat->size;
if (bootcat->size > fsdata->catsize)
to_copy = fsdata->catsize;
memcpy(bootcat->content, fsdata->catcontent, to_copy);
}
/* and set the image node */
image->bootcat->node = (IsoBoot*)new;
image->bootcat->node = bootcat;
new->type = LIBISO_BOOT;
new->refcount = 1;
} else {
@ -2834,7 +2944,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_file_source_stream_new(src, &stream);
if (ret < 0) {
free(name);
return ret;
goto ex;
}
/* take a ref to the src, as stream has taken our ref */
iso_file_source_ref(src);
@ -2843,7 +2953,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
if (file == NULL) {
free(name);
iso_stream_unref(stream);
return ISO_OUT_OF_MEM;
{ret = ISO_OUT_OF_MEM; goto ex;}
}
/* mark file as from old session */
@ -2867,7 +2977,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
if (ret < 0) {
free(name);
iso_stream_unref(stream);
return ret;
goto ex;
}
}
@ -2898,7 +3008,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
if (ret < 0) {
free(name);
iso_stream_unref(stream);
return ret;
goto ex;
}
} else {
/* and set the image node */
@ -2915,7 +3025,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
new = calloc(1, sizeof(IsoDir));
if (new == NULL) {
free(name);
return ISO_OUT_OF_MEM;
{ret = ISO_OUT_OF_MEM; goto ex;}
}
new->type = LIBISO_DIR;
new->refcount = 0;
@ -2924,18 +3034,19 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
case S_IFLNK:
{
/* source is a symbolic link */
char dest[LIBISOFS_NODE_PATH_MAX];
IsoSymlink *link;
LIBISO_ALLOC_MEM(dest, char, LIBISOFS_NODE_PATH_MAX);
ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
if (ret < 0) {
free(name);
return ret;
goto ex;
}
link = calloc(1, sizeof(IsoSymlink));
if (link == NULL) {
free(name);
return ISO_OUT_OF_MEM;
{ret = ISO_OUT_OF_MEM; goto ex;}
}
link->dest = strdup(dest);
link->node.type = LIBISO_SYMLINK;
@ -2956,7 +3067,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
special = calloc(1, sizeof(IsoSpecial));
if (special == NULL) {
free(name);
return ISO_OUT_OF_MEM;
{ret = ISO_OUT_OF_MEM; goto ex;}
}
special->dev = info.st_rdev;
special->node.type = LIBISO_SPECIAL;
@ -2998,13 +3109,15 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
}
*node = new;
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
failure:;
/* todo: stuff any possible memory leak here */
if (name != NULL)
free(name);
free(new);
ex:;
LIBISO_FREE_MEM(dest);
return ret;
}
@ -3130,12 +3243,13 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
struct iso_file_section *sections = NULL;
struct el_torito_boot_image *boot;
uint8_t *boot_image_buf = NULL, boot_info_found[16], buf[BLOCK_SIZE];
uint8_t *boot_image_buf = NULL, boot_info_found[16], *buf = NULL;
IsoStream *stream = NULL;
IsoFile *boot_file;
if (image->bootcat == NULL)
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
LIBISO_ALLOC_MEM(buf, uint8_t, BLOCK_SIZE);
for (i = 0; i < image->bootcat->num_bootimages; i++) {
boot = image->bootcat->bootimages[i];
boot_file = boot->image;
@ -3175,7 +3289,7 @@ int iso_image_eval_boot_info_table(IsoImage *image, struct iso_read_opts *opts,
ret = iso_stream_read(stream, boot_image_buf + (img_size - todo),
chunk);
if (ret != chunk) {
ret = (ret < 0) ? ret : ISO_FILE_READ_ERROR;
ret = (ret < 0) ? ret : (int) ISO_FILE_READ_ERROR;
goto ex;
}
todo -= chunk;
@ -3214,6 +3328,7 @@ ex:;
free(boot_image_buf);
if (stream != NULL)
iso_stream_close(stream);
LIBISO_FREE_MEM(buf);
return ret;
}
@ -3232,9 +3347,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
uint8_t *rpt;
IsoFileSource *boot_src;
IsoNode *node;
uint32_t old_checksum_start_lba;
uint32_t old_checksum_end_lba;
uint32_t old_checksum_idx_count;
char *old_checksum_array = NULL;
char checksum_type[81];
uint32_t checksum_size;
@ -3284,9 +3396,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
oldroot = image->root;
oldbootcat = image->bootcat; /* could be NULL */
image->bootcat = NULL;
old_checksum_start_lba = image->checksum_start_lba;
old_checksum_end_lba = image->checksum_end_lba;
old_checksum_idx_count = image->checksum_idx_count;
old_checksum_array = image->checksum_array;
image->checksum_array = NULL;
@ -3419,11 +3528,25 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
"patching may lead to bad results.");
}
if (image->bootcat->node == NULL) {
IsoNode *node = calloc(1, sizeof(IsoBoot));
IsoNode *node;
IsoBoot *bootcat;
node = calloc(1, sizeof(IsoBoot));
if (node == NULL) {
ret = ISO_OUT_OF_MEM;
goto import_revert;
}
bootcat = (IsoBoot *) node;
bootcat->lba = data->catblock;
bootcat->size = data->catsize;
bootcat->content = NULL;
if (bootcat->size > 0) {
bootcat->content = calloc(1, bootcat->size);
if (bootcat->content == NULL) {
ret = ISO_OUT_OF_MEM;
goto import_revert;
}
memcpy(bootcat->content, data->catcontent, bootcat->size);
}
node->type = LIBISO_BOOT;
node->mode = S_IFREG;
node->refcount = 1;
@ -3484,7 +3607,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
}
/* Load from image->checksum_end_lba */;
for (i = 0; i < size; i++) {
for (i = 0; i < (int) size; i++) {
rpt = (uint8_t *) (image->checksum_array + i * 2048);
ret = src->read_block(src, image->checksum_end_lba + i, rpt);
if (ret <= 0)
@ -3497,7 +3620,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
ret = ISO_OUT_OF_MEM;
goto import_revert;
}
for (i = 0; i < image->checksum_idx_count - 1; i++)
for (i = 0; i < (int) image->checksum_idx_count - 1; i++)
iso_md5_compute(ctx, image->checksum_array + i * 16, 16);
iso_md5_end(&ctx, md5);
for (i = 0; i < 16; i++)
@ -3528,9 +3651,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
el_torito_boot_catalog_free(image->bootcat);
image->root = oldroot;
image->bootcat = oldbootcat;
old_checksum_start_lba = image->checksum_start_lba;
old_checksum_end_lba = image->checksum_end_lba;
old_checksum_idx_count = image->checksum_idx_count;
image->checksum_array = old_checksum_array;
old_checksum_array = NULL;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -95,14 +95,14 @@ char* lfs_get_name(IsoFileSource *src)
static
int lfs_lstat(IsoFileSource *src, struct stat *info)
{
_LocalFsFileSource *data;
char *path;
if (src == NULL || info == NULL) {
return ISO_NULL_POINTER;
}
data = src->data;
path = lfs_get_path(src);
if (path == NULL)
return ISO_OUT_OF_MEM;
if (lstat(path, info) != 0) {
int err;
@ -128,6 +128,7 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
err = ISO_FILE_ERROR;
break;
}
free(path);
return err;
}
free(path);
@ -137,14 +138,14 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
static
int lfs_stat(IsoFileSource *src, struct stat *info)
{
_LocalFsFileSource *data;
char *path;
if (src == NULL || info == NULL) {
return ISO_NULL_POINTER;
}
data = src->data;
path = lfs_get_path(src);
if (path == NULL)
return ISO_OUT_OF_MEM;
if (stat(path, info) != 0) {
int err;
@ -170,6 +171,7 @@ int lfs_stat(IsoFileSource *src, struct stat *info)
err = ISO_FILE_ERROR;
break;
}
free(path);
return err;
}
free(path);
@ -180,13 +182,11 @@ static
int lfs_access(IsoFileSource *src)
{
int ret;
_LocalFsFileSource *data;
char *path;
if (src == NULL) {
return ISO_NULL_POINTER;
}
data = src->data;
path = lfs_get_path(src);
ret = iso_eaccess(path);
@ -413,7 +413,6 @@ static
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
{
int size, ret;
_LocalFsFileSource *data;
char *path;
if (src == NULL || buf == NULL) {
@ -424,7 +423,6 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
return ISO_WRONG_ARG_VALUE;
}
data = src->data;
path = lfs_get_path(src);
/*
@ -456,7 +454,7 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
/* NULL-terminate the buf */
ret = ISO_SUCCESS;
if (size >= bufsiz) {
if ((size_t) size >= bufsiz) {
ret = ISO_RR_PATH_TOO_LONG;
size = bufsiz - 1;
}
@ -497,9 +495,6 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
size_t num_attrs = 0, *value_lengths = NULL, result_len, sret;
char *path = NULL, **names = NULL, **values = NULL;
unsigned char *result = NULL;
_LocalFsFileSource *data;
data = src->data;
*aa_string = NULL;
@ -511,11 +506,18 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
to AAIP ACL representation. Clean out st_mode ACL entries.
*/
path = iso_file_source_get_path(src);
if (path == NULL) {
ret = ISO_NULL_POINTER;
goto ex;
}
ret = aaip_get_attr_list(path, &num_attrs, &names,
&value_lengths, &values,
(!(flag & 2)) | 2 | (flag & 4) | 16);
if (ret <= 0) {
ret = ISO_FILE_ERROR;
if (ret == -2)
ret = ISO_AAIP_NO_GET_LOCAL;
else
ret = ISO_FILE_ERROR;
goto ex;
}
if (num_attrs == 0)
@ -817,6 +819,15 @@ int iso_local_filesystem_new(IsoFilesystem **fs)
}
int iso_local_attr_support(int flag)
{
int ret;
ret= aaip_local_attr_support(flag & 255);
return ret;
}
int iso_local_get_acl_text(char *disk_path, char **text, int flag)
{
int ret;
@ -857,13 +868,19 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
int ret;
ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths,
values, (flag & (8 | 32)) | !(flag & 1));
values, (flag & (8 | 32 | 64)) | !(flag & 1));
if (ret <= 0) {
if (ret == -1)
return ISO_OUT_OF_MEM;
if (ret == -2)
return ISO_AAIP_BAD_AASTRING;
return ISO_AAIP_NO_SET_LOCAL;
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;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2011-2012 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -17,6 +18,7 @@
#include "image.h"
#include "filesrc.h"
#include "eltorito.h"
#include "util.h"
#include <stdlib.h>
#include <stdio.h>
@ -73,7 +75,7 @@ void iso1999_node_free(Iso1999Node *node)
return;
}
if (node->type == ISO1999_DIR) {
int i;
size_t i;
for (i = 0; i < node->info.dir->nchildren; i++) {
iso1999_node_free(node->info.dir->children[i]);
}
@ -307,7 +309,10 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
Iso1999Node **children;
IsoHTable *table;
int need_sort = 0;
char *full_name = NULL, *tmp = NULL;
LIBISO_ALLOC_MEM(full_name, char, 208);
LIBISO_ALLOC_MEM(tmp, char, 208);
nchildren = dir->info.dir->nchildren;
children = dir->info.dir->children;
@ -315,19 +320,18 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
(compare_function_t)strcmp, &table);
if (ret < 0) {
return ret;
goto ex;
}
for (i = 0; i < nchildren; ++i) {
char *name = children[i]->name;
ret = iso_htable_add(table, name, name);
if (ret < 0) {
goto mangle_cleanup;
goto ex;
}
}
for (i = 0; i < nchildren; ++i) {
char *name, *ext;
char full_name[208];
int max; /* computed max len for name, without extension */
int j = i;
int digits = 1; /* characters to change per name */
@ -384,7 +388,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
* This can't happen with current limit of digits.
*/
ret = ISO_ERROR;
goto mangle_cleanup;
goto ex;
}
}
/* ok, reduce name by digits */
@ -398,7 +402,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
}
max = 207 - digits;
name = full_name;
if (max < strlen(name)) {
if ((size_t) max < strlen(name)) {
name[max] = '\0';
}
/* let ext be an empty string */
@ -408,7 +412,6 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
ok = 1;
/* change name of each file */
for (k = i; k <= j; ++k) {
char tmp[208];
char fmt[16];
if (dot != NULL) {
sprintf(fmt, "%%s%%0%dd.%%s", digits);
@ -431,7 +434,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
char *new = strdup(tmp);
if (new == NULL) {
ret = ISO_OUT_OF_MEM;
goto mangle_cleanup;
goto ex;
}
iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"",
children[k]->name, new);
@ -459,7 +462,7 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
}
if (digits == 8) {
ret = ISO_MANGLE_TOO_MUCH_FILES;
goto mangle_cleanup;
goto ex;
}
i = j;
}
@ -473,8 +476,10 @@ int mangle_single_dir(Ecma119Image *img, Iso1999Node *dir)
ret = ISO_SUCCESS;
mangle_cleanup : ;
ex:;
iso_htable_destroy(table, NULL);
LIBISO_FREE_MEM(tmp);
LIBISO_FREE_MEM(full_name);
return ret;
}
@ -683,8 +688,9 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
: (uint8_t*)node->name;
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
IsoNode *iso;
len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1);
len_dr = 33 + len_fi + ((len_fi % 2) ? 0 : 1);
memcpy(rec->file_id, name, len_fi);
@ -714,7 +720,15 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
rec->len_dr[0] = len_dr;
iso_bb(rec->block, block, 4);
iso_bb(rec->length, len, 4);
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
*/
iso= node->node;
iso_datetime_7(rec->recording_time,
(t->dir_rec_mtime & 4) ? ( t->replace_timestamps ?
t->timestamp : iso->mtime )
: t->now, t->always_gmt);
rec->flags[0] = ((node->type == ISO1999_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
rec->len_fi[0] = len_fi;
@ -810,15 +824,15 @@ static
int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
{
int ret;
uint8_t buffer[BLOCK_SIZE];
uint8_t *buffer = NULL;
size_t i;
size_t fi_len, len;
/* buf will point to current write position on buffer */
uint8_t *buf = buffer;
uint8_t *buf;
/* initialize buffer with 0s */
memset(buffer, 0, BLOCK_SIZE);
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
buf = buffer;
/* write the "." and ".." entries first */
write_one_dir_record(t, dir, 0, buf, 1, 0);
@ -832,7 +846,7 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
/* compute len of directory entry */
fi_len = strlen(child->name);
len = fi_len + 33 + (fi_len % 2 ? 0 : 1);
len = fi_len + 33 + ((fi_len % 2) ? 0 : 1);
nsections = (child->type == ISO1999_FILE) ? child->info.file->nsections : 1;
for (section = 0; section < nsections; ++section) {
@ -840,7 +854,7 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
/* dir doesn't fit in current block */
ret = iso_write(t, buffer, BLOCK_SIZE);
if (ret < 0) {
return ret;
goto ex;
}
memset(buffer, 0, BLOCK_SIZE);
buf = buffer;
@ -853,6 +867,8 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
/* write the last block */
ret = iso_write(t, buffer, BLOCK_SIZE);
ex:;
LIBISO_FREE_MEM(buffer);
return ret;
}
@ -885,13 +901,17 @@ static
int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
{
size_t i, len;
uint8_t buf[256]; /* 256 is just a convenient size larger enought */
uint8_t *buf = NULL;
struct ecma119_path_table_record *rec;
void (*write_int)(uint8_t*, uint32_t, int);
Iso1999Node *dir;
uint32_t path_table_size;
int parent = 0;
int ret= ISO_SUCCESS;
uint8_t *zeros = NULL;
/* 256 is just a convenient size large enought */
LIBISO_ALLOC_MEM(buf, uint8_t, 256);
path_table_size = 0;
write_int = l_type ? iso_lsb : iso_msb;
@ -918,7 +938,7 @@ int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
ret = iso_write(t, buf, len);
if (ret < 0) {
/* error */
return ret;
goto ex;
}
path_table_size += len;
}
@ -926,11 +946,14 @@ int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
/* we need to fill the last block with zeros */
path_table_size %= BLOCK_SIZE;
if (path_table_size) {
uint8_t zeros[BLOCK_SIZE];
LIBISO_ALLOC_MEM(zeros, uint8_t, BLOCK_SIZE);
len = BLOCK_SIZE - path_table_size;
memset(zeros, 0, len);
ret = iso_write(t, zeros, len);
}
ex:;
LIBISO_FREE_MEM(zeros);
LIBISO_FREE_MEM(buf);
return ret;
}

View File

@ -1,6 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2011-2012 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -69,7 +70,7 @@ void joliet_node_free(JolietNode *node)
return;
}
if (node->type == JOLIET_DIR) {
int i;
size_t i;
for (i = 0; i < node->info.dir->nchildren; i++) {
joliet_node_free(node->info.dir->children[i]);
}
@ -348,7 +349,11 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
JolietNode **children;
IsoHTable *table;
int need_sort = 0;
uint16_t *full_name = NULL;
uint16_t *tmp = NULL;
LIBISO_ALLOC_MEM(full_name, uint16_t, LIBISO_JOLIET_NAME_MAX);
LIBISO_ALLOC_MEM(tmp, uint16_t, LIBISO_JOLIET_NAME_MAX);
nchildren = dir->info.dir->nchildren;
children = dir->info.dir->children;
@ -359,7 +364,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
(compare_function_t)ucscmp, &table);
if (ret < 0) {
return ret;
goto ex;
}
for (i = 0; i < nchildren; ++i) {
uint16_t *name = children[i]->name;
@ -371,7 +376,6 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
for (i = 0; i < nchildren; ++i) {
uint16_t *name, *ext;
uint16_t full_name[LIBISO_JOLIET_NAME_MAX];
int max; /* computed max len for name, without extension */
int j = i;
int digits = 1; /* characters to change per name */
@ -446,7 +450,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
max = maxchar + 1 - digits;
}
name = full_name;
if (max < ucslen(name)) {
if ((size_t) max < ucslen(name)) {
name[max] = 0;
}
/* let ext be an empty string */
@ -456,7 +460,6 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ok = 1;
/* change name of each file */
for (k = i; k <= j; ++k) {
uint16_t tmp[LIBISO_JOLIET_NAME_MAX];
while (1) {
ret = joliet_create_mangled_name(tmp, name, digits,
change, ext);
@ -518,7 +521,10 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
ret = ISO_SUCCESS;
mangle_cleanup : ;
ex:;
iso_htable_destroy(table, NULL);
LIBISO_FREE_MEM(tmp);
LIBISO_FREE_MEM(full_name);
return ret;
}
@ -752,8 +758,9 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
: (uint8_t*)node->name;
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
IsoNode *iso;
len_dr = 33 + len_fi + (len_fi % 2 ? 0 : 1);
len_dr = 33 + len_fi + ((len_fi % 2) ? 0 : 1);
memcpy(rec->file_id, name, len_fi);
@ -791,7 +798,15 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
rec->len_dr[0] = len_dr;
iso_bb(rec->block, block - t->eff_partition_offset, 4);
iso_bb(rec->length, len, 4);
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
*/
iso= node->node;
iso_datetime_7(rec->recording_time,
(t->dir_rec_mtime & 2) ? ( t->replace_timestamps ?
t->timestamp : iso->mtime )
: t->now, t->always_gmt);
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
rec->len_fi[0] = len_fi;
@ -919,15 +934,16 @@ static
int write_one_dir(Ecma119Image *t, JolietNode *dir)
{
int ret;
uint8_t buffer[BLOCK_SIZE];
uint8_t *buffer = NULL;
size_t i;
size_t fi_len, len;
/* buf will point to current write position on buffer */
uint8_t *buf = buffer;
uint8_t *buf;
/* initialize buffer with 0s */
memset(buffer, 0, BLOCK_SIZE);
LIBISO_ALLOC_MEM(buffer, uint8_t, BLOCK_SIZE);
buf = buffer;
/* write the "." and ".." entries first */
write_one_dir_record(t, dir, 0, buf, 1, 0);
@ -954,7 +970,7 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
/* dir doesn't fit in current block */
ret = iso_write(t, buffer, BLOCK_SIZE);
if (ret < 0) {
return ret;
goto ex;
}
memset(buffer, 0, BLOCK_SIZE);
buf = buffer;
@ -967,6 +983,8 @@ int write_one_dir(Ecma119Image *t, JolietNode *dir)
/* write the last block */
ret = iso_write(t, buffer, BLOCK_SIZE);
ex:;
LIBISO_FREE_MEM(buffer);
return ret;
}
@ -999,14 +1017,18 @@ static
int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
{
size_t i, len;
uint8_t buf[256]; /* 256 is just a convenient size larger enought */
uint8_t *buf = NULL;
struct ecma119_path_table_record *rec;
void (*write_int)(uint8_t*, uint32_t, int);
JolietNode *dir;
uint32_t path_table_size;
int parent = 0;
int ret= ISO_SUCCESS;
uint8_t *zeros = NULL;
/* 256 is just a convenient size large enought */
LIBISO_ALLOC_MEM(buf, uint8_t, 256);
LIBISO_ALLOC_MEM(zeros, uint8_t, BLOCK_SIZE);
path_table_size = 0;
write_int = l_type ? iso_lsb : iso_msb;
@ -1033,7 +1055,7 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
ret = iso_write(t, buf, len);
if (ret < 0) {
/* error */
return ret;
goto ex;
}
path_table_size += len;
}
@ -1041,11 +1063,13 @@ int write_path_table(Ecma119Image *t, JolietNode **pathlist, int l_type)
/* we need to fill the last block with zeros */
path_table_size %= BLOCK_SIZE;
if (path_table_size) {
uint8_t zeros[BLOCK_SIZE];
len = BLOCK_SIZE - path_table_size;
memset(zeros, 0, len);
ret = iso_write(t, zeros, len);
}
ex:;
LIBISO_FREE_MEM(zeros);
LIBISO_FREE_MEM(buf);
return ret;
}

View File

@ -4,7 +4,7 @@
/*
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
* Copyright (c) 2009-2011 Thomas Schmitt
* Copyright (c) 2009-2012 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -18,15 +18,32 @@
/*
*
* Applications must use 64 bit off_t, e.g. on 32-bit GNU/Linux by defining
* Applications must use 64 bit off_t.
* E.g. on 32-bit GNU/Linux by defining
* #define _LARGEFILE_SOURCE
* #define _FILE_OFFSET_BITS 64
* or take special precautions to interface with the library by 64 bit integers
* where this .h files prescribe off_t. Not to use 64 bit file i/o will keep
* the application from producing and processing ISO images of more than 2 GB
* size.
*
* The minimum requirement is to interface with the library by 64 bit signed
* integers where libisofs.h or libisoburn.h prescribe off_t.
* Failure to do so may result in surprising malfunction or memory faults.
*
* Application files which include libisofs/libisofs.h must provide
* definitions for uint32_t and uint8_t.
* This can be achieved either:
* - by using autotools which will define HAVE_STDINT_H or HAVE_INTTYPES_H
* according to its ./configure tests,
* - or by defining the macros HAVE_STDINT_H resp. HAVE_INTTYPES_H according
* to the local situation,
* - or by appropriately defining uint32_t and uint8_t by other means,
* e.g. by including inttypes.h before including libisofs.h
*/
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
/*
* Normally this API is operated via public functions and opaque object
@ -42,16 +59,90 @@
#include <sys/stat.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#else
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#endif
#include <stdlib.h>
/**
* The following two functions and three macros are utilities to help ensuring
* version match of application, compile time header, and runtime library.
*/
/**
* These three release version numbers tell the revision of this header file
* and of the API it describes. They are memorized by applications at
* compile time.
* They must show the same values as these symbols in ./configure.ac
* LIBISOFS_MAJOR_VERSION=...
* LIBISOFS_MINOR_VERSION=...
* LIBISOFS_MICRO_VERSION=...
* Note to anybody who does own work inside libisofs:
* Any change of configure.ac or libisofs.h has to keep up this equality !
*
* Before usage of these macros on your code, please read the usage discussion
* below.
*
* @since 0.6.2
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 2
#define iso_lib_header_version_micro 2
/**
* Get version of the libisofs library at runtime.
* NOTE: This function may be called before iso_init().
*
* @since 0.6.2
*/
void iso_lib_version(int *major, int *minor, int *micro);
/**
* Check at runtime if the library is ABI compatible with the given version.
* NOTE: This function may be called before iso_init().
*
* @return
* 1 lib is compatible, 0 is not.
*
* @since 0.6.2
*/
int iso_lib_is_compatible(int major, int minor, int micro);
/**
* Usage discussion:
*
* Some developers of the libburnia project have differing opinions how to
* ensure the compatibility of libaries and applications.
*
* It is about whether to use at compile time and at runtime the version
* numbers provided here. Thomas Schmitt advises to use them. Vreixo Formoso
* advises to use other means.
*
* At compile time:
*
* Vreixo Formoso advises to leave proper version matching to properly
* programmed checks in the the application's build system, which will
* eventually refuse compilation.
*
* Thomas Schmitt advises to use the macros defined here for comparison with
* the application's requirements of library revisions and to eventually
* break compilation.
*
* Both advises are combinable. I.e. be master of your build system and have
* #if checks in the source code of your application, nevertheless.
*
* At runtime (via iso_lib_is_compatible()):
*
* Vreixo Formoso advises to compare the application's requirements of
* library revisions with the runtime library. This is to allow runtime
* libraries which are young enough for the application but too old for
* the lib*.h files seen at compile time.
*
* Thomas Schmitt advises to compare the header revisions defined here with
* the runtime library. This is to enforce a strictly monotonous chain of
* revisions from app to header to library, at the cost of excluding some older
* libraries.
*
* These two advises are mutually exclusive.
*/
struct burn_source;
/**
@ -158,6 +249,15 @@ struct iso_file_section
uint32_t size;
};
/* If you get here because of a compilation error like
/usr/include/libisofs/libisofs.h:166: error:
expected specifier-qualifier-list before 'uint32_t'
then see the paragraph above about the definition of uint32_t.
*/
/**
* Context for iterate on directory children.
* @see iso_dir_get_children()
@ -860,15 +960,17 @@ extern ino_t serial_id;
struct IsoStream_Iface
{
/*
* Current version of the interface, set to 1 or 2.
* Current version of the interface.
* Version 0 (since 0.6.4)
* deprecated but still valid.
* Version 1 (since 0.6.8)
* update_size() added.
* Version 2 (since 0.6.18)
* get_input_stream() added. A filter stream must have version 2.
* get_input_stream() added.
* A filter stream must have version 2 at least.
* Version 3 (since 0.6.20)
* compare() added. A filter stream should have version 3.
* compare() added.
* A filter stream should have version 3 at least.
* Version 4 (since 1.0.2)
* clone_stream() added.
*/
@ -995,8 +1097,8 @@ struct IsoStream_Iface
* This is also appropriate if one has reason to implement stream.cmp_ino()
* without having an own special comparison algorithm.
*
* With filter streams the decision whether the underlying chains of
* streams match should be delegated to
* With filter streams, the decision whether the underlying chains of
* streams match, should be delegated to
* iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
* iso_stream_get_input_stream(s2, 0), 0);
*
@ -1168,89 +1270,6 @@ int iso_image_new(const char *name, IsoImage **image);
void iso_image_set_ignore_aclea(IsoImage *image, int what);
/**
* The following two functions three macros are utilities to help ensuring
* version match of application, compile time header, and runtime library.
*/
/**
* Get version of the libisofs library at runtime.
* NOTE: This function may be called before iso_init().
*
* @since 0.6.2
*/
void iso_lib_version(int *major, int *minor, int *micro);
/**
* Check at runtime if the library is ABI compatible with the given version.
* NOTE: This function may be called before iso_init().
*
* @return
* 1 lib is compatible, 0 is not.
*
* @since 0.6.2
*/
int iso_lib_is_compatible(int major, int minor, int micro);
/**
* These three release version numbers tell the revision of this header file
* and of the API it describes. They are memorized by applications at
* compile time.
* They must show the same values as these symbols in ./configure.ac
* LIBISOFS_MAJOR_VERSION=...
* LIBISOFS_MINOR_VERSION=...
* LIBISOFS_MICRO_VERSION=...
* Note to anybody who does own work inside libisofs:
* Any change of configure.ac or libisofs.h has to keep up this equality !
*
* Before usage of these macros on your code, please read the usage discussion
* below.
*
* @since 0.6.2
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 0
#define iso_lib_header_version_micro 8
/**
* Usage discussion:
*
* Some developers of the libburnia project have differing opinions how to
* ensure the compatibility of libaries and applications.
*
* It is about whether to use at compile time and at runtime the version
* numbers provided here. Thomas Schmitt advises to use them. Vreixo Formoso
* advises to use other means.
*
* At compile time:
*
* Vreixo Formoso advises to leave proper version matching to properly
* programmed checks in the the application's build system, which will
* eventually refuse compilation.
*
* Thomas Schmitt advises to use the macros defined here for comparison with
* the application's requirements of library revisions and to eventually
* break compilation.
*
* Both advises are combinable. I.e. be master of your build system and have
* #if checks in the source code of your application, nevertheless.
*
* At runtime (via iso_lib_is_compatible()):
*
* Vreixo Formoso advises to compare the application's requirements of
* library revisions with the runtime library. This is to allow runtime
* libraries which are young enough for the application but too old for
* the lib*.h files seen at compile time.
*
* Thomas Schmitt advises to compare the header revisions defined here with
* the runtime library. This is to enforce a strictly monotonous chain of
* revisions from app to header to library, at the cost of excluding some older
* libraries.
*
* These two advises are mutually exclusive.
*/
/**
* Creates an IsoWriteOpts for writing an image. You should set the options
* desired with the correspondent setters.
@ -1517,6 +1536,45 @@ int iso_write_opts_set_omit_version_numbers(IsoWriteOpts *opts, int omit);
*/
int iso_write_opts_set_allow_deep_paths(IsoWriteOpts *opts, int allow);
/**
* This call describes the directory where to store Rock Ridge relocated
* directories.
* If not iso_write_opts_set_allow_deep_paths(,1) is in effect, then it may
* become necessary to relocate directories so that no ECMA-119 file path
* has more than 8 components. These directories are grafted into either
* the root directory of the ISO image or into a dedicated relocation
* directory.
* For Rock Ridge, the relocated directories are linked forth and back to
* placeholders at their original positions in path level 8. Directories
* marked by Rock Ridge entry RE are to be considered artefacts of relocation
* and shall not be read into a Rock Ridge tree. Instead they are to be read
* via their placeholders and their links.
* For plain ECMA-119, the relocation directory and the relocated directories
* are just normal directories which contain normal files and directories.
* @param opts
* The option set to be manipulated.
* @param name
* The name of the relocation directory in the root directory. Do not
* prepend "/". An empty name or NULL will direct relocated directories
* into the root directory. This is the default.
* If the given name does not exist in the root directory when
* iso_image_create_burn_source() is called, and if there are directories
* at path level 8, then directory /name will be created automatically.
* The name given by this call will be compared with iso_node_get_name()
* of the directories in the root directory, not with the final ECMA-119
* names of those directories.
* @parm flags
* Bitfield for control purposes.
* bit0= Mark the relocation directory by a Rock Ridge RE entry, if it
* gets created during iso_image_create_burn_source(). This will
* make it invisible for most Rock Ridge readers.
* bit1= not settable via API (used internally)
* @return
* 1 success, < 0 error
* @since 1.2.2
*/
int iso_write_opts_set_rr_reloc(IsoWriteOpts *opts, char *name, int flags);
/**
* Allow path in the ISO-9660 tree to have more than 255 characters.
* This breaks ECMA-119 specification. Use with caution.
@ -1526,7 +1584,7 @@ int iso_write_opts_set_allow_deep_paths(IsoWriteOpts *opts, int allow);
int iso_write_opts_set_allow_longer_paths(IsoWriteOpts *opts, int allow);
/**
* Allow a single file or directory hierarchy to have up to 37 characters.
* Allow a single file or directory identifier to have up to 37 characters.
* This is larger than the 31 characters allowed by ISO level 2, and the
* extra space is taken from the version number, so this also forces
* omit_version_numbers.
@ -1557,13 +1615,15 @@ int iso_write_opts_set_no_force_dots(IsoWriteOpts *opts, int no);
* Allow lowercase characters in ISO-9660 filenames. By default, only
* uppercase characters, numbers and a few other characters are allowed.
* This breaks ECMA-119 specification. Use with caution.
* If lowercase is not allowed then those letters get mapped to uppercase
* letters.
*
* @since 0.6.2
*/
int iso_write_opts_set_allow_lowercase(IsoWriteOpts *opts, int allow);
/**
* Allow all ASCII characters to be appear on an ISO-9660 filename. Note
* Allow all 8-bit characters to appear on an ISO-9660 filename. Note
* that "/" and 0x0 characters are never allowed, even in RR names.
* This breaks ECMA-119 specification. Use with caution.
*
@ -1571,6 +1631,20 @@ int iso_write_opts_set_allow_lowercase(IsoWriteOpts *opts, int allow);
*/
int iso_write_opts_set_allow_full_ascii(IsoWriteOpts *opts, int allow);
/**
* If not iso_write_opts_set_allow_full_ascii() is set to 1:
* Allow all 7-bit characters that would be allowed by allow_full_ascii, but
* map lowercase to uppercase if iso_write_opts_set_allow_lowercase()
* is not set to 1.
* @param opts
* The option set to be manipulated.
* @param allow
* If not zero, then allow what is described above.
*
* @since 1.2.2
*/
int iso_write_opts_set_allow_7bit_ascii(IsoWriteOpts *opts, int allow);
/**
* Allow all characters to be part of Volume and Volset identifiers on
* the Primary Volume Descriptor. This breaks ISO-9660 contraints, but
@ -1634,9 +1708,35 @@ int iso_write_opts_set_rrip_1_10_px_ino(IsoWriteOpts *opts, int enable);
int iso_write_opts_set_aaip_susp_1_10(IsoWriteOpts *opts, int oldvers);
/**
* Store as ECMA-119 Directory Record timestamp the mtime of the source
* Store as ECMA-119 Directory Record timestamp the mtime of the source node
* rather than the image creation time.
* If storing of mtime is enabled, then the settings of
* iso_write_opts_set_replace_timestamps() apply. (replace==1 will revoke,
* replace==2 will override mtime by iso_write_opts_set_default_timestamp().
*
* Since version 1.2.0 this may apply also to Joliet and ISO 9660:1999. To
* reduce the probability of unwanted behavior changes between pre-1.2.0 and
* post-1.2.0, the bits for Joliet and ISO 9660:1999 also enable ECMA-119.
* The hopefully unlikely bit14 may then be used to disable mtime for ECMA-119.
*
* To enable mtime for all three directory trees, submit 7.
* To disable this feature completely, submit 0.
*
* @param opts
* The option set to be manipulated.
* @param allow
* If this parameter is negative, then mtime is enabled only for ECMA-119.
* With positive numbers, the parameter is interpreted as bit field :
* bit0= enable mtime for ECMA-119
* bit1= enable mtime for Joliet and ECMA-119
* bit2= enable mtime for ISO 9660:1999 and ECMA-119
* bit14= disable mtime for ECMA-119 although some of the other bits
* would enable it
* @since 1.2.0
* Before version 1.2.0 this applied only to ECMA-119 :
* 0 stored image creation time in ECMA-119 tree.
* Any other value caused storing of mtime.
* Joliet and ISO 9660:1999 always stored the image creation time.
* @since 0.6.12
*/
int iso_write_opts_set_dir_rec_mtime(IsoWriteOpts *opts, int allow);
@ -1764,8 +1864,10 @@ int iso_write_opts_set_default_gid(IsoWriteOpts *opts, gid_t gid);
/**
* 0 to use IsoNode timestamps, 1 to use recording time, 2 to use
* values from timestamp field. This has only meaning if RR extensions
* are enabled.
* values from timestamp field. This applies to the timestamps of Rock Ridge
* and if the use of mtime is enabled by iso_write_opts_set_dir_rec_mtime().
* In the latter case, value 1 will revoke the recording of mtime, value
* 2 will override mtime by iso_write_opts_set_default_timestamp().
*
* @see iso_write_opts_set_default_timestamp
* @since 0.6.2
@ -2858,6 +2960,35 @@ int iso_image_add_boot_image(IsoImage *image, const char *image_path,
int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
IsoFile **imgnode, IsoBoot **catnode);
/**
* Get detailed information about the boot catalog that was loaded from
* an ISO image.
* The boot catalog links the El Torito boot record at LBA 17 with the
* boot images which are IsoFile objects in the image. The boot catalog
* itself is not a regular file and thus will not deliver an IsoStream.
* Its content is usually quite short and can be obtained by this call.
*
* @param image
* The image to inquire.
* @param catnode
* Will return the boot catalog tree node. No extra ref is taken.
* @param lba
* Will return the block address of the boot catalog in the image.
* @param content
* Will return either NULL or an allocated memory buffer with the
* content bytes of the boot catalog.
* Dispose it by free() when no longer needed.
* @param size
* Will return the number of bytes in content.
* @return
* 1 if reply is valid, 0 if not boot catalog was loaded, < 0 on error.
*
* @since 1.1.2
*/
int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
char **content, off_t *size);
/**
* Get all El-Torito boot images of an ISO image.
*
@ -5742,6 +5873,30 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
* from local files.
*/
/**
* Inquire whether local filesystem operations with ACL or xattr are enabled
* inside libisofs. They may be disabled because of compile time decisions.
* E.g. because the operating system does not support these features or
* because libisofs has not yet an adapter to use them.
*
* @param flag
* Bitfield for control purposes
* bit0= inquire availability of ACL
* bit1= inquire availability of xattr
* bit2 - bit7= Reserved for future types.
* It is permissibile to set them to 1 already now.
* bit8 and higher: reserved, submit 0
* @return
* Bitfield corresponding to flag. If bits are set, th
* bit0= ACL adapter is enabled
* bit1= xattr adapter is enabled
* bit2 - bit7= Reserved for future types.
* bit8 and higher: reserved, do not interpret these
*
* @since 1.1.6
*/
int iso_local_attr_support(int flag);
/**
* Get an ACL of the given file in the local filesystem in long text form.
*
@ -5785,7 +5940,7 @@ int iso_local_get_acl_text(char *disk_path, char **text, int flag);
* bit5= in case of symbolic link: manipulate link target
* @return
* > 0 ok
* 0 no ACL manipulation adapter available
* 0 no ACL manipulation adapter available for desired ACL type
* -1 failure of system ACL service (see errno)
* -2 attempt to manipulate ACL of a symbolic link without bit5
* resp. with no suitable link target
@ -5874,6 +6029,9 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
* bit3= do not ignore eventual non-user attributes.
* I.e. those with a name which does not begin by "user."
* bit5= in case of symbolic link: manipulate link target
* bit6= @since 1.1.6
tolerate inappropriate presence or absence of
* directory "default" ACL
* @return
* 1 = ok
* < 0 = error
@ -6839,9 +6997,16 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
/** Reserved Rock Ridge leaf name (FAILURE, HIGH, -378) */
#define ISO_RR_NAME_RESERVED 0xE830FE86
/** Rock Ridge path too long (FAILURE, HIGH, -379) */
/** Rock Ridge path too long (FAILURE, HIGH, -379) */
#define ISO_RR_PATH_TOO_LONG 0xE830FE85
/** Attribute name cannot be represented (FAILURE, HIGH, -380) */
#define ISO_AAIP_BAD_ATTR_NAME 0xE830FE84
/** ACL text contains multiple entries of user::, group::, other::
(FAILURE, HIGH, -379) */
#define ISO_AAIP_ACL_MULT_OBJ 0xE830FE83
/* Internal developer note:
@ -7060,6 +7225,11 @@ struct burn_source {
/* currently none being tested */
/* Perform the operations promised by iso_write_opts_set_rr_reloc() */
#define Libisofs_with_rr_reloc_diR yes
/* ---------------------------- Experiments ---------------------------- */

View File

@ -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: *;
};

View File

@ -135,7 +135,7 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
static int h = 64, s = 32;
int i, warn_size = 0, id;
int i, id;
char *wpt;
off_t imgsize, cylsize, frac, padding, c, cc;
@ -164,7 +164,6 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
*img_blocks = imgsize / (off_t) 2048;
c = imgsize / cylsize;
if (c > 1024) {
warn_size = 1;
cc = 1024;
} else
cc = c;
@ -424,7 +423,7 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
/* # Offset 446
*/
for (part = 1 ; part <= 4; part++) {
if (part != part_number) {
if ((int) part != part_number) {
/* if this_partition != partition_number: write 16 zero bytes */
memset(wpt, 0, 16);
wpt+= 16;

View File

@ -229,10 +229,10 @@ static int md5_init(libisofs_md5_ctx *ctx, int flag)
static int md5_update(libisofs_md5_ctx *ctx, unsigned char *data,
int datalen, int flag)
{
unsigned int i, index, partlen;
int i, index, partlen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((ctx->count[0] >> 3) & 0x3F);
index = ((ctx->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((ctx->count[0] += ((uint32_t) datalen << 3)) <
((uint32_t) datalen << 3))
@ -621,11 +621,6 @@ int checksum_writer_write_data(IsoImageWriter *writer)
void *ctx = NULL;
char md5[16];
#ifdef NIX
char tag_block[2048];
int l;
#endif
if (writer == NULL) {
return ISO_ASSERT_FAILURE;
}
@ -724,15 +719,16 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
{
void *ctx = NULL;
off_t pos = 0, line_start;
int record_len, block_len, res, i;
char postext[40], md5[16], record[160];
int record_len, block_len, ret, i;
char postext[40], md5[16], *record = NULL;
LIBISO_ALLOC_MEM(record, char, 160);
line_start = strlen(tag_block);
iso_md5_compute(t->checksum_ctx, tag_block, line_start);
res = iso_md5_clone(t->checksum_ctx, &ctx);
if (res < 0)
ret = iso_md5_clone(t->checksum_ctx, &ctx);
if (ret < 0)
goto ex;
res = iso_md5_end(&ctx, md5);
ret = iso_md5_end(&ctx, md5);
pos = (off_t) t->checksum_tag_pos * (off_t) 2048 + line_start;
if(pos >= 1000000000)
@ -747,8 +743,8 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
"%2.2x", ((unsigned char *) md5)[i]);
record_len += 32;
res = iso_md5_start(&ctx);
if (res < 0)
ret = iso_md5_start(&ctx);
if (ret < 0)
goto ex;
iso_md5_compute(ctx, record, record_len);
iso_md5_end(&ctx, md5);
@ -765,11 +761,12 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
if (t->scdbackup_tag_written != NULL)
strncpy(t->scdbackup_tag_written, tag_block + line_start,
block_len - line_start);
res = ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
if (ctx != NULL)
iso_md5_end(&ctx, md5);
return res;
LIBISO_FREE_MEM(record);
return ret;
}
@ -783,20 +780,20 @@ ex:;
*/
int iso_md5_write_tag(Ecma119Image *t, int flag)
{
int res, mode, l, i, wres, tag_id_len;
int ret, mode, l, i, wres, tag_id_len;
void *ctx = NULL;
char md5[16], tag_block[2048], *tag_id;
char md5[16], *tag_block = NULL, *tag_id;
uint32_t size = 0, pos = 0, start;
LIBISO_ALLOC_MEM(tag_block, char, 2048);
start = t->checksum_range_start;
memset(tag_block, 0, 2048);
mode = flag & 255;
if (mode < 1 || mode > 4)
return ISO_WRONG_ARG_VALUE;
res = iso_md5_clone(t->checksum_ctx, &ctx);
if (res < 0)
return res;
res = iso_md5_end(&ctx, md5);
{ret = ISO_WRONG_ARG_VALUE; goto ex;}
ret = iso_md5_clone(t->checksum_ctx, &ctx);
if (ret < 0)
goto ex;
ret = iso_md5_end(&ctx, md5);
if (mode == 1) {
size = t->checksum_range_size;
pos = t->checksum_tag_pos;
@ -811,7 +808,7 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
}
size = pos - start;
}
if (res < 0)
if (ret < 0)
goto ex;
iso_util_tag_magic(mode, &tag_id, &tag_id_len, 0);
@ -833,8 +830,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
((unsigned char *) md5)[i]);
l+= 32;
res = iso_md5_start(&ctx);
if (res > 0) {
ret = iso_md5_start(&ctx);
if (ret > 0) {
iso_md5_compute(ctx, tag_block, l);
iso_md5_end(&ctx, md5);
strcpy(tag_block + l, " self=");
@ -849,8 +846,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
if (t->ms_block > 0) {
iso_msg_submit(t->image->id, ISO_SCDBACKUP_TAG_NOT_0, 0, NULL);
} else {
res = iso_md5_write_scdbackup_tag(t, tag_block, 0);
if (res < 0)
ret = iso_md5_write_scdbackup_tag(t, tag_block, 0);
if (ret < 0)
goto ex;
}
}
@ -861,16 +858,17 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
} else {
wres = iso_write(t, tag_block, 2048);
if (wres < 0) {
res = wres;
ret = wres;
goto ex;
}
}
res = ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
if (ctx != NULL)
iso_md5_end(&ctx, md5);
return res;
LIBISO_FREE_MEM(tag_block);
return ret;
}

View File

@ -245,15 +245,18 @@ int iso_set_abort_severity(char *severity)
void iso_msg_debug(int imgid, const char *fmt, ...)
{
char msg[MAX_MSG_LEN];
char *msg = NULL;
va_list ap;
LIBISO_ALLOC_MEM_VOID(msg, char, MAX_MSG_LEN);
va_start(ap, fmt);
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
va_end(ap);
libiso_msgs_submit(libiso_msgr, imgid, 0x00000002, LIBISO_MSGS_SEV_DEBUG,
LIBISO_MSGS_PRIO_ZERO, msg, 0, 0);
ex:;
LIBISO_FREE_MEM(msg);
}
const char *iso_error_to_msg(int errcode)
@ -461,6 +464,10 @@ const char *iso_error_to_msg(int errcode)
return "Reserved Rock Ridge leaf name";
case ISO_RR_PATH_TOO_LONG:
return "Rock Ridge path too long";
case ISO_AAIP_BAD_ATTR_NAME:
return "Attribute name cannot be represented";
case ISO_AAIP_ACL_MULT_OBJ:
return "ACL text contains multiple entries of user::, group::, other::";
default:
return "Unknown error";
}
@ -480,7 +487,7 @@ int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt, ...)
va_list ap;
/* when called with ISO_CANCELED, we don't need to submit any message */
if (errcode == ISO_CANCELED && fmt == NULL) {
if (errcode == (int) ISO_CANCELED && fmt == NULL) {
return ISO_CANCELED;
}

View File

@ -19,6 +19,7 @@
#include "aaip_0_2.h"
#include "messages.h"
#include "util.h"
#include "eltorito.h"
#include <stdlib.h>
@ -78,6 +79,14 @@ void iso_node_unref(IsoNode *node)
IsoSymlink *link = (IsoSymlink*) node;
free(link->dest);
}
break;
case LIBISO_BOOT:
{
IsoBoot *bootcat = (IsoBoot *) node;
if (bootcat->content != NULL)
free(bootcat->content);
}
break;
default:
/* other kind of nodes does not need to delete anything here */
break;
@ -1573,7 +1582,7 @@ int iso_aa_get_attrs(unsigned char *aa_string, size_t *num_attrs,
goto ex;
}
if (rpt - aa_string != len) {
if ((size_t) (rpt - aa_string) != len) {
/* aaip_decode_attrs() returns 2 but still bytes are left */
ret = ISO_AAIP_BAD_AASTRING;
goto ex;
@ -1615,7 +1624,9 @@ int iso_aa_lookup_attr(unsigned char *aa_string, char *name,
ret = iso_aa_get_attrs(aa_string, &num_attrs, &names,
&value_lengths, &values, 0);
for (i = 0; i < num_attrs; i++) {
if (ret < 0)
return ret;
for (i = 0; i < (int) num_attrs; i++) {
if (strcmp(names[i], name))
continue;
*value_length = value_lengths[i];
@ -2138,10 +2149,12 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
ret = aaip_encode_both_acl(access_text, default_text, st_mode,
&acl_len, &acl, 2 | 8);
}
if (ret <= 0) {
if (ret == -1)
ret = ISO_OUT_OF_MEM;
else if (ret <= 0 && ret >= -3)
ret = ISO_AAIP_BAD_ACL_TEXT;
if (ret <= 0)
goto ex;
}
if(acl == NULL) { /* Delete whole ACL attribute */
/* Update S_IRWXG by eventual "group::" ACL entry.
@ -2194,6 +2207,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
}
ret = aaip_encode_both_acl(access_text, default_text,
st_mode, &acl_len, &acl, 2 | 8);
if (ret < -3)
goto ex;
if (ret <= 0) {
ret = ISO_AAIP_BAD_ACL_TEXT;
goto ex;
@ -2850,7 +2865,7 @@ int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag)
ret = 0;
goto ex;
}
for (i = 0; i < value_len; i++)
for (i = 0; i < (int) value_len; i++)
idx = (idx << 8) | ((unsigned char *) value)[i];
if (idx == 0 || idx > image->checksum_idx_count - 1) {
/* (last index is not MD5 of a file) */

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2012 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -406,12 +406,15 @@ int rrip_SL_append_comp(size_t *n, uint8_t ***comps, char *s, int size, char fl)
#ifdef Libisofs_with_rrip_rR
/**
* Add to the given tree node a RR System Use Entry. This is an obsolete
* entry from before RRIP-1.10. Nevertheless mkisofs produces it and there
* is the suspicion that Solaris takes it as indication for Rock Ridge.
* Add a RR System Use Entry to the given tree node. This is an obsolete
* entry from before RRIP-1.10. Nevertheless mkisofs produces it. There
* is the suspicion that some operating systems could take it as indication
* for Rock Ridge.
*
* I once saw a copy of a RRIP spec which mentioned RR. Here i just use
* the same constant 5 bytes as produced by mkisofs.
* The meaning of the payload byte is documented e.g. in
* /usr/src/linux/fs/isofs/rock.h
* It announces the presence of entries PX, PN, SL, NM, CL, PL, RE, TF
* by payload byte bits 0 to 7.
*/
static
int rrip_add_RR(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
@ -426,7 +429,14 @@ int rrip_add_RR(Ecma119Image *t, Ecma119Node *n, struct susp_info *susp)
RR[1] = 'R';
RR[2] = 5;
RR[3] = 1;
RR[4] = 0201;
/* <<< ts B20307 : Not all directories have NM, many files have more entries */
RR[4] = 0x89; /* TF, NM , PX */
/* >>> ts B20307 : find out whether n carries
PX, PN, SL, NM, CL, PL, RE, TF and mark by bit0 to bit7 in RR[4]
*/
return susp_append(t, susp, RR);
}
@ -450,8 +460,8 @@ static
int rrip_add_SL(Ecma119Image *t, struct susp_info *susp, uint8_t **comp,
size_t n, int ce)
{
int ret, i, j;
int ret;
size_t i, j;
int total_comp_len = 0;
size_t pos, written = 0;
@ -988,7 +998,10 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
goto unannounced_ca;
namelen = namelen - (space - *su_size - 5);
/* >>> Need to handle lengths > 250 */;
/* >>> SUPER_LONG_RR: Need to handle CA part lengths > 250
(This cannot happen with name lengths <= 256, as a part
of the name will always fit into the directory entry.)
*/;
*ce = 5 + namelen;
*su_size = space;
@ -1054,8 +1067,8 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
* First, we check how many bytes fit in current
* SL field
*/
int fit = 255 - sl_len - 2;
if (clen - 250 <= fit) {
ssize_t fit = 255 - sl_len - 2;
if ((ssize_t) (clen - 250) <= fit) {
/*
* the component can be divided between this
* and another SL entry
@ -1233,7 +1246,17 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
/* we need to add a RE entry */
su_size += 4;
}
#ifdef Libisofs_with_rr_reloc_diR
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
(t->rr_reloc_flags & 1)) {
/* The dedicated relocation directory shall be marked by RE */
su_size += 4;
}
#endif /* Libisofs_with_rr_reloc_diR */
} else if (n->type == ECMA119_SPECIAL) {
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
/* block or char device, we need a PN entry */
@ -1257,7 +1280,8 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
/* "." or ".." entry */
su_size += 5; /* NM field */
if (!t->rrip_version_1_10)
su_size += 5; /* NM field */
if (type == 1 && n->parent == NULL) {
/*
@ -1342,7 +1366,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
size_t su_size_pd, ce_len_pd; /* predicted sizes of SUA and CA */
int ce_is_predicted = 0;
size_t aaip_sua_free= 0, aaip_len= 0;
size_t space;
int space;
if (t == NULL || n == NULL || info == NULL) {
return ISO_NULL_POINTER;
@ -1354,7 +1378,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
if (type < 0 || type > 2 || space < ISO_ROCKRIDGE_IN_DIR_REC) {
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
"Unknown node type %d or short RR space %d < %d in directory record",
type, (int) space, ISO_ROCKRIDGE_IN_DIR_REC);
type, space, ISO_ROCKRIDGE_IN_DIR_REC);
return ISO_ASSERT_FAILURE;
}
@ -1418,6 +1442,18 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
goto add_susp_cleanup;
}
}
#ifdef Libisofs_with_rr_reloc_diR
} else if(ecma119_is_dedicated_reloc_dir(t, n) &&
(t->rr_reloc_flags & 1)) {
/* The dedicated relocation directory shall be marked by RE */
ret = rrip_add_RE(t, node, info);
if (ret < 0)
goto add_susp_cleanup;
#endif /* Libisofs_with_rr_reloc_diR */
}
} else if (n->type == ECMA119_SPECIAL) {
if (S_ISBLK(n->node->mode) || S_ISCHR(n->node->mode)) {
@ -1438,7 +1474,7 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
if (info->suf_len + 28 > space) {
iso_msg_submit(t->image->id, ISO_ASSERT_FAILURE, 0,
"Directory Record overflow. name='%s' , suf_len=%d > space=%d - 28\n",
node->iso_name, (int) info->suf_len, (int) space);
node->iso_name, (int) info->suf_len, space);
return ISO_ASSERT_FAILURE;
}
@ -1460,9 +1496,11 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
/* Try whether NM, SL, AL will fit into SUA */
su_size_pd = info->suf_len;
ce_len_pd = ce_len;
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 0);
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
&su_size_pd, &ce_len_pd, 0);
if (ret == 0) { /* Have to use CA. 28 bytes of CE are necessary */
ret = susp_calc_nm_sl_al(t, n, space, &su_size_pd, &ce_len_pd, 1);
ret = susp_calc_nm_sl_al(t, n, (size_t) space,
&su_size_pd, &ce_len_pd, 1);
sua_free -= 28;
ce_is_predicted = 1;
}
@ -1554,8 +1592,8 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
* First, we check how many bytes fit in current
* SL field
*/
int fit = 255 - sl_len - 2;
if (clen - 250 <= fit) {
ssize_t fit = 255 - sl_len - 2;
if ((ssize_t) (clen - 250) <= fit) {
/*
* the component can be divided between this
* and another SL entry
@ -1668,7 +1706,10 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
* ..and the part that goes to continuation area.
*/
/* >>> Need a loop to handle lengths > 250 */;
/* >>> SUPER_LONG_RR : Need a loop to handle CA lengths > 250
(This cannot happen with name lengths <= 256, as a part
of the name will always fit into the directory entry.)
*/;
ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen),
0, 1);
@ -1711,9 +1752,36 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
/* "." or ".." entry */
/* write the NM entry */
ret = rrip_add_NM(t, info, NULL, 0, 1 << type, 0);
if (ret < 0) {
goto add_susp_cleanup;
if (t->rrip_version_1_10) {
/* RRIP-1.10:
"NM" System Use Fields recorded for the ISO 9660 directory
records with names (00) and (01), used to designate the
current and parent directories, respectively, should be
ignored. Instead, the receiving system should convert these
names to the appropriate receiving system-dependent
designations for the current and parent directories.
*/
/* mkisofs obviously writes no NM for '.' and '..' .
Program isoinfo shows empty names with records as of RRIP-1.12
*/
/* no op */;
} else {
/* RRIP-1.12:
If the ISO 9660 Directory Record File Identifier is (00), then
the CURRENT bit of the "NM" Flags field [...], if present, shall
be set to ONE. If the ISO 9660 Directory Record File Identifier
is (01), then the PARENT bit of the "NM" Flags field [...],
if present, shall be set to ONE.
[...]
"BP 3 - Length (LEN_NM)" shall specify as an 8-bit number the
length in bytes [...]. If bit position 1, 2, or 5 of the "NM"
Flags is set to ONE, the value of this field shall be 5 and no
Name Content shall be recorded.
[The CURRENT bit has position 1. The PARENT bit has position 2.]
*/
ret = rrip_add_NM(t, info, NULL, 0, 1 << type, 0);
if (ret < 0)
goto add_susp_cleanup;
}
if (type == 1 && n->parent == NULL) {
@ -1821,12 +1889,13 @@ void rrip_write_susp_fields(Ecma119Image *t, struct susp_info *info,
int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
{
size_t i;
uint8_t padding[BLOCK_SIZE];
uint8_t *padding = NULL;
int ret= ISO_SUCCESS;
if (info->n_ce_susp_fields == 0) {
return ret;
goto ex;
}
LIBISO_ALLOC_MEM(padding, uint8_t, BLOCK_SIZE);
for (i = 0; i < info->n_ce_susp_fields; i++) {
ret = iso_write(t, info->ce_susp_fields[i],
@ -1852,6 +1921,8 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
info->ce_susp_fields = NULL;
info->n_ce_susp_fields = 0;
info->ce_len = 0;
ex:;
LIBISO_FREE_MEM(padding);
return ret;
}

View File

@ -81,8 +81,7 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
* (IEEE 1281, SUSP. section 4)
*/
if (iter->ce_len) {
uint32_t block;
int nblocks;
uint32_t block, nblocks;
/* A CE has found, there is another continuation area */
nblocks = DIV_UP(iter->ce_off + iter->ce_len, BLOCK_SIZE);

View File

@ -214,6 +214,7 @@ int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
return ISO_SUCCESS;
}
static
IsoStreamIface fsrc_stream_class = {
4, /* version */
"fsrc",
@ -398,7 +399,7 @@ static
int cut_out_read(IsoStream *stream, void *buf, size_t count)
{
struct cut_out_stream *data = stream->data;
count = (size_t)MIN(data->size - data->pos, count);
count = (size_t) MIN((size_t) (data->size - data->pos), count);
if (count == 0) {
return 0;
}
@ -503,6 +504,7 @@ int cut_out_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
/*
* TODO update cut out streams to deal with update_size(). Seems hard.
*/
static
IsoStreamIface cut_out_stream_class = {
4, /* version */
"cout",
@ -647,7 +649,7 @@ int mem_read(IsoStream *stream, void *buf, size_t count)
return ISO_FILE_NOT_OPENED;
}
if (data->offset >= data->size) {
if (data->offset >= (ssize_t) data->size) {
return 0; /* EOF */
}
@ -748,6 +750,7 @@ int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
}
static
IsoStreamIface mem_stream_class = {
4, /* version */
"mem ",
@ -869,6 +872,10 @@ void iso_stream_get_file_name(IsoStream *stream, char *name)
if (!strncmp(type, "fsrc", 4)) {
FSrcStreamData *data = stream->data;
char *path = iso_file_source_get_path(data->src);
if (path == NULL) {
name[0] = 0;
return;
}
strncpy(name, path, PATH_MAX - 1);
name[PATH_MAX - 1] = 0;
free(path);
@ -1076,14 +1083,15 @@ int iso_stream_read_buffer(IsoStream *stream, char *buf, size_t count,
*/
int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag)
{
int res, is_open = 0;
char buffer[2048];
int ret, is_open = 0;
char * buffer = NULL;
void *ctx= NULL;
off_t file_size;
uint32_t b, nblocks;
size_t got_bytes;
IsoStream *input_stream;
LIBISO_ALLOC_MEM(buffer, char, 2048);
if (flag & 1) {
while(1) {
input_stream = iso_stream_get_input_stream(stream, 0);
@ -1094,36 +1102,37 @@ int iso_stream_make_md5(IsoStream *stream, char md5[16], int flag)
}
if (! iso_stream_is_repeatable(stream))
return 0;
res = iso_md5_start(&ctx);
if (res < 0)
return res;
res = iso_stream_open(stream);
if (res < 0)
return 0;
{ret = 0; goto ex;}
ret = iso_md5_start(&ctx);
if (ret < 0)
goto ex;
ret = iso_stream_open(stream);
if (ret < 0)
goto ex;
is_open = 1;
file_size = iso_stream_get_size(stream);
nblocks = DIV_UP(file_size, 2048);
for (b = 0; b < nblocks; ++b) {
res = iso_stream_read_buffer(stream, buffer, 2048, &got_bytes);
if (res < 0) {
res = 0;
ret = iso_stream_read_buffer(stream, buffer, 2048, &got_bytes);
if (ret < 0) {
ret = 0;
goto ex;
}
/* Do not use got_bytes to stay closer to IsoFileSrc processing */
if (file_size - b * 2048 > 2048)
res = 2048;
ret = 2048;
else
res = file_size - b * 2048;
iso_md5_compute(ctx, buffer, res);
ret = file_size - b * 2048;
iso_md5_compute(ctx, buffer, ret);
}
res = 1;
ret = 1;
ex:;
if (is_open)
iso_stream_close(stream);
if (ctx != NULL)
iso_md5_end(&ctx, md5);
return res;
LIBISO_FREE_MEM(buffer);
return ret;
}
/* API */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2008 Vreixo Formoso
* Copyright (c) 2010 Thomas Schmitt
* Copyright (c) 2010 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -387,7 +387,7 @@ static int make_mips_volume_header(Ecma119Image *t, uint8_t *buf, int flag)
/* 84 - 87 | boot_bytes | File length in bytes */
/* 88 - 311 | 0 | Volume Directory Entries 2 to 15 */
for (idx = 0; idx < t->image->num_mips_boot_files; idx++) {
for (idx = 0; (int) idx < t->image->num_mips_boot_files; idx++) {
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[idx],
&node, &ecma_node, "MIPS boot file", 0);
if (ret < 0)
@ -457,18 +457,19 @@ int iso_read_mipsel_elf(Ecma119Image *t, int flag)
{
uint32_t phdr_adr, todo, count;
int ret;
uint8_t elf_buf[2048];
uint8_t *elf_buf = NULL;
IsoNode *iso_node;
Ecma119Node *ecma_node;
IsoStream *stream;
if (t->image->num_mips_boot_files <= 0)
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
LIBISO_ALLOC_MEM(elf_buf, uint8_t, 2048);
ret = boot_nodes_from_iso_path(t, t->image->mips_boot_file_paths[0],
&iso_node, &ecma_node, "MIPS boot file", 0);
if (ret < 0)
return ret;
goto ex;
stream = iso_file_get_stream((IsoFile *) iso_node);
ret = iso_stream_open(stream);
@ -476,7 +477,7 @@ int iso_read_mipsel_elf(Ecma119Image *t, int flag)
iso_msg_submit(t->image->id, ret, 0,
"Cannot open designated MIPS boot file '%s'",
t->image->mips_boot_file_paths[0]);
return ret;
goto ex;
}
ret = iso_stream_read(stream, elf_buf, 32);
if (ret != 32) {
@ -485,7 +486,7 @@ cannot_read:;
iso_msg_submit(t->image->id, ret, 0,
"Cannot read from designated MIPS boot file '%s'",
t->image->mips_boot_file_paths[0]);
return ret;
goto ex;
}
@ -504,7 +505,7 @@ cannot_read:;
count = todo;
todo -= count;
ret = iso_stream_read(stream, elf_buf, count);
if (ret != count)
if (ret != (int) count)
goto cannot_read;
}
ret = iso_stream_read(stream, elf_buf, 20);
@ -521,7 +522,10 @@ cannot_read:;
t->mipsel_p_filesz = iso_read_lsb(elf_buf + 16, 4);
iso_stream_close(stream);
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(elf_buf);
return ret;
}
@ -679,7 +683,8 @@ static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag)
ret = write_sun_partition_entry(1, t->appended_partitions,
t->appended_part_start, t->appended_part_size,
ISO_SUN_CYL_SIZE, buf, 0);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}
@ -844,14 +849,15 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
int sa_type, ret, always_align;
uint32_t img_blocks;
off_t imgsize, cylsize = 0, frac;
char msg[160];
char *msg = NULL;
LIBISO_ALLOC_MEM(msg, char, 160);
sa_type = (t->system_area_options >> 2) & 0x3f;
if (sa_type != 0)
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
always_align = (t->system_area_options >> 8) & 3;
img_blocks = t->curblock;
img_blocks = t->curblock + t->tail_blocks;
imgsize = ((off_t) img_blocks) * (off_t) 2048;
if (((t->system_area_options & 3) || always_align)
&& (off_t) (t->partition_heads_per_cyl * t->partition_secs_per_head
@ -877,7 +883,7 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
}
if (always_align >= 2)
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
cylsize = 0;
if (t->catalog != NULL &&
@ -886,7 +892,7 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
an MBR from our built-in template. (Deprecated since 31 Mar 2010)
*/
if (img_blocks >= 0x40000000)
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
cylsize = 64 * 32 * 512;
} else if ((t->system_area_options & 2) || always_align) {
/* Patch externally provided system area as isohybrid MBR */
@ -894,18 +900,18 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
/* isohybrid makes only sense together with ISOLINUX boot image
and externally provided System Area.
*/
return ISO_ISOLINUX_CANT_PATCH;
{ret = ISO_ISOLINUX_CANT_PATCH; goto ex;}
}
cylsize = t->partition_heads_per_cyl * t->partition_secs_per_head
* 512;
}
if (cylsize == 0)
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
if (((double) imgsize) / (double) cylsize > 1024.0) {
iso_msgs_submit(0,
"Image size exceeds 1024 cylinders. Cannot align partition.",
0, "WARNING", 0);
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
}
frac = imgsize % cylsize;
@ -913,7 +919,7 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
frac = imgsize - ((off_t) img_blocks) * (off_t) 2048;
if (frac == 0)
return ISO_SUCCESS;
{ret = ISO_SUCCESS; goto ex;}
if (frac % 2048) {
sprintf(msg,
"Cylinder size %d not divisible by 2048. Cannot align partition.",
@ -922,5 +928,8 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
} else {
t->tail_blocks += frac / 2048;
}
return ISO_SUCCESS;
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(msg);
return ret;
}

View File

@ -478,12 +478,12 @@ int iso_tree_remove_exclude(IsoImage *image, const char *path)
return ISO_NULL_POINTER;
}
for (i = 0; i < image->nexcludes; ++i) {
for (i = 0; (int) i < image->nexcludes; ++i) {
if (strcmp(image->excludes[i], path) == 0) {
/* exclude found */
free(image->excludes[i]);
--image->nexcludes;
for (j = i; j < image->nexcludes; ++j) {
for (j = i; (int) j < image->nexcludes; ++j) {
image->excludes[j] = image->excludes[j+1];
}
image->excludes = realloc(image->excludes, image->nexcludes *
@ -761,11 +761,16 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
ret = iso_file_source_open(dir);
if (ret < 0) {
char *path = iso_file_source_get_path(dir);
path = iso_file_source_get_path(dir);
/* instead of the probable error, we throw a sorry event */
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
"Can't open dir %s", path);
free(path);
if (path != NULL) {
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
"Can't open dir %s", path);
free(path);
} else {
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
"Can't open dir. NULL pointer caught as dir name");
}
return ret;
}
@ -785,6 +790,11 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
}
path = iso_file_source_get_path(file);
if (path == NULL) {
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
"NULL pointer caught as file path");
return ret;
}
name = strrchr(path, '/') + 1;
if (image->follow_symlinks) {
@ -847,7 +857,7 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
ret = iso_dir_insert(parent, new, pos, replace);
if (ret < 0) {
iso_node_unref(new);
if (ret != ISO_NODE_NAME_NOT_UNIQUE) {
if (ret != (int) ISO_NODE_NAME_NOT_UNIQUE) {
/* error */
goto dir_rec_continue;
} else {

View File

@ -1,7 +1,7 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2007 Mario Danic
* Copyright (c) 2009 - 2011 Thomas Schmitt
* Copyright (c) 2009 - 2012 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -219,7 +219,7 @@ int strconv(const char *str, const char *icharset, const char *ocharset,
src = (char *)str;
ret = (char *)out;
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
if (n == -1) {
if (n == (size_t) -1) {
/* error */
iso_iconv_close(&conv, 0);
retval = ISO_CHARSET_CONV_ERROR;
@ -269,7 +269,7 @@ int strnconv(const char *str, const char *icharset, const char *ocharset,
src = (char *)str;
ret = (char *)out;
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
if (n == -1) {
if (n == (size_t) -1) {
/* error */
iso_iconv_close(&conv, 0);
retval = ISO_CHARSET_CONV_ERROR;
@ -336,7 +336,7 @@ int str2wchar(const char *icharset, const char *input, wchar_t **output)
src = (char *)input;
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
while (n == -1) {
while (n == (size_t) -1) {
if (errno == E2BIG) {
/* error, should never occur */
@ -382,12 +382,13 @@ conv_error:;
int str2ascii(const char *icharset, const char *input, char **output)
{
int result;
wchar_t *wsrc_;
char *ret;
char *ret_;
wchar_t *wsrc_ = NULL;
char *ret = NULL;
char *ret_ = NULL;
char *src;
struct iso_iconv_handle conv;
int conv_ret;
int direct_conv = 0;
/* That while loop smells like a potential show stopper */
size_t loop_counter = 0, loop_limit = 3;
@ -405,37 +406,58 @@ 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;
}
src = (char *)wsrc_;
numchars = wcslen(wsrc_);
if (result == (int) ISO_SUCCESS) {
src = (char *)wsrc_;
numchars = wcslen(wsrc_);
inbytes = numchars * sizeof(wchar_t);
loop_limit = inbytes + 3;
inbytes = numchars * sizeof(wchar_t);
loop_limit = inbytes + 3;
ret_ = malloc(numchars + 1);
if (ret_ == NULL) {
return ISO_OUT_OF_MEM;
}
outbytes = numchars;
ret = ret_;
ret_ = malloc(numchars + 1);
if (ret_ == NULL) {
return ISO_OUT_OF_MEM;
}
outbytes = numchars;
ret = ret_;
/* initialize iconv */
conv_ret = iso_iconv_open(&conv, "ASCII", "WCHAR_T", 0);
/* initialize iconv */
conv_ret = iso_iconv_open(&conv, "ASCII", "WCHAR_T", 0);
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) {
free(wsrc_);
free(ret_);
goto fallback;
conv_ret = iso_iconv_open(&conv, "ASCII", (char *) icharset, 0);
if (conv_ret <= 0)
goto fallback;
direct_conv = 1;
src = (char *) input;
inbytes = strlen(input);
loop_limit = inbytes + 3;
outbytes = (inbytes + 1) * sizeof(uint16_t);
ret_ = malloc(outbytes);
if (ret_ == NULL)
return ISO_OUT_OF_MEM;
ret = ret_;
}
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
while (n == -1) {
while (n == (size_t) -1) {
/* The destination buffer is too small. Stops here. */
if (errno == E2BIG)
break;
@ -458,8 +480,13 @@ int str2ascii(const char *icharset, const char *input, char **output)
/* There was an error with one character but some other remain
* to be converted. That's probably a multibyte character.
* See above comment. */
src += sizeof(wchar_t);
inbytes -= sizeof(wchar_t);
if (direct_conv) {
src++;
inbytes--;
} else {
src += sizeof(wchar_t);
inbytes -= sizeof(wchar_t);
}
if (!inbytes)
break;
@ -471,8 +498,9 @@ 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';
free(wsrc_);
*ret = 0;
if (wsrc_ != NULL)
free(wsrc_);
*output = ret_;
return ISO_SUCCESS;
@ -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,33 +569,54 @@ 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) {
if (result == (int) ISO_SUCCESS) {
src = (char *)wsrc_;
numchars = wcslen(wsrc_);
inbytes = numchars * sizeof(wchar_t);
loop_limit = inbytes + 3;
ret_ = malloc((numchars+1) * sizeof(uint16_t));
if (ret_ == NULL)
return ISO_OUT_OF_MEM;
outbytes = numchars * sizeof(uint16_t);
ret = ret_;
/* initialize iconv */
conv_ret = iso_iconv_open(&conv, "UCS-2BE", "WCHAR_T", 0);
if (conv_ret <= 0) {
free(wsrc_);
free(ret_);
}
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
return result;
}
src = (char *)wsrc_;
numchars = wcslen(wsrc_);
inbytes = numchars * sizeof(wchar_t);
loop_limit = inbytes + 3;
ret_ = malloc((numchars+1) * sizeof(uint16_t));
if (ret_ == NULL) {
return ISO_OUT_OF_MEM;
}
outbytes = numchars * sizeof(uint16_t);
ret = ret_;
/* initialize iconv */
conv_ret = iso_iconv_open(&conv, "UCS-2BE", "WCHAR_T", 0);
/* If this did not succeed : Try the untraditional direct conversion.
*/
if (conv_ret <= 0) {
free(wsrc_);
free(ret_);
return ISO_CHARSET_CONV_ERROR;
conv_ret = iso_iconv_open(&conv, "UCS-2BE", (char *) icharset, 0);
if (conv_ret <= 0) {
return ISO_CHARSET_CONV_ERROR;
}
direct_conv = 1;
src = (char *) input;
inbytes = strlen(input);
loop_limit = inbytes + 3;
outbytes = (inbytes + 1) * sizeof(uint16_t);
ret_ = malloc(outbytes);
if (ret_ == NULL)
return ISO_OUT_OF_MEM;
ret = ret_;
}
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
while (n == -1) {
while (n == (size_t) -1) {
/* The destination buffer is too small. Stops here. */
if (errno == E2BIG)
break;
@ -589,8 +639,13 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
/* There was an error with one character but some other remain
* to be converted. That's probably a multibyte character.
* See above comment. */
src += sizeof(wchar_t);
inbytes -= sizeof(wchar_t);
if (direct_conv) {
src++;
inbytes--;
} else {
src += sizeof(wchar_t);
inbytes -= sizeof(wchar_t);
}
if (!inbytes)
break;
@ -605,7 +660,8 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
/* close the ucs string */
set_ucsbe((uint16_t*) ret, '\0');
free(wsrc_);
if (wsrc_ != NULL)
free(wsrc_);
*output = (uint16_t*)ret_;
return ISO_SUCCESS;
@ -629,36 +685,75 @@ static int valid_j_char(uint16_t c)
&& cmp_ucsbe(&c, '\\');
}
/* @param relaxed bit0+1 0= strict ECMA-119
1= additionally allow lowercase (else map to upper)
2= allow all 8-bit characters
bit2 allow all 7-bit characters (but map to upper if
not bit0+1 == 2)
*/
static char map_fileid_char(char c, int relaxed)
{
char upper;
if (c == '/') /* Allowing slashes would cause lots of confusion */
return '_';
if ((relaxed & 3) == 2)
return c;
if (valid_d_char(c))
return c;
if ((relaxed & 4) && (c & 0x7f) == c && (c < 'a' || c > 'z'))
return c;
upper= toupper(c);
if (valid_d_char(upper)) {
if (relaxed & 3) {
/* lower chars are allowed */
return c;
}
return upper;
}
return '_';
}
static
char *iso_dirid(const char *src, int size)
char *iso_dirid(const char *src, int size, int relaxed)
{
size_t len, i;
char name[32];
len = strlen(src);
if (len > size) {
if ((int) len > size) {
len = size;
}
for (i = 0; i < len; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= toupper(src[i]);
name[i] = valid_d_char(c) ? c : '_';
#else /* Libisofs_old_ecma119_nameS */
name[i] = map_fileid_char(src[i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
name[len] = '\0';
return strdup(name);
}
char *iso_1_dirid(const char *src)
char *iso_1_dirid(const char *src, int relaxed)
{
return iso_dirid(src, 8);
return iso_dirid(src, 8, relaxed);
}
char *iso_2_dirid(const char *src)
{
return iso_dirid(src, 31);
return iso_dirid(src, 31, 0);
}
char *iso_1_fileid(const char *src)
char *iso_1_fileid(const char *src, int relaxed, int force_dots)
{
char *dot; /* Position of the last dot in the filename, will be used
* to calculate lname and lext. */
@ -669,7 +764,8 @@ char *iso_1_fileid(const char *src)
return NULL;
}
dot = strrchr(src, '.');
if (dot == src && strlen(src) > 4)
dot = NULL; /* Use the long extension instead of the empty name */
lext = dot ? strlen(dot + 1) : 0;
lname = strlen(src) - lext - (dot ? 1 : 0);
@ -682,19 +778,43 @@ char *iso_1_fileid(const char *src)
/* Convert up to 8 characters of the filename. */
for (i = 0; i < lname && i < 8; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= toupper(src[i]);
dest[pos++] = valid_d_char(c) ? c : '_';
#else /* Libisofs_old_ecma119_nameS */
if (dot == NULL && src[i] == '.')
dest[pos++] = '_'; /* make sure that ignored dots do not appear */
else
dest[pos++] = map_fileid_char(src[i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
/* This dot is mandatory, even if there is no extension. */
dest[pos++] = '.';
if (force_dots || lext > 0)
dest[pos++] = '.';
/* Convert up to 3 characters of the extension, if any. */
for (i = 0; i < lext && i < 3; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= toupper(src[lname + 1 + i]);
dest[pos++] = valid_d_char(c) ? c : '_';
#else /* Libisofs_old_ecma119_nameS */
dest[pos++] = map_fileid_char(src[lname + 1 + i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
dest[pos] = '\0';
@ -761,8 +881,11 @@ char *iso_2_fileid(const char *src)
* @param size
* Max len for the name
* @param relaxed
* 0 only allow d-characters, 1 allow also lowe case chars,
* 2 allow all characters
* bit0+1: 0 only allow d-characters,
* 1 allow also lowe case chars,
* 2 allow all 8-bit characters,
* bit2: allow 7-bit characters (but map lowercase to uppercase if
* not bit0+1 == 2)
*/
char *iso_r_dirid(const char *src, int size, int relaxed)
{
@ -770,13 +893,16 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
char *dest;
len = strlen(src);
if (len > size) {
if ((int) len > size) {
len = size;
}
dest = malloc(len + 1);
if (dest == NULL)
return NULL;
for (i = 0; i < len; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= src[i];
if (relaxed == 2) {
/* all chars are allowed */
@ -797,6 +923,13 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
dest[i] = '_';
}
}
#else /* Libisofs_old_ecma119_nameS */
dest[i] = map_fileid_char(src[i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
dest[len] = '\0';
@ -804,13 +937,17 @@ char *iso_r_dirid(const char *src, int size, int relaxed)
}
/**
* Create a file name suitable for an ISO image with relaxed constraints.
* Create a file name suitable for an ISO image with level > 1 and
* with relaxed constraints.
*
* @param len
* Max len for the name, without taken the "." into account.
* @param relaxed
* 0 only allow d-characters, 1 allow also lowe case chars,
* 2 allow all characters
* bit0+1: 0 only allow d-characters,
* 1 allow also lowe case chars,
* 2 allow all 8-bit characters,
* bit2: allow 7-bit characters (but map lowercase to uppercase if
* not bit0+1 == 2)
* @param forcedot
* Whether to ensure that "." is added
*/
@ -838,15 +975,15 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
*/
if (dot == NULL || *(dot + 1) == '\0') {
lname = strlen(src);
lnname = (lname > len) ? len : lname;
lnname = (lname > (int) len) ? (int) len : lname;
lext = lnext = 0;
} else {
lext = strlen(dot + 1);
lname = strlen(src) - lext - 1;
lnext = (strlen(src) > len + 1 && lext > 3) ?
(lname < len - 3 ? len - lname : 3)
(lname < (int) len - 3 ? (int) len - lname : 3)
: lext;
lnname = (strlen(src) > len + 1) ? len - lnext : lname;
lnname = (strlen(src) > len + 1) ? (int) len - lnext : lname;
}
if (lnname == 0 && lnext == 0) {
@ -857,6 +994,9 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
/* Convert up to lnname characters of the filename. */
for (i = 0; i < lnname; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= src[i];
if (relaxed == 2) {
/* all chars are allowed */
@ -877,6 +1017,13 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
dest[pos++] = '_';
}
}
#else /* Libisofs_old_ecma119_nameS */
dest[pos++] = map_fileid_char(src[i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
if (lnext > 0 || forcedot) {
dest[pos++] = '.';
@ -884,6 +1031,9 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
/* Convert up to lnext characters of the extension, if any. */
for (i = lname + 1; i < lname + 1 + lnext; i++) {
#ifdef Libisofs_old_ecma119_nameS
char c= src[i];
if (relaxed == 2) {
/* all chars are allowed */
@ -904,6 +1054,13 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
dest[pos++] = '_';
}
}
#else /* Libisofs_old_ecma119_nameS */
dest[pos++] = map_fileid_char(src[i], relaxed);
#endif /* ! Libisofs_old_ecma119_nameS */
}
dest[pos] = '\0';
@ -921,13 +1078,15 @@ ex:;
*/
uint16_t *iso_j_file_id(const uint16_t *src, int flag)
{
uint16_t *dot;
uint16_t *dot, *retval = NULL;
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
uint16_t dest[LIBISO_JOLIET_NAME_MAX];
uint16_t *dest = NULL;
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
if (src == NULL) {
return NULL;
goto ex;
}
if (flag & 2)
maxchar = 103;
@ -954,7 +1113,7 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
}
if (lnname == 0 && lnext == 0) {
return NULL;
goto ex;
}
pos = 0;
@ -989,7 +1148,10 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
is_done:;
set_ucsbe(dest + pos, '\0');
return ucsdup(dest);
retval = ucsdup(dest);
ex:;
LIBISO_FREE_MEM(dest);
return retval;
}
/* @param flag bit1= allow 103 characters rather than 64
@ -997,10 +1159,12 @@ is_done:;
uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
{
size_t len, i, maxchar = 64;
uint16_t dest[LIBISO_JOLIET_NAME_MAX]; /* was: 65 = 64 + 1 (\0) */
uint16_t *dest = NULL, *retval = NULL;
/* was: 65 = 64 + 1 (\0) */
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
if (src == NULL) {
return NULL;
goto ex;
}
if (flag & 2)
maxchar = 103;
@ -1018,7 +1182,10 @@ uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
}
}
set_ucsbe(dest + len, '\0');
return ucsdup(dest);
retval = ucsdup(dest);
ex:
LIBISO_FREE_MEM(dest);
return retval;
}
size_t ucslen(const uint16_t *str)
@ -1564,12 +1731,12 @@ void strncpy_pad(char *dest, const char *src, size_t max)
if (src != NULL) {
len = MIN(strlen(src), max);
for (i = 0; i < len; ++i)
dest[i] = src[i];
} else {
len = 0;
}
for (i = 0; i < len; ++i)
dest[i] = src[i];
for (i = len; i < max; ++i)
dest[i] = ' ';
}
@ -1601,7 +1768,7 @@ char *ucs2str(const char *buf, size_t len)
n = iso_iconv(&conv, &src, &inbytes, &str, &outbytes, 0);
iso_iconv_close(&conv, 0);
if (n == -1) {
if (n == (size_t) -1) {
/* error */
goto ex;
}
@ -1838,12 +2005,12 @@ int iso_util_eval_md5_tag(char *block, int desired, uint32_t lba,
*tag_type = 0;
decode_ret = iso_util_decode_md5_tag(block, tag_type, &pos,
&range_start, &range_size, next_tag, md5, 0);
if (decode_ret != 1 && decode_ret != ISO_MD5_AREA_CORRUPTED)
if (decode_ret != 1 && decode_ret != (int) ISO_MD5_AREA_CORRUPTED)
return 0;
if (*tag_type > 30)
goto unexpected_type;
if (decode_ret == ISO_MD5_AREA_CORRUPTED) {
if (decode_ret == (int) ISO_MD5_AREA_CORRUPTED) {
ret = decode_ret;
goto ex;
} else if (!((1 << *tag_type) & desired)) {
@ -1886,4 +2053,14 @@ ex:;
return ret;
}
void *iso_alloc_mem(size_t size, size_t count, int flag)
{
void *pt;
pt = calloc(size, count);
if(pt == NULL)
iso_msg_submit(-1, ISO_OUT_OF_MEM, 0, "Out of virtual memory");
return pt;
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2012 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -93,8 +93,11 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output);
*
* @param src
* The identifier, in ASCII encoding.
* @param relaxed
* 0 only allow d-characters, 1 allow also lowe case chars,
* 2 allow all characters
*/
char *iso_1_dirid(const char *src);
char *iso_1_dirid(const char *src, int relaxed);
/**
* Create a level 2 directory identifier.
@ -124,8 +127,13 @@ char *iso_r_dirid(const char *src, int size, int relaxed);
*
* @param src
* The identifier, in ASCII encoding.
* @param relaxed
* 0 only allow d-characters, 1 allow also lowe case chars,
* 2 allow all characters
* @param force_dots
* If 1 then prepend empty extension by SEPARATOR1 = '.'
*/
char *iso_1_fileid(const char *src);
char *iso_1_fileid(const char *src, int relaxed, int force_dots);
/**
* Create a level 2 file identifier.
@ -539,4 +547,24 @@ int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag);
/* ------------------------------------------------------------------------- */
void *iso_alloc_mem(size_t size, size_t count, int flag);
#define LIBISO_ALLOC_MEM(pt, typ, count) { \
pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \
if(pt == NULL) { \
ret= ISO_OUT_OF_MEM; goto ex; \
} }
#define LIBISO_ALLOC_MEM_VOID(pt, typ, count) { \
pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \
if(pt == NULL) { \
goto ex; \
} }
#define LIBISO_FREE_MEM(pt) { \
if(pt != NULL) \
free((char *) pt); \
}
#endif /*LIBISO_UTIL_H_*/

View File

@ -164,7 +164,7 @@ int iso_rbtree_insert(IsoRBTree *tree, void *data, void **item)
new = data;
added = 1;
} else {
struct iso_rbnode head = { 0 }; /* False tree root */
struct iso_rbnode head = { 0, {NULL, NULL}, 0 }; /* False tree root */
struct iso_rbnode *g, *t; /* Grandparent & parent */
struct iso_rbnode *p, *q; /* Iterator & parent */