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) 2009 - 2019 Thomas Schmitt
# Copyright (c) 2009 - 2024 Thomas Schmitt
# 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
@ -22,11 +22,12 @@ ACLOCAL_AMFLAGS = -I ./
libisofs_libisofs_la_LDFLAGS = \
-version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) $(LIBLDFLAGS)
# Eventually enabling system adapters for ACL and EA.
# ts A90409: Eventually enabling use of zlib.
# ts B00927: Eventually enabling use of libjte (Jigdo Template Extraction)
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(ZLIB_DEF) \
$(LIBJTE_DEF)
# Enabling system adapters for ACL and EA.
# ts A90409: Enabling use of zlib.
# ts B00927: Enabling use of libjte (Jigdo Template Extraction)
# ts C40713: Enabling system adapter for Linux chattr(1) flags
libisofs_libisofs_la_CFLAGS = $(LIBACL_DEF) $(XATTR_DEF) $(LFA_DEF) \
$(ZLIB_DEF) $(LIBJTE_DEF)
# ts A90114 : added aaip_0_2.*

View File

@ -286,6 +286,21 @@ XATTR_DEF="$XATTR_DEF $XATTR_ADDON_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
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:
isofs.hb
@ -224,7 +275,7 @@ Registered:
-------------------------------------------------------------------------------
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
makes use of AAIP. Please mail change requests to mailing list
<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
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
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 --------------------------------- */
@ -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
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
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."
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
@return 1 ok
2 ok, no permission to inspect non-user namespaces
@ -601,6 +604,10 @@ ex:;
I.e. those which are not from name space
EXTATTR_NAMESPACE_USER
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
@return >0 ok
<=0 error
@ -705,6 +712,19 @@ ex:;
#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 --------------------------------- */
@ -1094,3 +1114,12 @@ ex:;
#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
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
modify it under the terms of the GNU General Public License version 2
@ -42,6 +42,11 @@
#endif
#endif
#ifdef Libisofs_with_aaip_lfa_flagS
#include <sys/ioctl.h>
#include <linux/fs.h>
#endif
/* ------------------------------ Inquiry --------------------------------- */
@ -50,14 +55,16 @@
Bitfield for control purposes
bit0= inquire availability of ACL
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.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag. If bits are set, th
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types.
bit2= Linux-like file attribute flags adapter is enabled
bit3 - bit7= Reserved for future types.
bit8 and higher: reserved, do not interpret these
*/
int aaip_local_attr_support(int flag)
@ -68,11 +75,21 @@ int aaip_local_attr_support(int flag)
if(flag & 1)
ret|= 1;
#endif
#ifdef Libisofs_with_aaip_xattR
if(flag & 2)
ret|= 2;
#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);
}
@ -260,6 +277,8 @@ static int get_single_attr(char *path, char *name, size_t *value_length,
by "user."
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
@return 1 ok
(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
ssize_t i, num_names= 0;
#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 */
{ret= 1; goto ex;}
@ -349,6 +373,13 @@ ex:;
if(flag & 1)
num_names++;
#endif
#ifdef Libisofs_with_aaip_lfa_flagS
if(!(flag & 64))
num_names++;
#endif
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, &d_acl_text, 1 | (flag & 32));
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,
&acl_len, &acl, (flag & 2));
if(ret <= 0)
@ -415,6 +446,30 @@ ex:;
#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;
ex:;
#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 --------------------------------- */
@ -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 ---------------------------- */
/* --- private --- */

View File

@ -9,7 +9,7 @@
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
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);
/* 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 ------ */
/* 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
bit0= inquire availability of ACL
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.
bit8 and higher: reserved, submit 0
@return
Bitfield corresponding to flag. If bits are set, th
bit0= ACL adapter is enabled
bit1= xattr adapter is enabled
bit2 - bit7= Reserved for future types.
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
*/
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
by "user."
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
@return >0 ok
<=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);
/* 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 ---------------------------- */
/*
@ -515,5 +554,29 @@ int aaip_set_attr_list(char *path, size_t num_attrs, char **names,
size_t *value_lengths, char **values,
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 */

View File

@ -1,6 +1,6 @@
/*
* 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
* 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,
1 | (image->builder_ignore_acl << 1) |
(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)
image->blind_on_local_get_attrs = 1;
if (ret > 0 && aa_string != NULL) {

View File

@ -1,6 +1,6 @@
/*
* 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
* 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;
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;
goto ex;
}
/* Obtain EAs and ACLs ("access" and "default"). ACLs encoded according
to AAIP ACL representation. Clean out st_mode ACL entries.
Obtain Linux style attribute flags.
*/
path = iso_file_source_get_path(src);
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,
&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 == -2)
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,
size_t **value_lengths, char ***values, int flag)
{
int ret;
int ret, lfa;
lfa = (flag & 64) ^ 64;
ret = aaip_get_attr_list(disk_path,
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)
return ISO_AAIP_NO_GET_LOCAL;
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;
}
/*
* @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->builder_ignore_acl = 1;
img->builder_ignore_ea = 1;
img->builder_ignore_lfa_flags = 1;
img->truncate_mode = 1;
img->truncate_length = LIBISOFS_NODE_NAME_MAX;
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_ea = !!(what & 2);
image->builder_ignore_lfa_flags= !(what & 4);
image->builder_take_all_ea = !!(what & 8);
}
@ -637,6 +639,7 @@ int iso_image_get_ignore_aclea(IsoImage *image)
{
return image->builder_ignore_acl |
(image->builder_ignore_ea << 1) |
((!image->builder_ignore_lfa_flags) << 2) |
(image->builder_take_all_ea << 3);
}

View File

@ -145,6 +145,13 @@ struct Iso_Image
*/
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
* 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:
* bit0= ignore ACLs 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."
* @since 1.5.0
* 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
* local filesystem, not only "user."
* @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)
* <0 means failure and must b a valid libisofs error code
* (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);
/**
* 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 ----- */
/**
@ -7806,7 +7860,10 @@ int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names,
* Bitfield corresponding to flag.
* bit0= ACL 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
*
* @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
* 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.
* I.e. those with a name which does not begin by "user."
* bit5= in case of symbolic link: inquire link target
* bit6= obtain Linux-like file attribute flags (chattr) as "isofs.fa"
* bit15= free memory
* @return
* 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);
/**
* 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.
*/
#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) */
#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:
Place new error codes directly above this comment.

View File

@ -384,3 +384,13 @@ iso_zisofs_set_params;
serial_id;
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";
case ISO_CE_REMOVING_ATTR:
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:
return "Unknown error";
}

View File

@ -1,6 +1,6 @@
/*
* 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
* modify it under the terms of the GNU General Public License version 2
@ -2057,6 +2057,7 @@ ex:;
/* @param flag
bit0= delete ACL, too
bit1= delete file attribute flags (isofs.fa), too
*/
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 */
w = 0;
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]);
names[i] = NULL;
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.
* 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 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
* modify it under the terms of the GNU General Public License version 2
@ -1600,10 +1600,10 @@ try_again:
}
} else if (retry == 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) {
iso_msg_submit(t->image->id, ISO_CE_REMOVING_ATTR, 0,
"Removed ACL");
"Removed ACL and attribute flags");
goto try_again;
}
}

View File

@ -2510,3 +2510,103 @@ int iso_nowtime(time_t *now, int flag)
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;
}