Compare commits

...

45 Commits

Author SHA1 Message Date
d787ecbcd9 Version leap to 1.1.6 2011-09-27 14:29:18 +02:00
182edb3a00 Updated changelog 2011-09-26 19:10:13 +02:00
cb25d4d4e5 Clarified a remark about maximum length of RR name parts in CA. 2011-09-26 18:23:24 +02:00
afdef92343 Moved version number macros higher in libisofs/libisofs.h 2011-09-24 16:38:20 +02:00
2bc7084315 Adaptions and remarks about GNU/Hurd 2011-08-30 19:20:18 +02:00
6d10908a58 Detecting and rejecting multiple entries of user::, group::, other:: in ACL text 2011-08-24 09:23:02 +02:00
2ba54fafe7 New optional tolerance towards failure to restore "default" ACLS on FreeBSD. 2011-08-23 12:40:09 +02:00
ca63dac7e3 Enabled recording and restoring of extattr on FreeBSD.
Gave up unconditional ACL support in favor of configure control.
2011-08-22 17:10:13 +02:00
f885da8087 Avoided to restore xattr of namespace "isofs" if non-"user" restoring is
enabled.
2011-08-22 15:57:16 +02:00
8438db02cf Avoided to call calloc() for 0 bytes when reading Linux xattr. 2011-08-22 12:37:11 +02:00
ce19db5e19 Bug fix: On Solaris: False out-of-memory errors when writing images. 2011-08-19 12:40:45 +02:00
aeb5258ae2 Removed rogue comma from FreeBSD ACL adapter 2011-08-18 16:06:33 +02:00
f10c2d7779 New API call iso_local_attr_support() 2011-08-18 15:07:31 +02:00
82bfcf429a Bug fix: No ACLs were recorded on FreeBSD. 2011-08-18 10:29:34 +02:00
8fb8c01a0f Corrected a theoretical flaw in a code path which is not yet used. 2011-08-18 10:28:41 +02:00
73910e2f3c Bug fix: ACL entries of groups and of user id 0 were not properly recorded
and cannot be restored.
2011-08-18 10:26:09 +02:00
9c5fc21679 Small change in a comment 2011-08-18 10:24:47 +02:00
3a82f213e0 Implemented direct iconv conversion for the case that the traditional
two-step conversion via character set "WCHAR_T" fails. E.g. on Solaris.
2011-08-11 18:22:49 +02:00
6892c734e2 Bug fix: The function for restoring ACLs and xattr returned error on
FreeBSD, even if no xattr were to be restored.
2011-08-09 19:00:03 +02:00
66f6937c17 Clarified stream version prescription and made internal stream data
instances static.
2011-08-09 14:59:19 +02:00
baa5b7cd42 Added missing symbol serial_id to libisofs.ver 2011-08-09 14:58:46 +02:00
f2658ef173 Started new development cycle 2011-08-09 12:32:04 +02:00
ecdb3aeb1d Version leap to 1.1.5 2011-08-08 13:58:43 +02:00
745a878884 Version leap to 1.1.4 2011-08-08 09:35:46 +02:00
6ae8386c23 Bug fix: The function for restoring ACLs and xattr returned error on systems
other than Linux and FreeBSD, even if nothing was to be restored.
2011-08-08 08:25:18 +02:00
b90e613246 Reacted on warnings of cppcheck 2011-07-11 12:44:12 +02:00
bbc3caf86b Reacted on warnings of cppcheck 2011-07-11 12:43:12 +02:00
b086d53274 Reacted on warnings of cppcheck 2011-07-11 12:41:30 +02:00
17b36623a6 Version leap to 1.1.3 2011-07-08 14:42:09 +02:00
286648574d Version leap to 1.1.2 2011-07-08 10:28:12 +02:00
317bba395e Updated changelog 2011-07-08 10:25:24 +02:00
541b41b6a1 Clarified a comment about retrieving content of boot catalog. 2011-07-07 14:11:30 +02:00
91a8be5262 Silenced a warning of cppcheck about possible null pointer dereference. 2011-07-06 12:31:37 +02:00
91e99703b4 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 18:54:11 +02:00
dd7dac3397 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:07:35 +02:00
43d4833dd6 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:06:16 +02:00
dd1629b5ca Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:04:05 +02:00
bc8138ce78 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 16:00:29 +02:00
2d568c1dbb Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:56:26 +02:00
842b62d111 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:50:52 +02:00
4f3357e3ec Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:39:38 +02:00
9ffe91c372 Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:37:55 +02:00
7e2add413a Reacted on warnings of -Wunused-but-set-variable 2011-07-04 15:35:43 +02:00
004aefd0b7 New API call iso_image_get_bootcat() 2011-07-03 21:02:19 +02:00
00955ba85c Version leap to 1.1.1 2011-06-18 19:22:11 +02:00
24 changed files with 1325 additions and 281 deletions

View File

@ -1,3 +1,22 @@
libisofs-1.1.6.tar.gz Tue Sep 27 2011
===============================================================================
* Bug fix: On Solaris: False out-of-memory errors when writing images.
* Bug fix: On FreeBSD: No ACLs were recorded.
* Bug fix: ACL entries of groups and of user id 0 were not properly recorded
and cannot be restored.
* Bug fix: On FreeBSD: The function for restoring ACLs and xattr returned
error, even if no xattr were to be restored.
* New API call iso_local_attr_support()
* Enabled recording and restoring of extattr on FreeBSD.
libisofs-1.1.4.tar.gz Mon Aug 08 2011
===============================================================================
* Bug fix: The function for restoring ACLs and xattr returned error on systems
other than Linux and FreeBSD, even if nothing was to be restored.
libisofs-1.1.2.tar.gz Fri Jul 08 2011
===============================================================================
* New API call iso_image_get_bootcat()
libisofs-1.1.0.tar.gz Sat Jun 18 2011
===============================================================================

View File

