Compare commits
126 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
d787ecbcd9 | |||
182edb3a00 | |||
cb25d4d4e5 | |||
afdef92343 | |||
2bc7084315 | |||
6d10908a58 | |||
2ba54fafe7 | |||
ca63dac7e3 | |||
f885da8087 | |||
8438db02cf | |||
ce19db5e19 | |||
aeb5258ae2 | |||
f10c2d7779 | |||
82bfcf429a | |||
8fb8c01a0f | |||
73910e2f3c | |||
9c5fc21679 | |||
3a82f213e0 | |||
6892c734e2 | |||
66f6937c17 | |||
baa5b7cd42 | |||
f2658ef173 | |||
ecdb3aeb1d | |||
745a878884 | |||
6ae8386c23 | |||
b90e613246 | |||
bbc3caf86b | |||
b086d53274 | |||
17b36623a6 | |||
286648574d | |||
317bba395e | |||
541b41b6a1 | |||
91a8be5262 | |||
91e99703b4 | |||
dd7dac3397 | |||
43d4833dd6 | |||
dd1629b5ca | |||
bc8138ce78 | |||
2d568c1dbb | |||
842b62d111 | |||
4f3357e3ec | |||
9ffe91c372 | |||
7e2add413a | |||
004aefd0b7 | |||
00955ba85c | |||
4a79812d15 | |||
9b2f97e4b7 | |||
35cfb756be | |||
2835fccfa4 | |||
31c7f68990 | |||
4e0ca258de | |||
9653854462 | |||
6e95f8bbcb | |||
ce3aa0d5c7 | |||
d5bfc552c4 | |||
bad54a5967 | |||
49b0a89bfe | |||
265df5fbe3 | |||
f089bcf66a | |||
062e5f0bf0 | |||
d932bfcdea | |||
3ef67cb49d | |||
f08ae22dbe | |||
45d316d1ca | |||
4d8fc6ffee | |||
023e413624 | |||
d361186bca | |||
e7d9559d16 | |||
94eecbb123 | |||
777f74ea0b | |||
2b8d47ddd8 | |||
e839b7b368 | |||
1334027a83 | |||
8d3a0a6a9e | |||
7b7ea41f12 | |||
bb5886094e | |||
b076ce9b44 | |||
05f26898f3 | |||
a698f0ee22 | |||
e69854b35f | |||
228995c148 | |||
071e14f9b0 | |||
b08d6271ab | |||
431d31fff6 | |||
a37571c6c5 | |||
6e98006640 | |||
d264e818c3 | |||
d0f740facf | |||
944b5a6152 | |||
b51232fef4 | |||
99f037e210 | |||
c794a48a06 | |||
47d599e8c3 | |||
0a87e838df | |||
e945e38add | |||
6d68abc707 | |||
e80dd0735b | |||
c276681735 | |||
1d723f0834 | |||
1a4b2a2584 | |||
4eb2a7199c | |||
6d5e68fd01 | |||
fed8b23017 | |||
e3329a98a9 | |||
49efbdad76 | |||
9538a5d57b | |||
66dc6c2d0e | |||
81608815ae | |||
ae5ab4a08f | |||
76b6737570 | |||
9210a57500 | |||
8a752b50fa | |||
c38b1a3a3a | |||
73c9c7f244 | |||
0b9f03bb23 | |||
d1c3a017e3 | |||
b200feceed | |||
7958b2ea22 | |||
c0bdf4d3b5 | |||
71efc996e3 | |||
61383dea2d | |||
270cd1cad5 | |||
559e9b564d | |||
d8a56f60ef | |||
10e3b2939a | |||
ba67523278 |
@ -1,7 +1,7 @@
|
||||
Vreixo Formoso <metalpain2002@yahoo.es>,
|
||||
Mario Danic <mario.danic@gmail.com>,
|
||||
Thomas Schmitt <scdbackup@gmx.net>
|
||||
Copyright (C) 2007-2010 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||
Copyright (C) 2007-2011 Vreixo Formoso, Mario Danic, Thomas Schmitt
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
42
ChangeLog
42
ChangeLog
@ -1,6 +1,44 @@
|
||||
bzr branch lp:libisofs/for-libisoburn (to become libisofs-1.0.6.tar.gz)
|
||||
libisofs-1.1.6.tar.gz Tue Sep 27 2011
|
||||
===============================================================================
|
||||
- no novelties yet
|
||||
* 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
|
||||
1=MIPS Big Endian and 2=MIPS Little Endian caused SIGSEGV.
|
||||
* Bug fix: SIGSEGV if the path given by iso_image_add_mips_boot_file()
|
||||
does not exist in the image at image production time.
|
||||
* Bug fix: While loading an ISO image: Several reads to malloc
|
||||
memory occured with byte index -1. (Found by Valgrind after
|
||||
years of operation without visible problems.)
|
||||
* Bug fix: Closed a memory leak of 32 kB per loaded ISO image.
|
||||
|
||||
libisofs-1.0.6.tar.gz Sat Apr 09 2011
|
||||
===============================================================================
|
||||
* New API call iso_write_opts_set_joliet_long_names()
|
||||
* New error codes for oversized file addresses
|
||||
|
||||
libisofs-1.0.4.tar.gz Thu Mar 10 2011
|
||||
===============================================================================
|
||||
|
@ -6,6 +6,7 @@ pkgconfigdir=$(LIBBURNIA_PKGCONFDIR)
|
||||
libincludedir=$(includedir)/libisofs
|
||||
|
||||
lib_LTLIBRARIES = libisofs/libisofs.la
|
||||
ACLOCAL_AMFLAGS = -I ./
|
||||
|
||||
## ========================================================================= ##
|
||||
|
||||
|
1
README
1
README
@ -54,6 +54,7 @@ applications which use it. This dependency can be avoided by configure options
|
||||
--disable-libacl avoid use of ACL functions like acl_to_text()
|
||||
--disable-xattr avoid use of xattr functions like listxattr()
|
||||
--disable-zlib avoid use of zlib functions like compress2()
|
||||
--disable-libjte avoid use of libjte functions
|
||||
|
||||
See INSTALL file for general options of ./configure.
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
#!/bin/sh -x
|
||||
|
||||
aclocal
|
||||
aclocal -I .
|
||||
libtoolize --copy --force
|
||||
autoconf
|
||||
|
||||
# ts A61101 : libburn is not prepared for config.h
|
||||
# autoheader
|
||||
|
||||
automake --foreign --add-missing --copy --include-deps
|
||||
|
31
configure.ac
31
configure.ac
@ -1,4 +1,4 @@
|
||||
AC_INIT([libisofs], [1.0.4], [http://libburnia-project.org])
|
||||
AC_INIT([libisofs], [1.1.6], [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=4
|
||||
LIBISOFS_MINOR_VERSION=1
|
||||
LIBISOFS_MICRO_VERSION=6
|
||||
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.03.10 development jump has not yet happened
|
||||
# SONAME = 48 - 42 = 6 . Library name = libisofs.6.42.0
|
||||
LT_CURRENT=48
|
||||
LT_AGE=42
|
||||
# 2011.09.027 development jump has not yet happened
|
||||
# SONAME = 60 - 54 = 6 . Library name = libisofs.6.54.0
|
||||
LT_CURRENT=60
|
||||
LT_AGE=54
|
||||
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
|
||||
|
27
demo/demo.c
27
demo/demo.c
@ -50,6 +50,7 @@ static char helptext[][80] = {
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
#ifndef PATH_MAX
|
||||
@ -372,7 +373,11 @@ int gesture_iso(int argc, char **argv)
|
||||
iso_write_opts_free(opts);
|
||||
|
||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||
fwrite(buf, 1, 2048, fp);
|
||||
result = fwrite(buf, 1, 2048, fp);
|
||||
if (result < 2048) {
|
||||
printf ("Cannot write block. errno= %d\n", errno);
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
burn_src->free_data(burn_src);
|
||||
@ -537,7 +542,7 @@ int gesture_iso_read(int argc, char **argv)
|
||||
|
||||
int gesture_iso_cat(int argc, char **argv)
|
||||
{
|
||||
int res;
|
||||
int res, write_ret;
|
||||
IsoFilesystem *fs;
|
||||
IsoFileSource *file;
|
||||
struct stat info;
|
||||
@ -596,7 +601,11 @@ int gesture_iso_cat(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
while ((res = iso_file_source_read(file, buf, 1024)) > 0) {
|
||||
fwrite(buf, 1, res, stdout);
|
||||
write_ret = fwrite(buf, 1, res, stdout);
|
||||
if (write_ret < res) {
|
||||
printf ("Cannot write block to stdout. errno= %d\n", errno);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (res < 0) {
|
||||
fprintf(stderr, "Error reading, err = %d\n", res);
|
||||
@ -700,7 +709,11 @@ int gesture_iso_modify(int argc, char **argv)
|
||||
iso_write_opts_free(opts);
|
||||
|
||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||
fwrite(buf, 1, 2048, fp);
|
||||
result = fwrite(buf, 1, 2048, fp);
|
||||
if (result < 2048) {
|
||||
printf ("Cannot write block. errno= %d\n", errno);
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
burn_src->free_data(burn_src);
|
||||
@ -814,7 +827,11 @@ int gesture_iso_ms(int argc, char **argv)
|
||||
iso_write_opts_free(opts);
|
||||
|
||||
while (burn_src->read_xt(burn_src, buf, 2048) == 2048) {
|
||||
fwrite(buf, 1, 2048, fp);
|
||||
result = fwrite(buf, 1, 2048, fp);
|
||||
if (result < 2048) {
|
||||
printf ("Cannot write block. errno= %d\n", errno);
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
burn_src->free_data(burn_src);
|
||||
|
@ -1143,7 +1143,8 @@ HIDE_UNDOC_RELATIONS = YES
|
||||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
||||
# have no effect if this option is set to NO (the default)
|
||||
|
||||
HAVE_DOT = YES
|
||||
# ts B10415: dot causes sigsegv on Debian buildd
|
||||
HAVE_DOT = NO
|
||||
|
||||
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||
# will generate a graph for each documented class showing the direct and
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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)
|
||||
@ -401,7 +448,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
size_t i, consumed, acl_text_fill, acl_idx= 0, h_consumed;
|
||||
char *acl_text= NULL, *list= NULL;
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
size_t list_size= 0;
|
||||
ssize_t list_size= 0;
|
||||
#endif
|
||||
|
||||
#ifdef Libisofs_with_aaip_xattR
|
||||
@ -422,7 +469,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
list_size= llistxattr(path, list, list_size);
|
||||
if(list_size == -1)
|
||||
{ret= -5; goto ex;}
|
||||
for(i= 0; i < list_size; i+= strlen(list + i) + 1) {
|
||||
for(i= 0; i < (size_t) list_size; i+= strlen(list + i) + 1) {
|
||||
if(!(flag & 8))
|
||||
if(strncmp(list + i, "user.", 5))
|
||||
continue;
|
||||
@ -447,7 +494,11 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
continue;
|
||||
}
|
||||
/* Extended Attribute */
|
||||
if((flag & 1) && !(flag & 8))
|
||||
if(flag & 4)
|
||||
continue;
|
||||
if(strncmp(names[i], "isofs.", 6) == 0)
|
||||
continue;
|
||||
if(!(flag & 8))
|
||||
if(strncmp(names[i], "user.", 5))
|
||||
continue;
|
||||
|
||||
@ -475,6 +526,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
/* "access" ACL */
|
||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||
&consumed, NULL, 0, &acl_text_fill, 1);
|
||||
if(ret < -3)
|
||||
goto ex;
|
||||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
acl_text= calloc(acl_text_fill, 1);
|
||||
@ -482,6 +535,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
{ret= -1; goto ex;}
|
||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||
&consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
|
||||
if(ret < -3)
|
||||
goto ex;
|
||||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
has_default_acl= (ret == 2);
|
||||
@ -500,6 +555,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
ret= aaip_decode_acl((unsigned char *) (values[i] + consumed),
|
||||
value_lengths[i] - consumed, &h_consumed,
|
||||
NULL, 0, &acl_text_fill, 1);
|
||||
if(ret < -3)
|
||||
goto ex;
|
||||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
acl_text= calloc(acl_text_fill, 1);
|
||||
@ -508,11 +565,21 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
ret= aaip_decode_acl((unsigned char *) (values[i] + consumed),
|
||||
value_lengths[i] - consumed, &h_consumed,
|
||||
acl_text, acl_text_fill, &acl_text_fill, 0);
|
||||
if(ret < -3)
|
||||
goto ex;
|
||||
if(ret <= 0)
|
||||
{ret= -2; goto ex;}
|
||||
ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
|
||||
if(ret <= 0)
|
||||
{ret= -3; goto ex;}
|
||||
} else {
|
||||
if(!(flag & 64)) {
|
||||
|
||||
/* >>> ??? take offense from missing default ACL ?
|
||||
??? does Linux demand a default ACL for directories with access ACL ?
|
||||
*/;
|
||||
|
||||
}
|
||||
}
|
||||
ret= 1;
|
||||
ex:;
|
||||
|
@ -4,10 +4,10 @@
|
||||
Arbitrary Attribute Interchange Protocol , AAIP versions 0.2 , 1.0 , 2.0.
|
||||
Implementation of encoding and decoding xattr and ACL.
|
||||
|
||||
See test/aaip_0_2.h
|
||||
See libisofs/aaip_0_2.h
|
||||
http://libburnia-project.org/wiki/AAIP
|
||||
|
||||
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
|
||||
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
|
||||
|
||||
*/
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "libisofs.h"
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
#define Aaip_encode_debuG 1
|
||||
@ -95,7 +96,7 @@ size_t aaip_encode(size_t num_attrs, char **names,
|
||||
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;
|
||||
unsigned int number_of_fields, i, num_recs, ret;
|
||||
|
||||
/* 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;
|
||||
@ -187,7 +187,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
|
||||
aaip_encode_byte(result, result_fill, 0);
|
||||
return(1);
|
||||
}
|
||||
for(rpt= data; rpt - data < l;) {
|
||||
for(rpt= data; rpt - data < (ssize_t) l;) {
|
||||
todo= l - (rpt - data) + (prefix > 0);
|
||||
aaip_encode_byte(result, result_fill, (todo > 255));
|
||||
if(todo > 255)
|
||||
@ -198,7 +198,7 @@ static int aaip_encode_comp(unsigned char *result, size_t *result_fill,
|
||||
todo--;
|
||||
prefix= 0;
|
||||
}
|
||||
for(comp_start= rpt; rpt - comp_start < todo; rpt++)
|
||||
for(comp_start= rpt; rpt - comp_start < (ssize_t) todo; rpt++)
|
||||
aaip_encode_byte(result, result_fill, *((unsigned char *) rpt));
|
||||
}
|
||||
return(1);
|
||||
@ -268,7 +268,11 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
bit3= check for completeness of list and eventually
|
||||
fill up with entries deduced from st_mode
|
||||
@return >0 means ok
|
||||
0 means error
|
||||
<=0 means error
|
||||
-1= out of memory
|
||||
-2= program error with prediction of result size
|
||||
-3= error with conversion of name to uid or gid
|
||||
ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||
size_t *result_len, unsigned char **result, int flag)
|
||||
@ -279,8 +283,10 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||
*result_len= 0;
|
||||
bytes= aaip_encode_acl_text(acl_text, st_mode,
|
||||
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8)));
|
||||
if(bytes < -2)
|
||||
return(bytes);
|
||||
if(bytes < 0)
|
||||
return(0);
|
||||
return((int) bytes - 1);
|
||||
if(flag & 1) {
|
||||
*result_len= bytes;
|
||||
return(1);
|
||||
@ -292,9 +298,13 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||
*result_len= bytes;
|
||||
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
|
||||
(flag & (2 | 4 | 8)));
|
||||
if(bytes != *result_len) {
|
||||
if(bytes < -2)
|
||||
return(bytes);
|
||||
if(bytes < 0)
|
||||
return((int) bytes - 1);
|
||||
if((size_t) bytes != *result_len) {
|
||||
*result_len= 0;
|
||||
return(0);
|
||||
return(-2);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
@ -341,26 +351,31 @@ static int aaip_make_aaip_perms(int r, int w, int x)
|
||||
fill up with entries deduced from st_mode
|
||||
@return >=0 number of bytes produced resp. counted
|
||||
<0 means error
|
||||
-1: result size overflow
|
||||
-2: conversion errror with user name or group name
|
||||
ISO_AAIP_ACL_MULT_OBJ: multiple entries of user::, group::, other::
|
||||
*/
|
||||
static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
size_t result_size, unsigned char *result, int flag)
|
||||
{
|
||||
char *rpt, *npt, *cpt;
|
||||
int qualifier= 0, perms, type, i, qualifier_len= 0, num_recs, needed= 0;
|
||||
int qualifier= 0, perms, type, i, qualifier_len= 0, num_recs, needed= 0, ret;
|
||||
unsigned int has_u= 0, has_g= 0, has_o= 0, has_m= 0, is_trivial= 1;
|
||||
uid_t uid, huid;
|
||||
gid_t gid, hgid;
|
||||
ssize_t count= 0;
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
char name[1024];
|
||||
char *name = NULL;
|
||||
int name_size= 1024;
|
||||
double num;
|
||||
|
||||
LIBISO_ALLOC_MEM(name, char, name_size);
|
||||
if(flag & 4) {
|
||||
/* set SWITCH_MARK to indicate a default ACL */;
|
||||
if(!(flag & 1)) {
|
||||
if(count >= result_size)
|
||||
return(-1);
|
||||
if((size_t) count >= result_size)
|
||||
{ret= -1; goto ex;}
|
||||
result[count]= (Aaip_SWITCH_MARK << 4) | Aaip_EXEC;
|
||||
}
|
||||
count++;
|
||||
@ -384,9 +399,16 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
if(strncmp(rpt, "user:", 5) == 0) {
|
||||
if(cpt - rpt == 5) {
|
||||
type= Aaip_ACL_USER_OBJ;
|
||||
if (has_u) {
|
||||
|
||||
/* >>> Duplicate u:: entry. */;
|
||||
/* >>> ??? If it matches the previous one: ignore */
|
||||
|
||||
return((int) ISO_AAIP_ACL_MULT_OBJ);
|
||||
}
|
||||
has_u++;
|
||||
} else {
|
||||
if(cpt - (rpt + 5) >= sizeof(name))
|
||||
if(cpt - (rpt + 5) >= name_size)
|
||||
continue;
|
||||
is_trivial= 0;
|
||||
strncpy(name, rpt + 5, cpt - (rpt + 5));
|
||||
@ -396,8 +418,10 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
pwd= getpwnam(name);
|
||||
if(pwd == NULL) {
|
||||
num= aaip_numeric_id(name, 0);
|
||||
if(num <= 0)
|
||||
goto user_by_name;
|
||||
if(num <= 0) {
|
||||
/* ACL_USER is not part of AAIP 2.0 */
|
||||
{ret= -2; goto ex;}
|
||||
}
|
||||
uid= huid= num;
|
||||
} else
|
||||
uid= huid= pwd->pw_uid;
|
||||
@ -405,31 +429,44 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||
for(i= 0; huid != 0; i++)
|
||||
huid= huid >> 8;
|
||||
qualifier_len= i;
|
||||
if(qualifier_len <= 0)
|
||||
qualifier_len= 1;
|
||||
for(i= 0; i < qualifier_len ; i++)
|
||||
name[i]= uid >> (8 * (qualifier_len - i - 1));
|
||||
} else {
|
||||
user_by_name:;
|
||||
type= Aaip_ACL_USER;
|
||||
qualifier_len= strlen(name);
|
||||
if(qualifier_len <= 0)
|
||||
qualifier_len= 1;
|
||||
}
|
||||
qualifier= 1;
|
||||
}
|
||||
} else if(strncmp(rpt, "group:", 6) == 0) {
|
||||
if(cpt - rpt == 6) {
|
||||
type= Aaip_ACL_GROUP_OBJ;
|
||||
if (has_g) {
|
||||
|
||||
/* >>> Duplicate g:: entry. */;
|
||||
/* >>> ??? If it matches the previous one: ignore */
|
||||
|
||||
return((int) ISO_AAIP_ACL_MULT_OBJ);
|
||||
}
|
||||
has_g++;
|
||||
} else {
|
||||
if(cpt - (rpt + 6) >= sizeof(name))
|
||||
if(cpt - (rpt + 6) >= name_size)
|
||||
continue;
|
||||
is_trivial= 0;
|
||||
strncpy(name, rpt + 6, cpt - (rpt + 6));
|
||||
name[cpt - (rpt + 6)]= 0;
|
||||
if(flag & 2) {
|
||||
type= Aaip_ACL_GROUP_N;
|
||||
grp= getgrnam(name);
|
||||
if(grp == NULL) {
|
||||
num= aaip_numeric_id(name, 0);
|
||||
if(num <= 0)
|
||||
goto group_by_name;
|
||||
if(num <= 0) {
|
||||
/* ACL_GROUP is not part of AAIP 2.0 */
|
||||
{ret= -2; goto ex;}
|
||||
}
|
||||
gid= hgid= num;
|
||||
} else
|
||||
gid= hgid= grp->gr_gid;
|
||||
@ -437,18 +474,27 @@ user_by_name:;
|
||||
for(i= 0; hgid != 0; i++)
|
||||
hgid= hgid >> 8;
|
||||
qualifier_len= i;
|
||||
if(qualifier_len <= 0)
|
||||
qualifier_len= 1;
|
||||
for(i= 0; i < qualifier_len ; i++)
|
||||
name[i]= gid >> (8 * (qualifier_len - i - 1));
|
||||
|
||||
} else {
|
||||
group_by_name:;
|
||||
type= Aaip_ACL_GROUP;
|
||||
qualifier_len= strlen(name);
|
||||
if(qualifier_len <= 0)
|
||||
qualifier_len= 1;
|
||||
}
|
||||
qualifier= 1;
|
||||
}
|
||||
} else if(strncmp(rpt, "other:", 6) == 0) {
|
||||
type= Aaip_ACL_OTHER;
|
||||
if (has_o) {
|
||||
|
||||
/* >>> Duplicate o:: entry. */;
|
||||
/* >>> ??? If it matches the previous one: ignore */
|
||||
|
||||
return((int) ISO_AAIP_ACL_MULT_OBJ);
|
||||
}
|
||||
has_o++;
|
||||
} else if(strncmp(rpt, "mask:", 5) == 0) {
|
||||
type= Aaip_ACL_MASK;
|
||||
@ -461,8 +507,8 @@ group_by_name:;
|
||||
perms= aaip_make_aaip_perms(cpt[1] == 'r', cpt[2] == 'w', cpt[3] == 'x');
|
||||
|
||||
if(!(flag & 1)) {
|
||||
if(count >= result_size)
|
||||
return(-1);
|
||||
if((size_t) count >= result_size)
|
||||
{ret= -1; goto ex;}
|
||||
result[count]= perms | ((!!qualifier) << 3) | (type << 4);
|
||||
}
|
||||
count++;
|
||||
@ -470,8 +516,8 @@ group_by_name:;
|
||||
if(qualifier) {
|
||||
num_recs= (qualifier_len / 127) + !!(qualifier_len % 127);
|
||||
if(!(flag & 1)) {
|
||||
if(count + 1 > result_size)
|
||||
return(-1);
|
||||
if((size_t) (count + 1) > result_size)
|
||||
{ret= -1; goto ex;}
|
||||
for(i= 0; i < num_recs; i++) {
|
||||
if(i < num_recs - 1)
|
||||
result[count++]= 255;
|
||||
@ -480,8 +526,8 @@ group_by_name:;
|
||||
if(result[count - 1] == 0)
|
||||
result[count - 1]= 127;
|
||||
}
|
||||
if(count + (result[count - 1] & 127) > result_size)
|
||||
return(-1);
|
||||
if((size_t) (count + (result[count - 1] & 127)) > result_size)
|
||||
{ret= -1; goto ex;}
|
||||
memcpy(result + count, name + i * 127, result[count - 1] & 127);
|
||||
count+= result[count - 1] & 127;
|
||||
}
|
||||
@ -495,8 +541,8 @@ group_by_name:;
|
||||
if(flag & 1)
|
||||
count+= needed;
|
||||
else {
|
||||
if(count + needed > result_size)
|
||||
return(-1);
|
||||
if((size_t) (count + needed) > result_size)
|
||||
{ret= -1; goto ex;}
|
||||
}
|
||||
}
|
||||
if ((flag & 8) && needed > 0 && !(flag & 1)) {
|
||||
@ -521,7 +567,10 @@ group_by_name:;
|
||||
result[count++]= perms | (Aaip_ACL_MASK << 4);
|
||||
}
|
||||
}
|
||||
return(count);
|
||||
ret= count;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(name);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
@ -1120,9 +1169,9 @@ static int aaip_consume_rec_head(struct aaip_state *aaip,
|
||||
size_t todo;
|
||||
|
||||
todo= *num_data;
|
||||
if(todo > aaip->aa_missing)
|
||||
if(todo > (size_t) aaip->aa_missing)
|
||||
todo= aaip->aa_missing;
|
||||
if(todo >= aaip->rec_head_missing)
|
||||
if(todo >= (size_t) aaip->rec_head_missing)
|
||||
todo= aaip->rec_head_missing;
|
||||
if(!aaip->recs_invalid)
|
||||
aaip_push_to_recs(aaip, *data, todo, 0);
|
||||
@ -1144,9 +1193,9 @@ static int aaip_consume_rec_data(struct aaip_state *aaip,
|
||||
size_t todo;
|
||||
|
||||
todo= *num_data;
|
||||
if(todo > aaip->aa_missing)
|
||||
if(todo > (size_t) aaip->aa_missing)
|
||||
todo= aaip->aa_missing;
|
||||
if(todo > aaip->rec_missing)
|
||||
if(todo > (size_t) aaip->rec_missing)
|
||||
todo= aaip->rec_missing;
|
||||
if(!aaip->recs_invalid)
|
||||
aaip_push_to_recs(aaip, *data, todo, 1);
|
||||
@ -1178,7 +1227,7 @@ static int aaip_consume_aa_head(struct aaip_state *aaip,
|
||||
unsigned char aa_head[5];
|
||||
|
||||
todo= *num_data;
|
||||
if(todo >= aaip->aa_head_missing)
|
||||
if(todo >= (size_t) aaip->aa_head_missing)
|
||||
todo= aaip->aa_head_missing;
|
||||
aaip_push_to_recs(aaip, *data, todo, 0);
|
||||
aaip->aa_head_missing-= todo;
|
||||
@ -1225,7 +1274,7 @@ static int aaip_consume_aa_data(struct aaip_state *aaip,
|
||||
aaip_push_to_recs(aaip, zero_char, 1, 0);
|
||||
} else {
|
||||
/* fill in missing btes */
|
||||
for(i= 0; i < aaip->rec_missing; i++)
|
||||
for(i= 0; (int) i < aaip->rec_missing; i++)
|
||||
aaip_push_to_recs(aaip, zero_char, 1, 1);
|
||||
}
|
||||
aaip->rec_head_missing= 2;
|
||||
@ -1696,7 +1745,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
|
||||
unsigned char *data, size_t num_data, size_t *consumed,
|
||||
int flag)
|
||||
{
|
||||
int ret, was_non_aa= 0;
|
||||
int ret;
|
||||
struct aaip_state *aaip;
|
||||
size_t h_num, *h_lengths, i, new_mem, pair_consumed= 0;
|
||||
char **h_names, **h_values, *hpt;
|
||||
@ -1785,7 +1834,6 @@ int aaip_decode_attrs(struct aaip_state **handle,
|
||||
return(ret);
|
||||
|
||||
} else if(ret == -1) { /* non-AAIP field detected */
|
||||
was_non_aa= 1;
|
||||
if(pair_consumed <= 0)
|
||||
return(-4); /* interpretation did not advance */
|
||||
|
||||
@ -1968,14 +2016,16 @@ static int aaip_read_qualifier(unsigned char *data, size_t num_data,
|
||||
char *name, size_t name_size, size_t *name_fill,
|
||||
int flag)
|
||||
{
|
||||
int is_done= 0, rec_len= 0;
|
||||
int is_done= 0;
|
||||
size_t rec_len= 0;
|
||||
unsigned char *rpt;
|
||||
|
||||
*name_fill= 0;
|
||||
for(rpt= data; !is_done; rpt+= rec_len) {
|
||||
rec_len= (*rpt) & 127;
|
||||
is_done= !((*rpt) & 128);
|
||||
if(*name_fill + rec_len >= name_size || rpt + 1 + rec_len - data > num_data)
|
||||
if(*name_fill + rec_len >= name_size ||
|
||||
(size_t) (rpt + 1 + rec_len - data) > num_data)
|
||||
return(-1);
|
||||
memcpy(name + *name_fill, rpt + 1, rec_len);
|
||||
rpt+= 1 + rec_len;
|
||||
@ -2013,20 +2063,21 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
size_t *acl_text_fill, int flag)
|
||||
{
|
||||
unsigned char *rpt;
|
||||
char perm_text[4], *wpt, name[1024];
|
||||
int type, qualifier= 0, perm, ret, i, cnt;
|
||||
size_t w_size, name_fill= 0;
|
||||
char perm_text[4], *wpt, *name= NULL;
|
||||
int type, qualifier= 0, perm, ret, cnt, name_size= 1024;
|
||||
size_t w_size, name_fill= 0, i;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
|
||||
LIBISO_ALLOC_MEM(name, char, name_size);
|
||||
cnt= flag & 1;
|
||||
*consumed= 0;
|
||||
wpt= acl_text;
|
||||
w_size= acl_text_size;
|
||||
*acl_text_fill= 0;
|
||||
for(rpt= data; rpt - data < num_data; ) {
|
||||
for(rpt= data; (size_t) (rpt - data) < num_data; ) {
|
||||
perm= *rpt;
|
||||
strcpy(perm_text, "---");
|
||||
if(perm & Aaip_READ)
|
||||
@ -2038,14 +2089,14 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
|
||||
type= (*rpt) >> 4;
|
||||
if(type == Aaip_FUTURE_VERSION) /* indicate to caller: version mismatch */
|
||||
return(-3);
|
||||
{ret = -3; goto ex;}
|
||||
|
||||
qualifier= !!((*rpt) & 8);
|
||||
if(qualifier) {
|
||||
ret= aaip_read_qualifier(rpt + 1, num_data - (rpt + 1 - data),
|
||||
name, sizeof(name), &name_fill, 0);
|
||||
name, name_size, &name_fill, 0);
|
||||
if(ret <= 0)
|
||||
return(-1);
|
||||
{ret = -1; goto ex;}
|
||||
}
|
||||
|
||||
/* Advance read pointer */
|
||||
@ -2086,7 +2137,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
pwd= getpwuid(uid);
|
||||
if(pwd == NULL)
|
||||
sprintf(name, "%.f", (double) uid);
|
||||
else if(strlen(pwd->pw_name) >= sizeof(name))
|
||||
else if(strlen(pwd->pw_name) >= (size_t) name_size)
|
||||
sprintf(name, "%.f", (double) uid);
|
||||
else
|
||||
strcpy(name, pwd->pw_name);
|
||||
@ -2100,7 +2151,7 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
grp= getgrgid(gid);
|
||||
if(grp == NULL)
|
||||
sprintf(name, "%.f", (double) gid);
|
||||
else if(strlen(grp->gr_name) >= sizeof(name))
|
||||
else if(strlen(grp->gr_name) >= (size_t) name_size)
|
||||
sprintf(name, "%.f", (double) gid);
|
||||
else
|
||||
strcpy(name, grp->gr_name);
|
||||
@ -2108,15 +2159,17 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
||||
ret= aaip_write_acl_line(&wpt, &w_size, "group", name, perm_text, cnt);
|
||||
} else {
|
||||
/* indicate to caller: unknown type */
|
||||
return(-4);
|
||||
{ret = -4; goto ex;}
|
||||
}
|
||||
if(ret <= 0)
|
||||
return(-2);
|
||||
{ret = -2; goto ex;}
|
||||
}
|
||||
ret= 1;
|
||||
ex:;
|
||||
*acl_text_fill= w_size;
|
||||
if(flag & 1)
|
||||
*acl_text_fill= w_size + 1;
|
||||
(*acl_text_fill)++;
|
||||
LIBISO_FREE_MEM(name);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
@ -2133,6 +2186,13 @@ ex:;
|
||||
|
||||
#include "aaip-os-linux.c"
|
||||
|
||||
/* August 2011: aaip-os-linux.c would also work for GNU/Hurd : ifdef __GNU__
|
||||
Libraries and headers are present on Debian GNU/Hurd but there is no
|
||||
ACL or xattr support in the filesystems yet.
|
||||
Further, llistxattr() produces ENOSYS "Function not implemented".
|
||||
So it makes few sense to enable it here.
|
||||
*/
|
||||
|
||||
#else
|
||||
|
||||
#include "aaip-os-dummy.c"
|
||||
|
@ -56,7 +56,11 @@ size_t aaip_encode(size_t num_attrs, char **names,
|
||||
bit3= check for completeness of list and eventually
|
||||
fill up with entries deduced from st_mode
|
||||
@return >0 means ok
|
||||
0 means error
|
||||
<=0 means error
|
||||
-1= out of memory
|
||||
-2= program error with prediction of result size
|
||||
-3= error with conversion of name to uid or gid
|
||||
ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||
size_t *result_len, unsigned char **result, int flag);
|
||||
@ -80,7 +84,7 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||
bit3= check for completeness of list and eventually
|
||||
fill up with entries deduced from st_mode
|
||||
@return >0 means ok
|
||||
0 means error
|
||||
<=0 means error, see aaip_encode_acl
|
||||
*/
|
||||
int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode,
|
||||
size_t *result_len, unsigned char **result, int flag);
|
||||
@ -145,6 +149,24 @@ int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag);
|
||||
|
||||
/* ------ OS interface ------ */
|
||||
|
||||
/* See also API iso_local_attr_support().
|
||||
@param flag
|
||||
Bitfield for control purposes
|
||||
bit0= inquire availability of ACL
|
||||
bit1= inquire availability of xattr
|
||||
bit2 - bit7= Reserved for future types.
|
||||
It is permissibile to set them to 1 already now.
|
||||
bit8 and higher: reserved, submit 0
|
||||
@return
|
||||
Bitfield corresponding to flag. If bits are set, th
|
||||
bit0= ACL adapter is enabled
|
||||
bit1= xattr adapter is enabled
|
||||
bit2 - bit7= Reserved for future types.
|
||||
bit8 and higher: reserved, do not interpret these
|
||||
*/
|
||||
int aaip_local_attr_support(int flag);
|
||||
|
||||
|
||||
/* Obtain the ACL of the given file in long text form.
|
||||
@param path Path to the file
|
||||
@param text Will hold the result. This is a managed object which
|
||||
@ -478,6 +500,8 @@ int aaip_set_acl_text(char *path, char *text, int flag);
|
||||
-5 error with deleting attributes
|
||||
-6 support of xattr not enabled at compile time
|
||||
-7 support of ACL not enabled at compile time
|
||||
-8 unsupported xattr namespace
|
||||
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
|
||||
*/
|
||||
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||
size_t *value_lengths, char **values, int flag);
|
||||
|
@ -150,7 +150,7 @@ void iso_ring_buffer_free(IsoRingBuffer *buf)
|
||||
int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
||||
{
|
||||
size_t len;
|
||||
int bytes_write = 0;
|
||||
size_t bytes_write = 0;
|
||||
|
||||
if (buf == NULL || data == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -206,7 +206,7 @@ int iso_ring_buffer_write(IsoRingBuffer *buf, uint8_t *data, size_t count)
|
||||
int iso_ring_buffer_read(IsoRingBuffer *buf, uint8_t *dest, size_t count)
|
||||
{
|
||||
size_t len;
|
||||
int bytes_read = 0;
|
||||
size_t bytes_read = 0;
|
||||
|
||||
if (buf == NULL || dest == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -20,16 +20,13 @@
|
||||
#include "fsource.h"
|
||||
#include "image.h"
|
||||
#include "aaip_0_2.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX Libisofs_default_path_maX
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void iso_node_builder_ref(IsoNodeBuilder *builder)
|
||||
@ -75,6 +72,8 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
||||
iso_file_source_ref(src);
|
||||
|
||||
name = iso_file_source_get_name(src);
|
||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
||||
ret = iso_node_new_file(name, stream, &node);
|
||||
if (ret < 0) {
|
||||
iso_stream_unref(stream);
|
||||
@ -106,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 */
|
||||
@ -118,10 +119,12 @@ 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);
|
||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
||||
fs = iso_file_source_get_filesystem(src);
|
||||
new = NULL;
|
||||
|
||||
@ -157,10 +160,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
case S_IFLNK:
|
||||
{
|
||||
/* source is a symbolic link */
|
||||
char dest[PATH_MAX];
|
||||
IsoSymlink *link;
|
||||
|
||||
ret = iso_file_source_readlink(src, dest, PATH_MAX);
|
||||
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,19 +234,25 @@ 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
|
||||
void default_free(IsoNodeBuilder *builder)
|
||||
{
|
||||
/* The .free() method of IsoNodeBuilder shall free private data but not
|
||||
the builder itself. The latter is done in iso_node_builder_unref().
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,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);
|
||||
|
||||
@ -576,16 +576,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 +602,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 +612,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 +629,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 +638,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 +647,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 +661,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 +669,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 +710,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 +738,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 +746,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 +882,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 +912,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 +996,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 +1085,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 +1125,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 +1197,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 +1209,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 +1243,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 +1271,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 +1302,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 +1374,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 +1400,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;
|
||||
}
|
||||
|
||||
|
||||
@ -1398,7 +1416,7 @@ static
|
||||
void *write_function(void *arg)
|
||||
{
|
||||
int res, first_partition = 1, last_partition = 0, sa_type;
|
||||
size_t i;
|
||||
int i;
|
||||
IsoImageWriter *writer;
|
||||
|
||||
Ecma119Image *target = (Ecma119Image*)arg;
|
||||
@ -1412,7 +1430,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 +1487,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,
|
||||
@ -1650,6 +1668,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->allow_full_ascii = opts->allow_full_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;
|
||||
target->rrip_version_1_10 = opts->rrip_version_1_10;
|
||||
target->rrip_1_10_px_ino = opts->rrip_1_10_px_ino;
|
||||
target->aaip_susp_1_10 = opts->aaip_susp_1_10;
|
||||
@ -1948,7 +1967,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.
|
||||
*/
|
||||
@ -1974,7 +1993,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 */
|
||||
@ -2641,6 +2660,15 @@ int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_joliet_long_names(IsoWriteOpts *opts, int allow)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
opts->joliet_long_names = allow ? 1 : 0;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
int iso_write_opts_set_rrip_version_1_10(IsoWriteOpts *opts, int oldvers)
|
||||
{
|
||||
if (opts == NULL) {
|
||||
|
@ -161,6 +161,11 @@ struct iso_write_opts {
|
||||
*/
|
||||
unsigned int joliet_longer_paths :1;
|
||||
|
||||
/**
|
||||
* Allow Joliet names up to 103 characters rather than 64.
|
||||
*/
|
||||
unsigned int joliet_long_names :1;
|
||||
|
||||
/**
|
||||
* Write Rock Ridge info as of specification RRIP-1.10 rather than
|
||||
* RRIP-1.12: signature "RRIP_1991A" rather than "IEEE_1282",
|
||||
@ -459,6 +464,9 @@ struct ecma119_image
|
||||
/** Allow paths on Joliet tree to be larger than 240 bytes */
|
||||
unsigned int joliet_longer_paths :1;
|
||||
|
||||
/** Allow Joliet names up to 103 characters rather than 64 */
|
||||
unsigned int joliet_long_names :1;
|
||||
|
||||
/** Write old fashioned RRIP-1.10 rather than RRIP-1.12 */
|
||||
unsigned int rrip_version_1_10 :1;
|
||||
|
||||
|
@ -299,7 +299,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]);
|
||||
}
|
||||
@ -643,7 +643,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 */
|
||||
|
@ -239,6 +239,7 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
||||
IsoBoot *node;
|
||||
IsoNode **pos;
|
||||
time_t now;
|
||||
int ret;
|
||||
|
||||
if (parent == NULL || name == NULL || boot == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -248,9 +249,9 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* find place where to insert */
|
||||
pos = &(parent->children);
|
||||
@ -274,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);
|
||||
@ -383,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 */
|
||||
@ -486,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);
|
||||
@ -597,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)
|
||||
{
|
||||
@ -759,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 =
|
||||
@ -767,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;
|
||||
@ -836,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;
|
||||
@ -895,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;
|
||||
}
|
||||
@ -935,7 +962,11 @@ IsoStreamIface catalog_stream_class = {
|
||||
catalog_read,
|
||||
catalog_is_repeatable,
|
||||
catalog_get_id,
|
||||
catalog_free
|
||||
catalog_free,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1126,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 */
|
||||
@ -1155,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) {
|
||||
@ -1163,7 +1193,6 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
cat = t->catalog;
|
||||
iso_msg_debug(t->image->id, "Write El-Torito boot record");
|
||||
|
||||
memset(&vol, 0, sizeof(struct ecma119_boot_rec_vol_desc));
|
||||
|
@ -26,6 +26,14 @@
|
||||
struct Iso_Boot
|
||||
{
|
||||
IsoNode node;
|
||||
|
||||
/* Want to get content of loaded boot catalog.
|
||||
Vreixo took care not to make it an IsoFile at load time.
|
||||
So this is implemented independently of IsoStream.
|
||||
*/
|
||||
uint32_t lba;
|
||||
off_t size;
|
||||
char *content;
|
||||
};
|
||||
|
||||
/* Not more than 32 so that all entries fit into 2048 bytes */
|
||||
|
@ -335,11 +335,11 @@ 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;
|
||||
@ -350,10 +350,11 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
#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;
|
||||
|
||||
@ -562,13 +563,15 @@ ex:;
|
||||
iso_md5_end(&ctx, md5);
|
||||
|
||||
#ifdef Libisofs_with_libjtE
|
||||
if (jte_begun) {
|
||||
if (jte_begun && t != NULL) {
|
||||
libjte_end_data_file(t->libjte_handle);
|
||||
iso_libjte_forward_msgs(t->libjte_handle, t->image->id,
|
||||
ISO_LIBJTE_END_FAILED, 0);
|
||||
}
|
||||
#endif /* Libisofs_with_libjtE */
|
||||
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
LIBISO_FREE_MEM(name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -394,7 +394,7 @@ int gzip_stream_convert(IsoStream *stream, void *buf, size_t desired, int flag)
|
||||
if (cnv_ret == Z_STREAM_ERROR || cnv_ret == Z_BUF_ERROR) {
|
||||
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
|
||||
}
|
||||
if (strm->avail_out < rng->out_buffer_size)
|
||||
if ((int) strm->avail_out < rng->out_buffer_size)
|
||||
break; /* output is available */
|
||||
if (strm->avail_in == 0) /* all pending input consumed */
|
||||
break;
|
||||
|
@ -576,7 +576,8 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
|
||||
rng->block_pointers[i] =
|
||||
iso_read_lsb((uint8_t *) (rng->block_pointers + i), 4);
|
||||
if (i > 0)
|
||||
if (rng->block_pointers[i] - rng->block_pointers[i - 1]
|
||||
if ((int) (rng->block_pointers[i] -
|
||||
rng->block_pointers[i - 1])
|
||||
> block_max)
|
||||
block_max = rng->block_pointers[i]
|
||||
- rng->block_pointers[i - 1];
|
||||
@ -619,7 +620,7 @@ int ziso_stream_uncompress(IsoStream *stream, void *buf, size_t desired)
|
||||
if (ret != Z_OK)
|
||||
return (rng->error_ret = ISO_ZLIB_COMPR_ERR);
|
||||
rng->buffer_fill = buf_len;
|
||||
if (buf_len < rng->block_size &&
|
||||
if ((int) buf_len < rng->block_size &&
|
||||
i != rng->block_pointer_fill - 1)
|
||||
return (rng->error_ret = ISO_ZISOFS_WRONG_INPUT);
|
||||
} else if(ret == 0) {
|
||||
|
@ -35,11 +35,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX Libisofs_default_path_maX
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Options for image reading.
|
||||
* There are four kind of options:
|
||||
@ -298,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 ;
|
||||
@ -397,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;
|
||||
@ -475,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;
|
||||
|
||||
@ -491,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 */
|
||||
@ -515,7 +515,7 @@ 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;
|
||||
@ -560,7 +560,7 @@ int read_dir(ImageFileSourceData *data)
|
||||
free(ifsdata);
|
||||
free(child);
|
||||
}
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
/* add to the child list */
|
||||
@ -569,7 +569,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
|
||||
@ -586,7 +586,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
|
||||
@ -953,6 +956,7 @@ int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
{
|
||||
char *dest;
|
||||
size_t len;
|
||||
int ret;
|
||||
ImageFileSourceData *data;
|
||||
|
||||
if (src == NULL || buf == NULL || src->data == NULL) {
|
||||
@ -971,14 +975,15 @@ int ifs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
|
||||
dest = (char*)data->data.content;
|
||||
len = strlen(dest);
|
||||
if (bufsiz <= len) {
|
||||
|
||||
ret = ISO_SUCCESS;
|
||||
if (len >= bufsiz) {
|
||||
ret = ISO_RR_PATH_TOO_LONG;
|
||||
len = bufsiz - 1;
|
||||
}
|
||||
|
||||
strncpy(buf, dest, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
return ISO_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -1248,7 +1253,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;
|
||||
|
||||
@ -1258,7 +1264,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;
|
||||
@ -1277,7 +1283,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;}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1288,7 +1294,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 */
|
||||
@ -1303,13 +1309,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);
|
||||
}
|
||||
@ -1324,7 +1330,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) {
|
||||
@ -1365,7 +1371,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;}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1383,7 +1389,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) {
|
||||
@ -1452,7 +1458,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.
|
||||
@ -1584,13 +1590,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);
|
||||
@ -1602,6 +1609,7 @@ int iso_file_source_new_ifs(IsoImageFilesystem *fs, IsoFileSource *parent,
|
||||
sprintf(msg,
|
||||
"Character set name recorded in ISO image: '%.80s'",
|
||||
cs_value);
|
||||
free(cs_value);
|
||||
}
|
||||
iso_msgs_submit(0, msg, 0, "NOTE", 0);
|
||||
cs_value = NULL;
|
||||
@ -1623,7 +1631,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);
|
||||
@ -1645,7 +1653,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);
|
||||
@ -1678,15 +1686,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 */
|
||||
@ -1712,24 +1722,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
|
||||
@ -1765,7 +1775,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 */
|
||||
@ -1833,13 +1843,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;
|
||||
}
|
||||
|
||||
@ -1848,25 +1862,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 */
|
||||
@ -1875,6 +1890,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;
|
||||
}
|
||||
|
||||
@ -1915,7 +1932,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;
|
||||
|
||||
@ -1928,8 +1944,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) {
|
||||
@ -2037,10 +2051,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 */
|
||||
@ -2063,6 +2075,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);
|
||||
}
|
||||
|
||||
@ -2077,14 +2093,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 */
|
||||
@ -2099,7 +2116,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 */
|
||||
@ -2107,11 +2124,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 */
|
||||
@ -2119,9 +2136,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.");
|
||||
@ -2206,10 +2224,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
|
||||
@ -2242,11 +2263,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;
|
||||
|
||||
@ -2294,7 +2316,10 @@ int read_pvm(_ImageFsData *data, uint32_t block)
|
||||
* example.
|
||||
*/
|
||||
|
||||
return ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2304,16 +2329,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;
|
||||
@ -2324,7 +2351,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 */
|
||||
@ -2332,7 +2359,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 */
|
||||
@ -2342,6 +2369,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);
|
||||
@ -2360,10 +2388,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;
|
||||
@ -2385,7 +2424,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;
|
||||
}
|
||||
|
||||
|
||||
@ -2399,11 +2462,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;
|
||||
@ -2418,11 +2482,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;
|
||||
@ -2456,7 +2521,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;
|
||||
@ -2465,6 +2531,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;
|
||||
}
|
||||
|
||||
@ -2476,21 +2543,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 */
|
||||
@ -2498,6 +2566,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;
|
||||
|
||||
@ -2592,8 +2662,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;
|
||||
}
|
||||
}
|
||||
@ -2714,11 +2784,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;
|
||||
}
|
||||
|
||||
@ -2766,10 +2839,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;
|
||||
|
||||
@ -2782,7 +2857,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;
|
||||
@ -2793,7 +2868,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;
|
||||
@ -2811,7 +2886,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);
|
||||
}
|
||||
@ -2822,11 +2897,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 {
|
||||
@ -2836,7 +2930,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);
|
||||
@ -2845,7 +2939,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 */
|
||||
@ -2869,7 +2963,7 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
if (ret < 0) {
|
||||
free(name);
|
||||
iso_stream_unref(stream);
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2900,7 +2994,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 */
|
||||
@ -2917,7 +3011,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;
|
||||
@ -2926,18 +3020,19 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||
case S_IFLNK:
|
||||
{
|
||||
/* source is a symbolic link */
|
||||
char dest[PATH_MAX];
|
||||
IsoSymlink *link;
|
||||
|
||||
ret = iso_file_source_readlink(src, dest, PATH_MAX);
|
||||
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;
|
||||
@ -2958,7 +3053,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;
|
||||
@ -3000,13 +3095,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;
|
||||
}
|
||||
|
||||
@ -3132,12 +3229,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;
|
||||
@ -3177,7 +3275,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;
|
||||
@ -3216,6 +3314,7 @@ ex:;
|
||||
free(boot_image_buf);
|
||||
if (stream != NULL)
|
||||
iso_stream_close(stream);
|
||||
LIBISO_FREE_MEM(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3234,9 +3333,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;
|
||||
@ -3286,9 +3382,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;
|
||||
|
||||
@ -3421,11 +3514,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;
|
||||
@ -3486,7 +3593,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)
|
||||
@ -3499,7 +3606,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++)
|
||||
@ -3530,9 +3637,6 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
el_torito_boot_catalog_free(image->bootcat);
|
||||
image->root = oldroot;
|
||||
image->bootcat = oldbootcat;
|
||||
old_checksum_start_lba = image->checksum_start_lba;
|
||||
old_checksum_end_lba = image->checksum_end_lba;
|
||||
old_checksum_idx_count = image->checksum_idx_count;
|
||||
image->checksum_array = old_checksum_array;
|
||||
old_checksum_array = NULL;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2
|
||||
@ -95,14 +95,14 @@ char* lfs_get_name(IsoFileSource *src)
|
||||
static
|
||||
int lfs_lstat(IsoFileSource *src, struct stat *info)
|
||||
{
|
||||
_LocalFsFileSource *data;
|
||||
char *path;
|
||||
|
||||
if (src == NULL || info == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
data = src->data;
|
||||
path = lfs_get_path(src);
|
||||
if (path == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
if (lstat(path, info) != 0) {
|
||||
int err;
|
||||
@ -128,6 +128,7 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
|
||||
err = ISO_FILE_ERROR;
|
||||
break;
|
||||
}
|
||||
free(path);
|
||||
return err;
|
||||
}
|
||||
free(path);
|
||||
@ -137,14 +138,14 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
|
||||
static
|
||||
int lfs_stat(IsoFileSource *src, struct stat *info)
|
||||
{
|
||||
_LocalFsFileSource *data;
|
||||
char *path;
|
||||
|
||||
if (src == NULL || info == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
data = src->data;
|
||||
path = lfs_get_path(src);
|
||||
if (path == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
if (stat(path, info) != 0) {
|
||||
int err;
|
||||
@ -170,6 +171,7 @@ int lfs_stat(IsoFileSource *src, struct stat *info)
|
||||
err = ISO_FILE_ERROR;
|
||||
break;
|
||||
}
|
||||
free(path);
|
||||
return err;
|
||||
}
|
||||
free(path);
|
||||
@ -180,13 +182,11 @@ static
|
||||
int lfs_access(IsoFileSource *src)
|
||||
{
|
||||
int ret;
|
||||
_LocalFsFileSource *data;
|
||||
char *path;
|
||||
|
||||
if (src == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
data = src->data;
|
||||
path = lfs_get_path(src);
|
||||
|
||||
ret = iso_eaccess(path);
|
||||
@ -412,8 +412,7 @@ int lfs_readdir(IsoFileSource *src, IsoFileSource **child)
|
||||
static
|
||||
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
{
|
||||
int size;
|
||||
_LocalFsFileSource *data;
|
||||
int size, ret;
|
||||
char *path;
|
||||
|
||||
if (src == NULL || buf == NULL) {
|
||||
@ -424,14 +423,13 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
|
||||
data = src->data;
|
||||
path = lfs_get_path(src);
|
||||
|
||||
/*
|
||||
* invoke readlink, with bufsiz -1 to reserve an space for
|
||||
* the NULL character
|
||||
*/
|
||||
size = readlink(path, buf, bufsiz - 1);
|
||||
size = readlink(path, buf, bufsiz);
|
||||
free(path);
|
||||
if (size < 0) {
|
||||
/* error */
|
||||
@ -455,8 +453,13 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
|
||||
}
|
||||
|
||||
/* NULL-terminate the buf */
|
||||
ret = ISO_SUCCESS;
|
||||
if ((size_t) size >= bufsiz) {
|
||||
ret = ISO_RR_PATH_TOO_LONG;
|
||||
size = bufsiz - 1;
|
||||
}
|
||||
buf[size] = '\0';
|
||||
return ISO_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static
|
||||
@ -492,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;
|
||||
|
||||
@ -506,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)
|
||||
@ -812,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;
|
||||
@ -852,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;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
* @param image
|
||||
* Location where the image pointer will be stored.
|
||||
* @return
|
||||
* 1 sucess, < 0 error
|
||||
* 1 success, < 0 error
|
||||
*/
|
||||
int iso_image_new(const char *name, IsoImage **image)
|
||||
{
|
||||
@ -142,6 +142,8 @@ void iso_image_unref(IsoImage *image)
|
||||
free(image->biblio_file_id);
|
||||
if (image->used_inodes != NULL)
|
||||
free(image->used_inodes);
|
||||
if (image->system_area_data != NULL)
|
||||
free(image->system_area_data);
|
||||
iso_image_free_checksums(image, 0);
|
||||
free(image);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 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
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -684,7 +689,7 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
|
||||
|
||||
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
||||
|
||||
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);
|
||||
|
||||
@ -810,15 +815,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 +837,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 +845,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 +858,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 +892,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 +929,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 +937,14 @@ int write_path_table(Ecma119Image *t, Iso1999Node **pathlist, int l_type)
|
||||
/* we need to fill the last block with zeros */
|
||||
path_table_size %= BLOCK_SIZE;
|
||||
if (path_table_size) {
|
||||
uint8_t zeros[BLOCK_SIZE];
|
||||
LIBISO_ALLOC_MEM(zeros, uint8_t, BLOCK_SIZE);
|
||||
len = BLOCK_SIZE - path_table_size;
|
||||
memset(zeros, 0, len);
|
||||
ret = iso_write(t, zeros, len);
|
||||
}
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(zeros);
|
||||
LIBISO_FREE_MEM(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* Copyright (c) 2011 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
|
||||
@ -19,6 +20,7 @@
|
||||
#include "filesrc.h"
|
||||
#include "eltorito.h"
|
||||
#include "libisofs.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -42,12 +44,11 @@ int get_joliet_name(Ecma119Image *t, IsoNode *iso, uint16_t **name)
|
||||
iso_msg_debug(t->image->id, "Can't convert %s", iso->name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TODO #00022 : support relaxed constraints in joliet filenames */
|
||||
if (iso->type == LIBISO_DIR) {
|
||||
jname = iso_j_dir_id(ucs_name);
|
||||
jname = iso_j_dir_id(ucs_name, t->joliet_long_names << 1);
|
||||
} else {
|
||||
jname = iso_j_file_id(ucs_name, !!(t->no_force_dots & 2));
|
||||
jname = iso_j_file_id(ucs_name,
|
||||
(t->joliet_long_names << 1) | !!(t->no_force_dots & 2));
|
||||
}
|
||||
free(ucs_name);
|
||||
if (jname != NULL) {
|
||||
@ -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]);
|
||||
}
|
||||
@ -303,8 +304,15 @@ int joliet_create_mangled_name(uint16_t *dest, uint16_t *src, int digits,
|
||||
int ret, pos;
|
||||
uint16_t *ucsnumber;
|
||||
char fmt[16];
|
||||
char nstr[72]; /* The only caller of this function allocates dest with 66
|
||||
elements and limits digits to < 8 */
|
||||
char nstr[72];
|
||||
/* was: The only caller of this function allocates dest
|
||||
with 66 elements and limits digits to < 8
|
||||
But this does not match the usage of nstr which has to take
|
||||
the decimal representation of an int.
|
||||
*/
|
||||
|
||||
if (digits >= 8)
|
||||
return ISO_ASSERT_FAILURE;
|
||||
|
||||
sprintf(fmt, "%%0%dd", digits);
|
||||
sprintf(nstr, fmt, number);
|
||||
@ -337,19 +345,26 @@ static
|
||||
int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
{
|
||||
int ret;
|
||||
int i, nchildren;
|
||||
int i, nchildren, maxchar = 64;
|
||||
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;
|
||||
|
||||
if (t->joliet_long_names)
|
||||
maxchar = 103;
|
||||
|
||||
/* a hash table will temporary hold the names, for fast searching */
|
||||
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;
|
||||
@ -361,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[66];
|
||||
int max; /* computed max len for name, without extension */
|
||||
int j = i;
|
||||
int digits = 1; /* characters to change per name */
|
||||
@ -380,7 +394,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
* A max of 7 characters is good enought, it allows handling up to
|
||||
* 9,999,999 files with same name.
|
||||
*/
|
||||
/* Important: joliet_create_mangled_name() relies on digits < 72 */
|
||||
/* Important: joliet_create_mangled_name() relies on digits < 8 */
|
||||
|
||||
while (digits < 8) {
|
||||
int ok, k;
|
||||
@ -403,7 +417,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
ext = dot + 1;
|
||||
|
||||
extlen = ucslen(ext);
|
||||
max = 65 - extlen - 1 - digits;
|
||||
max = maxchar + 1 - extlen - 1 - digits;
|
||||
if (max <= 0) {
|
||||
/* this can happen if extension is too long */
|
||||
if (extlen + max > 3) {
|
||||
@ -413,7 +427,7 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
*/
|
||||
extlen = extlen + max - 1;
|
||||
ext[extlen] = 0;
|
||||
max = 66 - extlen - 1 - digits;
|
||||
max = maxchar + 2 - extlen - 1 - digits;
|
||||
} else {
|
||||
/*
|
||||
* error, we don't support extensions < 3
|
||||
@ -430,13 +444,13 @@ int mangle_single_dir(Ecma119Image *t, JolietNode *dir)
|
||||
} else {
|
||||
/* Directory, or file without extension */
|
||||
if (children[i]->type == JOLIET_DIR) {
|
||||
max = 65 - digits;
|
||||
max = maxchar + 1 - digits;
|
||||
dot = NULL; /* dots have no meaning in dirs */
|
||||
} else {
|
||||
max = 65 - digits;
|
||||
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 */
|
||||
@ -446,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[66];
|
||||
while (1) {
|
||||
ret = joliet_create_mangled_name(tmp, name, digits,
|
||||
change, ext);
|
||||
@ -508,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;
|
||||
}
|
||||
|
||||
@ -743,7 +759,7 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
||||
|
||||
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
||||
|
||||
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);
|
||||
|
||||
@ -909,15 +925,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);
|
||||
@ -944,7 +961,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;
|
||||
@ -957,6 +974,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;
|
||||
}
|
||||
|
||||
@ -989,14 +1008,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;
|
||||
|
||||
@ -1023,7 +1046,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;
|
||||
}
|
||||
@ -1031,11 +1054,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;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,10 @@
|
||||
#include "libisofs.h"
|
||||
#include "ecma119.h"
|
||||
|
||||
/* was formerly 66 = 64 + 2. Now 105 = 103 + 2.
|
||||
*/
|
||||
#define LIBISO_JOLIET_NAME_MAX 105
|
||||
|
||||
enum joliet_node_type {
|
||||
JOLIET_FILE,
|
||||
JOLIET_DIR
|
||||
|
@ -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 1
|
||||
#define iso_lib_header_version_micro 6
|
||||
|
||||
/**
|
||||
* 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()
|
||||
@ -440,7 +540,10 @@ struct iso_filesystem
|
||||
|
||||
/**
|
||||
* Retrieve a file from its absolute path inside the filesystem.
|
||||
*
|
||||
* @param file
|
||||
* Returns a pointer to a IsoFileSource object representing the
|
||||
* file. It has to be disposed by iso_file_source_unref() when
|
||||
* no longer needed.
|
||||
* @return
|
||||
* 1 success, < 0 error (has to be a valid libisofs error code)
|
||||
* Error codes:
|
||||
@ -857,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.
|
||||
*/
|
||||
@ -992,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);
|
||||
*
|
||||
@ -1165,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 4
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -1585,6 +1607,15 @@ int iso_write_opts_set_relaxed_vol_atts(IsoWriteOpts *opts, int allow);
|
||||
*/
|
||||
int iso_write_opts_set_joliet_longer_paths(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* Allow leaf names in the Joliet tree to have up to 103 characters.
|
||||
* Normal limit is 64.
|
||||
* This breaks Joliet specification. Use with caution.
|
||||
*
|
||||
* @since 1.0.6
|
||||
*/
|
||||
int iso_write_opts_set_joliet_long_names(IsoWriteOpts *opts, int allow);
|
||||
|
||||
/**
|
||||
* Write Rock Ridge info as of specification RRIP-1.10 rather than RRIP-1.12:
|
||||
* signature "RRIP_1991A" rather than "IEEE_1282", field PX without file
|
||||
@ -2075,9 +2106,9 @@ int iso_write_opts_set_part_offset(IsoWriteOpts *opts,
|
||||
tests. It can be prevented by ./configure option --disable-libjte .
|
||||
@since 0.6.38
|
||||
*/
|
||||
#define iso_libjte_req_major 0
|
||||
#define iso_libjte_req_minor 1
|
||||
#define iso_libjte_req_micro 1
|
||||
#define iso_libjte_req_major 1
|
||||
#define iso_libjte_req_minor 0
|
||||
#define iso_libjte_req_micro 0
|
||||
|
||||
/**
|
||||
* Associate a libjte environment object to the upcomming write run.
|
||||
@ -2846,6 +2877,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.
|
||||
*
|
||||
@ -5172,11 +5232,12 @@ int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child);
|
||||
* @param src
|
||||
* An IsoFileSource corresponding to a symbolic link.
|
||||
* @param buf
|
||||
* allocated buffer of at least bufsiz bytes.
|
||||
* The dest. will be copied there, and it will be NULL-terminated
|
||||
* Allocated buffer of at least bufsiz bytes.
|
||||
* The destination string will be copied there, and it will be 0-terminated
|
||||
* if the return value indicates success or ISO_RR_PATH_TOO_LONG.
|
||||
* @param bufsiz
|
||||
* characters to be copied. Destination link will be truncated if
|
||||
* it is larger than given size. This includes the 0x0 character.
|
||||
* Maximum number of buf characters + 1. The string will be truncated if
|
||||
* it is larger than bufsiz - 1 and ISO_RR_PATH_TOO_LONG. will be returned.
|
||||
* @return
|
||||
* 1 on success, < 0 on error
|
||||
* Error codes:
|
||||
@ -5187,6 +5248,7 @@ int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child);
|
||||
* ISO_OUT_OF_MEM
|
||||
* ISO_FILE_BAD_PATH
|
||||
* ISO_FILE_DOESNT_EXIST
|
||||
* ISO_RR_PATH_TOO_LONG (@since 1.0.6)
|
||||
*
|
||||
* @since 0.6.2
|
||||
*/
|
||||
@ -5728,6 +5790,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.
|
||||
*
|
||||
@ -5771,7 +5857,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
|
||||
@ -5860,6 +5946,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
|
||||
@ -6819,6 +6908,23 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
||||
/** Found copied superblock checksum tag (WARNING, HIGH, -376) */
|
||||
#define ISO_MD5_TAG_COPIED 0xD030FE88
|
||||
|
||||
/** Rock Ridge leaf name too long (FAILURE, HIGH, -377) */
|
||||
#define ISO_RR_NAME_TOO_LONG 0xE830FE87
|
||||
|
||||
/** Reserved Rock Ridge leaf name (FAILURE, HIGH, -378) */
|
||||
#define ISO_RR_NAME_RESERVED 0xE830FE86
|
||||
|
||||
/** 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:
|
||||
Place new error codes directly above this comment.
|
||||
|
@ -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;
|
||||
@ -282,6 +284,7 @@ iso_write_opts_set_hardlinks;
|
||||
iso_write_opts_set_iso1999;
|
||||
iso_write_opts_set_iso_level;
|
||||
iso_write_opts_set_joliet;
|
||||
iso_write_opts_set_joliet_long_names;
|
||||
iso_write_opts_set_joliet_longer_paths;
|
||||
iso_write_opts_set_max_37_char_filenames;
|
||||
iso_write_opts_set_ms_block;
|
||||
@ -309,5 +312,6 @@ iso_write_opts_set_will_cancel;
|
||||
iso_zisofs_get_params;
|
||||
iso_zisofs_get_refcounts;
|
||||
iso_zisofs_set_params;
|
||||
serial_id;
|
||||
local: *;
|
||||
};
|
||||
|
@ -135,7 +135,7 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
|
||||
|
||||
static int h = 64, s = 32;
|
||||
|
||||
int i, warn_size = 0, id;
|
||||
int i, id;
|
||||
char *wpt;
|
||||
off_t imgsize, cylsize, frac, padding, c, cc;
|
||||
|
||||
@ -164,7 +164,6 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
|
||||
*img_blocks = imgsize / (off_t) 2048;
|
||||
c = imgsize / cylsize;
|
||||
if (c > 1024) {
|
||||
warn_size = 1;
|
||||
cc = 1024;
|
||||
} else
|
||||
cc = c;
|
||||
@ -424,7 +423,7 @@ int make_isolinux_mbr(int32_t *img_blocks, uint32_t boot_lba,
|
||||
/* # Offset 446
|
||||
*/
|
||||
for (part = 1 ; part <= 4; part++) {
|
||||
if (part != part_number) {
|
||||
if ((int) part != part_number) {
|
||||
/* if this_partition != partition_number: write 16 zero bytes */
|
||||
memset(wpt, 0, 16);
|
||||
wpt+= 16;
|
||||
|
@ -229,10 +229,10 @@ static int md5_init(libisofs_md5_ctx *ctx, int flag)
|
||||
static int md5_update(libisofs_md5_ctx *ctx, unsigned char *data,
|
||||
int datalen, int flag)
|
||||
{
|
||||
unsigned int i, index, partlen;
|
||||
int i, index, partlen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (unsigned int)((ctx->count[0] >> 3) & 0x3F);
|
||||
index = ((ctx->count[0] >> 3) & 0x3F);
|
||||
/* Update number of bits */
|
||||
if ((ctx->count[0] += ((uint32_t) datalen << 3)) <
|
||||
((uint32_t) datalen << 3))
|
||||
@ -621,11 +621,6 @@ int checksum_writer_write_data(IsoImageWriter *writer)
|
||||
void *ctx = NULL;
|
||||
char md5[16];
|
||||
|
||||
#ifdef NIX
|
||||
char tag_block[2048];
|
||||
int l;
|
||||
#endif
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
@ -724,15 +719,16 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
||||
{
|
||||
void *ctx = NULL;
|
||||
off_t pos = 0, line_start;
|
||||
int record_len, block_len, res, i;
|
||||
char postext[40], md5[16], record[160];
|
||||
int record_len, block_len, ret, i;
|
||||
char postext[40], md5[16], *record = NULL;
|
||||
|
||||
LIBISO_ALLOC_MEM(record, char, 160);
|
||||
line_start = strlen(tag_block);
|
||||
iso_md5_compute(t->checksum_ctx, tag_block, line_start);
|
||||
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||
if (res < 0)
|
||||
ret = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
res = iso_md5_end(&ctx, md5);
|
||||
ret = iso_md5_end(&ctx, md5);
|
||||
|
||||
pos = (off_t) t->checksum_tag_pos * (off_t) 2048 + line_start;
|
||||
if(pos >= 1000000000)
|
||||
@ -747,8 +743,8 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
||||
"%2.2x", ((unsigned char *) md5)[i]);
|
||||
record_len += 32;
|
||||
|
||||
res = iso_md5_start(&ctx);
|
||||
if (res < 0)
|
||||
ret = iso_md5_start(&ctx);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
iso_md5_compute(ctx, record, record_len);
|
||||
iso_md5_end(&ctx, md5);
|
||||
@ -765,11 +761,12 @@ int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
||||
if (t->scdbackup_tag_written != NULL)
|
||||
strncpy(t->scdbackup_tag_written, tag_block + line_start,
|
||||
block_len - line_start);
|
||||
res = ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (ctx != NULL)
|
||||
iso_md5_end(&ctx, md5);
|
||||
return res;
|
||||
LIBISO_FREE_MEM(record);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -783,20 +780,20 @@ ex:;
|
||||
*/
|
||||
int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
{
|
||||
int res, mode, l, i, wres, tag_id_len;
|
||||
int ret, mode, l, i, wres, tag_id_len;
|
||||
void *ctx = NULL;
|
||||
char md5[16], tag_block[2048], *tag_id;
|
||||
char md5[16], *tag_block = NULL, *tag_id;
|
||||
uint32_t size = 0, pos = 0, start;
|
||||
|
||||
LIBISO_ALLOC_MEM(tag_block, char, 2048);
|
||||
start = t->checksum_range_start;
|
||||
memset(tag_block, 0, 2048);
|
||||
mode = flag & 255;
|
||||
if (mode < 1 || mode > 4)
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||
if (res < 0)
|
||||
return res;
|
||||
res = iso_md5_end(&ctx, md5);
|
||||
{ret = ISO_WRONG_ARG_VALUE; goto ex;}
|
||||
ret = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
ret = iso_md5_end(&ctx, md5);
|
||||
if (mode == 1) {
|
||||
size = t->checksum_range_size;
|
||||
pos = t->checksum_tag_pos;
|
||||
@ -811,7 +808,7 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
}
|
||||
size = pos - start;
|
||||
}
|
||||
if (res < 0)
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
|
||||
iso_util_tag_magic(mode, &tag_id, &tag_id_len, 0);
|
||||
@ -833,8 +830,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
((unsigned char *) md5)[i]);
|
||||
l+= 32;
|
||||
|
||||
res = iso_md5_start(&ctx);
|
||||
if (res > 0) {
|
||||
ret = iso_md5_start(&ctx);
|
||||
if (ret > 0) {
|
||||
iso_md5_compute(ctx, tag_block, l);
|
||||
iso_md5_end(&ctx, md5);
|
||||
strcpy(tag_block + l, " self=");
|
||||
@ -849,8 +846,8 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
if (t->ms_block > 0) {
|
||||
iso_msg_submit(t->image->id, ISO_SCDBACKUP_TAG_NOT_0, 0, NULL);
|
||||
} else {
|
||||
res = iso_md5_write_scdbackup_tag(t, tag_block, 0);
|
||||
if (res < 0)
|
||||
ret = iso_md5_write_scdbackup_tag(t, tag_block, 0);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
@ -861,16 +858,17 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
} else {
|
||||
wres = iso_write(t, tag_block, 2048);
|
||||
if (wres < 0) {
|
||||
res = wres;
|
||||
ret = wres;
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
res = ISO_SUCCESS;
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (ctx != NULL)
|
||||
iso_md5_end(&ctx, md5);
|
||||
return res;
|
||||
LIBISO_FREE_MEM(tag_block);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -245,15 +245,18 @@ int iso_set_abort_severity(char *severity)
|
||||
|
||||
void iso_msg_debug(int imgid, const char *fmt, ...)
|
||||
{
|
||||
char msg[MAX_MSG_LEN];
|
||||
char *msg = NULL;
|
||||
va_list ap;
|
||||
|
||||
LIBISO_ALLOC_MEM_VOID(msg, char, MAX_MSG_LEN);
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
libiso_msgs_submit(libiso_msgr, imgid, 0x00000002, LIBISO_MSGS_SEV_DEBUG,
|
||||
LIBISO_MSGS_PRIO_ZERO, msg, 0, 0);
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(msg);
|
||||
}
|
||||
|
||||
const char *iso_error_to_msg(int errcode)
|
||||
@ -455,6 +458,16 @@ const char *iso_error_to_msg(int errcode)
|
||||
return "Extended information class offers no cloning method";
|
||||
case ISO_MD5_TAG_COPIED:
|
||||
return "Found copied superblock checksum tag";
|
||||
case ISO_RR_NAME_TOO_LONG:
|
||||
return "Rock Ridge leaf name too long";
|
||||
case ISO_RR_NAME_RESERVED:
|
||||
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";
|
||||
}
|
||||
@ -474,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;
|
||||
}
|
||||
|
||||
|
109
libisofs/node.c
109
libisofs/node.c
@ -19,6 +19,7 @@
|
||||
#include "aaip_0_2.h"
|
||||
#include "messages.h"
|
||||
#include "util.h"
|
||||
#include "eltorito.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -28,11 +29,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX Libisofs_default_path_maX
|
||||
#endif
|
||||
|
||||
|
||||
struct dir_iter_data
|
||||
{
|
||||
/* points to the last visited child, to NULL before start */
|
||||
@ -83,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;
|
||||
@ -325,6 +329,7 @@ enum IsoNodeType iso_node_get_type(IsoNode *node)
|
||||
int iso_node_set_name(IsoNode *node, const char *name)
|
||||
{
|
||||
char *new;
|
||||
int ret;
|
||||
|
||||
if ((IsoNode*)node->parent == node) {
|
||||
/* you can't change name of the root node */
|
||||
@ -332,9 +337,9 @@ int iso_node_set_name(IsoNode *node, const char *name)
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (node->parent != NULL) {
|
||||
/* check if parent already has a node with same name */
|
||||
@ -1005,10 +1010,11 @@ const char *iso_symlink_get_dest(const IsoSymlink *link)
|
||||
int iso_symlink_set_dest(IsoSymlink *link, const char *dest)
|
||||
{
|
||||
char *d;
|
||||
if (!iso_node_is_valid_link_dest(dest)) {
|
||||
/* guard against null or empty dest */
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
int ret;
|
||||
|
||||
ret = iso_node_is_valid_link_dest(dest);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
d = strdup(dest);
|
||||
if (d == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
@ -1159,22 +1165,23 @@ int iso_node_is_valid_name(const char *name)
|
||||
{
|
||||
/* a name can't be NULL */
|
||||
if (name == NULL) {
|
||||
return 0;
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* guard against the empty string or big names... */
|
||||
if (name[0] == '\0' || strlen(name) > 255) {
|
||||
return 0;
|
||||
}
|
||||
if (name[0] == '\0')
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||
return ISO_RR_NAME_TOO_LONG;
|
||||
|
||||
/* ...against "." and ".." names... */
|
||||
if (!strcmp(name, ".") || !strcmp(name, "..")) {
|
||||
return 0;
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
}
|
||||
|
||||
/* ...and against names with '/' */
|
||||
if (strchr(name, '/') != NULL) {
|
||||
return 0;
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -1192,13 +1199,14 @@ int iso_node_is_valid_link_dest(const char *dest)
|
||||
|
||||
/* a dest can't be NULL */
|
||||
if (dest == NULL) {
|
||||
return 0;
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* guard against the empty string or big dest... */
|
||||
if (dest[0] == '\0' || strlen(dest) > PATH_MAX) {
|
||||
return 0;
|
||||
}
|
||||
if (dest[0] == '\0')
|
||||
return ISO_RR_NAME_RESERVED;
|
||||
if (strlen(dest) > LIBISOFS_NODE_PATH_MAX)
|
||||
return ISO_RR_PATH_TOO_LONG;
|
||||
|
||||
/* check that all components are valid */
|
||||
if (!strcmp(dest, "/")) {
|
||||
@ -1208,7 +1216,7 @@ int iso_node_is_valid_link_dest(const char *dest)
|
||||
|
||||
ptr = strdup(dest);
|
||||
if (ptr == NULL) {
|
||||
return 0;
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
@ -1216,7 +1224,7 @@ int iso_node_is_valid_link_dest(const char *dest)
|
||||
while (component) {
|
||||
if (strcmp(component, ".") && strcmp(component, "..")) {
|
||||
ret = iso_node_is_valid_name(component);
|
||||
if (ret == 0) {
|
||||
if (ret < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1375,15 +1383,16 @@ int iso_node_new_root(IsoDir **root)
|
||||
int iso_node_new_dir(char *name, IsoDir **dir)
|
||||
{
|
||||
IsoDir *new;
|
||||
int ret;
|
||||
|
||||
if (dir == NULL || name == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
new = calloc(1, sizeof(IsoDir));
|
||||
if (new == NULL) {
|
||||
@ -1400,15 +1409,16 @@ int iso_node_new_dir(char *name, IsoDir **dir)
|
||||
int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
||||
{
|
||||
IsoFile *new;
|
||||
int ret;
|
||||
|
||||
if (file == NULL || name == NULL || stream == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
new = calloc(1, sizeof(IsoFile));
|
||||
if (new == NULL) {
|
||||
@ -1428,21 +1438,21 @@ int iso_node_new_file(char *name, IsoStream *stream, IsoFile **file)
|
||||
int iso_node_new_symlink(char *name, char *dest, IsoSymlink **link)
|
||||
{
|
||||
IsoSymlink *new;
|
||||
int ret;
|
||||
|
||||
if (link == NULL || name == NULL || dest == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* check if destination is valid */
|
||||
if (!iso_node_is_valid_link_dest(dest)) {
|
||||
/* guard against null or empty dest */
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_link_dest(dest);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
new = calloc(1, sizeof(IsoSymlink));
|
||||
if (new == NULL) {
|
||||
@ -1464,6 +1474,7 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
|
||||
IsoSpecial **special)
|
||||
{
|
||||
IsoSpecial *new;
|
||||
int ret;
|
||||
|
||||
if (special == NULL || name == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
@ -1473,9 +1484,9 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
|
||||
}
|
||||
|
||||
/* check if the name is valid */
|
||||
if (!iso_node_is_valid_name(name)) {
|
||||
return ISO_WRONG_ARG_VALUE;
|
||||
}
|
||||
ret = iso_node_is_valid_name(name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
new = calloc(1, sizeof(IsoSpecial));
|
||||
if (new == NULL) {
|
||||
@ -1571,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;
|
||||
@ -1613,13 +1624,15 @@ 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];
|
||||
*value = calloc(*value_length + 1, 1);
|
||||
if (*value == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
found = ISO_OUT_OF_MEM;
|
||||
break;
|
||||
}
|
||||
if (*value_length > 0)
|
||||
@ -2136,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.
|
||||
@ -2192,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;
|
||||
@ -2848,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) */
|
||||
|
@ -30,6 +30,29 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Maximum length of a leaf name in the libisofs node tree. This is currently
|
||||
restricted by the implemented maximum length of a Rock Ridge name.
|
||||
This might later become larger and may then be limited to smaller values.
|
||||
|
||||
Rock Ridge specs do not impose an explicit limit on name length.
|
||||
But 255 is also specified by
|
||||
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
|
||||
which says
|
||||
NAME_MAX >= _XOPEN_NAME_MAX = 255
|
||||
*/
|
||||
#define LIBISOFS_NODE_NAME_MAX 255
|
||||
|
||||
|
||||
/* Maximum length of a path in the libisofs node tree.
|
||||
Rock Ridge specs do not impose an explicit limit on path length.
|
||||
|
||||
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
|
||||
says
|
||||
PATH_MAX >= _XOPEN_PATH_MAX = 1024
|
||||
*/
|
||||
#define LIBISOFS_NODE_PATH_MAX 1024
|
||||
|
||||
|
||||
/**
|
||||
* The extended information is a way to attach additional information to each
|
||||
* IsoNode. External applications may want to use this extension system to
|
||||
@ -286,7 +309,7 @@ int iso_node_new_special(char *name, mode_t mode, dev_t dev,
|
||||
* Check if a given name is valid for an iso node.
|
||||
*
|
||||
* @return
|
||||
* 1 if yes, 0 if not
|
||||
* 1 if yes, <0 if not. The value is a specific ISO_* error code.
|
||||
*/
|
||||
int iso_node_is_valid_name(const char *name);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso
|
||||
* Copyright (c) 2007 Mario Danic
|
||||
* 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
|
||||
@ -337,7 +337,12 @@ static
|
||||
int rrip_add_NM(Ecma119Image *t, struct susp_info *susp, char *name, int size,
|
||||
int flags, int ce)
|
||||
{
|
||||
uint8_t *NM = malloc(size + 5);
|
||||
uint8_t *NM;
|
||||
|
||||
if (size > 250)
|
||||
return ISO_ASSERT_FAILURE;
|
||||
|
||||
NM = malloc(size + 5);
|
||||
if (NM == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
@ -445,8 +450,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;
|
||||
|
||||
@ -945,6 +950,7 @@ int aaip_xinfo_cloner(void *old_data, void **new_data, int flag)
|
||||
* (*su_size and *ce stay unaltered in this case)
|
||||
* <0= error:
|
||||
* -1= not enough SUA space for 28 bytes of CE entry
|
||||
* -2= out of memory
|
||||
*/
|
||||
static
|
||||
int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
@ -981,6 +987,12 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
if (!(flag & 1))
|
||||
goto unannounced_ca;
|
||||
namelen = namelen - (space - *su_size - 5);
|
||||
|
||||
/* >>> 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;
|
||||
}
|
||||
@ -993,6 +1005,8 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
int cew = (*ce != 0); /* are we writing to CA ? */
|
||||
|
||||
dest = get_rr_fname(t, ((IsoSymlink*)n->node)->dest);
|
||||
if (dest == NULL)
|
||||
return -2;
|
||||
prev = dest;
|
||||
cur = strchr(prev, '/');
|
||||
while (1) {
|
||||
@ -1021,8 +1035,10 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
||||
* TODO this can be handled better, but for now SL
|
||||
* will be completelly moved into the CA
|
||||
*/
|
||||
if (!(flag & 1))
|
||||
if (!(flag & 1)) {
|
||||
free(dest);
|
||||
goto unannounced_ca;
|
||||
}
|
||||
cew = 1;
|
||||
} else {
|
||||
sl_len += clen;
|
||||
@ -1041,8 +1057,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
|
||||
@ -1236,13 +1252,16 @@ size_t rrip_calc_len(Ecma119Image *t, Ecma119Node *n, int type, size_t used_up,
|
||||
/* Try without CE */
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 0);
|
||||
if (ret == 0) /* Retry with CE */
|
||||
susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
|
||||
ret = susp_calc_nm_sl_al(t, n, space, &su_size, ce, 1);
|
||||
if (ret == -2)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
} else {
|
||||
|
||||
/* "." or ".." entry */
|
||||
|
||||
su_size += 5; /* NM field */
|
||||
if (!t->rrip_version_1_10)
|
||||
su_size += 5; /* NM field */
|
||||
|
||||
if (type == 1 && n->parent == NULL) {
|
||||
/*
|
||||
@ -1327,7 +1346,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;
|
||||
@ -1339,7 +1358,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;
|
||||
}
|
||||
|
||||
@ -1423,7 +1442,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;
|
||||
}
|
||||
|
||||
@ -1445,12 +1464,18 @@ 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 */
|
||||
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;
|
||||
}
|
||||
if (ret == -2) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto add_susp_cleanup;
|
||||
}
|
||||
|
||||
/* NM entry */
|
||||
if (5 + namelen <= sua_free) {
|
||||
@ -1535,8 +1560,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
|
||||
@ -1648,6 +1673,12 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
|
||||
/*
|
||||
* ..and the part that goes to continuation area.
|
||||
*/
|
||||
|
||||
/* >>> 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);
|
||||
if (ret < 0) {
|
||||
@ -1689,9 +1720,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) {
|
||||
@ -1799,12 +1857,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],
|
||||
@ -1830,6 +1889,8 @@ int rrip_write_ce_fields(Ecma119Image *t, struct susp_info *info)
|
||||
info->ce_susp_fields = NULL;
|
||||
info->n_ce_susp_fields = 0;
|
||||
info->ce_len = 0;
|
||||
ex:;
|
||||
LIBISO_FREE_MEM(padding);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -81,8 +81,7 @@ int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue)
|
||||
* (IEEE 1281, SUSP. section 4)
|
||||
*/
|
||||
if (iter->ce_len) {
|
||||
uint32_t block;
|
||||
int nblocks;
|
||||
uint32_t block, nblocks;
|
||||
|
||||
/* A CE has found, there is another continuation area */
|
||||
nblocks = DIV_UP(iter->ce_off + iter->ce_len, BLOCK_SIZE);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "stream.h"
|
||||
#include "fsource.h"
|
||||
#include "util.h"
|
||||
#include "node.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -213,6 +214,7 @@ int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
IsoStreamIface fsrc_stream_class = {
|
||||
4, /* version */
|
||||
"fsrc",
|
||||
@ -397,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;
|
||||
}
|
||||
@ -502,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",
|
||||
@ -646,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 */
|
||||
}
|
||||
|
||||
@ -747,6 +750,7 @@ int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
IsoStreamIface mem_stream_class = {
|
||||
4, /* version */
|
||||
"mem ",
|
||||
@ -769,7 +773,7 @@ IsoStreamIface mem_stream_class = {
|
||||
* When the Stream refcount reach 0, the buffer is free(3).
|
||||
*
|
||||
* @return
|
||||
* 1 sucess, < 0 error
|
||||
* 1 success, < 0 error
|
||||
*/
|
||||
int iso_memory_stream_new(unsigned char *buf, size_t size, IsoStream **stream)
|
||||
{
|
||||
@ -868,7 +872,12 @@ 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);
|
||||
strncpy(name, path, PATH_MAX);
|
||||
if (path == NULL) {
|
||||
name[0] = 0;
|
||||
return;
|
||||
}
|
||||
strncpy(name, path, PATH_MAX - 1);
|
||||
name[PATH_MAX - 1] = 0;
|
||||
free(path);
|
||||
} else if (!strncmp(type, "boot", 4)) {
|
||||
strcpy(name, "BOOT CATALOG");
|
||||
@ -1074,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);
|
||||
@ -1092,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 */
|
||||
|
@ -29,7 +29,8 @@ typedef struct
|
||||
/**
|
||||
* Get an identifier for the file of the source, for debug purposes
|
||||
* @param name
|
||||
* Should provide at least PATH_MAX bytes
|
||||
* Must provide at least PATH_MAX bytes. If no PATH_MAX is defined
|
||||
* then assume PATH_MAX = Libisofs_default_path_maX from libisofs.h
|
||||
*/
|
||||
void iso_stream_get_file_name(IsoStream *stream, char *name);
|
||||
|
||||
|
@ -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
|
||||
@ -305,9 +305,9 @@ static int boot_nodes_from_iso_path(Ecma119Image *t, char *path,
|
||||
int ret;
|
||||
|
||||
ret = iso_tree_path_to_node(t->image, path, iso_node);
|
||||
if (ret < 0) {
|
||||
if (ret <= 0) {
|
||||
iso_msg_submit(t->image->id, ISO_BOOT_FILE_MISSING, 0,
|
||||
"Cannot find %s '%s'", purpose, path);
|
||||
"Cannot find in ISO image: %s '%s'", purpose, path);
|
||||
return ISO_BOOT_FILE_MISSING;
|
||||
}
|
||||
if ((*iso_node)->type != LIBISO_FILE) {
|
||||
@ -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;
|
||||
}
|
||||
|
@ -32,11 +32,6 @@
|
||||
#include <fnmatch.h>
|
||||
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX Libisofs_default_path_maX
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Add a new directory to the iso tree.
|
||||
*
|
||||
@ -483,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 *
|
||||
@ -579,20 +574,19 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
||||
*node = NULL;
|
||||
}
|
||||
|
||||
fs = image->fs;
|
||||
result = fs->get_by_path(fs, path, &file);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* find place where to insert */
|
||||
result = iso_dir_exists(parent, name, &pos);
|
||||
if (result) {
|
||||
/* a node with same name already exists */
|
||||
iso_file_source_unref(file);
|
||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||
}
|
||||
|
||||
fs = image->fs;
|
||||
result = fs->get_by_path(fs, path, &file);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = image->builder->create_node(image->builder, image, file, &new);
|
||||
|
||||
/* free the file */
|
||||
@ -767,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;
|
||||
}
|
||||
|
||||
@ -791,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) {
|
||||
@ -853,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 {
|
||||
@ -973,26 +977,33 @@ int iso_tree_path_to_node(IsoImage *image, const char *path, IsoNode **node)
|
||||
|
||||
char *iso_tree_get_node_path(IsoNode *node)
|
||||
{
|
||||
if (node == NULL || node->parent == NULL) {
|
||||
char *path = NULL, *parent_path = NULL;
|
||||
|
||||
if (node == NULL || node->parent == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((IsoNode*)node->parent == node) {
|
||||
return strdup("/");
|
||||
} else {
|
||||
char path[PATH_MAX];
|
||||
char *parent_path = iso_tree_get_node_path((IsoNode*)node->parent);
|
||||
if (parent_path == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
parent_path = iso_tree_get_node_path((IsoNode*)node->parent);
|
||||
if (parent_path == NULL)
|
||||
goto ex;
|
||||
if (strlen(parent_path) == 1) {
|
||||
snprintf(path, PATH_MAX, "/%s", node->name);
|
||||
path = calloc(1, strlen(node->name) + 2);
|
||||
if (path == NULL)
|
||||
goto ex;
|
||||
sprintf(path, "/%s", node->name);
|
||||
} else {
|
||||
snprintf(path, PATH_MAX, "%s/%s", parent_path, node->name);
|
||||
path = calloc(1, strlen(parent_path) + strlen(node->name) + 2);
|
||||
if (path == NULL)
|
||||
goto ex;
|
||||
sprintf(path, "%s/%s", parent_path, node->name);
|
||||
}
|
||||
free(parent_path);
|
||||
return strdup(path);
|
||||
}
|
||||
ex:;
|
||||
if (parent_path != NULL)
|
||||
free(parent_path);
|
||||
return path;
|
||||
}
|
||||
|
||||
/* ------------------------- tree cloning ------------------------------ */
|
||||
|
257
libisofs/util.c
257
libisofs/util.c
@ -16,6 +16,7 @@
|
||||
#include "util.h"
|
||||
#include "libisofs.h"
|
||||
#include "messages.h"
|
||||
#include "joliet.h"
|
||||
#include "../version.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -218,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;
|
||||
@ -268,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;
|
||||
@ -335,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 */
|
||||
@ -381,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;
|
||||
@ -404,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;
|
||||
@ -457,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;
|
||||
@ -470,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;
|
||||
@ -516,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;
|
||||
@ -539,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;
|
||||
@ -588,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;
|
||||
@ -604,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;
|
||||
@ -635,7 +692,7 @@ char *iso_dirid(const char *src, int size)
|
||||
char name[32];
|
||||
|
||||
len = strlen(src);
|
||||
if (len > size) {
|
||||
if ((int) len > size) {
|
||||
len = size;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
@ -769,7 +826,7 @@ 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);
|
||||
@ -837,15 +894,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) {
|
||||
@ -916,16 +973,22 @@ ex:;
|
||||
|
||||
/*
|
||||
bit0= no_force_dots
|
||||
bit1= allow 103 characters rather than 64
|
||||
*/
|
||||
uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
{
|
||||
uint16_t *dot;
|
||||
size_t lname, lext, lnname, lnext, pos, i;
|
||||
uint16_t dest[66]; /* 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
|
||||
uint16_t *dot, *retval = NULL;
|
||||
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
|
||||
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;
|
||||
|
||||
dot = ucsrchr(src, '.');
|
||||
|
||||
@ -937,18 +1000,19 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
|
||||
*/
|
||||
if (dot == NULL || cmp_ucsbe(dot + 1, '\0') == 0) {
|
||||
lname = ucslen(src);
|
||||
lnname = (lname > 64) ? 64 : lname;
|
||||
lnname = (lname > maxchar) ? maxchar : lname;
|
||||
lext = lnext = 0;
|
||||
} else {
|
||||
lext = ucslen(dot + 1);
|
||||
lname = ucslen(src) - lext - 1;
|
||||
lnext = (ucslen(src) > 65 && lext > 3) ? (lname < 61 ? 64 - lname : 3)
|
||||
lnext = (ucslen(src) > maxchar + 1 && lext > 3)
|
||||
? (lname < maxchar - 3 ? maxchar - lname : 3)
|
||||
: lext;
|
||||
lnname = (ucslen(src) > 65) ? 64 - lnext : lname;
|
||||
lnname = (ucslen(src) > maxchar + 1) ? maxchar - lnext : lname;
|
||||
}
|
||||
|
||||
if (lnname == 0 && lnext == 0) {
|
||||
return NULL;
|
||||
goto ex;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
@ -983,21 +1047,30 @@ 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;
|
||||
}
|
||||
|
||||
uint16_t *iso_j_dir_id(const uint16_t *src)
|
||||
/* @param flag bit1= allow 103 characters rather than 64
|
||||
*/
|
||||
uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
|
||||
{
|
||||
size_t len, i;
|
||||
uint16_t dest[65]; /* 65 = 64 + 1 (\0) */
|
||||
size_t len, i, maxchar = 64;
|
||||
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;
|
||||
|
||||
len = ucslen(src);
|
||||
if (len > 64) {
|
||||
len = 64;
|
||||
if (len > maxchar) {
|
||||
len = maxchar;
|
||||
}
|
||||
for (i = 0; i < len; i++) {
|
||||
uint16_t c = src[i];
|
||||
@ -1008,7 +1081,10 @@ uint16_t *iso_j_dir_id(const uint16_t *src)
|
||||
}
|
||||
}
|
||||
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)
|
||||
@ -1526,16 +1602,17 @@ char *iso_util_strcopy(const char *buf, size_t len)
|
||||
return str;
|
||||
}
|
||||
|
||||
char *iso_util_strcopy_untail(const char *buf, size_t len)
|
||||
char *iso_util_strcopy_untail(const char *buf, size_t len_in)
|
||||
{
|
||||
char *str;
|
||||
int len;
|
||||
|
||||
str = iso_util_strcopy(buf, len);
|
||||
str = iso_util_strcopy(buf, len_in);
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
/* remove trailing spaces */
|
||||
for (len = len-1; len >= 0; --len) {
|
||||
for (len = len_in - 1; len >= 0; --len) {
|
||||
if (str[len] != ' ')
|
||||
break;
|
||||
str[len] = 0;
|
||||
@ -1553,12 +1630,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] = ' ';
|
||||
}
|
||||
@ -1590,7 +1667,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;
|
||||
}
|
||||
@ -1827,12 +1904,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)) {
|
||||
@ -1875,4 +1952,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;
|
||||
}
|
||||
|
||||
|
@ -153,13 +153,15 @@ char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot);
|
||||
|
||||
/**
|
||||
* Create a Joliet file identifier that consists of name and extension. The
|
||||
* combined name and extension length will not exceed 128 bytes, and the
|
||||
* name and extension will be separated (.). All characters consist of
|
||||
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
|
||||
* combined name and extension length will normally not exceed 64 characters
|
||||
* (= 128 bytes). The name and the extension will be separated (.).
|
||||
* All characters consist of 2 bytes and the resulting string is
|
||||
* NULL-terminated by a 2-byte NULL.
|
||||
*
|
||||
* Note that version number and (;1) is not appended.
|
||||
* @param flag
|
||||
* bit0= no_force_dots
|
||||
* bit1= allow 103 characters rather than 64
|
||||
* @return
|
||||
* NULL if the original name and extension both are of length 0.
|
||||
*/
|
||||
@ -171,10 +173,12 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag);
|
||||
* and the name and extension will be separated (.). All characters consist of
|
||||
* 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL.
|
||||
*
|
||||
* @param flag
|
||||
* bit1= allow 103 characters rather than 64
|
||||
* @return
|
||||
* NULL if the original name and extension both are of length 0.
|
||||
*/
|
||||
uint16_t *iso_j_dir_id(const uint16_t *src);
|
||||
uint16_t *iso_j_dir_id(const uint16_t *src, int flag);
|
||||
|
||||
/**
|
||||
* Like strlen, but for Joliet strings.
|
||||
@ -535,4 +539,24 @@ int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag);
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
||||
void *iso_alloc_mem(size_t size, size_t count, int flag);
|
||||
|
||||
#define LIBISO_ALLOC_MEM(pt, typ, count) { \
|
||||
pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \
|
||||
if(pt == NULL) { \
|
||||
ret= ISO_OUT_OF_MEM; goto ex; \
|
||||
} }
|
||||
|
||||
#define LIBISO_ALLOC_MEM_VOID(pt, typ, count) { \
|
||||
pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \
|
||||
if(pt == NULL) { \
|
||||
goto ex; \
|
||||
} }
|
||||
|
||||
#define LIBISO_FREE_MEM(pt) { \
|
||||
if(pt != NULL) \
|
||||
free((char *) pt); \
|
||||
}
|
||||
|
||||
|
||||
#endif /*LIBISO_UTIL_H_*/
|
||||
|
@ -164,7 +164,7 @@ int iso_rbtree_insert(IsoRBTree *tree, void *data, void **item)
|
||||
new = data;
|
||||
added = 1;
|
||||
} else {
|
||||
struct iso_rbnode head = { 0 }; /* False tree root */
|
||||
struct iso_rbnode head = { 0, {NULL, NULL}, 0 }; /* False tree root */
|
||||
|
||||
struct iso_rbnode *g, *t; /* Grandparent & parent */
|
||||
struct iso_rbnode *p, *q; /* Iterator & parent */
|
||||
|
Reference in New Issue
Block a user