Enabled recording and restoring of extattr on FreeBSD.
Gave up unconditional ACL support in favor of configure control.
This commit is contained in:
parent
f885da8087
commit
ca63dac7e3
14
configure.ac
14
configure.ac
@ -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
|
||||||
|
@ -24,15 +24,17 @@
|
|||||||
#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 --------------------------------- */
|
/* ------------------------------ Inquiry --------------------------------- */
|
||||||
|
|
||||||
@ -59,6 +61,10 @@ int aaip_local_attr_support(int flag)
|
|||||||
if(flag & 1)
|
if(flag & 1)
|
||||||
ret|= 1;
|
ret|= 1;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef Libisofs_with_freebsd_extattR
|
||||||
|
if(flag & 2)
|
||||||
|
ret|= 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
@ -167,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().
|
||||||
|
|
||||||
@ -182,7 +531,9 @@ 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
|
||||||
@ -196,9 +547,12 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
ssize_t i, num_names;
|
ssize_t i, num_names;
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_aaip_acL
|
||||||
size_t a_acl_len= 0;
|
size_t a_acl_len= 0;
|
||||||
unsigned char *a_acl= NULL;
|
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;}
|
||||||
@ -245,18 +599,21 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
|
|||||||
if((*names)[*num_attrs] == NULL)
|
if((*names)[*num_attrs] == NULL)
|
||||||
{ret= -1; goto ex;}
|
{ret= -1; goto ex;}
|
||||||
(*values)[*num_attrs]= (char *) a_acl;
|
(*values)[*num_attrs]= (char *) a_acl;
|
||||||
|
a_acl= NULL;
|
||||||
(*value_lengths)[*num_attrs]= a_acl_len;
|
(*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(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) {
|
||||||
@ -279,6 +636,8 @@ ex:;
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_old_freebsd_acl_adapteR */
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------ Setters --------------------------------- */
|
/* ------------------------------ Setters --------------------------------- */
|
||||||
|
|
||||||
@ -288,6 +647,7 @@ 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
|
||||||
@return > 0 ok
|
@return > 0 ok
|
||||||
-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 ACL support not enabled at compile time
|
||||||
@ -338,6 +698,190 @@ ex:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
||||||
|
@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
|
||||||
|
*/
|
||||||
|
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 <= 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 <= 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);
|
||||||
|
if(ret <= 0)
|
||||||
|
{ret= -3; goto ex;}
|
||||||
|
#else
|
||||||
|
{ret= -7; goto ex;}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(has_default_acl) {
|
||||||
|
|
||||||
|
/* >>> EXTATTR : Give opportunity to ignore default ACLs */;
|
||||||
|
|
||||||
|
{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.
|
||||||
@ -433,4 +977,5 @@ ex:;
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* Libisofs_old_freebsd_acl_adapteR */
|
||||||
|
|
||||||
|
@ -876,6 +876,8 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
|
|||||||
return ISO_AAIP_BAD_AASTRING;
|
return ISO_AAIP_BAD_AASTRING;
|
||||||
if (ret == -6 || ret == -7)
|
if (ret == -6 || ret == -7)
|
||||||
return ISO_AAIP_NOT_ENABLED;
|
return ISO_AAIP_NOT_ENABLED;
|
||||||
|
if (ret == -8)
|
||||||
|
return ISO_AAIP_BAD_ATTR_NAME;
|
||||||
return ISO_AAIP_NO_SET_LOCAL;
|
return ISO_AAIP_NO_SET_LOCAL;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -6912,9 +6912,11 @@ 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
|
||||||
|
|
||||||
|
|
||||||
/* Internal developer note:
|
/* Internal developer note:
|
||||||
|
@ -464,6 +464,8 @@ 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";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user