New API calls iso_local_get_lfa_flags(), iso_local_set_lfa_flags(), iso_node_get_lfa_flags(), iso_node_set_lfa_flags(), iso_util_decode_lfa_flags(), iso_util_encode_lfa_flags()

This commit is contained in:
Thomas Schmitt 2024-07-16 15:05:11 +02:00
parent 425f5d0fdd
commit d78028fca4
18 changed files with 844 additions and 32 deletions

View File

@ -1,6 +1,6 @@
# Copyright (c) 2007 Vreixo Formoso # Copyright (c) 2007 Vreixo Formoso
# Copyright (c) 2009 - 2019 Thomas Schmitt # Copyright (c) 2009 - 2024 Thomas Schmitt
# Provided under the terms of the GNU General Public License version 2 or later. # Provided under the terms of the GNU General Public License version 2 or later.
# ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4 # ts A90315 : LIBBURNIA_PKGCONFDIR is defined OS specific in acinclude.m4
@ -22,11 +22,12 @@ ACLOCAL_AMFLAGS = -I ./
libisofs_libisofs_la_LDFLAGS = \ libisofs_libisofs_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS) -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS)
# Eventually enabling system adapters for ACL and EA. # Enabling system adapters for ACL and EA.
# ts A90409: Eventually enabling use of zlib. # ts A90409: Enabling use of zlib.
# ts B00927: Eventually enabling use of libjte (Jigdo Template Extraction) # ts B00927: Enabling use of libjte (Jigdo Template Extraction)
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(ZLIB_DEF) \ # ts C40713: Enabling system adapter for Linux chattr(1) flags
$(LIBJTE_DEF) libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(LFA_DEF) \
$(ZLIB_DEF) $(LIBJTE_DEF)
# ts A90114 : added aaip_0_2.* # ts A90114 : added aaip_0_2.*

View File

@ -286,6 +286,21 @@ XATTR_DEF="$XATTR_DEF $XATTR_ADDON_DEF"
AC_SUBST(XATTR_DEF) AC_SUBST(XATTR_DEF)
dnl ts C40713
LFA_DEF=
AC_ARG_ENABLE(linux-attr-flags,
[ --enable-linux-attr-flags Enable processing of Linux chattr(1) flags, default=yes],
, linux_attr_flags=yes)
if test x"$linux_attr_flags" = xyes; then
AC_CHECK_HEADER(linux/fs.h, LFA_DEF="-DLibisofs_with_aaip_lfa_flagS",
LFA_DEF=)
fi
if test x"$LFA_DEF" = x; then
echo "disabled Linux chattr(1) flags"
else
echo "enabled Linux chattr(1) flags"
fi
AC_SUBST(LFA_DEF)
dnl ts A90409 dnl ts A90409
AC_ARG_ENABLE(zlib, AC_ARG_ENABLE(zlib,

View File

@ -126,6 +126,57 @@ Registered:
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Name:
isofs.fa
Purpose:
Records the file attribute flags as of Linux program chattr(1) and
ioctl(FS_IOC_GETFLAGS) in <linux/fs.h> as bits in a byte string.
Known from Debian GNU/Linux 8 to 12 are:
bit0= FS_SECRM_FL 's' zero blocks on deletion
bit1= FS_UNRM_FL 'u' on delete prepare for undelete
bit2= FS_COMPR_FL 'c' compress
bit3= FS_SYNC_FL 'S' synchronous write
bit4= FS_IMMUTABLE_FL 'i' immutable
bit5= FS_APPEND_FL 'a' appending write only
bit6= FS_NODUMP_FL 'd' dump(8) shall ignore this file
bit7= FS_NOATIME_FL 'A' do not update atime
bit8= FS_DIRTY_FL 'Z' compressed dirty file
bit9= FS_COMPRBLK_FL (? one or more compressed clusters)
bit10= FS_NOCOMP_FL 'm' do not compress
bit11= FS_ECOMPR_FL 'E' compression error (old)
FS_ENCRYPT_FL 'E' encrypted file (new)
bit12= FS_BTREE_FL (? btree format dir)
FS_INDEX_FL 'I' hash-indexed directory ?
bit13= FS_IMAGIC_FL (? AFS directory)
bit14= FS_JOURNAL_DATA_FL 'j' data journalling
bit15= FS_NOTAIL_FL 't' no tail-merging
bit16= FS_DIRSYNC_FL 'D' synchronous directory updates
bit17= FS_TOPDIR_FL 'T' top of directory hierarchy
bit18= FS_HUGE_FILE_FL ('h' huge file ? 'h' old, FS_HUGE_FILE_FL new)
bit19= FS_EXTENT_FL 'e' using extents
bit20= FS_DIRECTIO_FL (? use direct i/o) (old)
FS_VERITY_FL 'V' fs-verity enabled (new)
bit21= FS_EA_INODE_FL (? Inode used for large EA)
bit22= FS_EOFBLOCKS_FL (? reserved for ext4)
bit23= FS_NOCOW_FL 'C' no copy on write
bit25= FS_DAX_FL 'x' direct access
bit28= FS_INLINE_DATA_FL 'N' data stored in inode
bit29= FS_PROJINHERIT_FL 'P' project hierarchy
bit30= FS_CASEFOLD_FL 'F' case-insensitive directory lookups
bit31= FS_RESERVED_FL (? reserved for ext2 lib)
Format of Value:
A byte string which begins with the most significant byte.
Example:
(FS_SECRM_FL|FS_APPEND_FL|FS_NOCOMP_FL) = 0x421
{ 4 , 33 }
Registered:
12 Jul 2024 by Thomas Schmitt for libisofs.
-------------------------------------------------------------------------------
Name: Name:
isofs.hb isofs.hb
@ -224,7 +275,7 @@ Registered:
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
This text is under This text is under
Copyright (c) 2009 - 2015 Thomas Schmitt <scdbackup@gmx.net> Copyright (c) 2009 - 2024 Thomas Schmitt <scdbackup@gmx.net>
It shall only be modified in sync with libisofs and other software which It shall only be modified in sync with libisofs and other software which
makes use of AAIP. Please mail change requests to mailing list makes use of AAIP. Please mail change requests to mailing list
<bug-xorriso@gnu.org> or to the copyright holder in private. <bug-xorriso@gnu.org> or to the copyright holder in private.

View File

@ -11,7 +11,7 @@
To be included by aaip_0_2.c To be included by aaip_0_2.c
Copyright (c) 2009 - 2011 Thomas Schmitt Copyright (c) 2009 - 2024 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
@ -82,6 +82,19 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
} }
/* Obtain the file attribute flags of the given file as bit array in uint64_t.
The bit numbers are compatible to the FS_*_FL definitions in Linux.
*/
int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag)
{
*lfa_flags= 0;
*max_bit= -1;
*os_errno= 0;
return(0);
}
/* ------------------------------ Setters --------------------------------- */ /* ------------------------------ Setters --------------------------------- */
@ -134,3 +147,11 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
} }
int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
int *os_errno, int flag)
{
*os_errno= 0;
return(0);
}

