New flag bit7 with iso_local_set_attrs() to avoid unnecessary write attempts. New return value 2 of IsoFileSource.get_aa_string() and iso_local_get_attrs(). New API calls iso_image_was_blind_attrs(), iso_local_set_attrs_errno().

This commit is contained in:
Thomas Schmitt 2017-10-23 10:36:10 +02:00
parent 7d45c88cff
commit 4b031b58ea
11 changed files with 334 additions and 106 deletions

View File

@ -99,10 +99,14 @@ int aaip_set_acl_text(char *path, char *text, int flag)
-7 support of ACL not enabled at compile time
*/
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 *errnos,
int flag)
{
size_t i;
for(i= 0; i < num_attrs; i++)
errnos[i]= 0;
for(i= 0; i < num_attrs; i++) {
if(names[i] == NULL || values[i] == NULL)
continue;

View File

@ -228,6 +228,10 @@ static int aaip_extattr_make_list(char *path, int attrnamespace,
*list_size = 0;
return(2);
}
if(errno == EPERM && attrnamespace == EXTATTR_NAMESPACE_SYSTEM) {
*list_size = 0;
return(3);
}
return(0);
}
if(*list_size == 0)
@ -312,6 +316,54 @@ static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
return(1);
}
static int get_single_attr(char *path, char *name, size_t *value_length,
char **value_bytes, int flag)
{
char *namept;
int attrnamespace;
ssize_t value_ret;
*value_bytes= NULL;
*value_length= 0;
if(strncmp(name, "user.", 5) == 0) {
attrnamespace= EXTATTR_NAMESPACE_USER;
namept= name + 5;
} else {
if(!(flag & 8))
return(0);
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
namept= name + 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)
return(0);
*value_bytes= calloc(value_ret + 1, 1);
if(*value_bytes == NULL)
return(-1);
/* Obtain value */
if(flag & 32) /* follow link */
value_ret= extattr_get_file(path, attrnamespace, namept,
*value_bytes, (size_t) value_ret);
else
value_ret= extattr_get_link(path, attrnamespace, namept,
*value_bytes, (size_t) value_ret);
if(value_ret == -1) {
free(*value_bytes);
*value_bytes= NULL;
*value_length= 0;
return(0);
}
*value_length= value_ret;
return(1);
}
#endif /* Libisofs_with_freebsd_extattR */
@ -332,7 +384,8 @@ static int aaip_extattr_make_namelist(char *path, char *attrnamespace,
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
@return 1 ok
2 ok, no permission to inspect non-user namespaces
<=0 error
-1= out of memory
-2= program error with prediction of result size
@ -350,11 +403,10 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
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;
char *list= NULL, *user_list= NULL, *sys_list= NULL;
ssize_t value_ret, list_size= 0, user_list_size= 0;
ssize_t sys_list_size= 0;
int attrnamespace;
int acl_names= 0;
int acl_names= 0, no_perm_for_system= 0;
#endif
if(flag & (1 << 15)) { /* Free memory */
@ -391,6 +443,8 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
&sys_list, &sys_list_size, flag & 32);
if(ret <= 0)
{ret= -1; goto ex;}
if(ret == 3)
no_perm_for_system= 1;
}
/* Check for NUL in names, convert into a linuxish list of namespace.name */
@ -445,45 +499,10 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
}
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)
value_ret= get_single_attr(path, (*names)[i], *value_lengths + i,
*values + i, flag & (8 | 32));
if(value_ret <= 0)
{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;
}
}
@ -494,8 +513,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
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 */
if(a_acl_text == NULL) {
/* empty ACL / only st_mode info was found in ACL */
ret= 1 + no_perm_for_system;
goto ex;
}
ret= aaip_encode_acl(a_acl_text, (mode_t) 0, &a_acl_len, &a_acl, flag & 2);
if(ret <= 0)
goto ex;
@ -514,7 +536,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
#endif /* Libisofs_with_aaip_acL */
ret= 1;
ret= 1 + no_perm_for_system;
ex:;
#ifdef Libisofs_with_aaip_acL
if(a_acl != NULL)
@ -773,6 +795,15 @@ static int aaip_extattr_delete_names(char *path, int attrnamespace,
#endif /* Libisofs_with_freebsd_extattR */
static void register_errno(int *errnos, int i, int in_errno)
{
if(in_errno > 0)
errnos[i]= in_errno;
else
errnos[i]= -1;
}
/* Bring the given attributes and/or ACLs into effect with the given file.
@param flag Bitfield for control purposes
bit0= decode and set ACLs
@ -784,6 +815,8 @@ static int aaip_extattr_delete_names(char *path, int attrnamespace,
bit5= in case of symbolic link: manipulate link target
bit6= tolerate inappropriate presence or absence of
directory default ACL
bit7= void setting a name value pair if it already
exists and has the desired value.
@return 1 success
-1 error memory allocation
-2 error with decoding of ACL
@ -796,17 +829,23 @@ static int aaip_extattr_delete_names(char *path, int attrnamespace,
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)
size_t *value_lengths, char **values,
int *errnos, int flag)
{
int ret, has_default_acl= 0;
int ret, has_default_acl= 0, end_ret= 1;
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;
char *user_list= NULL, *sys_list= NULL, *namept, *old_value;
ssize_t user_list_size= 0, sys_list_size= 0, value_ret;
int attrnamespace;
size_t old_value_l;
int skip;
#endif
for(i= 0; i < num_attrs; i++)
errnos[i]= 0;
#ifdef Libisofs_with_freebsd_extattR
if(flag & 2) { /* Delete all file attributes */
@ -855,16 +894,35 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
attrnamespace= EXTATTR_NAMESPACE_SYSTEM;
namept= names[i] + 7;
} else {
{ret= -8; goto ex;}
register_errno(errnos, i, (int) EFAULT);
end_ret= -8;
continue;
}
skip= 0;
if(flag & 128) {
value_ret= get_single_attr(path, names[i], &old_value_l,
&old_value, flag & (8 | 32));
if(value_ret > 0 && old_value_l == value_lengths[i]) {
if(memcmp(old_value, values[i], value_lengths[i]) == 0)
skip= 1;
}
if(old_value != NULL)
free(old_value);
}
if(!skip) {
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;}
if(ret == -1) {
register_errno(errnos, i, errno);
if(end_ret != 1)
end_ret= -4;
continue;
}
}
#else
@ -879,8 +937,12 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
}
/* Decode ACLs */
/* It is important that this happens after restoring xattr which might be
representations of ACL, too. If isofs ACL are enabled, then they shall
override the xattr ones.
*/
if(acl_idx == 0)
{ret= 1; goto ex;}
{ret= end_ret; goto ex;}
i= acl_idx - 1;
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
@ -902,6 +964,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
#ifdef Libisofs_with_aaip_acL
ret= aaip_set_acl_text(path, acl_text, flag & (32 | 64));
if(ret == -1)
register_errno(errnos, i, errno);
if(ret <= 0)
{ret= -3; goto ex;}
#else
@ -911,7 +975,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
if(has_default_acl && !(flag & 64))
{ret= -3; goto ex;}
ret= 1;
ret= end_ret;
ex:;
if(acl_text != NULL)
free(acl_text);

