Compare commits
38 Commits
release-1.
...
release-1.
Author | SHA1 | Date | |
---|---|---|---|
5f76be9d76 | |||
305fe3f496 | |||
191c3245af | |||
b5b30b1c75 | |||
6a1bbaa902 | |||
bddc44d1ca | |||
9b61ff377c | |||
22fed6bedb | |||
3433592f69 | |||
d787ecbcd9 | |||
182edb3a00 | |||
cb25d4d4e5 | |||
afdef92343 | |||
2bc7084315 | |||
6d10908a58 | |||
2ba54fafe7 | |||
ca63dac7e3 | |||
f885da8087 | |||
8438db02cf | |||
ce19db5e19 | |||
aeb5258ae2 | |||
f10c2d7779 | |||
82bfcf429a | |||
8fb8c01a0f | |||
73910e2f3c | |||
9c5fc21679 | |||
3a82f213e0 | |||
6892c734e2 | |||
66f6937c17 | |||
baa5b7cd42 | |||
f2658ef173 | |||
ecdb3aeb1d | |||
745a878884 | |||
6ae8386c23 | |||
b90e613246 | |||
bbc3caf86b | |||
b086d53274 | |||
17b36623a6 |
21
ChangeLog
21
ChangeLog
@ -1,3 +1,24 @@
|
|||||||
|
libisofs-1.2.0.tar.gz Sat Jan 28 2012
|
||||||
|
===============================================================================
|
||||||
|
* Extended influence of iso_write_opts_set_dir_rec_mtime() to Joliet and
|
||||||
|
ISO 9660:1999.
|
||||||
|
|
||||||
|
libisofs-1.1.6.tar.gz Tue Sep 27 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: On Solaris: False out-of-memory errors when writing images.
|
||||||
|
* Bug fix: On FreeBSD: No ACLs were recorded.
|
||||||
|
* Bug fix: ACL entries of groups and of user id 0 were not properly recorded
|
||||||
|
and cannot be restored.
|
||||||
|
* Bug fix: On FreeBSD: The function for restoring ACLs and xattr returned
|
||||||
|
error, even if no xattr were to be restored.
|
||||||
|
* New API call iso_local_attr_support()
|
||||||
|
* Enabled recording and restoring of extattr on FreeBSD.
|
||||||
|
|
||||||
|
libisofs-1.1.4.tar.gz Mon Aug 08 2011
|
||||||
|
===============================================================================
|
||||||
|
* Bug fix: The function for restoring ACLs and xattr returned error on systems
|
||||||
|
other than Linux and FreeBSD, even if nothing was to be restored.
|
||||||
|
|
||||||
libisofs-1.1.2.tar.gz Fri Jul 08 2011
|
libisofs-1.1.2.tar.gz Fri Jul 08 2011
|
||||||
===============================================================================
|
===============================================================================
|
||||||
* New API call iso_image_get_bootcat()
|
* New API call iso_image_get_bootcat()
|
||||||
|
@ -220,6 +220,12 @@ demo_demo_SOURCES = demo/demo.c
|
|||||||
# test/mocked_fsrc.h \
|
# test/mocked_fsrc.h \
|
||||||
# test/mocked_fsrc.c
|
# test/mocked_fsrc.c
|
||||||
|
|
||||||
|
# "make clean" shall remove a few stubborn .libs directories
|
||||||
|
# which George Danchev reported Dec 03 2011.
|
||||||
|
# Learned from: http://www.gnu.org/software/automake/manual/automake.html#Clean
|
||||||
|
clean-local:
|
||||||
|
-rm -rf demo/.libs
|
||||||
|
|
||||||
## ========================================================================= ##
|
## ========================================================================= ##
|
||||||
|
|
||||||
## Build documentation (You need Doxygen for this to work)
|
## Build documentation (You need Doxygen for this to work)
|
||||||
@ -250,6 +256,7 @@ nodist_pkgconfig_DATA = \
|
|||||||
# ts A80114 : added aaip-os*
|
# ts A80114 : added aaip-os*
|
||||||
|
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
|
bootstrap \
|
||||||
libisofs-1.pc.in \
|
libisofs-1.pc.in \
|
||||||
version.h.in \
|
version.h.in \
|
||||||
doc/doxygen.conf.in \
|
doc/doxygen.conf.in \
|
||||||
|
28
configure.ac
28
configure.ac
@ -1,4 +1,4 @@
|
|||||||
AC_INIT([libisofs], [1.1.2], [http://libburnia-project.org])
|
AC_INIT([libisofs], [1.2.0], [http://libburnia-project.org])
|
||||||
AC_PREREQ([2.50])
|
AC_PREREQ([2.50])
|
||||||
dnl AC_CONFIG_HEADER([config.h])
|
dnl AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
@ -40,8 +40,8 @@ dnl
|
|||||||
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
dnl If LIBISOFS_*_VERSION changes, be sure to change AC_INIT above to match.
|
||||||
dnl
|
dnl
|
||||||
LIBISOFS_MAJOR_VERSION=1
|
LIBISOFS_MAJOR_VERSION=1
|
||||||
LIBISOFS_MINOR_VERSION=1
|
LIBISOFS_MINOR_VERSION=2
|
||||||
LIBISOFS_MICRO_VERSION=2
|
LIBISOFS_MICRO_VERSION=0
|
||||||
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
LIBISOFS_VERSION=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION.$LIBISOFS_MICRO_VERSION
|
||||||
|
|
||||||
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
AC_SUBST(LIBISOFS_MAJOR_VERSION)
|
||||||
@ -51,10 +51,10 @@ AC_SUBST(LIBISOFS_VERSION)
|
|||||||
|
|
||||||
dnl Libtool versioning
|
dnl Libtool versioning
|
||||||
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
LT_RELEASE=$LIBISOFS_MAJOR_VERSION.$LIBISOFS_MINOR_VERSION
|
||||||
# 2011.07.08 development jump has not yet happened
|
# 2012.01.28 development jump has not yet happened
|
||||||
# SONAME = 56 - 50 = 6 . Library name = libisofs.6.50.0
|
# SONAME = 62 - 56 = 6 . Library name = libisofs.6.56.0
|
||||||
LT_CURRENT=56
|
LT_CURRENT=62
|
||||||
LT_AGE=50
|
LT_AGE=56
|
||||||
LT_REVISION=0
|
LT_REVISION=0
|
||||||
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE`
|
||||||
|
|
||||||
@ -160,14 +160,19 @@ LIBBURNIA_SET_PKGCONFIG
|
|||||||
dnl Add compiler-specific flags
|
dnl Add compiler-specific flags
|
||||||
|
|
||||||
AC_ARG_ENABLE(libacl,
|
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)
|
, enable_libacl=yes)
|
||||||
if test "x$enable_libacl" = xyes; then
|
if test "x$enable_libacl" = xyes; then
|
||||||
dnl Check whether there is libacl-devel and libacl-runtime.
|
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
|
dnl If not, erase this macro which would enable use of acl_to_text and others
|
||||||
LIBACL_DEF="-DLibisofs_with_aaip_acL"
|
LIBACL_DEF="-DLibisofs_with_aaip_acL"
|
||||||
dnl The empty yes case obviously causes -lacl to be linked
|
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
|
else
|
||||||
LIBACL_DEF=
|
LIBACL_DEF=
|
||||||
fi
|
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
|
dnl If not, erase this macro which would enable use of listxattr and others
|
||||||
XATTR_DEF="-DLibisofs_with_aaip_xattR"
|
XATTR_DEF="-DLibisofs_with_aaip_xattR"
|
||||||
AC_CHECK_HEADER(attr/xattr.h, AC_CHECK_LIB(c, listxattr, X= , XATTR_DEF= ), XATTR_DEF= )
|
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
|
else
|
||||||
XATTR_DEF=
|
XATTR_DEF=
|
||||||
fi
|
fi
|
||||||
|
@ -157,9 +157,10 @@ types. "system." is file system dependent and often restricted in the
|
|||||||
choice of names. "user." is portable and allows to choose about any name.
|
choice of names. "user." is portable and allows to choose about any name.
|
||||||
|
|
||||||
Namespace "isofs." is defined for internal use of AAIP enhanced ISO 9660
|
Namespace "isofs." is defined for internal use of AAIP enhanced ISO 9660
|
||||||
file systems. Names in this namespace should be registered at libburnia.org.
|
file systems. Names in this namespace should be registered at
|
||||||
|
libburnia-project.org.
|
||||||
|
|
||||||
Further namespaces may be registered at libburnia.org.
|
Further namespaces may be registered at libburnia-project.org.
|
||||||
|
|
||||||
The reserved start bytes of names have the following meaning
|
The reserved start bytes of names have the following meaning
|
||||||
0x01 escape reserved character at start of name
|
0x01 escape reserved character at start of name
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
To be included by aaip_0_2.c
|
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>
|
#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 --------------------------------- */
|
/* ------------------------------ Getters --------------------------------- */
|
||||||
|
|
||||||
/* Obtain the ACL of the given file in long text form.
|
/* 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;
|
continue;
|
||||||
}
|
}
|
||||||
/* Extended Attribute */
|
/* Extended Attribute */
|
||||||
if(!(flag & 4))
|
if(flag & 4)
|
||||||
return(-6);
|
continue;
|
||||||
|
if(!(flag & 8))
|
||||||
|
if(strncmp(names[i], "user.", 5))
|
||||||
|
continue;
|
||||||
|
return(-6);
|
||||||
}
|
}
|
||||||
if(flag & 2)
|
if(flag & 2)
|
||||||
return(-6);
|
return(-6);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
To be included by aaip_0_2.c
|
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 <sys/stat.h>
|
||||||
#include <errno.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
|
#ifdef Libisofs_with_aaip_acL
|
||||||
#include <sys/acl.h>
|
#include <sys/acl.h>
|
||||||
#endif
|
#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 --------------------------------- */
|
/* ------------------------------ 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
|
/* Obtain the Extended Attributes and/or the ACLs of the given file in a form
|
||||||
that is ready for aaip_encode().
|
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)
|
bit0= obtain ACL (access and eventually default)
|
||||||
bit1= use numeric ACL qualifiers rather than names
|
bit1= use numeric ACL qualifiers rather than names
|
||||||
bit2= do not encode attributes other than ACL
|
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
|
bit4= do not return trivial ACL that matches st_mode
|
||||||
bit15= free memory of names, value_lengths, values
|
bit15= free memory of names, value_lengths, values
|
||||||
@return >0 ok
|
@return >0 ok
|
||||||
<=0 error
|
<=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,
|
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||||
size_t **value_lengths, char ***values, int flag)
|
size_t **value_lengths, char ***values, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ssize_t i, num_names;
|
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;
|
char *acl_text= NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
if(flag & (1 << 15)) { /* Free memory */
|
if(flag & (1 << 15)) { /* Free memory */
|
||||||
{ret= 1; goto ex;}
|
{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("");
|
(*names)[*num_attrs]= strdup("");
|
||||||
if((*names)[*num_attrs] == NULL)
|
if((*names)[*num_attrs] == NULL)
|
||||||
{ret= -1; goto ex;}
|
{ret= -1; goto ex;}
|
||||||
(*values)[*num_attrs]= (char *) acl;
|
(*values)[*num_attrs]= (char *) a_acl;
|
||||||
(*value_lengths)[*num_attrs]= acl_len;
|
a_acl= NULL;
|
||||||
|
(*value_lengths)[*num_attrs]= a_acl_len;
|
||||||
(*num_attrs)++;
|
(*num_attrs)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Libisofs_with_aaip_acL */
|
#endif /* ! Libisofs_with_aaip_acL */
|
||||||
|
|
||||||
ret= 1;
|
ret= 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
#ifdef Libisofs_with_aaip_acL
|
||||||
if(a_acl != NULL)
|
if(a_acl != NULL)
|
||||||
free(a_acl);
|
free(a_acl);
|
||||||
if(d_acl != NULL)
|
|
||||||
free(d_acl);
|
|
||||||
if(acl_text != NULL)
|
if(acl_text != NULL)
|
||||||
aaip_get_acl_text("", &acl_text, 1 << 15); /* free */
|
aaip_get_acl_text("", &acl_text, 1 << 15); /* free */
|
||||||
|
#endif /* Libisofs_with_aaip_acL */
|
||||||
|
|
||||||
if(ret <= 0 || (flag & (1 << 15))) {
|
if(ret <= 0 || (flag & (1 << 15))) {
|
||||||
if(*names != NULL) {
|
if(*names != NULL) {
|
||||||
@ -242,14 +630,14 @@ ex:;
|
|||||||
free((*values)[i]);
|
free((*values)[i]);
|
||||||
free(*values);
|
free(*values);
|
||||||
}
|
}
|
||||||
if(acl != NULL)
|
|
||||||
free(acl);
|
|
||||||
*values= NULL;
|
*values= NULL;
|
||||||
*num_attrs= 0;
|
*num_attrs= 0;
|
||||||
}
|
}
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_old_freebsd_acl_adapteR */
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------ Setters --------------------------------- */
|
/* ------------------------------ Setters --------------------------------- */
|
||||||
|
|
||||||
@ -259,9 +647,14 @@ ex:;
|
|||||||
@param text The input text (0 terminated, ACL long text form)
|
@param text The input text (0 terminated, ACL long text form)
|
||||||
@param flag Bitfield for control purposes
|
@param flag Bitfield for control purposes
|
||||||
bit0= set default ACL rather than access ACL
|
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
|
@return > 0 ok
|
||||||
|
0 no suitable ACL manipulation adapter available
|
||||||
-1 failure of system ACL service (see errno)
|
-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)
|
int aaip_set_acl_text(char *path, char *text, int flag)
|
||||||
{
|
{
|
||||||
@ -302,13 +695,200 @@ ex:
|
|||||||
|
|
||||||
#else /* Libisofs_with_aaip_acL */
|
#else /* Libisofs_with_aaip_acL */
|
||||||
|
|
||||||
return(-2);
|
return(0);
|
||||||
|
|
||||||
#endif /* ! Libisofs_with_aaip_acL */
|
#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.
|
/* 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.
|
Note: There are no Extended Attributes in FreeBSD. So only ACL get set.
|
||||||
@ -317,6 +897,9 @@ ex:
|
|||||||
bit0= decode and set ACLs
|
bit0= decode and set ACLs
|
||||||
( bit1= first clear all existing attributes of the file )
|
( bit1= first clear all existing attributes of the file )
|
||||||
( bit2= do not set attributes other than ACLs )
|
( 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
|
@return 1 success
|
||||||
-1 error memory allocation
|
-1 error memory allocation
|
||||||
-2 error with decoding of ACL
|
-2 error with decoding of ACL
|
||||||
@ -338,6 +921,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||||||
continue;
|
continue;
|
||||||
if(names[i][0] == 0) { /* Decode ACLs */
|
if(names[i][0] == 0) { /* Decode ACLs */
|
||||||
/* access ACL */
|
/* access ACL */
|
||||||
|
if(!(flag & 1))
|
||||||
|
continue;
|
||||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||||
&consumed, NULL, 0, &acl_text_fill, 1);
|
&consumed, NULL, 0, &acl_text_fill, 1);
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
@ -379,8 +964,14 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{ret= -3; goto ex;}
|
{ret= -3; goto ex;}
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
|
if(flag & 4)
|
||||||
|
continue;
|
||||||
|
if(!(flag & 8))
|
||||||
|
if(strncmp(names[i], "user.", 5))
|
||||||
|
continue;
|
||||||
was_xattr= 1;
|
was_xattr= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret= 1;
|
ret= 1;
|
||||||
if(was_xattr)
|
if(was_xattr)
|
||||||
@ -393,4 +984,5 @@ ex:;
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_old_freebsd_acl_adapteR */
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
To be included by aaip_0_2.c
|
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
|
#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 --------------------------------- */
|
/* ------------------------------ Getters --------------------------------- */
|
||||||
|
|
||||||
/* Obtain the ACL of the given file in long text form.
|
/* 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
|
bit15= free memory of names, value_lengths, values
|
||||||
@return >0 ok
|
@return >0 ok
|
||||||
<=0 error
|
<=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,
|
int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
||||||
size_t **value_lengths, char ***values, int flag)
|
size_t **value_lengths, char ***values, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char *list= NULL;
|
ssize_t i, num_names= 0;
|
||||||
ssize_t list_size= 0, i, num_names= 0;
|
|
||||||
unsigned char *acl= NULL;
|
|
||||||
char *a_acl_text= NULL, *d_acl_text= NULL;
|
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_acL
|
#ifdef Libisofs_with_aaip_acL
|
||||||
|
unsigned char *acl= NULL;
|
||||||
|
char *a_acl_text= NULL, *d_acl_text= NULL;
|
||||||
size_t acl_len= 0;
|
size_t acl_len= 0;
|
||||||
#endif
|
#endif
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
ssize_t value_ret, retry= 0;
|
char *list= NULL;
|
||||||
|
ssize_t value_ret, retry= 0, list_size= 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(flag & (1 << 15)) { /* Free memory */
|
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;
|
*values= NULL;
|
||||||
|
|
||||||
/* Set up arrays */
|
/* Set up arrays */
|
||||||
if(!(flag & 4)) { /* Get xattr names */
|
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
|
|
||||||
|
if(!(flag & 4)) { /* Get xattr names */
|
||||||
if(flag & 32)
|
if(flag & 32)
|
||||||
list_size= listxattr(path, list, 0);
|
list_size= listxattr(path, list, 0);
|
||||||
else
|
else
|
||||||
list_size= llistxattr(path, list, 0);
|
list_size= llistxattr(path, list, 0);
|
||||||
if(list_size == -1)
|
if(list_size == -1) {
|
||||||
{ret= -1; goto ex;}
|
if(errno == ENOSYS) /* Function not implemented */
|
||||||
list= calloc(list_size, 1);
|
list_size= 0; /* Handle as if xattr was disabled at compile time */
|
||||||
if(list == NULL)
|
else
|
||||||
{ret= -1; goto ex;}
|
{ret= -1; goto ex;}
|
||||||
if(flag & 32)
|
}
|
||||||
list_size= listxattr(path, list, list_size);
|
if(list_size > 0) {
|
||||||
else
|
list= calloc(list_size, 1);
|
||||||
list_size= llistxattr(path, list, list_size);
|
if(list == NULL)
|
||||||
if(list_size == -1)
|
{ret= -1; goto ex;}
|
||||||
{ret= -1; goto ex;}
|
if(flag & 32)
|
||||||
|
list_size= listxattr(path, list, list_size);
|
||||||
#else /* Libisofs_with_aaip_xattR */
|
else
|
||||||
|
list_size= llistxattr(path, list, list_size);
|
||||||
list= strdup("");
|
if(list_size == -1)
|
||||||
|
{ret= -1; goto ex;}
|
||||||
#endif /* ! Libisofs_with_aaip_xattR */
|
}
|
||||||
|
|
||||||
for(i= 0; i < list_size; i+= strlen(list + i) + 1)
|
for(i= 0; i < list_size; i+= strlen(list + i) + 1)
|
||||||
num_names++;
|
num_names++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* ! Libisofs_with_aaip_xattR */
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_acL
|
#ifdef Libisofs_with_aaip_acL
|
||||||
|
|
||||||
if(flag & 1)
|
if(flag & 1)
|
||||||
num_names++;
|
num_names++;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(num_names == 0)
|
if(num_names == 0)
|
||||||
@ -219,7 +259,10 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
(*values)[i]= NULL;
|
(*values)[i]= NULL;
|
||||||
(*value_lengths)[i]= 0;
|
(*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;
|
for(i= 0; i < list_size && (size_t) num_names > *num_attrs;
|
||||||
i+= strlen(list + i) + 1) {
|
i+= strlen(list + i) + 1) {
|
||||||
if(!(flag & 8))
|
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)
|
if((*names)[(*num_attrs) - 1] == NULL)
|
||||||
{ret= -1; goto ex;}
|
{ret= -1; goto ex;}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Libisofs_with_aaip_xattR
|
|
||||||
|
|
||||||
if(!(flag & 4)) { /* Get xattr values */
|
|
||||||
for(i= 0; (size_t) i < *num_attrs; i++) {
|
for(i= 0; (size_t) i < *num_attrs; i++) {
|
||||||
if(!(flag & 8))
|
if(!(flag & 8))
|
||||||
if(strncmp((*names)[i], "user.", 5))
|
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;
|
ret= 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
#ifdef Libisofs_with_aaip_acL
|
||||||
if(a_acl_text != NULL)
|
if(a_acl_text != NULL)
|
||||||
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
|
aaip_get_acl_text("", &a_acl_text, 1 << 15); /* free */
|
||||||
if(d_acl_text != NULL)
|
if(d_acl_text != NULL)
|
||||||
aaip_get_acl_text("", &d_acl_text, 1 << 15); /* free */
|
aaip_get_acl_text("", &d_acl_text, 1 << 15); /* free */
|
||||||
|
if(acl != NULL)
|
||||||
|
free(acl);
|
||||||
|
#endif
|
||||||
|
#ifdef Libisofs_with_aaip_xattR
|
||||||
if(list != NULL)
|
if(list != NULL)
|
||||||
free(list);
|
free(list);
|
||||||
|
#endif
|
||||||
|
|
||||||
if(ret <= 0 || (flag & (1 << 15))) {
|
if(ret <= 0 || (flag & (1 << 15))) {
|
||||||
if(*names != NULL) {
|
if(*names != NULL) {
|
||||||
for(i= 0; (size_t) i < *num_attrs; i++)
|
for(i= 0; (size_t) i < *num_attrs; i++)
|
||||||
@ -312,8 +357,6 @@ ex:;
|
|||||||
free((*values)[i]);
|
free((*values)[i]);
|
||||||
free(*values);
|
free(*values);
|
||||||
}
|
}
|
||||||
if(acl != NULL)
|
|
||||||
free(acl);
|
|
||||||
*values= NULL;
|
*values= NULL;
|
||||||
*num_attrs= 0;
|
*num_attrs= 0;
|
||||||
}
|
}
|
||||||
@ -384,7 +427,9 @@ ex:
|
|||||||
bit3= do not ignore eventual non-user attributes.
|
bit3= do not ignore eventual non-user attributes.
|
||||||
I.e. those with a name which does not begin
|
I.e. those with a name which does not begin
|
||||||
by "user."
|
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
|
@return 1 success
|
||||||
-1 error memory allocation
|
-1 error memory allocation
|
||||||
-2 error with decoding of ACL
|
-2 error with decoding of ACL
|
||||||
@ -393,6 +438,8 @@ ex:
|
|||||||
-5 error with deleting attributes
|
-5 error with deleting attributes
|
||||||
-6 support of xattr not enabled at compile time
|
-6 support of xattr not enabled at compile time
|
||||||
-7 support of ACL 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,
|
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||||
size_t *value_lengths, char **values, int flag)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
/* Extended Attribute */
|
/* 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))
|
if(strncmp(names[i], "user.", 5))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -475,6 +526,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
|||||||
/* "access" ACL */
|
/* "access" ACL */
|
||||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||||
&consumed, NULL, 0, &acl_text_fill, 1);
|
&consumed, NULL, 0, &acl_text_fill, 1);
|
||||||
|
if(ret < -3)
|
||||||
|
goto ex;
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{ret= -2; goto ex;}
|
{ret= -2; goto ex;}
|
||||||
acl_text= calloc(acl_text_fill, 1);
|
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= -1; goto ex;}
|
||||||
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
|
||||||
&consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
|
&consumed, acl_text, acl_text_fill, &acl_text_fill, 0);
|
||||||
|
if(ret < -3)
|
||||||
|
goto ex;
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{ret= -2; goto ex;}
|
{ret= -2; goto ex;}
|
||||||
has_default_acl= (ret == 2);
|
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),
|
ret= aaip_decode_acl((unsigned char *) (values[i] + consumed),
|
||||||
value_lengths[i] - consumed, &h_consumed,
|
value_lengths[i] - consumed, &h_consumed,
|
||||||
NULL, 0, &acl_text_fill, 1);
|
NULL, 0, &acl_text_fill, 1);
|
||||||
|
if(ret < -3)
|
||||||
|
goto ex;
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{ret= -2; goto ex;}
|
{ret= -2; goto ex;}
|
||||||
acl_text= calloc(acl_text_fill, 1);
|
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),
|
ret= aaip_decode_acl((unsigned char *) (values[i] + consumed),
|
||||||
value_lengths[i] - consumed, &h_consumed,
|
value_lengths[i] - consumed, &h_consumed,
|
||||||
acl_text, acl_text_fill, &acl_text_fill, 0);
|
acl_text, acl_text_fill, &acl_text_fill, 0);
|
||||||
|
if(ret < -3)
|
||||||
|
goto ex;
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{ret= -2; goto ex;}
|
{ret= -2; goto ex;}
|
||||||
ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
|
ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
|
||||||
if(ret <= 0)
|
if(ret <= 0)
|
||||||
{ret= -3; goto ex;}
|
{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;
|
ret= 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
@ -95,8 +95,8 @@ size_t aaip_encode(size_t num_attrs, char **names,
|
|||||||
size_t *value_lengths, char **values,
|
size_t *value_lengths, char **values,
|
||||||
size_t *result_len, unsigned char **result, int flag)
|
size_t *result_len, unsigned char **result, int flag)
|
||||||
{
|
{
|
||||||
size_t mem_size= 0, comp_size;
|
size_t mem_size= 0, comp_size, ret;
|
||||||
unsigned int number_of_fields, i, num_recs, ret;
|
unsigned int number_of_fields, i, num_recs;
|
||||||
|
|
||||||
/* Predict memory needs, number of SUSP fields and component records */
|
/* Predict memory needs, number of SUSP fields and component records */
|
||||||
*result_len= 0;
|
*result_len= 0;
|
||||||
@ -158,9 +158,9 @@ size_t aaip_encode(size_t num_attrs, char **names,
|
|||||||
ret= 0;
|
ret= 0;
|
||||||
for(i= 0; i < *result_len; i+= ((unsigned char *) (*result))[i + 2])
|
for(i= 0; i < *result_len; i+= ((unsigned char *) (*result))[i + 2])
|
||||||
ret++;
|
ret++;
|
||||||
if(ret != number_of_fields) {
|
if(ret != (int) number_of_fields) {
|
||||||
fprintf(stderr, "aaip_encode(): WRONG NUMBER OF FIELDS %d <> %d\n",
|
fprintf(stderr, "aaip_encode(): WRONG NUMBER OF FIELDS %d <> %d\n",
|
||||||
number_of_fields, ret);
|
(int) number_of_fields, ret);
|
||||||
}
|
}
|
||||||
#endif /* Aaip_encode_debuG */
|
#endif /* Aaip_encode_debuG */
|
||||||
|
|
||||||
@ -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
|
bit3= check for completeness of list and eventually
|
||||||
fill up with entries deduced from st_mode
|
fill up with entries deduced from st_mode
|
||||||
@return >0 means ok
|
@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,
|
int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||||
size_t *result_len, unsigned char **result, int flag)
|
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;
|
*result_len= 0;
|
||||||
bytes= aaip_encode_acl_text(acl_text, st_mode,
|
bytes= aaip_encode_acl_text(acl_text, st_mode,
|
||||||
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8)));
|
(size_t) 0, NULL, 1 | (flag & (2 | 4 | 8)));
|
||||||
|
if(bytes < -2)
|
||||||
|
return(bytes);
|
||||||
if(bytes < 0)
|
if(bytes < 0)
|
||||||
return(0);
|
return((int) bytes - 1);
|
||||||
if(flag & 1) {
|
if(flag & 1) {
|
||||||
*result_len= bytes;
|
*result_len= bytes;
|
||||||
return(1);
|
return(1);
|
||||||
@ -292,9 +298,13 @@ int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
|||||||
*result_len= bytes;
|
*result_len= bytes;
|
||||||
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
|
bytes= aaip_encode_acl_text(acl_text, st_mode, *result_len, *result,
|
||||||
(flag & (2 | 4 | 8)));
|
(flag & (2 | 4 | 8)));
|
||||||
|
if(bytes < -2)
|
||||||
|
return(bytes);
|
||||||
|
if(bytes < 0)
|
||||||
|
return((int) bytes - 1);
|
||||||
if((size_t) bytes != *result_len) {
|
if((size_t) bytes != *result_len) {
|
||||||
*result_len= 0;
|
*result_len= 0;
|
||||||
return(0);
|
return(-2);
|
||||||
}
|
}
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
@ -341,6 +351,9 @@ static int aaip_make_aaip_perms(int r, int w, int x)
|
|||||||
fill up with entries deduced from st_mode
|
fill up with entries deduced from st_mode
|
||||||
@return >=0 number of bytes produced resp. counted
|
@return >=0 number of bytes produced resp. counted
|
||||||
<0 means error
|
<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,
|
static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
||||||
size_t result_size, unsigned char *result, int flag)
|
size_t result_size, unsigned char *result, int flag)
|
||||||
@ -386,6 +399,13 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||||||
if(strncmp(rpt, "user:", 5) == 0) {
|
if(strncmp(rpt, "user:", 5) == 0) {
|
||||||
if(cpt - rpt == 5) {
|
if(cpt - rpt == 5) {
|
||||||
type= Aaip_ACL_USER_OBJ;
|
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++;
|
has_u++;
|
||||||
} else {
|
} else {
|
||||||
if(cpt - (rpt + 5) >= name_size)
|
if(cpt - (rpt + 5) >= name_size)
|
||||||
@ -398,8 +418,10 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||||||
pwd= getpwnam(name);
|
pwd= getpwnam(name);
|
||||||
if(pwd == NULL) {
|
if(pwd == NULL) {
|
||||||
num= aaip_numeric_id(name, 0);
|
num= aaip_numeric_id(name, 0);
|
||||||
if(num <= 0)
|
if(num <= 0) {
|
||||||
goto user_by_name;
|
/* ACL_USER is not part of AAIP 2.0 */
|
||||||
|
{ret= -2; goto ex;}
|
||||||
|
}
|
||||||
uid= huid= num;
|
uid= huid= num;
|
||||||
} else
|
} else
|
||||||
uid= huid= pwd->pw_uid;
|
uid= huid= pwd->pw_uid;
|
||||||
@ -407,31 +429,44 @@ static ssize_t aaip_encode_acl_text(char *acl_text, mode_t st_mode,
|
|||||||
for(i= 0; huid != 0; i++)
|
for(i= 0; huid != 0; i++)
|
||||||
huid= huid >> 8;
|
huid= huid >> 8;
|
||||||
qualifier_len= i;
|
qualifier_len= i;
|
||||||
|
if(qualifier_len <= 0)
|
||||||
|
qualifier_len= 1;
|
||||||
for(i= 0; i < qualifier_len ; i++)
|
for(i= 0; i < qualifier_len ; i++)
|
||||||
name[i]= uid >> (8 * (qualifier_len - i - 1));
|
name[i]= uid >> (8 * (qualifier_len - i - 1));
|
||||||
} else {
|
} else {
|
||||||
user_by_name:;
|
|
||||||
type= Aaip_ACL_USER;
|
type= Aaip_ACL_USER;
|
||||||
qualifier_len= strlen(name);
|
qualifier_len= strlen(name);
|
||||||
|
if(qualifier_len <= 0)
|
||||||
|
qualifier_len= 1;
|
||||||
}
|
}
|
||||||
qualifier= 1;
|
qualifier= 1;
|
||||||
}
|
}
|
||||||
} else if(strncmp(rpt, "group:", 6) == 0) {
|
} else if(strncmp(rpt, "group:", 6) == 0) {
|
||||||
if(cpt - rpt == 6) {
|
if(cpt - rpt == 6) {
|
||||||
type= Aaip_ACL_GROUP_OBJ;
|
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++;
|
has_g++;
|
||||||
} else {
|
} else {
|
||||||
if(cpt - (rpt + 6) >= name_size)
|
if(cpt - (rpt + 6) >= name_size)
|
||||||
continue;
|
continue;
|
||||||
is_trivial= 0;
|
is_trivial= 0;
|
||||||
strncpy(name, rpt + 6, cpt - (rpt + 6));
|
strncpy(name, rpt + 6, cpt - (rpt + 6));
|
||||||
|
name[cpt - (rpt + 6)]= 0;
|
||||||
if(flag & 2) {
|
if(flag & 2) {
|
||||||
type= Aaip_ACL_GROUP_N;
|
type= Aaip_ACL_GROUP_N;
|
||||||
grp= getgrnam(name);
|
grp= getgrnam(name);
|
||||||
if(grp == NULL) {
|
if(grp == NULL) {
|
||||||
num= aaip_numeric_id(name, 0);
|
num= aaip_numeric_id(name, 0);
|
||||||
if(num <= 0)
|
if(num <= 0) {
|
||||||
goto group_by_name;
|
/* ACL_GROUP is not part of AAIP 2.0 */
|
||||||
|
{ret= -2; goto ex;}
|
||||||
|
}
|
||||||
gid= hgid= num;
|
gid= hgid= num;
|
||||||
} else
|
} else
|
||||||
gid= hgid= grp->gr_gid;
|
gid= hgid= grp->gr_gid;
|
||||||
@ -439,18 +474,27 @@ user_by_name:;
|
|||||||
for(i= 0; hgid != 0; i++)
|
for(i= 0; hgid != 0; i++)
|
||||||
hgid= hgid >> 8;
|
hgid= hgid >> 8;
|
||||||
qualifier_len= i;
|
qualifier_len= i;
|
||||||
|
if(qualifier_len <= 0)
|
||||||
|
qualifier_len= 1;
|
||||||
for(i= 0; i < qualifier_len ; i++)
|
for(i= 0; i < qualifier_len ; i++)
|
||||||
name[i]= gid >> (8 * (qualifier_len - i - 1));
|
name[i]= gid >> (8 * (qualifier_len - i - 1));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
group_by_name:;
|
|
||||||
type= Aaip_ACL_GROUP;
|
type= Aaip_ACL_GROUP;
|
||||||
qualifier_len= strlen(name);
|
qualifier_len= strlen(name);
|
||||||
|
if(qualifier_len <= 0)
|
||||||
|
qualifier_len= 1;
|
||||||
}
|
}
|
||||||
qualifier= 1;
|
qualifier= 1;
|
||||||
}
|
}
|
||||||
} else if(strncmp(rpt, "other:", 6) == 0) {
|
} else if(strncmp(rpt, "other:", 6) == 0) {
|
||||||
type= Aaip_ACL_OTHER;
|
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++;
|
has_o++;
|
||||||
} else if(strncmp(rpt, "mask:", 5) == 0) {
|
} else if(strncmp(rpt, "mask:", 5) == 0) {
|
||||||
type= Aaip_ACL_MASK;
|
type= Aaip_ACL_MASK;
|
||||||
@ -2122,8 +2166,9 @@ int aaip_decode_acl(unsigned char *data, size_t num_data, size_t *consumed,
|
|||||||
}
|
}
|
||||||
ret= 1;
|
ret= 1;
|
||||||
ex:;
|
ex:;
|
||||||
|
*acl_text_fill= w_size;
|
||||||
if(flag & 1)
|
if(flag & 1)
|
||||||
*acl_text_fill= w_size + 1;
|
(*acl_text_fill)++;
|
||||||
LIBISO_FREE_MEM(name);
|
LIBISO_FREE_MEM(name);
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
@ -2141,6 +2186,13 @@ ex:;
|
|||||||
|
|
||||||
#include "aaip-os-linux.c"
|
#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
|
#else
|
||||||
|
|
||||||
#include "aaip-os-dummy.c"
|
#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
|
bit3= check for completeness of list and eventually
|
||||||
fill up with entries deduced from st_mode
|
fill up with entries deduced from st_mode
|
||||||
@return >0 means ok
|
@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,
|
int aaip_encode_acl(char *acl_text, mode_t st_mode,
|
||||||
size_t *result_len, unsigned char **result, int flag);
|
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
|
bit3= check for completeness of list and eventually
|
||||||
fill up with entries deduced from st_mode
|
fill up with entries deduced from st_mode
|
||||||
@return >0 means ok
|
@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,
|
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);
|
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 ------ */
|
/* ------ 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.
|
/* Obtain the ACL of the given file in long text form.
|
||||||
@param path Path to the file
|
@param path Path to the file
|
||||||
@param text Will hold the result. This is a managed object which
|
@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
|
-5 error with deleting attributes
|
||||||
-6 support of xattr not enabled at compile time
|
-6 support of xattr not enabled at compile time
|
||||||
-7 support of ACL 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,
|
int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
|
||||||
size_t *value_lengths, char **values, int flag);
|
size_t *value_lengths, char **values, int flag);
|
||||||
|
@ -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;
|
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
||||||
IsoNode *iso;
|
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);
|
memcpy(rec->file_id, name, len_fi);
|
||||||
|
|
||||||
@ -402,7 +402,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
|||||||
rec->len_dr[0] = len_dr + (info != NULL ? info->suf_len : 0);
|
rec->len_dr[0] = len_dr + (info != NULL ? info->suf_len : 0);
|
||||||
iso_bb(rec->block, block - t->eff_partition_offset, 4);
|
iso_bb(rec->block, block - t->eff_partition_offset, 4);
|
||||||
iso_bb(rec->length, len, 4);
|
iso_bb(rec->length, len, 4);
|
||||||
if (t->dir_rec_mtime) {
|
if (t->dir_rec_mtime & 1) {
|
||||||
iso= node->node;
|
iso= node->node;
|
||||||
iso_datetime_7(rec->recording_time,
|
iso_datetime_7(rec->recording_time,
|
||||||
t->replace_timestamps ? t->timestamp : iso->mtime,
|
t->replace_timestamps ? t->timestamp : iso->mtime,
|
||||||
@ -629,7 +629,7 @@ int write_one_dir(Ecma119Image *t, Ecma119Node *dir, Ecma119Node *parent)
|
|||||||
for (section = 0; section < nsections; ++section) {
|
for (section = 0; section < nsections; ++section) {
|
||||||
|
|
||||||
/* compute len of directory entry */
|
/* 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)) {
|
if (need_version_number(t, child)) {
|
||||||
len += 2;
|
len += 2;
|
||||||
}
|
}
|
||||||
@ -2701,7 +2701,13 @@ int iso_write_opts_set_dir_rec_mtime(IsoWriteOpts *opts, int allow)
|
|||||||
if (opts == NULL) {
|
if (opts == NULL) {
|
||||||
return ISO_NULL_POINTER;
|
return ISO_NULL_POINTER;
|
||||||
}
|
}
|
||||||
opts->dir_rec_mtime = allow ? 1 : 0;
|
if (allow < 0)
|
||||||
|
allow = 1;
|
||||||
|
else if (allow & (1 << 14))
|
||||||
|
allow &= ~1;
|
||||||
|
else if (allow & 6)
|
||||||
|
allow |= 1;
|
||||||
|
opts->dir_rec_mtime = allow & 7;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,8 +202,9 @@ struct iso_write_opts {
|
|||||||
* to expect that we do have a creation timestamp with the source.
|
* to expect that we do have a creation timestamp with the source.
|
||||||
* mkisofs writes mtimes and the result seems more suitable if mounted
|
* mkisofs writes mtimes and the result seems more suitable if mounted
|
||||||
* without Rock Ridge support.)
|
* without Rock Ridge support.)
|
||||||
|
* bit0= ECMA-119, bit1= Joliet, bit2= ISO 9660:1999
|
||||||
*/
|
*/
|
||||||
unsigned int dir_rec_mtime :1;
|
unsigned int dir_rec_mtime :3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute MD5 checksum for the whole session and record it as index 0 of
|
* Compute MD5 checksum for the whole session and record it as index 0 of
|
||||||
@ -476,8 +477,10 @@ struct ecma119_image
|
|||||||
/* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12. */
|
/* Write AAIP as extension according to SUSP 1.10 rather than SUSP 1.12. */
|
||||||
unsigned int aaip_susp_1_10 :1;
|
unsigned int aaip_susp_1_10 :1;
|
||||||
|
|
||||||
/* Store in ECMA-119 timestamp mtime of source */
|
/* Store in ECMA-119, Joliet, ISO 9660:1999 timestamp the mtime of source
|
||||||
unsigned int dir_rec_mtime :1;
|
bit0= ECMA-119, bit1= Joliet, bit2= ISO 9660:1999.
|
||||||
|
*/
|
||||||
|
unsigned int dir_rec_mtime :3;
|
||||||
|
|
||||||
unsigned int md5_session_checksum :1;
|
unsigned int md5_session_checksum :1;
|
||||||
unsigned int md5_file_checksums :2;
|
unsigned int md5_file_checksums :2;
|
||||||
|
@ -514,7 +514,10 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
|
|||||||
&value_lengths, &values,
|
&value_lengths, &values,
|
||||||
(!(flag & 2)) | 2 | (flag & 4) | 16);
|
(!(flag & 2)) | 2 | (flag & 4) | 16);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
ret = ISO_FILE_ERROR;
|
if (ret == -2)
|
||||||
|
ret = ISO_AAIP_NO_GET_LOCAL;
|
||||||
|
else
|
||||||
|
ret = ISO_FILE_ERROR;
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
if (num_attrs == 0)
|
if (num_attrs == 0)
|
||||||
@ -816,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 iso_local_get_acl_text(char *disk_path, char **text, int flag)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -856,13 +868,19 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths,
|
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 <= 0) {
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
if (ret == -2)
|
if (ret == -2)
|
||||||
return ISO_AAIP_BAD_AASTRING;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2011 Thomas Schmitt
|
* Copyright (c) 2011-2012 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -688,8 +688,9 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
|
|||||||
: (uint8_t*)node->name;
|
: (uint8_t*)node->name;
|
||||||
|
|
||||||
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
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);
|
memcpy(rec->file_id, name, len_fi);
|
||||||
|
|
||||||
@ -719,7 +720,15 @@ void write_one_dir_record(Ecma119Image *t, Iso1999Node *node, int file_id,
|
|||||||
rec->len_dr[0] = len_dr;
|
rec->len_dr[0] = len_dr;
|
||||||
iso_bb(rec->block, block, 4);
|
iso_bb(rec->block, block, 4);
|
||||||
iso_bb(rec->length, len, 4);
|
iso_bb(rec->length, len, 4);
|
||||||
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
|
||||||
|
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||||
|
*/
|
||||||
|
iso= node->node;
|
||||||
|
iso_datetime_7(rec->recording_time,
|
||||||
|
(t->dir_rec_mtime & 4) ? ( t->replace_timestamps ?
|
||||||
|
t->timestamp : iso->mtime )
|
||||||
|
: t->now, t->always_gmt);
|
||||||
|
|
||||||
rec->flags[0] = ((node->type == ISO1999_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
rec->flags[0] = ((node->type == ISO1999_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
||||||
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
|
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
|
||||||
rec->len_fi[0] = len_fi;
|
rec->len_fi[0] = len_fi;
|
||||||
@ -837,7 +846,7 @@ int write_one_dir(Ecma119Image *t, Iso1999Node *dir)
|
|||||||
|
|
||||||
/* compute len of directory entry */
|
/* compute len of directory entry */
|
||||||
fi_len = strlen(child->name);
|
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;
|
nsections = (child->type == ISO1999_FILE) ? child->info.file->nsections : 1;
|
||||||
for (section = 0; section < nsections; ++section) {
|
for (section = 0; section < nsections; ++section) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2007 Mario Danic
|
* Copyright (c) 2007 Mario Danic
|
||||||
* Copyright (c) 2011 Thomas Schmitt
|
* Copyright (c) 2011-2012 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -758,8 +758,9 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
|||||||
: (uint8_t*)node->name;
|
: (uint8_t*)node->name;
|
||||||
|
|
||||||
struct ecma119_dir_record *rec = (struct ecma119_dir_record*)buf;
|
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);
|
memcpy(rec->file_id, name, len_fi);
|
||||||
|
|
||||||
@ -797,7 +798,15 @@ void write_one_dir_record(Ecma119Image *t, JolietNode *node, int file_id,
|
|||||||
rec->len_dr[0] = len_dr;
|
rec->len_dr[0] = len_dr;
|
||||||
iso_bb(rec->block, block - t->eff_partition_offset, 4);
|
iso_bb(rec->block, block - t->eff_partition_offset, 4);
|
||||||
iso_bb(rec->length, len, 4);
|
iso_bb(rec->length, len, 4);
|
||||||
iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
|
||||||
|
/* was: iso_datetime_7(rec->recording_time, t->now, t->always_gmt);
|
||||||
|
*/
|
||||||
|
iso= node->node;
|
||||||
|
iso_datetime_7(rec->recording_time,
|
||||||
|
(t->dir_rec_mtime & 2) ? ( t->replace_timestamps ?
|
||||||
|
t->timestamp : iso->mtime )
|
||||||
|
: t->now, t->always_gmt);
|
||||||
|
|
||||||
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
rec->flags[0] = ((node->type == JOLIET_DIR) ? 2 : 0) | (multi_extend ? 0x80 : 0);
|
||||||
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
|
iso_bb(rec->vol_seq_number, (uint32_t) 1, 2);
|
||||||
rec->len_fi[0] = len_fi;
|
rec->len_fi[0] = len_fi;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
||||||
* Copyright (c) 2009-2011 Thomas Schmitt
|
* Copyright (c) 2009-2012 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* 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
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -61,6 +61,88 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The following two functions and three macros are utilities to help ensuring
|
||||||
|
* version match of application, compile time header, and runtime library.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* These three release version numbers tell the revision of this header file
|
||||||
|
* and of the API it describes. They are memorized by applications at
|
||||||
|
* compile time.
|
||||||
|
* They must show the same values as these symbols in ./configure.ac
|
||||||
|
* LIBISOFS_MAJOR_VERSION=...
|
||||||
|
* LIBISOFS_MINOR_VERSION=...
|
||||||
|
* LIBISOFS_MICRO_VERSION=...
|
||||||
|
* Note to anybody who does own work inside libisofs:
|
||||||
|
* Any change of configure.ac or libisofs.h has to keep up this equality !
|
||||||
|
*
|
||||||
|
* Before usage of these macros on your code, please read the usage discussion
|
||||||
|
* below.
|
||||||
|
*
|
||||||
|
* @since 0.6.2
|
||||||
|
*/
|
||||||
|
#define iso_lib_header_version_major 1
|
||||||
|
#define iso_lib_header_version_minor 2
|
||||||
|
#define iso_lib_header_version_micro 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
struct burn_source;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -878,15 +960,17 @@ extern ino_t serial_id;
|
|||||||
struct IsoStream_Iface
|
struct IsoStream_Iface
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Current version of the interface, set to 1 or 2.
|
* Current version of the interface.
|
||||||
* Version 0 (since 0.6.4)
|
* Version 0 (since 0.6.4)
|
||||||
* deprecated but still valid.
|
* deprecated but still valid.
|
||||||
* Version 1 (since 0.6.8)
|
* Version 1 (since 0.6.8)
|
||||||
* update_size() added.
|
* update_size() added.
|
||||||
* Version 2 (since 0.6.18)
|
* 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)
|
* 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)
|
* Version 4 (since 1.0.2)
|
||||||
* clone_stream() added.
|
* clone_stream() added.
|
||||||
*/
|
*/
|
||||||
@ -1013,8 +1097,8 @@ struct IsoStream_Iface
|
|||||||
* This is also appropriate if one has reason to implement stream.cmp_ino()
|
* This is also appropriate if one has reason to implement stream.cmp_ino()
|
||||||
* without having an own special comparison algorithm.
|
* without having an own special comparison algorithm.
|
||||||
*
|
*
|
||||||
* With filter streams the decision whether the underlying chains of
|
* With filter streams, the decision whether the underlying chains of
|
||||||
* streams match should be delegated to
|
* streams match, should be delegated to
|
||||||
* iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
* iso_stream_cmp_ino(iso_stream_get_input_stream(s1, 0),
|
||||||
* iso_stream_get_input_stream(s2, 0), 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);
|
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 2
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* Creates an IsoWriteOpts for writing an image. You should set the options
|
||||||
* desired with the correspondent setters.
|
* desired with the correspondent setters.
|
||||||
@ -1652,9 +1653,35 @@ int iso_write_opts_set_rrip_1_10_px_ino(IsoWriteOpts *opts, int enable);
|
|||||||
int iso_write_opts_set_aaip_susp_1_10(IsoWriteOpts *opts, int oldvers);
|
int iso_write_opts_set_aaip_susp_1_10(IsoWriteOpts *opts, int oldvers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store as ECMA-119 Directory Record timestamp the mtime of the source
|
* Store as ECMA-119 Directory Record timestamp the mtime of the source node
|
||||||
* rather than the image creation time.
|
* rather than the image creation time.
|
||||||
|
* If storing of mtime is enabled, then the settings of
|
||||||
|
* iso_write_opts_set_replace_timestamps() apply. (replace==1 will revoke,
|
||||||
|
* replace==2 will override mtime by iso_write_opts_set_default_timestamp().
|
||||||
*
|
*
|
||||||
|
* Since version 1.2.0 this may apply also to Joliet and ISO 9660:1999. To
|
||||||
|
* reduce the probability of unwanted behavior changes between pre-1.2.0 and
|
||||||
|
* post-1.2.0, the bits for Joliet and ISO 9660:1999 also enable ECMA-119.
|
||||||
|
* The hopefully unlikely bit14 may then be used to disable mtime for ECMA-119.
|
||||||
|
*
|
||||||
|
* To enable mtime for all three directory trees, submit 7.
|
||||||
|
* To disable this feature completely, submit 0.
|
||||||
|
*
|
||||||
|
* @param opts
|
||||||
|
* The option set to be manipulated.
|
||||||
|
* @param allow
|
||||||
|
* If this parameter is negative, then mtime is enabled only for ECMA-119.
|
||||||
|
* With positive numbers, the parameter is interpreted as bit field :
|
||||||
|
* bit0= enable mtime for ECMA-119
|
||||||
|
* bit1= enable mtime for Joliet and ECMA-119
|
||||||
|
* bit2= enable mtime for ISO 9660:1999 and ECMA-119
|
||||||
|
* bit14= disable mtime for ECMA-119 although some of the other bits
|
||||||
|
* would enable it
|
||||||
|
* @since 1.2.0
|
||||||
|
* Before version 1.2.0 this applied only to ECMA-119 :
|
||||||
|
* 0 stored image creation time in ECMA-119 tree.
|
||||||
|
* Any other value caused storing of mtime.
|
||||||
|
* Joliet and ISO 9660:1999 always stored the image creation time.
|
||||||
* @since 0.6.12
|
* @since 0.6.12
|
||||||
*/
|
*/
|
||||||
int iso_write_opts_set_dir_rec_mtime(IsoWriteOpts *opts, int allow);
|
int iso_write_opts_set_dir_rec_mtime(IsoWriteOpts *opts, int allow);
|
||||||
@ -1782,8 +1809,10 @@ int iso_write_opts_set_default_gid(IsoWriteOpts *opts, gid_t gid);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 0 to use IsoNode timestamps, 1 to use recording time, 2 to use
|
* 0 to use IsoNode timestamps, 1 to use recording time, 2 to use
|
||||||
* values from timestamp field. This has only meaning if RR extensions
|
* values from timestamp field. This applies to the timestamps of Rock Ridge
|
||||||
* are enabled.
|
* and if the use of mtime is enabled by iso_write_opts_set_dir_rec_mtime().
|
||||||
|
* In the latter case, value 1 will revoke the recording of mtime, value
|
||||||
|
* 2 will override mtime by iso_write_opts_set_default_timestamp().
|
||||||
*
|
*
|
||||||
* @see iso_write_opts_set_default_timestamp
|
* @see iso_write_opts_set_default_timestamp
|
||||||
* @since 0.6.2
|
* @since 0.6.2
|
||||||
@ -5789,6 +5818,30 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
|
|||||||
* from local files.
|
* 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.
|
* Get an ACL of the given file in the local filesystem in long text form.
|
||||||
*
|
*
|
||||||
@ -5832,7 +5885,7 @@ int iso_local_get_acl_text(char *disk_path, char **text, int flag);
|
|||||||
* bit5= in case of symbolic link: manipulate link target
|
* bit5= in case of symbolic link: manipulate link target
|
||||||
* @return
|
* @return
|
||||||
* > 0 ok
|
* > 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)
|
* -1 failure of system ACL service (see errno)
|
||||||
* -2 attempt to manipulate ACL of a symbolic link without bit5
|
* -2 attempt to manipulate ACL of a symbolic link without bit5
|
||||||
* resp. with no suitable link target
|
* resp. with no suitable link target
|
||||||
@ -5921,6 +5974,9 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
|
|||||||
* bit3= do not ignore eventual non-user attributes.
|
* bit3= do not ignore eventual non-user attributes.
|
||||||
* I.e. those with a name which does not begin by "user."
|
* 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= @since 1.1.6
|
||||||
|
tolerate inappropriate presence or absence of
|
||||||
|
* directory "default" ACL
|
||||||
* @return
|
* @return
|
||||||
* 1 = ok
|
* 1 = ok
|
||||||
* < 0 = error
|
* < 0 = error
|
||||||
@ -6886,9 +6942,16 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
/** Reserved Rock Ridge leaf name (FAILURE, HIGH, -378) */
|
/** Reserved Rock Ridge leaf name (FAILURE, HIGH, -378) */
|
||||||
#define ISO_RR_NAME_RESERVED 0xE830FE86
|
#define ISO_RR_NAME_RESERVED 0xE830FE86
|
||||||
|
|
||||||
/** Rock Ridge path too long (FAILURE, HIGH, -379) */
|
/** Rock Ridge path too long (FAILURE, HIGH, -379) */
|
||||||
#define ISO_RR_PATH_TOO_LONG 0xE830FE85
|
#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:
|
/* Internal developer note:
|
||||||
|
@ -125,6 +125,7 @@ iso_init;
|
|||||||
iso_init_with_flag;
|
iso_init_with_flag;
|
||||||
iso_lib_is_compatible;
|
iso_lib_is_compatible;
|
||||||
iso_lib_version;
|
iso_lib_version;
|
||||||
|
iso_local_attr_support;
|
||||||
iso_local_get_acl_text;
|
iso_local_get_acl_text;
|
||||||
iso_local_get_attrs;
|
iso_local_get_attrs;
|
||||||
iso_local_get_perms_wo_acl;
|
iso_local_get_perms_wo_acl;
|
||||||
@ -311,5 +312,6 @@ iso_write_opts_set_will_cancel;
|
|||||||
iso_zisofs_get_params;
|
iso_zisofs_get_params;
|
||||||
iso_zisofs_get_refcounts;
|
iso_zisofs_get_refcounts;
|
||||||
iso_zisofs_set_params;
|
iso_zisofs_set_params;
|
||||||
|
serial_id;
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
@ -464,6 +464,10 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Reserved Rock Ridge leaf name";
|
return "Reserved Rock Ridge leaf name";
|
||||||
case ISO_RR_PATH_TOO_LONG:
|
case ISO_RR_PATH_TOO_LONG:
|
||||||
return "Rock Ridge 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:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
@ -2149,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,
|
ret = aaip_encode_both_acl(access_text, default_text, st_mode,
|
||||||
&acl_len, &acl, 2 | 8);
|
&acl_len, &acl, 2 | 8);
|
||||||
}
|
}
|
||||||
if (ret <= 0) {
|
if (ret == -1)
|
||||||
ret = ISO_OUT_OF_MEM;
|
ret = ISO_OUT_OF_MEM;
|
||||||
|
else if (ret <= 0 && ret >= -3)
|
||||||
|
ret = ISO_AAIP_BAD_ACL_TEXT;
|
||||||
|
if (ret <= 0)
|
||||||
goto ex;
|
goto ex;
|
||||||
}
|
|
||||||
|
|
||||||
if(acl == NULL) { /* Delete whole ACL attribute */
|
if(acl == NULL) { /* Delete whole ACL attribute */
|
||||||
/* Update S_IRWXG by eventual "group::" ACL entry.
|
/* Update S_IRWXG by eventual "group::" ACL entry.
|
||||||
@ -2205,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,
|
ret = aaip_encode_both_acl(access_text, default_text,
|
||||||
st_mode, &acl_len, &acl, 2 | 8);
|
st_mode, &acl_len, &acl, 2 | 8);
|
||||||
|
if (ret < -3)
|
||||||
|
goto ex;
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
ret = ISO_AAIP_BAD_ACL_TEXT;
|
ret = ISO_AAIP_BAD_ACL_TEXT;
|
||||||
goto ex;
|
goto ex;
|
||||||
|
@ -988,7 +988,10 @@ int susp_calc_nm_sl_al(Ecma119Image *t, Ecma119Node *n, size_t space,
|
|||||||
goto unannounced_ca;
|
goto unannounced_ca;
|
||||||
namelen = namelen - (space - *su_size - 5);
|
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;
|
*ce = 5 + namelen;
|
||||||
*su_size = space;
|
*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.
|
* ..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),
|
ret = rrip_add_NM(t, info, name + namelen, strlen(name + namelen),
|
||||||
0, 1);
|
0, 1);
|
||||||
|
@ -214,6 +214,7 @@ int fsrc_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
IsoStreamIface fsrc_stream_class = {
|
IsoStreamIface fsrc_stream_class = {
|
||||||
4, /* version */
|
4, /* version */
|
||||||
"fsrc",
|
"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.
|
* TODO update cut out streams to deal with update_size(). Seems hard.
|
||||||
*/
|
*/
|
||||||
|
static
|
||||||
IsoStreamIface cut_out_stream_class = {
|
IsoStreamIface cut_out_stream_class = {
|
||||||
4, /* version */
|
4, /* version */
|
||||||
"cout",
|
"cout",
|
||||||
@ -748,6 +750,7 @@ int mem_clone_stream(IsoStream *old_stream, IsoStream **new_stream,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
IsoStreamIface mem_stream_class = {
|
IsoStreamIface mem_stream_class = {
|
||||||
4, /* version */
|
4, /* version */
|
||||||
"mem ",
|
"mem ",
|
||||||
|
158
libisofs/util.c
158
libisofs/util.c
@ -382,12 +382,13 @@ conv_error:;
|
|||||||
int str2ascii(const char *icharset, const char *input, char **output)
|
int str2ascii(const char *icharset, const char *input, char **output)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
wchar_t *wsrc_;
|
wchar_t *wsrc_ = NULL;
|
||||||
char *ret;
|
char *ret = NULL;
|
||||||
char *ret_;
|
char *ret_ = NULL;
|
||||||
char *src;
|
char *src;
|
||||||
struct iso_iconv_handle conv;
|
struct iso_iconv_handle conv;
|
||||||
int conv_ret;
|
int conv_ret;
|
||||||
|
int direct_conv = 0;
|
||||||
|
|
||||||
/* That while loop smells like a potential show stopper */
|
/* That while loop smells like a potential show stopper */
|
||||||
size_t loop_counter = 0, loop_limit = 3;
|
size_t loop_counter = 0, loop_limit = 3;
|
||||||
@ -405,33 +406,54 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
|||||||
return ISO_NULL_POINTER;
|
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
|
/* convert the string to a wide character string. Note: outbytes
|
||||||
* is in fact the number of characters in the string and doesn't
|
* is in fact the number of characters in the string and doesn't
|
||||||
* include the last NULL character.
|
* include the last NULL character.
|
||||||
*/
|
*/
|
||||||
|
conv_ret = 0;
|
||||||
result = str2wchar(icharset, input, &wsrc_);
|
result = str2wchar(icharset, input, &wsrc_);
|
||||||
if (result < 0) {
|
if (result == (int) ISO_SUCCESS) {
|
||||||
goto fallback;
|
src = (char *)wsrc_;
|
||||||
}
|
numchars = wcslen(wsrc_);
|
||||||
src = (char *)wsrc_;
|
|
||||||
numchars = wcslen(wsrc_);
|
|
||||||
|
|
||||||
inbytes = numchars * sizeof(wchar_t);
|
inbytes = numchars * sizeof(wchar_t);
|
||||||
loop_limit = inbytes + 3;
|
loop_limit = inbytes + 3;
|
||||||
|
|
||||||
ret_ = malloc(numchars + 1);
|
ret_ = malloc(numchars + 1);
|
||||||
if (ret_ == NULL) {
|
if (ret_ == NULL) {
|
||||||
return ISO_OUT_OF_MEM;
|
return ISO_OUT_OF_MEM;
|
||||||
}
|
}
|
||||||
outbytes = numchars;
|
outbytes = numchars;
|
||||||
ret = ret_;
|
ret = ret_;
|
||||||
|
|
||||||
/* initialize iconv */
|
/* initialize iconv */
|
||||||
conv_ret = iso_iconv_open(&conv, "ASCII", "WCHAR_T", 0);
|
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) {
|
if (conv_ret <= 0) {
|
||||||
free(wsrc_);
|
conv_ret = iso_iconv_open(&conv, "ASCII", (char *) icharset, 0);
|
||||||
free(ret_);
|
if (conv_ret <= 0)
|
||||||
goto fallback;
|
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);
|
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
|
/* There was an error with one character but some other remain
|
||||||
* to be converted. That's probably a multibyte character.
|
* to be converted. That's probably a multibyte character.
|
||||||
* See above comment. */
|
* See above comment. */
|
||||||
src += sizeof(wchar_t);
|
if (direct_conv) {
|
||||||
inbytes -= sizeof(wchar_t);
|
src++;
|
||||||
|
inbytes--;
|
||||||
|
} else {
|
||||||
|
src += sizeof(wchar_t);
|
||||||
|
inbytes -= sizeof(wchar_t);
|
||||||
|
}
|
||||||
|
|
||||||
if (!inbytes)
|
if (!inbytes)
|
||||||
break;
|
break;
|
||||||
@ -471,8 +498,9 @@ int str2ascii(const char *icharset, const char *input, char **output)
|
|||||||
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
}
|
}
|
||||||
iso_iconv_close(&conv, 0);
|
iso_iconv_close(&conv, 0);
|
||||||
*ret='\0';
|
*ret = 0;
|
||||||
free(wsrc_);
|
if (wsrc_ != NULL)
|
||||||
|
free(wsrc_);
|
||||||
|
|
||||||
*output = ret_;
|
*output = ret_;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
@ -517,12 +545,13 @@ int cmp_ucsbe(const uint16_t *ucs, char c)
|
|||||||
int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
wchar_t *wsrc_;
|
wchar_t *wsrc_ = NULL;
|
||||||
char *src;
|
char *src;
|
||||||
char *ret;
|
char *ret = NULL;
|
||||||
char *ret_;
|
char *ret_ = NULL;
|
||||||
struct iso_iconv_handle conv;
|
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 */
|
/* That while loop smells like a potential show stopper */
|
||||||
size_t loop_counter = 0, loop_limit = 3;
|
size_t loop_counter = 0, loop_limit = 3;
|
||||||
@ -540,29 +569,50 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
|||||||
* is in fact the number of characters in the string and doesn't
|
* is in fact the number of characters in the string and doesn't
|
||||||
* include the last NULL character.
|
* 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_);
|
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;
|
return result;
|
||||||
}
|
|
||||||
src = (char *)wsrc_;
|
|
||||||
numchars = wcslen(wsrc_);
|
|
||||||
|
|
||||||
inbytes = numchars * sizeof(wchar_t);
|
/* If this did not succeed : Try the untraditional direct conversion.
|
||||||
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) {
|
if (conv_ret <= 0) {
|
||||||
free(wsrc_);
|
conv_ret = iso_iconv_open(&conv, "UCS-2BE", (char *) icharset, 0);
|
||||||
free(ret_);
|
if (conv_ret <= 0) {
|
||||||
return ISO_CHARSET_CONV_ERROR;
|
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);
|
n = iso_iconv(&conv, &src, &inbytes, &ret, &outbytes, 0);
|
||||||
@ -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
|
/* There was an error with one character but some other remain
|
||||||
* to be converted. That's probably a multibyte character.
|
* to be converted. That's probably a multibyte character.
|
||||||
* See above comment. */
|
* See above comment. */
|
||||||
src += sizeof(wchar_t);
|
if (direct_conv) {
|
||||||
inbytes -= sizeof(wchar_t);
|
src++;
|
||||||
|
inbytes--;
|
||||||
|
} else {
|
||||||
|
src += sizeof(wchar_t);
|
||||||
|
inbytes -= sizeof(wchar_t);
|
||||||
|
}
|
||||||
|
|
||||||
if (!inbytes)
|
if (!inbytes)
|
||||||
break;
|
break;
|
||||||
@ -605,7 +660,8 @@ int str2ucs(const char *icharset, const char *input, uint16_t **output)
|
|||||||
|
|
||||||
/* close the ucs string */
|
/* close the ucs string */
|
||||||
set_ucsbe((uint16_t*) ret, '\0');
|
set_ucsbe((uint16_t*) ret, '\0');
|
||||||
free(wsrc_);
|
if (wsrc_ != NULL)
|
||||||
|
free(wsrc_);
|
||||||
|
|
||||||
*output = (uint16_t*)ret_;
|
*output = (uint16_t*)ret_;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
Reference in New Issue
Block a user