View File

@ -7,7 +7,7 @@
To be included by aaip_0_2.c for FreeBSD, NetBSD, and OpenBSD To be included by aaip_0_2.c for FreeBSD, NetBSD, and OpenBSD
Copyright (c) 2009 - 2016 Thomas Schmitt Copyright (c) 2009 - 2024 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
@ -388,6 +388,9 @@ static int get_single_attr(char *path, char *name, size_t *value_length,
by "user." by "user."
bit4= do not return trivial ACL that matches st_mode bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target bit5= in case of symbolic link: inquire link target
bit6= do not obtain Linux style file attribute flags
(chattr).
This obtaining is not implemented here anyways.
bit15= free memory of names, value_lengths, values bit15= free memory of names, value_lengths, values
@return 1 ok @return 1 ok
2 ok, no permission to inspect non-user namespaces 2 ok, no permission to inspect non-user namespaces
@ -601,6 +604,10 @@ ex:;
I.e. those which are not from name space I.e. those which are not from name space
EXTATTR_NAMESPACE_USER EXTATTR_NAMESPACE_USER
bit4= do not return trivial ACL that matches st_mode bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target
bit6= do not obtain Linux style file attribute flags
(chattr).
This obtaining is not implemented here anyways.
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
@ -705,6 +712,19 @@ ex:;
#endif /* Libisofs_old_freebsd_acl_adapteR */ #endif /* Libisofs_old_freebsd_acl_adapteR */
/* Obtain the file attribute flags of the given file as bit array in uint64_t.
The bit numbers are compatible to the FS_*_FL definitions in Linux.
*/
int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag)
{
*lfa_flags= 0;
*max_bit= -1;
*os_errno= 0;
return(0);
}
/* ------------------------------ Setters --------------------------------- */ /* ------------------------------ Setters --------------------------------- */
@ -1094,3 +1114,12 @@ ex:;
#endif /* Libisofs_old_freebsd_acl_adapteR */ #endif /* Libisofs_old_freebsd_acl_adapteR */
int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
int *os_errno, int flag)
{
*os_errno= 0;
return(0);
}

View File