View File

@ -159,6 +159,41 @@ int aaip_get_acl_text(char *path, char **text, int flag)
}
#ifdef Libisofs_with_aaip_xattR
static int get_single_attr(char *path, char *name, size_t *value_length,
char **value_bytes, int flag)
{
ssize_t value_ret;
*value_bytes= NULL;
*value_length= 0;
if(flag & 32)
value_ret= getxattr(path, name, NULL, 0);
else
value_ret= lgetxattr(path, name, NULL, 0);
if(value_ret == -1)
return(0);
*value_bytes= calloc(value_ret + 1, 1);
if(*value_bytes == NULL)
return(-1);
if(flag & 32)
value_ret= getxattr(path, name, *value_bytes, value_ret);
else
value_ret= lgetxattr(path, name, *value_bytes, value_ret);
if(value_ret == -1) {
free(*value_bytes);
*value_bytes= NULL;
*value_length= 0;
return(0);
}
*value_length= value_ret;
return(1);
}
#endif /* Libisofs_with_aaip_xattR */
/* 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
@ -176,7 +211,9 @@ int aaip_get_acl_text(char *path, char **text, int flag)
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
@return 1 ok
(reserved for FreeBSD: 2 ok, no permission to inspect
non-user namespaces.)
<=0 error
-1= out of memory
-2= program error with prediction of result size
@ -195,7 +232,7 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
#endif
#ifdef Libisofs_with_aaip_xattR
char *list= NULL;
ssize_t value_ret, retry= 0, list_size= 0;
ssize_t value_ret, list_size= 0;
#define Libisofs_aaip_get_attr_activE yes
#endif
#ifdef Libisofs_aaip_get_attr_activE
@ -288,27 +325,10 @@ ex:;
if(!(flag & 8))
if(strncmp((*names)[i], "user.", 5))
continue;
if(flag & 32)
value_ret= getxattr(path, (*names)[i], NULL, 0);
else
value_ret= lgetxattr(path, (*names)[i], NULL, 0);
if(value_ret == -1)
continue;
(*values)[i]= calloc(value_ret + 1, 1);
if((*values)[i] == NULL)
value_ret= get_single_attr(path, (*names)[i], *value_lengths + i,
*values + i, flag & 32);
if(value_ret <= 0)
{ret= -1; goto ex;}
if(flag & 32)
value_ret= getxattr(path, (*names)[i], (*values)[i], value_ret);
else
value_ret= lgetxattr(path, (*names)[i], (*values)[i], 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;
}
}
@ -434,6 +454,15 @@ ex:
}
static void register_errno(int *errnos, int i)
{
if(errno > 0)
errnos[i]= errno;
else
errnos[i]= -1;
}
/* Bring the given attributes and/or ACLs into effect with the given file.
@param flag Bitfield for control purposes
bit0= decode and set ACLs
@ -445,6 +474,9 @@ ex:
bit5= in case of symbolic link: manipulate link target
bit6= tolerate inappropriate presence or absence of
directory default ACL
bit7= @since 1.5.0
avoid setting a name value pair if it already
exists and has the desired value.
@return 1 success
-1 error memory allocation
-2 error with decoding of ACL
@ -457,20 +489,25 @@ ex:
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)
size_t *value_lengths, char **values,
int *errnos, int flag)
{
int ret;
int ret, end_ret= 1;
size_t i, consumed, acl_text_fill, acl_idx= 0;
char *acl_text= NULL;
#ifdef Libisofs_with_aaip_xattR
char *list= NULL;
ssize_t list_size= 0;
char *list= NULL, *old_value;
ssize_t list_size= 0, value_ret;
size_t old_value_l;
int skip;
#endif
#ifdef Libisofs_with_aaip_acL
size_t h_consumed;
int has_default_acl= 0;
#endif
for(i= 0; i < num_attrs; i++)
errnos[i]= 0;
#ifdef Libisofs_with_aaip_xattR
@ -525,12 +562,28 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
#ifdef Libisofs_with_aaip_xattR
skip= 0;
if(flag & 128) {
value_ret= get_single_attr(path, names[i], &old_value_l,
&old_value, flag & 32);
if(value_ret > 0 && old_value_l == value_lengths[i]) {
if(memcmp(old_value, values[i], value_lengths[i]) == 0)
skip= 1;
}
if(old_value != NULL)
free(old_value);
}
if(!skip) {
if(flag & 32)
ret= setxattr(path, names[i], values[i], value_lengths[i], 0);
else
ret= lsetxattr(path, names[i], values[i], value_lengths[i], 0);
if(ret == -1)
{ret= -4; goto ex;}
if(ret == -1) {
register_errno(errnos, i);
end_ret= -4;
continue;
}
}
#else
@ -540,9 +593,13 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
}
/* Decode ACLs */
/* Decode ACLs */
/* It is important that this happens after restoring xattr which might be
representations of ACL, too. If isofs ACL are enabled, then they shall
override the xattr ones.
*/
if(acl_idx == 0)
{ret= 1; goto ex;}
{ret= end_ret; goto ex;}
i= acl_idx - 1;
/* "access" ACL */
ret= aaip_decode_acl((unsigned char *) values[i], value_lengths[i],
@ -566,6 +623,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
has_default_acl= (ret == 2);
ret= aaip_set_acl_text(path, acl_text, flag & 32);
if(ret == -1)
register_errno(errnos, i);
if(ret <= 0)
{ret= -3; goto ex;}
/* "default" ACL */
@ -590,6 +649,8 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
if(ret <= 0)
{ret= -2; goto ex;}
ret= aaip_set_acl_text(path, acl_text, 1 | (flag & 32));
if(ret == -1)
register_errno(errnos, i);
if(ret <= 0)
{ret= -3; goto ex;}
} else {
@ -601,7 +662,7 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
}
}
ret= 1;
ret= end_ret;
#else