@ -1,4 +1,4 @@
AC_INIT([libisofs], [1.1.0], [http://libburnia-project.org])
AC_INIT([libisofs], [1.1.6], [http://libburnia-project.org])
AC_PREREQ([2.50])
dnl AC_CONFIG_HEADER([config.h])
@ -41,7 +41,7 @@ dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
dnl
LIBISOFS_MAJOR_VERSION=1
LIBISOFS_MINOR_VERSION=1
LIBISOFS_MICRO_VERSION=0
LIBISOFS_MICRO_VERSION=6
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
AC_SUBST(LIBISOFS_MAJOR_VERSION)
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
dnl Libtool versioning
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
# 2011.06.18 development jump has not yet happened
# SONAME = 54 - 48 = 6 . Library name = libisofs.6.48.0
LT_CURRENT=54
LT_AGE=48
# 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`
@ -160,14 +160,19 @@ LIBBURNIA_SET_PKGCONFIG
dnl Add compiler-specific flags
AC_ARG_ENABLE(libacl,
[ --enable-libacl Enable use of libacl by libisofs, default=yes],
[ --enable-libacl Enable use of ACL functions by libisofs, default=yes],
, enable_libacl=yes)
if test "x$enable_libacl" = xyes; then
dnl Check whether there is libacl-devel and libacl-runtime.
dnl If not, erase this macro which would enable use of acl_to_text and others
LIBACL_DEF="-DLibisofs_with_aaip_acL"
dnl The empty yes case obviously causes -lacl to be linked
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , LIBACL_DEF= ), LIBACL_DEF= )
has_acl_h_but_no_func=0
AC_CHECK_HEADER(sys/acl.h, AC_CHECK_LIB(acl, acl_to_text, , has_acl_h_but_no_libacl=1 ), LIBACL_DEF= )
if test "$has_acl_h_but_no_libacl" = 1
then
AC_CHECK_LIB(c, acl_to_text, X= , LIBACL_DEF= )
fi
else
LIBACL_DEF=
fi
@ -183,6 +188,11 @@ dnl Check whether there is the header for Linux xattr.
dnl If not, erase this macro which would enable use of listxattr and others
XATTR_DEF="-DLibisofs_with_aaip_xattR"
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= , XATTR_DEF= ), XATTR_DEF= )
if test "x$XATTR_DEF" = x
then
XATTR_DEF="-DLibisofs_with_freebsd_extattR"
AC_CHECK_HEADER(sys/extattr.h, AC_CHECK_LIB(c, extattr_list_file, X=, XATTR_DEF= ), XATTR_DEF= )
fi
else
XATTR_DEF=
fi

View File

@ -11,7 +11,7 @@
To be included by aaip_0_2.c
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
*/
@ -28,6 +28,29 @@
#include <sys/stat.h>
/* ------------------------------ Inquiry --------------------------------- */
/* See also API iso_local_attr_support().
@param flag
Bitfield for control purposes
bit0= inquire availability of ACL
bit1= inquire availability of xattr
bit2 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag. If bits are set, th
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these
*/
int aaip_local_attr_support(int flag)
{
return(0);
}
/* ------------------------------ Getters --------------------------------- */
/* Obtain the ACL of the given file in long text form.
@ -89,7 +112,11 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
continue;
}
/* Extended Attribute */
if(!(flag & 4))
if(flag & 4)
continue;
if(!(flag & 8))
if(strncmp(names[i], "user.", 5))
continue;
return(-6);
}
if(flag & 2)

View File

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

View File