@ -7,7 +7,7 @@
To be included by aaip_0_2.c for Linux To be included by aaip_0_2.c for Linux
Copyright (c) 2009 - 2022 Thomas Schmitt Copyright (c) 2009 - 2024 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
@ -42,6 +42,11 @@
#endif #endif
#endif #endif
#ifdef Libisofs_with_aaip_lfa_flagS
#include <sys/ioctl.h>
#include <linux/fs.h>
#endif
/* ------------------------------ Inquiry --------------------------------- */ /* ------------------------------ Inquiry --------------------------------- */
@ -50,14 +55,16 @@
Bitfield for control purposes Bitfield for control purposes
bit0= inquire availability of ACL bit0= inquire availability of ACL
bit1= inquire availability of xattr bit1= inquire availability of xattr
bit2 - bit7= Reserved for future types. bit2= inquire availability of Linux-like file attribute flags
bit3 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now. It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0 bit8 and higher: reserved, submit 0
@return @return
Bitfield corresponding to flag. If bits are set, th Bitfield corresponding to flag. If bits are set, th
bit0= ACL adapter is enabled bit0= ACL adapter is enabled
bit1= xattr adapter is enabled bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types. bit2= Linux-like file attribute flags adapter is enabled
bit3 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these bit8 and higher: reserved, do not interpret these
*/ */
int aaip_local_attr_support(int flag) int aaip_local_attr_support(int flag)
@ -68,11 +75,21 @@ int aaip_local_attr_support(int flag)
if(flag & 1) if(flag & 1)
ret|= 1; ret|= 1;
#endif #endif
#ifdef Libisofs_with_aaip_xattR #ifdef Libisofs_with_aaip_xattR
if(flag & 2) if(flag & 2)
ret|= 2; ret|= 2;
#endif #endif
#ifdef Libisofs_with_aaip_lfa_flagS
#ifdef FS_IOC_GETFLAGS
#ifdef FS_IOC_SETFLAGS
if(flag & 4)
ret|= 4;
#endif
#endif
#endif
return(ret); return(ret);
} }
@ -260,6 +277,8 @@ static int get_single_attr(char *path, char *name, size_t *value_length,
by "user." by "user."
bit4= do not return trivial ACL that matches st_mode bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target bit5= in case of symbolic link: inquire link target
bit6= do not obtain Linux style file attribute flags
(chattr)
bit15= free memory of names, value_lengths, values bit15= free memory of names, value_lengths, values
@return 1 ok @return 1 ok
(reserved for FreeBSD: 2 ok, no permission to inspect (reserved for FreeBSD: 2 ok, no permission to inspect
@ -288,6 +307,11 @@ int aaip_get_attr_list(char *path, size_t *num_attrs, char ***names,
#ifdef Libisofs_aaip_get_attr_activE #ifdef Libisofs_aaip_get_attr_activE
ssize_t i, num_names= 0; ssize_t i, num_names= 0;
#endif #endif
#ifdef Libisofs_with_aaip_lfa_flagS
uint64_t lfa_flags;
int max_bit, os_errno, lfa_length;
unsigned char lfa_value[8];
#endif
if(flag & (1 << 15)) { /* Free memory */ if(flag & (1 << 15)) { /* Free memory */
{ret= 1; goto ex;} {ret= 1; goto ex;}
@ -349,6 +373,13 @@ ex:;
if(flag & 1) if(flag & 1)
num_names++; num_names++;
#endif
#ifdef Libisofs_with_aaip_lfa_flagS
if(!(flag & 64))
num_names++;
#endif #endif
if(num_names == 0) if(num_names == 0)
@ -397,7 +428,7 @@ ex:;
aaip_get_acl_text(path, &a_acl_text, flag & (16 | 32)); aaip_get_acl_text(path, &a_acl_text, flag & (16 | 32));
aaip_get_acl_text(path, &d_acl_text, 1 | (flag & 32)); aaip_get_acl_text(path, &d_acl_text, 1 | (flag & 32));
if(a_acl_text == NULL && d_acl_text == NULL) if(a_acl_text == NULL && d_acl_text == NULL)
{ret= 1; goto ex;} goto try_lfa_flags;
ret= aaip_encode_both_acl(a_acl_text, d_acl_text, (mode_t) 0, ret= aaip_encode_both_acl(a_acl_text, d_acl_text, (mode_t) 0,
&acl_len, &acl, (flag & 2)); &acl_len, &acl, (flag & 2));
if(ret <= 0) if(ret <= 0)
@ -415,6 +446,30 @@ ex:;
#endif /* Libisofs_with_aaip_acL */ #endif /* Libisofs_with_aaip_acL */
try_lfa_flags:;
#ifdef Libisofs_with_aaip_lfa_flagS
if(!(flag & 64)) {
ret= aaip_get_lfa_flags(path, &lfa_flags, &max_bit, &os_errno, 0);
if(ret > 0) {
ret= aaip_encode_lfa_flags(lfa_flags, lfa_value, &lfa_length, 0);
if(ret > 0) {
(*names)[*num_attrs]= strdup("isofs.fa");
if((*names)[*num_attrs] == NULL)
{ret= -1; goto ex;}
(*values)[*num_attrs]= calloc(lfa_length, 1);
if((*values)[*num_attrs] == NULL)
{ret= -1; goto ex;}
memcpy((*values)[*num_attrs], (char *) lfa_value, lfa_length);
(*value_lengths)[*num_attrs]= lfa_length;
(*num_attrs)++;
}
}
}
#endif /* Libisofs_with_aaip_lfa_flagS */
ret= 1; ret= 1;
ex:; ex:;
#ifdef Libisofs_with_aaip_acL #ifdef Libisofs_with_aaip_acL
@ -455,6 +510,69 @@ ex:;
} }
/* Obtain the file attribute flags of the given file as bit array in uint64_t.
The bit numbers are compatible to the FS_*_FL definitions in Linux
include file <linux/fs.h>. A (possibly outdated) copy of them is in
doc/susp_aaip_isofs_names.txt, name isofs.fa .
The attribute flags of other systems may or may not be mappable to these
flags.
@param path Path to the file
@param lfa_flags Will get filled with the FS_*_FL
@param max_bit Will tell the highest bit that is possibly set
(-1 = surely no bit is valid)
@param flag Bitfield for control purposes. Submit 0.
@return 1= ok, all local attribute flags are in lfa_flags
2= ok, but some local flags could not be mapped to
the FS_*_FL bits
0= local flag retrieval not enabled at compile time
<0 error with system calls
*/
int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag)
{
int ret= 0;
#ifdef Libisofs_with_aaip_lfa_flagS
int fd;
long ioctl_result= 0;
#endif
*lfa_flags= 0;
*max_bit= -1;
*os_errno= 0;
#ifdef Libisofs_with_aaip_lfa_flagS
#ifdef FS_IOC_GETFLAGS
fd= open(path, O_RDONLY | O_NDELAY);
if(fd == -1) {
aaip_local_error("open", path, errno, 0);
*os_errno= errno;
return(-1);
}
ret= ioctl(fd, FS_IOC_GETFLAGS, &ioctl_result);
close(fd);
if(ret == -1) {
aaip_local_error("ioctl(FS_IOC_GETFLAGS)", path, errno, 0);
*os_errno= errno;
return(-1);
}
*lfa_flags= ioctl_result;
if(*lfa_flags < 1 << 24)
*max_bit= 23;
else if(*lfa_flags < (uint64_t) 1 << 32)
*max_bit= 31;
else
*max_bit= sizeof(long) * 8 - 1;
ret= 1;
#endif /* FS_IOC_GETFLAGS */
#endif /* Libisofs_with_aaip_lfa_flagS */
return(ret);
}
/* ------------------------------ Setters --------------------------------- */ /* ------------------------------ Setters --------------------------------- */
@ -749,3 +867,49 @@ ex:;
} }
int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
int *os_errno, int flag)
{
int ret= 0;
#ifdef Libisofs_with_aaip_lfa_flagS
int fd;
long ioctl_arg;
#endif
*os_errno= 0;
#ifdef Libisofs_with_aaip_lfa_flagS
#ifdef FS_IOC_GETFLAGS
if(max_bit > (int) sizeof(long) * 8 - 1) {
aaip_local_error("ioctl(FS_IOC_SETFLAGS) with too many bits", path, 0, 0);
return(-1);
}
fd= open(path, O_RDONLY | O_NDELAY);
if(fd == -1) {
aaip_local_error("open", path, errno, 0);
*os_errno= errno;
return(-1);
}
if(max_bit < 0)
ioctl_arg= 0;
else
ioctl_arg= lfa_flags;
ret= ioctl(fd, FS_IOC_SETFLAGS, ioctl_arg);
close(fd);
if(ret == -1) {
aaip_local_error("ioctl(FS_IOC_SETFLAGS)", path, errno, 0);
*os_errno= errno;
return(-1);
}
ret= 1;
#endif /* FS_IOC_GETFLAGS */
#endif /* Libisofs_with_aaip_lfa_flagS */
return(ret);
}

View File

@ -900,6 +900,26 @@ int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag)
} }
int aaip_encode_lfa_flags(uint64_t lfa_flags, unsigned char value[8],
int *length, int flag)
{
int i, l;
*length = 1;
value[0] = 0;
/* How many bytes are needed to catch all set bits ? Minimum is 1. */
l= 8;
for(i= 1; i < l; i++)
if(lfa_flags < (uint64_t) 1 << (i * 8))
break;
*length= i;
for(i= 0; i < *length; i++)
value[*length - 1 - i]= (lfa_flags >> (8 * i)) & 0xff;
return(1);
}
/* --------------------------------- Decoder ---------------------------- */ /* --------------------------------- Decoder ---------------------------- */
/* --- private --- */ /* --- private --- */