View File

@ -2188,6 +2188,11 @@ ex:;
/* ----------------------- Adapter for operating systems ----------------- */
#ifdef Libisofs_use_os_dummY
#include "aaip-os-dummy.c"
#else
#ifdef __FreeBSD__
#include "aaip-os-freebsd.c"
@ -2239,4 +2244,5 @@ ex:;
#endif /* ! __NetBSD__ */
#endif /* ! __FreeBSD_kernel__ */
#endif /* ! __FreeBSD__ */
#endif /* ! Libisofs_use_os_dummY */

View File

@ -507,7 +507,8 @@ int aaip_set_acl_text(char *path, char *text, int flag);
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);
size_t *value_lengths, char **values,
int *errnos, int flag);
#endif /* ! Aaip_h_is_includeD */

View File

@ -254,7 +254,9 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
1 | (image->builder_ignore_acl << 1) |
(image->builder_ignore_ea << 2) |
(image->builder_take_all_ea << 3));
if (ret == 1 && aa_string != NULL) {
if(ret == 2)
image->blind_on_local_get_attrs = 1;
if (ret > 0 && aa_string != NULL) {
ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
if (ret < 0)
goto ex;

View File

@ -499,7 +499,7 @@ void lfs_free(IsoFileSource *src)
static
int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
{
int ret;
int ret, no_non_user_perm= 0;
size_t num_attrs = 0, *value_lengths = NULL, result_len;
ssize_t sret;
char *path = NULL, **names = NULL, **values = NULL;
@ -529,6 +529,9 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
ret = ISO_FILE_ERROR;
goto ex;
}
if(ret == 2)
no_non_user_perm= 1;
if (num_attrs == 0)
result = NULL;
else {
@ -540,7 +543,7 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
}
}
*aa_string = result;
ret = 1;
ret = 1 + no_non_user_perm;
ex:;
if (path != NULL)
free(path);
@ -867,17 +870,19 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
(flag & (1 | 4 | 8 | 32 | (1 << 15))) | 2 | 16);
if (ret <= 0)
return ISO_AAIP_NO_GET_LOCAL;
return 1;
return 1 + (ret == 2);
}
int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
int iso_local_set_attrs_errno(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values,
int *errnos, int flag)
{
int ret;
ret = aaip_set_attr_list(disk_path, num_attrs, names, value_lengths,
values, (flag & (8 | 32 | 64)) | !(flag & 1));
values, errnos,
(flag & (8 | 32 | 64 | 128)) | !(flag & 1));
if (ret <= 0) {
if (ret == -1)
return ISO_OUT_OF_MEM;
@ -895,6 +900,25 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
}
int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag)
{
int ret;
int *errnos = NULL;
if(num_attrs > 0) {
errnos= calloc(num_attrs, sizeof(int));
if(errnos == NULL)
return ISO_OUT_OF_MEM;
}
ret= iso_local_set_attrs_errno(disk_path, num_attrs, names, value_lengths,
values, errnos, flag);
if(errnos != NULL)
free(errnos);
return ret;
}
int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag)
{
struct stat stbuf;

View File

@ -203,6 +203,7 @@ int iso_image_new(const char *name, IsoImage **image)
img->hfsplus_blessed[i] = NULL;
img->collision_warnings = 0;
img->imported_sa_info = NULL;
img->blind_on_local_get_attrs = 0;
*image = img;
return ISO_SUCCESS;
@ -1137,3 +1138,15 @@ int iso_image_truncate_name(IsoImage *image, const char *name, char **namept,
return ret;
}
/* API */
int iso_image_was_blind_attrs(IsoImage *image, int flag)
{
int ret;
ret = image->blind_on_local_get_attrs;
if (flag & 1)
image->blind_on_local_get_attrs = 0;
return ret;
}

View File

@ -247,6 +247,11 @@ struct Iso_Image
/* Contains the assessment of boot aspects of the loaded image */
struct iso_imported_sys_area *imported_sa_info;
/* Whether some local filesystem xattr namespace could not be explored
* during node building.
*/
int blind_on_local_get_attrs;
};