@ -7,7 +7,7 @@
To be included by aaip_0_2.c
Copyright (c) 2009 Thomas Schmitt, libburnia project, GPLv2+
Copyright (c) 2009 - 2011 Thomas Schmitt, libburnia project, GPLv2+
*/
@ -34,6 +34,40 @@
#endif
/* ------------------------------ Inquiry --------------------------------- */
/* See also API iso_local_attr_support().
@param flag
Bitfield for control purposes
bit0= inquire availability of ACL
bit1= inquire availability of xattr
bit2 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag. If bits are set, th
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these
*/
int aaip_local_attr_support(int flag)
{
int ret= 0;
#ifdef Libisofs_with_aaip_acL
if(flag & 1)
ret|= 1;
#endif
#ifdef Libisofs_with_aaip_xattR
if(flag & 2)
ret|= 2;
#endif
return(ret);
}
/* ------------------------------ Getters --------------------------------- */
/* Obtain the ACL of the given file in long text form.
@ -144,21 +178,24 @@ int aaip_get_acl_text(char *path, char **text, int flag)
bit15= free memory of names, value_lengths, values
@return >0 ok
<=0 error
-1= out of memory
-2= program error with prediction of result size
-3= error with conversion of name to uid or gid
*/
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
size_t **value_lengths, char ***values, int flag)
{
int ret;
char *list= NULL;
ssize_t list_size= 0, i, num_names= 0;
unsigned char *acl= NULL;
char *a_acl_text= NULL, *d_acl_text= NULL;
ssize_t i, num_names= 0;
#ifdef Libisofs_with_aaip_acL
unsigned char *acl= NULL;
char *a_acl_text= NULL, *d_acl_text= NULL;
size_t acl_len= 0;
#endif
#ifdef Libisofs_with_aaip_xattR
ssize_t value_ret, retry= 0;
char *list= NULL;
ssize_t value_ret, retry= 0, list_size= 0;
#endif
if(flag & (1 << 15)) { /* Free memory */
@ -171,16 +208,21 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
*values= NULL;
/* Set up arrays */
if(!(flag & 4)) { /* Get xattr names */
#ifdef Libisofs_with_aaip_xattR
if(!(flag & 4)) { /* Get xattr names */
if(flag & 32)
list_size= listxattr(path, list, 0);
else
list_size= llistxattr(path, list, 0);
if(list_size == -1)
if(list_size == -1) {
if(errno == ENOSYS) /* Function not implemented */
list_size= 0; /* Handle as if xattr was disabled at compile time */
else
{ret= -1; goto ex;}
}
if(list_size > 0) {
list= calloc(list_size, 1);
if(list == NULL)
{ret= -1; goto ex;}
@ -190,20 +232,18 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
list_size= llistxattr(path, list, list_size);
if(list_size == -1)
{ret= -1; goto ex;}
#else /* Libisofs_with_aaip_xattR */
list= strdup("");
#endif /* ! Libisofs_with_aaip_xattR */
}
for(i= 0; i < list_size; i+= strlen(list + i) + 1)
num_names++;
}
#endif /* ! Libisofs_with_aaip_xattR */
#ifdef Libisofs_with_aaip_acL
if(flag & 1)
num_names++;
#endif
if(num_names == 0)
@ -219,7 +259,10 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
(*values)[i]= NULL;
(*value_lengths)[i]= 0;
}
if(!(flag & 4)) {
#ifdef Libisofs_with_aaip_xattR
if(!(flag & 4)) { /* Get xattr values */
for(i= 0; i < list_size && (size_t) num_names > *num_attrs;
i+= strlen(list + i) + 1) {
if(!(flag & 8))
@ -229,11 +272,6 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
if((*names)[(*num_attrs) - 1] == NULL)
{ret= -1; goto ex;}
}
}
#ifdef Libisofs_with_aaip_xattR
if(!(flag & 4)) { /* Get xattr values */
for(i= 0; (size_t) i < *num_attrs; i++) {
if(!(flag & 8))
if(strncmp((*names)[i], "user.", 5))
@ -291,12 +329,19 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
ret= 1;
ex:;
#ifdef Libisofs_with_aaip_acL
if(a_acl_text != NULL)
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
if(d_acl_text != NULL)
aaip_get_acl_text("", &d_acl_text, 1 << 15); /* free */
if(acl != NULL)
free(acl);
#endif
#ifdef Libisofs_with_aaip_xattR
if(list != NULL)
free(list);
#endif
if(ret <= 0 || (flag & (1 << 15))) {
if(*names != NULL) {
for(i= 0; (size_t) i < *num_attrs; i++)
@ -312,8 +357,6 @@ ex:;
free((*values)[i]);
free(*values);
}
if(acl != NULL)
free(acl);
*values= NULL;
*num_attrs= 0;
}
@ -385,6 +428,8 @@ ex:
I.e. those with a name which does not begin
by "user."
bit5= in case of symbolic link: manipulate link target
bit6= tolerate inappropriate presence or absense of
directory default ACL
@return 1 success
-1 error memory allocation
-2 error with decoding of ACL
@ -393,6 +438,8 @@ ex:
-5 error with deleting attributes
-6 support of xattr not enabled at compile time
-7 support of ACL not enabled at compile time
( -8 unsupported xattr namespace )
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
@ -447,7 +494,11 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
continue;
}
/* Extended Attribute */
if((flag & 1) && !(flag & 8))
if(flag & 4)
continue;
if(strncmp(names[i], "isofs.", 6) == 0)
continue;
if(!(flag & 8))
if(strncmp(names[i], "user.", 5))
continue;
@ -475,6 +526,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
/* "access" ACL */
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
&consumed, NULL, 0, &acl_text_fill, 1);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
acl_text= calloc(acl_text_fill, 1);
@ -482,6 +535,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
{ret= -1; goto ex;}
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
&consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
has_default_acl= (ret == 2);
@ -500,6 +555,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
ret= aaip_decode_acl((unsigned char *) (values[i] + consumed),
value_lengths[i] - consumed, &h_consumed,
NULL, 0, &acl_text_fill, 1);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
acl_text= calloc(acl_text_fill, 1);
@ -508,11 +565,21 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
ret= aaip_decode_acl((unsigned char *) (values[i] + consumed),
value_lengths[i] - consumed, &h_consumed,
acl_text, acl_text_fill, &acl_text_fill, 0);
if(ret < -3)
goto ex;
if(ret <= 0)
{ret= -2; goto ex;}
ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
if(ret <= 0)
{ret= -3; goto ex;}
} else {
if(!(flag & 64)) {
/* >>> ??? take offense from missing default ACL ?
??? does Linux demand a default ACL for directories with access ACL ?
*/;
}
}
ret= 1;
ex:;

View File

@ -96,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;
@ -106,7 +106,6 @@ size_t aaip_encode(size_t num_attrs, char **names,
if(ret <= 0)
return(ret);
mem_size+= comp_size;
total_recs= num_recs;
}
number_of_fields= mem_size / 250 + !!(mem_size % 250);
mem_size+= number_of_fields * 5;
@ -269,7 +268,11 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
bit3= check for completeness of list and eventually
fill up with entries deduced from st_mode
@return >0 means ok
0 means error
<=0 means error
-1= out of memory
-2= program error with prediction of result size
-3= error with conversion of name to uid or gid
ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other::
*/
int aaip_encode_acl(char *acl_text, mode_t st_mode,
size_t *result_len, unsigned char **result, int flag)
@ -280,8 +283,10 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
*result_len= 0;
bytes= aaip_encode_acl_text(acl_text, st_mode,
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8)));
if(bytes < -2)
return(bytes);
if(bytes < 0)
return(0);
return((int) bytes - 1);
if(flag & 1) {
*result_len= bytes;
return(1);
@ -293,9 +298,13 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
*result_len= bytes;
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
(flag & (2 | 4 | 8)));
if(bytes < -2)
return(bytes);
if(bytes < 0)
return((int) bytes - 1);
if((size_t) bytes != *result_len) {
*result_len= 0;
return(0);
return(-2);
}
return(1);
}
@ -342,6 +351,9 @@ static int aaip_make_aaip_perms(int r, int w, int x)
fill up with entries deduced from st_mode
@return >=0 number of bytes produced resp. counted
<0 means error
-1: result size overflow
-2: conversion errror with user name or group name
ISO_AAIP_ACL_MULT_OBJ: multiple entries of user::, group::, other::
*/
static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
size_t result_size, unsigned char *result, int flag)
@ -387,6 +399,13 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
if(strncmp(rpt, "user:", 5) == 0) {
if(cpt - rpt == 5) {
type= Aaip_ACL_USER_OBJ;
if (has_u) {
/* >>> Duplicate u:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
return((int) ISO_AAIP_ACL_MULT_OBJ);
}
has_u++;
} else {
if(cpt - (rpt + 5) >= name_size)
@ -399,8 +418,10 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
pwd= getpwnam(name);
if(pwd == NULL) {
num= aaip_numeric_id(name, 0);
if(num <= 0)
goto user_by_name;
if(num <= 0) {
/* ACL_USER is not part of AAIP 2.0 */
{ret= -2; goto ex;}
}
uid= huid= num;
} else
uid= huid= pwd->pw_uid;
@ -408,31 +429,44 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
for(i= 0; huid != 0; i++)
huid= huid >> 8;
qualifier_len= i;
if(qualifier_len <= 0)
qualifier_len= 1;
for(i= 0; i < qualifier_len ; i++)
name[i]= uid >> (8 * (qualifier_len - i - 1));
} else {
user_by_name:;
type= Aaip_ACL_USER;
qualifier_len= strlen(name);
if(qualifier_len <= 0)
qualifier_len= 1;
}
qualifier= 1;
}
} else if(strncmp(rpt, "group:", 6) == 0) {
if(cpt - rpt == 6) {
type= Aaip_ACL_GROUP_OBJ;
if (has_g) {
/* >>> Duplicate g:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
return((int) ISO_AAIP_ACL_MULT_OBJ);
}
has_g++;
} else {
if(cpt - (rpt + 6) >= name_size)
continue;
is_trivial= 0;
strncpy(name, rpt + 6, cpt - (rpt + 6));
name[cpt - (rpt + 6)]= 0;
if(flag & 2) {
type= Aaip_ACL_GROUP_N;
grp= getgrnam(name);
if(grp == NULL) {
num= aaip_numeric_id(name, 0);
if(num <= 0)
goto group_by_name;
if(num <= 0) {
/* ACL_GROUP is not part of AAIP 2.0 */
{ret= -2; goto ex;}
}
gid= hgid= num;
} else
gid= hgid= grp->gr_gid;
@ -440,18 +474,27 @@ user_by_name:;
for(i= 0; hgid != 0; i++)
hgid= hgid >> 8;
qualifier_len= i;
if(qualifier_len <= 0)
qualifier_len= 1;
for(i= 0; i < qualifier_len ; i++)
name[i]= gid >> (8 * (qualifier_len - i - 1));
} else {
group_by_name:;
type= Aaip_ACL_GROUP;
qualifier_len= strlen(name);
if(qualifier_len <= 0)
qualifier_len= 1;
}
qualifier= 1;
}
} else if(strncmp(rpt, "other:", 6) == 0) {
type= Aaip_ACL_OTHER;
if (has_o) {
/* >>> Duplicate o:: entry. */;
/* >>> ??? If it matches the previous one: ignore */
return((int) ISO_AAIP_ACL_MULT_OBJ);
}
has_o++;
} else if(strncmp(rpt, "mask:", 5) == 0) {
type= Aaip_ACL_MASK;
@ -1702,7 +1745,7 @@ int aaip_decode_attrs(struct aaip_state **handle,
unsigned char *data, size_t num_data, size_t *consumed,
int flag)
{
int ret, was_non_aa= 0;
int ret;
struct aaip_state *aaip;
size_t h_num, *h_lengths, i, new_mem, pair_consumed= 0;
char **h_names, **h_values, *hpt;
@ -1791,7 +1834,6 @@ int aaip_decode_attrs(struct aaip_state **handle,
return(ret);
} else if(ret == -1) { /* non-AAIP field detected */
was_non_aa= 1;
if(pair_consumed <= 0)
return(-4); /* interpretation did not advance */
@ -2124,8 +2166,9 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
}
ret= 1;
ex:;
*acl_text_fill= w_size;
if(flag & 1)
*acl_text_fill= w_size + 1;
(*acl_text_fill)++;
LIBISO_FREE_MEM(name);
return(ret);
}
@ -2143,6 +2186,13 @@ ex:;
#include "aaip-os-linux.c"
/* August 2011: aaip-os-linux.c would also work for GNU/Hurd : ifdef __GNU__
Libraries and headers are present on Debian GNU/Hurd but there is no
ACL or xattr support in the filesystems yet.
Further, llistxattr() produces ENOSYS "Function not implemented".
So it makes few sense to enable it here.
*/
#else
#include "aaip-os-dummy.c"

View File

@ -56,7 +56,11 @@ size_t aaip_encode(size_t num_attrs, char **names,
bit3= check for completeness of list and eventually
fill up with entries deduced from st_mode
@return >0 means ok
0 means error
<=0 means error
-1= out of memory
-2= program error with prediction of result size
-3= error with conversion of name to uid or gid
ISO_AAIP_ACL_MULT_OBJ= multiple entries of user::, group::, other::
*/
int aaip_encode_acl(char *acl_text, mode_t st_mode,
size_t *result_len, unsigned char **result, int flag);
@ -80,7 +84,7 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
bit3= check for completeness of list and eventually
fill up with entries deduced from st_mode
@return >0 means ok
0 means error
<=0 means error, see aaip_encode_acl
*/
int aaip_encode_both_acl(char *a_acl_text, char *d_acl_text, mode_t st_mode,
size_t *result_len, unsigned char **result, int flag);
@ -145,6 +149,24 @@ int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag);
/* ------ OS interface ------ */
/* See also API iso_local_attr_support().
@param flag
Bitfield for control purposes
bit0= inquire availability of ACL
bit1= inquire availability of xattr
bit2 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag. If bits are set, th
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these
*/
int aaip_local_attr_support(int flag);
/* Obtain the ACL of the given file in long text form.
@param path Path to the file
@param text Will hold the result. This is a managed object which
@ -478,6 +500,8 @@ int aaip_set_acl_text(char *path, char *text, int flag);
-5 error with deleting attributes
-6 support of xattr not enabled at compile time
-7 support of ACL not enabled at compile time
-8 unsupported xattr namespace
ISO_AAIP_ACL_MULT_OBJ multiple entries of user::, group::, other::
*/
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag);