View File

@ -9,7 +9,7 @@
test/aaip_0_2.h - Public declarations test/aaip_0_2.h - Public declarations
Copyright (c) 2009 - 2016 Thomas Schmitt Copyright (c) 2009 - 2024 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
@ -155,6 +155,17 @@ int aaip_cleanout_st_mode(char *acl_text, mode_t *st_mode, int flag);
int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag); int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag);
/* Encode a Linux style file attribute flag bits array to a byte string
which represents the flags bits in isofs.fa .
@param lfa_flags Bit array as obtained by aaip_get_lfa_flags()
@param value Will be filled with 1 to 8 byte values
@param length Will return the number of filled-in value bytes
@return <0 failure
*/
int aaip_encode_lfa_flags(uint64_t lfa_flags, unsigned char value[8],
int *length, int flag);
/* ------ OS interface ------ */ /* ------ OS interface ------ */
/* See also API iso_local_attr_support(). /* See also API iso_local_attr_support().
@ -162,14 +173,17 @@ int aaip_add_acl_st_mode(char *acl_text, mode_t st_mode, int flag);
Bitfield for control purposes Bitfield for control purposes
bit0= inquire availability of ACL bit0= inquire availability of ACL
bit1= inquire availability of xattr bit1= inquire availability of xattr
bit2 - bit7= Reserved for future types. bit2= inquire availability of Linux-like file attribute flags
bit3 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now. It is permissibile to set them to 1 already now.
bit8 and higher: reserved, submit 0 bit8 and higher: reserved, submit 0
@return @return
Bitfield corresponding to flag. If bits are set, th Bitfield corresponding to flag. If bits are set, th
bit0= ACL adapter is enabled bit0= ACL adapter is enabled
bit1= xattr adapter is enabled bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types. bit2= Linux-like file attribute flags adapter is enabled
bit3 - bit7= Reserved for future types.
It is permissibile to set them to 1 already now.
bit8 and higher: reserved, do not interpret these bit8 and higher: reserved, do not interpret these
*/ */
int aaip_local_attr_support(int flag); int aaip_local_attr_support(int flag);
@ -210,6 +224,9 @@ int aaip_get_acl_text(char *path, char **text, int flag);
I.e. those with a name which does not begin I.e. those with a name which does not begin
by "user." by "user."
bit4= do not return trivial ACL that matches st_mode bit4= do not return trivial ACL that matches st_mode
bit5= in case of symbolic link: inquire link target
bit6= do not obtain Linux style file attribute flags
(chattr)
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
@ -218,6 +235,28 @@ 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);
/* Obtain the file attribute flags of the given file as bit array in uint64_t.
The bit numbers are compatible to the FS_*_FL definitions in Linux
include file <linux/fs.h>. A (possibly outdated) copy of them is in
doc/susp_aaip_isofs_names.txt, name isofs.fa .
The attribute flags of other systems may or may not be mappable to these
flags.
@param path Path to the file
@param lfa_flags Will get filled with the FS_*_FL
@param max_bit Will tell the highest bit that is possibly set
(-1 = surely no bit is valid)
@param os_errno Will get filled with errno if a system call fails
@param flag Bitfield for control purposes. Submit 0.
@return 1= ok, all local attribute flags are in lfa_flags
2= ok, but some local flags could not be mapped to
the FS_*_FL bits
0= local flags retrieval not enabled at compile time
<0 error with system calls
*/
int aaip_get_lfa_flags(char *path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag);
/* --------------------------------- Decoder ---------------------------- */ /* --------------------------------- Decoder ---------------------------- */
/* /*
@ -515,5 +554,29 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, size_t *value_lengths, char **values,
int *errnos, int flag); int *errnos, int flag);
/* Bring the given file attribute flags into effect with the given file.
The bit numbers are compatible to the FS_*_FL definitions in Linux
include file <linux/fs.h>. A (possibly outdated) copy of them is in
doc/susp_aaip_isofs_names.txt, name isofs.fa .
The attribute flags of other systems may or may not be mappable to these
flags.
@param path Path to the file
@param lfa_flags File attribute flag bits
@param max_bit Gives an upper limit of the highest set flag bit.
(-1 = surely no bit is valid)
On Linux this must be smaller than sizeof(long) * 8.
@param os_errno Will get filled with errno if a system call fails
@param flag Bitfield for control purposes. Submit 0.
@return 1= ok, all lfa_flags bits were written
2= ok, but some FS_*_FL bits could not be mapped to
local flags
0= local flags setting not enabled at compile time
<0 error with system calls or with max_bit
*/
int aaip_set_lfa_flags(char *path, uint64_t lfa_flags, int max_bit,
int *os_errno, int flag);
#endif /* ! Aaip_h_is_includeD */ #endif /* ! Aaip_h_is_includeD */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2015 Thomas Schmitt * Copyright (c) 2009 - 2024 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
@ -253,7 +253,8 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
ret = iso_file_source_get_aa_string(src, &aa_string, ret = iso_file_source_get_aa_string(src, &aa_string,
1 | (image->builder_ignore_acl << 1) | 1 | (image->builder_ignore_acl << 1) |
(image->builder_ignore_ea << 2) | (image->builder_ignore_ea << 2) |
(image->builder_take_all_ea << 3)); (image->builder_take_all_ea << 3) |
((!image->builder_ignore_lfa_flags) << 4));
if(ret == 2) if(ret == 2)
image->blind_on_local_get_attrs = 1; image->blind_on_local_get_attrs = 1;
if (ret > 0 && aa_string != NULL) { if (ret > 0 && aa_string != NULL) {

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2017 Thomas Schmitt * Copyright (c) 2009 - 2024 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
@ -507,12 +507,14 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
*aa_string = NULL; *aa_string = NULL;
if ((flag & 6 ) == 6) { /* Neither ACL nor xattr shall be read */ if ((flag & (2 | 4 | 16) ) == (2 | 4)) {
/* Neither ACL nor xattr shall be read, lfa_flags are not wanted */
ret = 1; ret = 1;
goto ex; goto ex;
} }
/* Obtain EAs and ACLs ("access" and "default"). ACLs encoded according /* Obtain EAs and ACLs ("access" and "default"). ACLs encoded according
to AAIP ACL representation. Clean out st_mode ACL entries. to AAIP ACL representation. Clean out st_mode ACL entries.
Obtain Linux style attribute flags.
*/ */
path = iso_file_source_get_path(src); path = iso_file_source_get_path(src);
if (path == NULL) { if (path == NULL) {
@ -521,7 +523,8 @@ int lfs_get_aa_string(IsoFileSource *src, unsigned char **aa_string, int flag)
} }
ret = aaip_get_attr_list(path, &num_attrs, &names, ret = aaip_get_attr_list(path, &num_attrs, &names,
&value_lengths, &values, &value_lengths, &values,
(!(flag & 2)) | 2 | (flag & 4) | (flag & 8) | 16); (!(flag & 2)) | 2 | (flag & 4) | (flag & 8) | 16 |
((!(flag & 16)) << 6));
if (ret <= 0) { if (ret <= 0) {
if (ret == -2) if (ret == -2)
ret = ISO_AAIP_NO_GET_LOCAL; ret = ISO_AAIP_NO_GET_LOCAL;
@ -863,11 +866,13 @@ int iso_local_set_acl_text(char *disk_path, char *text, int flag)
int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names, int iso_local_get_attrs(char *disk_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, lfa;
lfa = (flag & 64) ^ 64;
ret = aaip_get_attr_list(disk_path, ret = aaip_get_attr_list(disk_path,
num_attrs, names, value_lengths, values, num_attrs, names, value_lengths, values,
(flag & (1 | 4 | 8 | 32 | (1 << 15))) | 2 | 16); (flag & (1 | 4 | 8 | 32 | (1 << 15))) |
2 | 16 | lfa);
if (ret <= 0) if (ret <= 0)
return ISO_AAIP_NO_GET_LOCAL; return ISO_AAIP_NO_GET_LOCAL;
return 1 + (ret == 2); return 1 + (ret == 2);
@ -940,3 +945,90 @@ int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag)
return 1; return 1;
} }
/*
* @param flag
* Bitfield for control purposes
* bit5= in case of symbolic link: inquire link target
* @return
* 1= ok, lfa_flags is valid
* 2= ok, but some local flags could not be mapped to the FS_*_FL bits
* 3= ok, symbolic link encountered, flag bit5 not set, lfa_flags set to 0
* 0= local flags retrieval not enabled at compile time
* <0= error with system calls
*/
int iso_local_get_lfa_flags(char *disk_path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag)
{
int ret;
struct stat stbuf;
*lfa_flags = 0;
*max_bit = -1;
*os_errno = 0;
if (flag & 32)
ret = stat(disk_path, &stbuf);
else
ret = lstat(disk_path, &stbuf);
if (ret == -1) {
*os_errno = errno;
return -1;
}
if ((stbuf.st_mode & S_IFMT) == S_IFLNK && !(flag & 32))
return 3;
ret= aaip_get_lfa_flags(disk_path, lfa_flags, max_bit, os_errno, 0);
if(ret == 0)
return ISO_AAIP_NOT_ENABLED;
if (ret < 0)
return ISO_AAIP_NO_GET_LOCAL;
return ret;
}
/*
* @param flag Bitfield for control purposes
* bit0= do not try to set known superuser flags
* bit1= set only known chattr settable flags
* bit5= in case of symbolic link: inquire link target
* @return
* 1 = ok, all lfa_flags bits were written
* 2 = ok, but some FS_*_FL bits could not be mapped to local flags
* 3 = ok, symbolic link encountered, flag bit5 not set, nothing done
* <0 = error
*/
int iso_local_set_lfa_flags(char *disk_path, uint64_t lfa_flags, int max_bit,
int *os_errno, int flag)
{
int ret;
struct stat stbuf;
/* chattr letters: User: sucSdAmtDTCxPF
Superuser: iaj
Non-settable: Z(9)EI(13)heV(21)(22)N(31)
*/
static uint64_t known_user_mask = 0x628384cf;
static uint64_t known_su_mask = 0x00004030;
*os_errno = 0;
if (flag & 32)
ret = stat(disk_path, &stbuf);
else
ret = lstat(disk_path, &stbuf);
if (ret == -1) {
*os_errno = errno;
return -1;
}
if ((stbuf.st_mode & S_IFMT) == S_IFLNK && !(flag & 32))
return 3;
if (flag & 1)
lfa_flags &= ~known_su_mask;
if (flag & 2)
lfa_flags &= known_user_mask | known_su_mask;
ret= aaip_set_lfa_flags(disk_path, lfa_flags, max_bit, os_errno, 0);
if(ret == 0)
return ISO_AAIP_NOT_ENABLED;
if(ret < 0)
return ISO_AAIP_NO_SET_LOCAL;
return ret;
}

View File

@ -200,6 +200,7 @@ int iso_image_new(const char *name, IsoImage **image)
img->import_src = NULL; img->import_src = NULL;
img->builder_ignore_acl = 1; img->builder_ignore_acl = 1;
img->builder_ignore_ea = 1; img->builder_ignore_ea = 1;
img->builder_ignore_lfa_flags = 1;
img->truncate_mode = 1; img->truncate_mode = 1;
img->truncate_length = LIBISOFS_NODE_NAME_MAX; img->truncate_length = LIBISOFS_NODE_NAME_MAX;
img->truncate_buffer[0] = 0; img->truncate_buffer[0] = 0;
@ -629,6 +630,7 @@ void iso_image_set_ignore_aclea(IsoImage *image, int what)
{ {
image->builder_ignore_acl = (what & 1); image->builder_ignore_acl = (what & 1);
image->builder_ignore_ea = !!(what & 2); image->builder_ignore_ea = !!(what & 2);
image->builder_ignore_lfa_flags= !(what & 4);
image->builder_take_all_ea = !!(what & 8); image->builder_take_all_ea = !!(what & 8);
} }
@ -637,6 +639,7 @@ int iso_image_get_ignore_aclea(IsoImage *image)
{ {
return image->builder_ignore_acl | return image->builder_ignore_acl |
(image->builder_ignore_ea << 1) | (image->builder_ignore_ea << 1) |
((!image->builder_ignore_lfa_flags) << 2) |
(image->builder_take_all_ea << 3); (image->builder_take_all_ea << 3);
} }

View File

@ -145,6 +145,13 @@ struct Iso_Image
*/ */
unsigned int builder_ignore_ea : 1; unsigned int builder_ignore_ea : 1;
/**
* Whether to ignore Linux style file attribute flags (chattr).
* Not in effect with loading a complete ISO image but only with image
* manipulation.
*/
unsigned int builder_ignore_lfa_flags : 1;
/** /**
* If not builder_ignore_ea : import all xattr namespaces from local * If not builder_ignore_ea : import all xattr namespaces from local
* filesystem, not only "user. * filesystem, not only "user.

View File

@ -1307,6 +1307,10 @@ int iso_image_new(const char *name, IsoImage **image);
* A bit field which sets the behavior: * A bit field which sets the behavior:
* bit0= ignore ACLs if the external file object bears some * bit0= ignore ACLs if the external file object bears some
* bit1= ignore xattr if the external file object bears some * bit1= ignore xattr if the external file object bears some
* bit2= read Linux-like file attribute flags (chattr)
* if the external file object bears some.
* (I.e. a do-not-ignore, because ignoring was default before)
* @since 1.5.8
* bit3= if not bit1: import all xattr namespaces, not only "user." * bit3= if not bit1: import all xattr namespaces, not only "user."
* @since 1.5.0 * @since 1.5.0
* all other bits are reserved * all other bits are reserved
@ -7263,6 +7267,9 @@ int iso_file_source_readlink(IsoFileSource *src, char *buf, size_t bufsiz);
* bit3= if not bit2: import all xattr namespaces from * bit3= if not bit2: import all xattr namespaces from
* local filesystem, not only "user." * local filesystem, not only "user."
* @since 1.5.0 * @since 1.5.0
* bit4= Try to get Linux-like file attribute flags (chattr)
* as "isofs.fa"
* @since 1.5.8
* @return 1 means success (*aa_string == NULL is possible) * @return 1 means success (*aa_string == NULL is possible)
* <0 means failure and must b a valid libisofs error code * <0 means failure and must b a valid libisofs error code
* (e.g. ISO_FILE_ERROR if no better one can be found). * (e.g. ISO_FILE_ERROR if no better one can be found).
@ -7780,6 +7787,53 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag); size_t *value_lengths, char **values, int flag);
/**
* Obtain the Linux-like file attribute flags (chattr) as bit array.
* The bit numbers are compatible to the FS_*_FL definitions in Linux
* include file <linux/fs.h>. A (possibly outdated) copy of them is in
* doc/susp_aaip_isofs_names.txt, name isofs.fa .
*
* @param node
* The node that is to be inquired.
* @param lfa_flags
* Will get filled with the FS_*_FL bits
* @param max_bit
* Will tell the highest bit that is possibly set
* (-1 = surely no bit is valid)
* @param flag
* Bitfield for control purposes. Submit 0.
* @return
* 1 = ok, lfa_flags and max_bit are valid
* 0 = no Linux-like file attributes are associated with the node
* < 0 = error
*
* @since 1.5.8
*/
int iso_node_get_lfa_flags(IsoNode *node, uint64_t *lfa_flags, int *max_bit,
int flag);
/**
* Set the Linux-like file attribute flags (chattr) which are associated with
* the node.
* The bit numbers are compatible to the FS_*_FL definitions in Linux
* include file <linux/fs.h>. A (possibly outdated) copy of them is in
* doc/susp_aaip_isofs_names.txt, name isofs.fa .
*
* @param node
* The node that is to be manipulated.
* @param lfa_flags
* File attribute flag bits
* @param flag
* Bitfield for control purposes. Submit 0.
* @return
* 1 = ok
* < 0 = error
*
* @since 1.5.8
*/
int iso_node_set_lfa_flags(IsoNode *node, uint64_t lfa_flags, int flag);
/* ----- This is an interface to ACL and xattr of the local filesystem ----- */ /* ----- This is an interface to ACL and xattr of the local filesystem ----- */
/** /**
@ -7806,7 +7860,10 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
* Bitfield corresponding to flag. * Bitfield corresponding to flag.
* bit0= ACL adapter is enabled * bit0= ACL adapter is enabled
* bit1= xattr adapter is enabled * bit1= xattr adapter is enabled
* bit2 - bit7= Reserved for future types. * bit2= Linux-like file attribute flags (chattr) adapter is enabled
* @since 1.5.8
* bit3 - bit7= Reserved for future types.
* It is permissibile to set them to 1 already now.
* bit8 and higher: reserved, do not interpret these * bit8 and higher: reserved, do not interpret these
* *
* @since 1.1.6 * @since 1.1.6
@ -7888,7 +7945,8 @@ int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag);
/** /**
* Get xattr and non-trivial ACLs of the given file in the local filesystem. * Get xattr, non-trivial ACLs, and possible Linux-like file attribute flags
* (chattr) of the given file in the local filesystem.
* The resulting data has finally to be disposed by a call to this function * The resulting data has finally to be disposed by a call to this function
* with flag bit15 set. * with flag bit15 set.
* *
@ -7913,6 +7971,7 @@ int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag);
* bit3= do not ignore non-user attributes. * bit3= do not ignore 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: inquire link target * bit5= in case of symbolic link: inquire link target
* bit6= obtain Linux-like file attribute flags (chattr) as "isofs.fa"
* bit15= free memory * bit15= free memory
* @return * @return
* 1 ok * 1 ok
@ -7978,6 +8037,121 @@ int iso_local_set_attrs(char *disk_path, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag); size_t *value_lengths, char **values, int flag);
/**
* Obtain the Linux-like file attribute flags (chattr) of the given file as
* bit array.
* The bit numbers are compatible to the FS_*_FL definitions in Linux
* include file <linux/fs.h>. A (possibly outdated) copy of them is in
* doc/susp_aaip_isofs_names.txt, name isofs.fa .
* The attribute flags of other systems may or may not be mappable to these
* flags.
* @param disk_path
* Path to the file
* @param lfa_flags
* Will get filled with the FS_*_FL bits
* @param max_bit
* Will tell the highest bit that is possibly set
* (-1 = surely no bit is valid)
* @param os_errno
* Will get filled with errno if a system call fails.
* Else it will be filled with 0.
* @param flag
* Bitfield for control purposes
* bit5= in case of symbolic link: inquire link target
* @return
* 1 = ok, lfa_flags is valid
* 2 = ok, but some local flags could not be mapped to the FS_*_FL bits
* 3 = ok, symbolic link encountered, flag bit5 not set,lfa_flags set to 0
* <0 = error
*
* @since 1.5.8
*/
int iso_local_get_lfa_flags(char *disk_path, uint64_t *lfa_flags, int *max_bit,
int *os_errno, int flag);
/**
* Bring the given Linux-like file attribute flags (chattr) into effect with
* the given file.
* The bit numbers are compatible to the FS_*_FL definitions in Linux
* include file <linux/fs.h>. A (possibly outdated) copy of them is in
* doc/susp_aaip_isofs_names.txt, name isofs.fa .
* The attribute flags of other systems may or may not be mappable to these
* flags.
* @param disk_path
* Path to the file
* @param lfa_flags
* File attribute flag bits
* @param max_bit
* Gives an upper limit of the highest possibly set flag bit.
* (-1 = surely no bit is valid)
* On Linux this must be smaller than sizeof(long) * 8.
* @param os_errno
* Will get filled with errno if a system call fails.
* Else it will be filled with 0.
* @param flag
* Bitfield for control purposes
* bit0= do not try to set known chattr superuser flags: iaj
* bit1= set only known chattr settable flags: sucSiadAmjtDTCxPF
* bit5= in case of symbolic link: operate on link target
* @return
* 1 = ok, all lfa_flags bits were written
* 2 = ok, but some FS_*_FL bits could not be mapped to local flags
* 3 = ok, symbolic link encountered, flag bit5 not set, nothing done
* <0 = error
*
* @since 1.5.8
*/
int iso_local_set_lfa_flags(char *disk_path, uint64_t lfa_flags, int max_bit,
int *os_errno, int flag);
/**
* Convert the known set bits of the given Linux-like file attribute flags
* to a string of flag letters like expected by chattr(1).
*
* @param lfa_flags
* File attribute flag bits to be converted
* @param flags_text
* Will return the string of known set flag letters.
* If it is not returned as NULL, then submit it to free(2) when
* no longer needed.
* @param flag
* Bitfield for control purposes.
* bit0= produce lsattr(1) format with '-' and peculiar sequence
* (This might be more prone to ISO_LFA_UNKNOWN_BIT.
* Some versions of lsattr showed less bits. Maybe newer versions
* will show more bits.)
* @return
* >0 = success
* <0 = error
* ISO_LFA_UNKNOWN_BIT indicates a partial result in flags_text
*
* @since 1.5.8
*/
int iso_util_encode_lfa_flags(uint64_t lfa_flags, char **flags_text, int flag);
/**
* Convert the given string of flag letters to a bit array usable by
* iso_*_set_lfa_flags(). The letters are as expected by chattr(1) or shown
* by lsattr(1).
*
* @param flags_text
* The string of flag letters to be converted
* @param lfa_flags
* Will return the resultig file attribute flag bits
* @param flag
* Bitfield for control purposes. Submit 0.
* @return
* >0 = success
* <0 = error
*
* @since 1.5.8
*/
int iso_util_decode_lfa_flags(char *flags_text, uint64_t *lfa_flags, int flag);
/* Default in case that the compile environment has no macro PATH_MAX. /* Default in case that the compile environment has no macro PATH_MAX.
*/ */
#define Libisofs_default_path_maX 4096 #define Libisofs_default_path_maX 4096
@ -9460,6 +9634,14 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
(WARNING,HIGH, -429) */ (WARNING,HIGH, -429) */
#define ISO_CE_REMOVING_ATTR 0xD030FE53 #define ISO_CE_REMOVING_ATTR 0xD030FE53
/** Unknown Linux-like chattr letter encountered during conversion
(WARNING,HIGH, -430) */
#define ISO_LFA_UNKNOWN_LETTER 0xD030FE52
/** Unknown Linux-like file attribute flag bit encountered during conversion
(WARNING,HIGH, -431) */
#define ISO_LFA_UNKNOWN_BIT 0xD030FE51
/* Internal developer note: /* Internal developer note:
Place new error codes directly above this comment. Place new error codes directly above this comment.

View File

@ -384,3 +384,13 @@ iso_zisofs_set_params;
serial_id; serial_id;
local: *; local: *;
}; };
LIBISOFS6_1.5.8 {
iso_local_get_lfa_flags;
iso_local_set_lfa_flags;
iso_node_get_lfa_flags;
iso_node_set_lfa_flags;
iso_util_decode_lfa_flags;
iso_util_encode_lfa_flags;
} LIBISOFS6;

View File

@ -573,6 +573,10 @@ const char *iso_error_to_msg(int errcode)
return "Too many CE entries for single file when mounted by Linux"; return "Too many CE entries for single file when mounted by Linux";
case ISO_CE_REMOVING_ATTR: case ISO_CE_REMOVING_ATTR:
return "Too many CE entries for single file, removing attributes"; return "Too many CE entries for single file, removing attributes";
case ISO_LFA_UNKNOWN_LETTER:
return "Unknown Linux-like chattr letter encountered during conversion";
case ISO_LFA_UNKNOWN_BIT:
return "Unknown Linux-like file attribute flag bit encountered during conversion";
default: default:
return "Unknown error"; return "Unknown error";
} }

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2007 Vreixo Formoso * Copyright (c) 2007 Vreixo Formoso
* Copyright (c) 2009 - 2023 Thomas Schmitt * Copyright (c) 2009 - 2024 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
@ -2057,6 +2057,7 @@ ex:;
/* @param flag /* @param flag
bit0= delete ACL, too bit0= delete ACL, too
bit1= delete file attribute flags (isofs.fa), too
*/ */
int iso_node_remove_fattr(IsoNode *node, int flag) int iso_node_remove_fattr(IsoNode *node, int flag)
{ {
@ -2072,7 +2073,8 @@ int iso_node_remove_fattr(IsoNode *node, int flag)
/* Delete variables of all namespaces except isofs */ /* Delete variables of all namespaces except isofs */
w = 0; w = 0;
for (i = 0; i < num_attrs; i++) { for (i = 0; i < num_attrs; i++) {
if (strncmp(names[i], "isofs.", 6) != 0) { if (strncmp(names[i], "isofs.", 6) != 0 ||
((flag & 2) && strcmp(names[i], "isofs.fa") == 0)) {
free(names[i]); free(names[i]);
names[i] = NULL; names[i] = NULL;
free(values[i]); free(values[i]);
@ -2452,6 +2454,53 @@ ex:;
} }
int iso_node_set_lfa_flags(IsoNode *node, uint64_t lfa_flags, int flag)
{
static char *names = "isofs.fa";
static size_t value_lengths[1];
unsigned char value[8];
char *valuept;
int ret, l;
ret = aaip_encode_lfa_flags(lfa_flags, value, &l, 0);
if (ret < 0)
return ret;
value_lengths[0] = l;
valuept= (char *) value;
ret = iso_node_set_attrs(node, (size_t) 1,
&names, value_lengths, &valuept, 2 | 8);
return ret;
}
int iso_node_get_lfa_flags(IsoNode *node, uint64_t *lfa_flags, int *max_bit,
int flag)
{
int ret, i;
size_t value_len;
char *value = NULL;
*lfa_flags = 0;
*max_bit = -1;
ret = iso_node_lookup_attr(node, "isofs.fa", &value_len, &value, 0);
if (ret <= 0)
return ret;
if (value_len <= 0) {
*max_bit = 7;
return 1;
}
if (value_len > 8) {
value += value_len - 8;
value_len = 8;
}
for (i = 0; i < (int) value_len; i++)
*lfa_flags = (*lfa_flags << 8) | ((unsigned char *) value)[i];
*max_bit = value_len * 8 - 1;
return 1;
}
/* Function to identify and manage ZF parameters. /* Function to identify and manage ZF parameters.
* data is supposed to be a pointer to struct zisofs_zf_info * data is supposed to be a pointer to struct zisofs_zf_info
*/ */

View File

@ -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) 2009 - 2023 Thomas Schmitt * Copyright (c) 2009 - 2024 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
@ -1600,10 +1600,10 @@ try_again:
} }
} else if (retry == 2) { } else if (retry == 2) {
if ((t->opts->max_ce_drop_attr & 15) >= 2) { if ((t->opts->max_ce_drop_attr & 15) >= 2) {
ret = iso_node_remove_fattr(n->node, 1); ret = iso_node_remove_fattr(n->node, 1 | 2);
if (ret > 0) { if (ret > 0) {
iso_msg_submit(t->image->id, ISO_CE_REMOVING_ATTR, 0, iso_msg_submit(t->image->id, ISO_CE_REMOVING_ATTR, 0,
"Removed ACL"); "Removed ACL and attribute flags");
goto try_again; goto try_again;
} }
} }

View File

@ -2510,3 +2510,103 @@ int iso_nowtime(time_t *now, int flag)
return 2; return 2;
} }
/* Bit sequence as of Linux 6.1.0 <linux/fs.h> FS_*_FL .
Letters as of e2fsprogs 1.47.1, man chattr and lib/pf.c for lsattr(1).
*/
static char lfa_flag_letters[] = { 's', 'u', 'c', 'S', 'i', 'a', 'd', 'A',
'Z', '-', 'm', 'E', 'I', '-', 'j', 't',
'D', 'T', 'h', 'e', 'V', '-', '-', 'C',
'-', 'x', '-', '-', 'N', 'P', 'F', '-' };
/* Sequence and coverage as of e2fsprogs 1.47.1, lib/pf.c for lsattr(1) */
static int lsattr_permutation[] = { 0, 1, 3, 16, 4, 5, 6, 7,
2, 11, 14, 12, 15, 17, 19, 23,
25, 30, 28, 29, 20, 10, -1};
static int num_lsattr_bits = 22;
static int max_lsattr_bit = 30;
static int non_lsattr_bits[] = { 8, 9, 13, 18, 21, 22, 24, 26, 27, -1 };
/* @param flag bit0= produce lsattr format with '-' and peculiar sequence
*/
int iso_util_encode_lfa_flags(uint64_t lfa_flags, char **flags_text, int flag)
{
int i, len = 0, w = 0, was_unknown = 0, pi;
*flags_text = NULL;
if (flag & 1)
goto lsattr_format;
for (i = 0; i < 64; i++)
if (lfa_flags & (((uint64_t) 1) << i))
len++;
*flags_text = calloc(len + 1, 1);
if (*flags_text == NULL)
return ISO_OUT_OF_MEM;
for (i = 0; i < 64; i++) {
if (!(lfa_flags & (((uint64_t) 1) << i)))
continue;
if (lfa_flag_letters[i] == '-') {
was_unknown = 1;
} else {
(*flags_text)[w++] = lfa_flag_letters[i];
}
}
flags_text[w] = 0;
if (was_unknown)
return ISO_LFA_UNKNOWN_BIT;
return ISO_SUCCESS;
lsattr_format:;
*flags_text = calloc(num_lsattr_bits + 1, 1);
if (*flags_text == NULL)
return ISO_OUT_OF_MEM;
for (i = 0; i < num_lsattr_bits; i++) {
pi = lsattr_permutation[i];
if (pi < 0)
break;
if (lfa_flags & (((uint64_t) 1) << pi)) {
(*flags_text)[w++] = lfa_flag_letters[pi];
} else {
(*flags_text)[w++] = '-';
}
}
(*flags_text)[num_lsattr_bits] = 0;
for (i = 0; non_lsattr_bits[i] >= 0; i++)
if (lfa_flags & (((uint64_t) 1) << non_lsattr_bits[i]))
return ISO_LFA_UNKNOWN_BIT;
for (i= max_lsattr_bit + 1; i < 63; i++)
if (lfa_flags & (((uint64_t) 1) << i))
return ISO_LFA_UNKNOWN_BIT;
return ISO_SUCCESS;
}
int iso_util_decode_lfa_flags(char *flags_text, uint64_t *lfa_flags, int flag)
{
int i, j, was_unknown = 0;
*lfa_flags = 0;
for (i = 0; flags_text[i] != 0; i++) {
if (flags_text[i] == '-')
continue;
for (j = 0; j < 64; j++)
if (lfa_flag_letters[j] == flags_text[i])
break;
if (j >= 64) {
was_unknown = 1;
continue;
}
*lfa_flags |= ((uint64_t) 1) << j;
}
if (was_unknown)
return ISO_LFA_UNKNOWN_LETTER;
return 1;
}