View File

@ -867,6 +867,10 @@ struct IsoFileSource_Iface
* The caller is responsible for finally calling free()
* on non-NULL results.
* @return 1 means success (*aa_string == NULL is possible)
* 2 means success, but it is possible that attributes
* exist in non-user namespaces which could not be
* explored due to lack of permission.
* @since 1.5.0
* <0 means failure and must b a valid libisofs error code
* (e.g. ISO_FILE_ERROR if no better one can be found).
* @since 0.6.14
@ -6357,6 +6361,28 @@ int iso_tree_clone(IsoNode *node,
*/
int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir);
/**
* Inquire whether some local filesystem xattr namespace could not be explored
* during node building. This may happen due to lack of adminstrator privileges
* e.g. on FreeBSD namespace "system".
* It may well be that the processed local files have no attributes which
* would require special privileges. But already their existence was neither
* denied nor confirmed.
*
* @param image
* The image to inquire.
* @param flag
* Bitfield for control purposes:
* bit0 = reset internal value to 0
* @return
* 1 = Exploration was prevented
* 0 = No such prevention occured
*
* @since 1.5.0
*/
int iso_image_was_blind_attrs(IsoImage *image, int flag);
/**
* Locate a node by its absolute path in the image.
* The IsoImage context defines a maximum permissible name length and a mode
@ -7585,6 +7611,9 @@ int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag);
* bit15= free memory
* @return
* 1 ok
* 2 ok, but it is possible that attributes exist in non-user namespaces
* which could not be explored due to lack of permission.
* @since 1.5.0
* < 0 failure
*
* @since 0.6.14
@ -7608,6 +7637,11 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
* Array of byte lengths for each attribute payload
* @param values
* Array of pointers to the attribute payload bytes
* @param errnos
* Array of integers to return error numbers if encountered at the attempt
* to process the name-value pair at the given array index number:
* 0 = no error , -1 = unknown error
* >0 = errno as of local system calls to set xattr and ACLs
* @param flag
* Bitfield for control purposes
* bit0= do not attach ACLs from an eventual attribute with empty name
@ -7615,12 +7649,24 @@ int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names,
* I.e. those with a name which does not begin by "user."
* bit5= in case of symbolic link: manipulate link target
* bit6= @since 1.1.6
tolerate inappropriate presence or absence of
* tolerate inappropriate presence or absence of
* directory "default" ACL
* bit7= @since 1.5.0
* avoid setting a name value pair if it already exists and
* has the desired value.
* @return
* 1 = ok
* < 0 = error
*
* @since 1.5.0
*/
int iso_local_set_attrs_errno(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values,
int *errnos, int flag);
/**
* Older version of iso_local_set_attrs_errno() without the errnos array.
* All other parameters and the return value have the same meaning.
*
* @since 0.6.14
*/
int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,

View File

@ -153,6 +153,7 @@ iso_image_set_volume_id;
iso_image_tree_clone;
iso_image_unref;
iso_image_update_sizes;
iso_image_was_blind_attrs;
iso_init;
iso_init_with_flag;
iso_interval_reader_destroy;
@ -166,6 +167,7 @@ iso_local_get_attrs;
iso_local_get_perms_wo_acl;
iso_local_set_acl_text;
iso_local_set_attrs;
iso_local_set_attrs_errno;
iso_md5_clone;
iso_md5_compute;
iso_md5_end;