View File

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

View File

@ -275,6 +275,9 @@ int iso_tree_add_boot_node(IsoDir *parent, const char *name, IsoBoot **boot)
free(node);
return ISO_OUT_OF_MEM;
}
node->lba = 0;
node->size = 0;
node->content = NULL;
/* atributes from parent */
node->node.mode = S_IFREG | (parent->node.mode & 0444);
@ -598,6 +601,30 @@ int iso_image_get_boot_image(IsoImage *image, ElToritoBootImage **boot,
return ISO_SUCCESS;
}
int iso_image_get_bootcat(IsoImage *image, IsoBoot **catnode, uint32_t *lba,
char **content, off_t *size)
{
IsoBoot *bootcat;
*catnode = NULL;
*lba = 0;
*content = NULL;
*size = 0;
bootcat = image->bootcat->node;
if (bootcat == NULL)
return 0;
*catnode = bootcat;
*lba = bootcat->lba;
*size = bootcat->size;
if (bootcat->size > 0 && bootcat->content != NULL) {
*content = calloc(1, bootcat->size);
if (*content == NULL)
return ISO_OUT_OF_MEM;
memcpy(*content, bootcat->content, bootcat->size);
}
return 1;
}
int iso_image_get_all_boot_imgs(IsoImage *image, int *num_boots,
ElToritoBootImage ***boots, IsoFile ***bootnodes, int flag)
{
@ -760,7 +787,6 @@ write_validation_entry(uint8_t *buf, uint8_t platform_id,
static void
write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
{
int pi;
char *id_string;
struct el_torito_section_header *e =
@ -768,7 +794,7 @@ write_section_header(uint8_t *buf, Ecma119Image *t, int idx, int num_entries)
/* 0x90 = more section headers follow , 0x91 = final section */
e->header_indicator[0] = 0x90 + (idx == t->catalog->num_bootimages - 1);
pi= e->platform_id[0] = t->catalog->bootimages[idx]->platform_id;
e->platform_id[0] = t->catalog->bootimages[idx]->platform_id;
e->num_entries[0] = num_entries & 0xff;
e->num_entries[1] = (num_entries >> 8) & 0xff;;
id_string = (char *) e->id_string;
@ -1160,7 +1186,6 @@ static
int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
{
Ecma119Image *t;
struct el_torito_boot_catalog *cat;
struct ecma119_boot_rec_vol_desc vol;
if (writer == NULL) {
@ -1168,7 +1193,6 @@ int eltorito_writer_write_vol_desc(IsoImageWriter *writer)
}
t = writer->target;
cat = t->catalog;
iso_msg_debug(t->image->id, "Write El-Torito boot record");
memset(&vol, 0, sizeof(struct ecma119_boot_rec_vol_desc));

View File

@ -26,6 +26,14 @@
struct Iso_Boot
{
IsoNode node;
/* Want to get content of loaded boot catalog.
Vreixo took care not to make it an IsoFile at load time.
So this is implemented independently of IsoStream.
*/
uint32_t lba;
off_t size;
char *content;
};
/* Not more than 32 so that all entries fit into 2048 bytes */

View File

@ -293,6 +293,8 @@ typedef struct
uint32_t bootblocks[Libisofs_max_boot_imageS];
uint32_t catblock; /**< Block for El-Torito catalog */
off_t catsize; /* Size of boot catalog in bytes */
char *catcontent;
/* Whether inode numbers from PX entries shall be discarded */
unsigned int make_new_ino : 1 ;
@ -1930,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;
@ -1943,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) {
@ -2052,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 */
@ -2078,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);
}
@ -2328,14 +2329,15 @@ ex:;
static
int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
{
int ret, i, rx, last_done, idx;
int ret, i, rx, last_done, idx, bufsize;
struct el_torito_validation_entry *ve;
struct el_torito_section_header *sh;
struct el_torito_section_entry *entry; /* also usable as default_entry */
unsigned char *buffer = NULL;
unsigned char *buffer = NULL, *rpt;
LIBISO_ALLOC_MEM(buffer, unsigned char, BLOCK_SIZE);
data->num_bootimgs = 0;
data->catsize = 0;
ret = data->src->read_block(data->src, block, buffer);
if (ret < 0) {
goto ex;
@ -2367,6 +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);
@ -2385,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;
@ -2410,6 +2424,27 @@ int read_el_torito_boot_catalog(_ImageFsData *data, uint32_t block)
}
}
after_bootblocks:;
if(data->catsize > 0) {
if(data->catcontent != NULL)
free(data->catcontent);
if(data->catsize > 10 * BLOCK_SIZE)
data->catsize = 10 * BLOCK_SIZE;
bufsize = data->catsize;
if (bufsize % BLOCK_SIZE)
bufsize += BLOCK_SIZE - (bufsize % BLOCK_SIZE);
data->catcontent = calloc(bufsize , 1);
if(data->catcontent == NULL) {
data->catsize = 0;
ret = ISO_OUT_OF_MEM;
goto ex;
}
for(rx = 0; rx < bufsize; rx += BLOCK_SIZE) {
rpt = (unsigned char *) (data->catcontent + rx);
ret = data->src->read_block(data->src, block + rx / BLOCK_SIZE, rpt);
if (ret < 0)
goto ex;
}
}
ret = ISO_SUCCESS;
ex:;
LIBISO_FREE_MEM(buffer);
@ -2531,6 +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;
@ -2802,9 +2839,10 @@ static
int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
IsoFileSource *src, IsoNode **node)
{
int ret, idx;
int ret, idx, to_copy;
struct stat info;
IsoNode *new;
IsoBoot *bootcat;
char *name;
char *dest = NULL;
ImageFileSourceData *data;
@ -2861,9 +2899,28 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
free(name);
goto ex;
}
bootcat = (IsoBoot *) new;
bootcat->lba = data->sections[0].block;
bootcat->size = info.st_size;
if (bootcat->size > 10 * BLOCK_SIZE)
bootcat->size = 10 * BLOCK_SIZE;
bootcat->content = NULL;
if (bootcat->size > 0) {
bootcat->content = calloc(1, bootcat->size);
if (bootcat->content == NULL) {
ret = ISO_OUT_OF_MEM;
free(name);
free(new);
goto ex;
}
to_copy = bootcat->size;
if (bootcat->size > fsdata->catsize)
to_copy = fsdata->catsize;
memcpy(bootcat->content, fsdata->catcontent, to_copy);
}
/* and set the image node */
image->bootcat->node = (IsoBoot*)new;
image->bootcat->node = bootcat;
new->type = LIBISO_BOOT;
new->refcount = 1;
} else {
@ -3276,9 +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;
@ -3328,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;
@ -3463,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;
@ -3572,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;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 Thomas Schmitt
* Copyright (c) 2009 - 2011 Thomas Schmitt
*
* This file is part of the libisofs project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@ -95,13 +95,11 @@ char* lfs_get_name(IsoFileSource *src)
static
int lfs_lstat(IsoFileSource *src, struct stat *info)
{
_LocalFsFileSource *data;
char *path;
if (src == NULL || info == NULL) {
return ISO_NULL_POINTER;
}
data = src->data;
path = lfs_get_path(src);
if (path == NULL)
return ISO_OUT_OF_MEM;
@ -140,13 +138,11 @@ int lfs_lstat(IsoFileSource *src, struct stat *info)
static
int lfs_stat(IsoFileSource *src, struct stat *info)
{
_LocalFsFileSource *data;
char *path;
if (src == NULL || info == NULL) {
return ISO_NULL_POINTER;
}
data = src->data;
path = lfs_get_path(src);
if (path == NULL)
return ISO_OUT_OF_MEM;
@ -186,13 +182,11 @@ static
int lfs_access(IsoFileSource *src)
{
int ret;
_LocalFsFileSource *data;
char *path;
if (src == NULL) {
return ISO_NULL_POINTER;
}
data = src->data;
path = lfs_get_path(src);
ret = iso_eaccess(path);
@ -419,7 +413,6 @@ static
int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
{
int size, ret;
_LocalFsFileSource *data;
char *path;
if (src == NULL || buf == NULL) {
@ -430,7 +423,6 @@ int lfs_readlink(IsoFileSource *src, char *buf, size_t bufsiz)
return ISO_WRONG_ARG_VALUE;
}
data = src->data;
path = lfs_get_path(src);
/*
@ -503,9 +495,6 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
size_t num_attrs = 0, *value_lengths = NULL, result_len, sret;
char *path = NULL, **names = NULL, **values = NULL;
unsigned char *result = NULL;
_LocalFsFileSource *data;
data = src->data;
*aa_string = NULL;
@ -525,6 +514,9 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
&value_lengths, &values,
(!(flag & 2)) | 2 | (flag & 4) | 16);
if (ret <= 0) {
if (ret == -2)
ret = ISO_AAIP_NO_GET_LOCAL;
else
ret = ISO_FILE_ERROR;
goto ex;
}
@ -827,6 +819,15 @@ int iso_local_filesystem_new(IsoFilesystem **fs)
}
int iso_local_attr_support(int flag)
{
int ret;
ret= aaip_local_attr_support(flag & 255);
return ret;
}
int iso_local_get_acl_text(char *disk_path, char **text, int flag)
{
int ret;
@ -867,13 +868,19 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
int ret;
ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths,
values, (flag & (8 | 32)) | !(flag & 1));
values, (flag & (8 | 32 | 64)) | !(flag & 1));
if (ret <= 0) {
if (ret == -1)
return ISO_OUT_OF_MEM;
if (ret == -2)
return ISO_AAIP_BAD_AASTRING;
if (ret >= -5)
return ISO_AAIP_NO_SET_LOCAL;
if (ret == -6 || ret == -7)
return ISO_AAIP_NOT_ENABLED;
if (ret == -8)
return ISO_AAIP_BAD_ATTR_NAME;
return ret;
}
return 1;
}

View File

@ -689,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);
@ -837,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) {

View File

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

View File

@ -61,6 +61,88 @@
#include <stdlib.h>
/**
* The following two functions and three macros are utilities to help ensuring
* version match of application, compile time header, and runtime library.
*/
/**
* These three release version numbers tell the revision of this header file
* and of the API it describes. They are memorized by applications at
* compile time.
* They must show the same values as these symbols in ./configure.ac
* LIBISOFS_MAJOR_VERSION=...
* LIBISOFS_MINOR_VERSION=...
* LIBISOFS_MICRO_VERSION=...
* Note to anybody who does own work inside libisofs:
* Any change of configure.ac or libisofs.h has to keep up this equality !
*
* Before usage of these macros on your code, please read the usage discussion
* below.
*
* @since 0.6.2
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 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;
/**
@ -878,15 +960,17 @@ extern ino_t serial_id;
struct IsoStream_Iface
{
/*
* Current version of the interface, set to 1 or 2.
* Current version of the interface.
* Version 0 (since 0.6.4)
* deprecated but still valid.
* Version 1 (since 0.6.8)
* update_size() added.
* Version 2 (since 0.6.18)
* get_input_stream() added. A filter stream must have version 2.
* get_input_stream() added.
* A filter stream must have version 2 at least.
* Version 3 (since 0.6.20)
* compare() added. A filter stream should have version 3.
* compare() added.
* A filter stream should have version 3 at least.
* Version 4 (since 1.0.2)
* clone_stream() added.
*/
@ -1013,8 +1097,8 @@ struct IsoStream_Iface
* This is also appropriate if one has reason to implement stream.cmp_ino()
* without having an own special comparison algorithm.
*
* With filter streams the decision whether the underlying chains of
* streams match should be delegated to
* With filter streams, the decision whether the underlying chains of
* streams match, should be delegated to
* iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
* iso_stream_get_input_stream(s2, 0), 0);
*
@ -1186,89 +1270,6 @@ int iso_image_new(const char *name, IsoImage **image);
void iso_image_set_ignore_aclea(IsoImage *image, int what);
/**
* The following two functions three macros are utilities to help ensuring
* version match of application, compile time header, and runtime library.
*/
/**
* Get version of the libisofs library at runtime.
* NOTE: This function may be called before iso_init().
*
* @since 0.6.2
*/
void iso_lib_version(int *major, int *minor, int *micro);
/**
* Check at runtime if the library is ABI compatible with the given version.
* NOTE: This function may be called before iso_init().
*
* @return
* 1 lib is compatible, 0 is not.
*
* @since 0.6.2
*/
int iso_lib_is_compatible(int major, int minor, int micro);
/**
* These three release version numbers tell the revision of this header file
* and of the API it describes. They are memorized by applications at
* compile time.
* They must show the same values as these symbols in ./configure.ac
* LIBISOFS_MAJOR_VERSION=...
* LIBISOFS_MINOR_VERSION=...
* LIBISOFS_MICRO_VERSION=...
* Note to anybody who does own work inside libisofs:
* Any change of configure.ac or libisofs.h has to keep up this equality !
*
* Before usage of these macros on your code, please read the usage discussion
* below.
*
* @since 0.6.2
*/
#define iso_lib_header_version_major 1
#define iso_lib_header_version_minor 1
#define iso_lib_header_version_micro 0
/**
* Usage discussion:
*
* Some developers of the libburnia project have differing opinions how to
* ensure the compatibility of libaries and applications.
*
* It is about whether to use at compile time and at runtime the version
* numbers provided here. Thomas Schmitt advises to use them. Vreixo Formoso
* advises to use other means.
*
* At compile time:
*
* Vreixo Formoso advises to leave proper version matching to properly
* programmed checks in the the application's build system, which will
* eventually refuse compilation.
*
* Thomas Schmitt advises to use the macros defined here for comparison with
* the application's requirements of library revisions and to eventually
* break compilation.
*
* Both advises are combinable. I.e. be master of your build system and have
* #if checks in the source code of your application, nevertheless.
*
* At runtime (via iso_lib_is_compatible()):
*
* Vreixo Formoso advises to compare the application's requirements of
* library revisions with the runtime library. This is to allow runtime
* libraries which are young enough for the application but too old for
* the lib*.h files seen at compile time.
*
* Thomas Schmitt advises to compare the header revisions defined here with
* the runtime library. This is to enforce a strictly monotonous chain of
* revisions from app to header to library, at the cost of excluding some older
* libraries.
*
* These two advises are mutually exclusive.
*/
/**
* Creates an IsoWriteOpts for writing an image. You should set the options
* desired with the correspondent setters.
@ -2876,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.
*
@ -5760,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.
*
@ -5803,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
@ -5892,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
@ -6860,6 +6917,13 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
/** Rock Ridge path too long (FAILURE, HIGH, -379) */
#define ISO_RR_PATH_TOO_LONG 0xE830FE85
/** Attribute name cannot be represented (FAILURE, HIGH, -380) */
#define ISO_AAIP_BAD_ATTR_NAME 0xE830FE84
/** ACL text contains multiple entries of user::, group::, other::
(FAILURE, HIGH, -379) */
#define ISO_AAIP_ACL_MULT_OBJ 0xE830FE83
/* Internal developer note:

View File

@ -88,6 +88,7 @@ iso_image_get_all_boot_imgs;
iso_image_get_application_id;
iso_image_get_attached_data;
iso_image_get_biblio_file_id;
iso_image_get_bootcat;
iso_image_get_boot_image;
iso_image_get_copyright_file_id;
iso_image_get_data_preparer_id;
@ -124,6 +125,7 @@ iso_init;
iso_init_with_flag;
iso_lib_is_compatible;
iso_lib_version;
iso_local_attr_support;
iso_local_get_acl_text;
iso_local_get_attrs;
iso_local_get_perms_wo_acl;
@ -310,5 +312,6 @@ iso_write_opts_set_will_cancel;
iso_zisofs_get_params;
iso_zisofs_get_refcounts;
iso_zisofs_set_params;
serial_id;
local: *;
};

View File

@ -135,7 +135,7 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
static int h = 64, s = 32;
int i, warn_size = 0, id;
int i, id;
char *wpt;
off_t imgsize, cylsize, frac, padding, c, cc;
@ -164,7 +164,6 @@ int make_isohybrid_mbr(int bin_lba, int *img_blocks, char *mbr, int flag)
*img_blocks = imgsize / (off_t) 2048;
c = imgsize / cylsize;
if (c > 1024) {
warn_size = 1;
cc = 1024;
} else
cc = c;

View File

@ -247,9 +247,8 @@ void iso_msg_debug(int imgid, const char *fmt, ...)
{
char *msg = NULL;
va_list ap;
int ret;
LIBISO_ALLOC_MEM(msg, char, MAX_MSG_LEN);
LIBISO_ALLOC_MEM_VOID(msg, char, MAX_MSG_LEN);
va_start(ap, fmt);
vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
va_end(ap);
@ -465,6 +464,10 @@ const char *iso_error_to_msg(int errcode)
return "Reserved Rock Ridge leaf name";
case ISO_RR_PATH_TOO_LONG:
return "Rock Ridge path too long";
case ISO_AAIP_BAD_ATTR_NAME:
return "Attribute name cannot be represented";
case ISO_AAIP_ACL_MULT_OBJ:
return "ACL text contains multiple entries of user::, group::, other::";
default:
return "Unknown error";
}

View File

@ -19,6 +19,7 @@
#include "aaip_0_2.h"
#include "messages.h"
#include "util.h"
#include "eltorito.h"
#include <stdlib.h>
@ -78,6 +79,14 @@ void iso_node_unref(IsoNode *node)
IsoSymlink *link = (IsoSymlink*) node;
free(link->dest);
}
break;
case LIBISO_BOOT:
{
IsoBoot *bootcat = (IsoBoot *) node;
if (bootcat->content != NULL)
free(bootcat->content);
}
break;
default:
/* other kind of nodes does not need to delete anything here */
break;
@ -1615,6 +1624,8 @@ int iso_aa_lookup_attr(unsigned char *aa_string, char *name,
ret = iso_aa_get_attrs(aa_string, &num_attrs, &names,
&value_lengths, &values, 0);
if (ret < 0)
return ret;
for (i = 0; i < (int) num_attrs; i++) {
if (strcmp(names[i], name))
continue;
@ -2138,10 +2149,12 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
ret = aaip_encode_both_acl(access_text, default_text, st_mode,
&acl_len, &acl, 2 | 8);
}
if (ret <= 0) {
if (ret == -1)
ret = ISO_OUT_OF_MEM;
else if (ret <= 0 && ret >= -3)
ret = ISO_AAIP_BAD_ACL_TEXT;
if (ret <= 0)
goto ex;
}
if(acl == NULL) { /* Delete whole ACL attribute */
/* Update S_IRWXG by eventual "group::" ACL entry.
@ -2194,6 +2207,8 @@ int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text,
}
ret = aaip_encode_both_acl(access_text, default_text,
st_mode, &acl_len, &acl, 2 | 8);
if (ret < -3)
goto ex;
if (ret <= 0) {
ret = ISO_AAIP_BAD_ACL_TEXT;
goto ex;

View File

@ -988,7 +988,10 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
goto unannounced_ca;
namelen = namelen - (space - *su_size - 5);
/* >>> Need to handle lengths > 250 */;
/* >>> SUPER_LONG_RR: Need to handle CA part lengths > 250
(This cannot happen with name lengths <= 256, as a part
of the name will always fit into the directory entry.)
*/;
*ce = 5 + namelen;
*su_size = space;
@ -1671,7 +1674,10 @@ int rrip_get_susp_fields(Ecma119Image *t, Ecma119Node *n, int type,
* ..and the part that goes to continuation area.
*/
/* >>> Need a loop to handle lengths > 250 */;
/* >>> SUPER_LONG_RR : Need a loop to handle CA lengths > 250
(This cannot happen with name lengths <= 256, as a part
of the name will always fit into the directory entry.)
*/;
ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen),
0, 1);

View File

@ -214,6 +214,7 @@ int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
return ISO_SUCCESS;
}
static
IsoStreamIface fsrc_stream_class = {
4, /* version */
"fsrc",
@ -503,6 +504,7 @@ int cut_out_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
/*
* TODO update cut out streams to deal with update_size(). Seems hard.
*/
static
IsoStreamIface cut_out_stream_class = {
4, /* version */
"cout",
@ -748,6 +750,7 @@ int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
}
static
IsoStreamIface mem_stream_class = {
4, /* version */
"mem ",

View File

@ -683,7 +683,8 @@ static int make_sun_disk_label(Ecma119Image *t, uint8_t *buf, int flag)
ret = write_sun_partition_entry(1, t->appended_partitions,
t->appended_part_start, t->appended_part_size,
ISO_SUN_CYL_SIZE, buf, 0);
if (ret < 0)
return ret;
return ISO_SUCCESS;
}

View File

@ -382,12 +382,13 @@ conv_error:;
int str2ascii(const char *icharset, const char *input, char **output)
{
int result;
wchar_t *wsrc_;
char *ret;
char *ret_;
wchar_t *wsrc_ = NULL;
char *ret = NULL;
char *ret_ = NULL;
char *src;
struct iso_iconv_handle conv;
int conv_ret;
int direct_conv = 0;
/* That while loop smells like a potential show stopper */
size_t loop_counter = 0, loop_limit = 3;
@ -405,14 +406,17 @@ int str2ascii(const char *icharset, const char *input, char **output)
return ISO_NULL_POINTER;
}
/* First try the traditional way via intermediate character set WCHAR_T.
* Up to August 2011 this was the only way. But it will not work if
* there is no character set "WCHAR_T". E.g. on Solaris.
*/
/* convert the string to a wide character string. Note: outbytes
* is in fact the number of characters in the string and doesn't
* include the last NULL character.
*/
conv_ret = 0;
result = str2wchar(icharset, input, &wsrc_);
if (result < 0) {
goto fallback;
}
if (result == (int) ISO_SUCCESS) {
src = (char *)wsrc_;
numchars = wcslen(wsrc_);
@ -431,7 +435,25 @@ int str2ascii(const char *icharset, const char *input, char **output)
if (conv_ret <= 0) {
free(wsrc_);
free(ret_);
}
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
return result;
/* If this did not succeed : Try the untraditional direct conversion.
*/
if (conv_ret <= 0) {
conv_ret = iso_iconv_open(&conv, "ASCII", (char *) icharset, 0);
if (conv_ret <= 0)
goto fallback;
direct_conv = 1;
src = (char *) input;
inbytes = strlen(input);
loop_limit = inbytes + 3;
outbytes = (inbytes + 1) * sizeof(uint16_t);
ret_ = malloc(outbytes);
if (ret_ == NULL)
return ISO_OUT_OF_MEM;
ret = ret_;
}
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
@ -458,8 +480,13 @@ int str2ascii(const char *icharset, const char *input, char **output)
/* There was an error with one character but some other remain
* to be converted. That's probably a multibyte character.
* See above comment. */
if (direct_conv) {
src++;
inbytes--;
} else {
src += sizeof(wchar_t);
inbytes -= sizeof(wchar_t);
}
if (!inbytes)
break;
@ -471,7 +498,8 @@ int str2ascii(const char *icharset, const char *input, char **output)
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
}
iso_iconv_close(&conv, 0);
*ret='\0';
*ret = 0;
if (wsrc_ != NULL)
free(wsrc_);
*output = ret_;
@ -517,12 +545,13 @@ int cmp_ucsbe(const uint16_t *ucs, char c)
int str2ucs(const char *icharset, const char *input, uint16_t **output)
{
int result;
wchar_t *wsrc_;
wchar_t *wsrc_ = NULL;
char *src;
char *ret;
char *ret_;
char *ret = NULL;
char *ret_ = NULL;
struct iso_iconv_handle conv;
int conv_ret;
int conv_ret = 0;
int direct_conv = 0;
/* That while loop smells like a potential show stopper */
size_t loop_counter = 0, loop_limit = 3;
@ -540,10 +569,13 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
* is in fact the number of characters in the string and doesn't
* include the last NULL character.
*/
/* First try the traditional way via intermediate character set WCHAR_T.
* Up to August 2011 this was the only way. But it will not work if
* there is no character set "WCHAR_T". E.g. on Solaris.
*/
conv_ret = 0;
result = str2wchar(icharset, input, &wsrc_);
if (result < 0) {
return result;
}
if (result == (int) ISO_SUCCESS) {
src = (char *)wsrc_;
numchars = wcslen(wsrc_);
@ -551,9 +583,8 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
loop_limit = inbytes + 3;
ret_ = malloc((numchars+1) * sizeof(uint16_t));
if (ret_ == NULL) {
if (ret_ == NULL)
return ISO_OUT_OF_MEM;
}
outbytes = numchars * sizeof(uint16_t);
ret = ret_;
@ -562,8 +593,27 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
if (conv_ret <= 0) {
free(wsrc_);
free(ret_);
}
} else if (result != (int) ISO_CHARSET_CONV_ERROR)
return result;
/* If this did not succeed : Try the untraditional direct conversion.
*/
if (conv_ret <= 0) {
conv_ret = iso_iconv_open(&conv, "UCS-2BE", (char *) icharset, 0);
if (conv_ret <= 0) {
return ISO_CHARSET_CONV_ERROR;
}
direct_conv = 1;
src = (char *) input;
inbytes = strlen(input);
loop_limit = inbytes + 3;
outbytes = (inbytes + 1) * sizeof(uint16_t);
ret_ = malloc(outbytes);
if (ret_ == NULL)
return ISO_OUT_OF_MEM;
ret = ret_;
}
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
while (n == (size_t) -1) {
@ -589,8 +639,13 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
/* There was an error with one character but some other remain
* to be converted. That's probably a multibyte character.
* See above comment. */
if (direct_conv) {
src++;
inbytes--;
} else {
src += sizeof(wchar_t);
inbytes -= sizeof(wchar_t);
}
if (!inbytes)
break;
@ -605,6 +660,7 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
/* close the ucs string */
set_ucsbe((uint16_t*) ret, '\0');
if (wsrc_ != NULL)
free(wsrc_);
*output = (uint16_t*)ret_;
@ -924,9 +980,8 @@ uint16_t *iso_j_file_id(const uint16_t *src, int flag)
uint16_t *dot, *retval = NULL;
size_t lname, lext, lnname, lnext, pos, i, maxchar = 64;
uint16_t *dest = NULL;
int ret;
LIBISO_ALLOC_MEM(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
/* was: 66 = 64 (name + ext) + 1 (.) + 1 (\0) */
if (src == NULL) {
@ -1004,9 +1059,8 @@ uint16_t *iso_j_dir_id(const uint16_t *src, int flag)
{
size_t len, i, maxchar = 64;
uint16_t *dest = NULL, *retval = NULL;
int ret;
/* was: 65 = 64 + 1 (\0) */
LIBISO_ALLOC_MEM(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
LIBISO_ALLOC_MEM_VOID(dest, uint16_t, LIBISO_JOLIET_NAME_MAX);
if (src == NULL) {
goto ex;
@ -1576,12 +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] = ' ';
}

View File

@ -547,6 +547,12 @@ void *iso_alloc_mem(size_t size, size_t count, int flag);
ret= ISO_OUT_OF_MEM; goto ex; \
} }
#define LIBISO_ALLOC_MEM_VOID(pt, typ, count) { \
pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \
if(pt == NULL) { \
goto ex; \
} }
#define LIBISO_FREE_MEM(pt) { \
if(pt != NULL) \
free((char *) pt); \