diff --git a/xorriso/aux_objects.c b/xorriso/aux_objects.c index ee1e9135..e125c238 100644 --- a/xorriso/aux_objects.c +++ b/xorriso/aux_objects.c @@ -940,15 +940,17 @@ int Linkitem_get_link_count(struct LinkiteM *item, int flag) struct PermiteM { char *disk_path; struct stat stbuf; - int immutable; /* bit0= set chattr immutable bit - bit1= only set immutable bit + int chattr_flags; /* bit0= set chattr immutable bit + bit1= only set chattr bits + bit2= set chattr append-only bit */ struct PermiteM *next; }; /* @param flag bit0= Linux chattr immutable bit is set - bit1= when popping only set immutable bit + bit1= when popping only set chattr bits + bit2= Linux chattr append-only bit is set */ int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf, int flag) @@ -960,7 +962,7 @@ int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf, return(-1); m->disk_path= NULL; memcpy(&(m->stbuf), stbuf, sizeof(struct stat)); - m->immutable= flag & 3; + m->chattr_flags= flag & 7; m->next= *o; m->disk_path= strdup(disk_path); @@ -979,7 +981,7 @@ failed:; /* @param flag bit0= minimal transfer: access permissions only bit1= do not set timestamps - bit2= do not set chattr flag i "immutable" + bit2= do not set chattr flags */ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, struct XorrisO *xorriso, int flag) @@ -1001,7 +1003,7 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, } for(m= *o; m!=stopper; m= m_next) { - if(!(m->immutable & 2)) { + if(!(m->chattr_flags & 2)) { ret= chmod(m->disk_path, m->stbuf.st_mode); if(ret==-1) { if(xorriso!=NULL) { @@ -1015,7 +1017,7 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, } } - if(!((flag & 1) || (m->immutable & 2))) { + if(!((flag & 1) || (m->chattr_flags & 2))) { ret= chown(m->disk_path, m->stbuf.st_uid, m->stbuf.st_gid); /* don't complain if it fails */ if(!(flag&2)) { @@ -1032,9 +1034,10 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, } } - if((m->immutable & 1) && !(flag & 4)) { + if((m->chattr_flags & (1 | 4)) && !(flag & 4)) { /* It seems tradition here to just complain but to go on to return 1 */ - Xorriso_set_local_chattr_i(xorriso, m->disk_path, 0); + Xorriso_set_local_chattr_ia(xorriso, m->disk_path, + (m->chattr_flags & 1) | ((m->chattr_flags & 4) >> 1)); } m_next= m->next; @@ -1047,11 +1050,11 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, /* Look for stack item with disk_path - @return 0= nothing found, 1= *stbuf and *immutable are valid + @return 0= nothing found, 1= *stbuf and *chattr_flags are valid */ int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper, struct XorrisO *xorriso, - char *disk_path, struct stat **stbuf, int *immutable, + char *disk_path, struct stat **stbuf, int *chattr_flags, int flag) { struct PermiteM *m; @@ -1061,7 +1064,7 @@ int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper, for(m= *o; m != NULL; m= m->next) { if(strcmp(m->disk_path, disk_path) == 0) { *stbuf= &(m->stbuf); - *immutable= m->immutable; + *chattr_flags= m->chattr_flags; return(1); } if(m->next == stopper) diff --git a/xorriso/aux_objects.h b/xorriso/aux_objects.h index d979b06b..16f6d5ae 100644 --- a/xorriso/aux_objects.h +++ b/xorriso/aux_objects.h @@ -181,13 +181,14 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, struct XorrisO *xorriso, int flag); /* Look for stack item with disk_path - @param immutable bit0= when popping: set chattr immutable bit - bit1= when popping: only set immutable bit - @return 0= nothing found, 1= *stbuf and *immutable are valid + @param chattr_flag bit0= when popping: set chattr bit 'i' + bit1= when popping: only set chattr bits + bit2= when popping: set chattr bit 'a' + @return 0= nothing found, 1= *stbuf and *chattr_flags are valid */ int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper, struct XorrisO *xorriso, - char *disk_path, struct stat **stbuf, int *immutable, + char *disk_path, struct stat **stbuf, int *chattr_flags, int flag); #endif /* ! Xorriso_pvt_auxobj_includeD */ diff --git a/xorriso/read_run.c b/xorriso/read_run.c index 2a1938f0..e5aa8889 100644 --- a/xorriso/read_run.c +++ b/xorriso/read_run.c @@ -436,45 +436,61 @@ uint64_t Xorriso__lfa_bits(char *lfa_text) } -int Xorriso_set_local_chattr_i(struct XorrisO *xorriso, char *disk_path, +/* @param flag bit0= set i + bit1= set a +*/ +int Xorriso_set_local_chattr_ia(struct XorrisO *xorriso, char *disk_path, int flag) { int ret, max_bit= 31, os_errno; - static uint64_t lfa_i= 0xffffffff; + uint64_t lfa_flags= 0; + static uint64_t lfa_i= 0xffffffff, lfa_a= 0; - if(lfa_i == 0xffffffff) + if(lfa_i == 0xffffffff) { lfa_i= Xorriso__lfa_bits("i"); - - ret= iso_local_set_lfa_flags(disk_path, lfa_i, max_bit, lfa_i, &os_errno, 4); - ret= Xorriso_report_chattr_outcome(xorriso, disk_path, lfa_i, lfa_i, - ret, os_errno, 0); + lfa_a= Xorriso__lfa_bits("a"); + } + if(flag & 1) + lfa_flags|= lfa_i; + if(flag & 2) + lfa_flags|= lfa_a; + if(lfa_flags == 0) + return(1); + ret= Xorriso_local_set_lfa_flags(xorriso, disk_path, lfa_flags, max_bit, + lfa_flags, &os_errno, 0); if(ret <= 0) return(ret); return(1); } -/* If present and enabled: restore chattr i */ -int Xorriso_restore_chattr_i(struct XorrisO *xorriso, IsoNode *node, +/* If present and enabled: restore chattr i and/or a */ +int Xorriso_restore_chattr_ia(struct XorrisO *xorriso, IsoNode *node, char *disk_path, int flag) { int ret, max_bit; - uint64_t lfa_flags, mask; - static uint64_t lfa_i= 0xffffffff; + uint64_t lfa_flags, mask, chattr_flag= 0; + static uint64_t lfa_i= 0xffffffff, lfa_a= 0; - if(lfa_i == 0xffffffff) + if(lfa_i == 0xffffffff) { lfa_i= Xorriso__lfa_bits("i"); + lfa_a= Xorriso__lfa_bits("a"); + } if((xorriso->do_aaip & (1 << 12))) { mask= iso_util_get_effective_lfa_mask(xorriso->lfa_restore_mask, (!!(xorriso->do_aaip & (1 << 13))) | ((!!(xorriso->do_aaip & (1 << 14))) << 1)); - if(!(mask & lfa_i)) + if(!(mask & (lfa_i | lfa_a))) return(2); ret= iso_node_get_lfa_flags(node, &lfa_flags, &max_bit, 0); if(ret > 0) { - if(lfa_flags & lfa_i) { - ret= Xorriso_set_local_chattr_i(xorriso, disk_path, 0); + if(lfa_flags & lfa_i) + chattr_flag|= 1; + if(lfa_flags & lfa_a) + chattr_flag|= 2; + if(chattr_flag) { + ret= Xorriso_set_local_chattr_ia(xorriso, disk_path, chattr_flag); if(ret <= 0) return(ret); return(1); @@ -552,13 +568,13 @@ int Xorriso_restore_timestamps(struct XorrisO *xorriso, char *disk_path, /* @param flag bit0= minimal transfer: access permissions only bit1= keep directory open: keep owner, allow rwx for owner and push directory onto xorriso->perm_stack - @return 1=ok , 2=ok, lfa "i" pushed to permstack, <=0 error + @return 1=ok , 2=ok, lfa "i" and/or "a" pushed to permstack, <=0 error */ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, IsoNode *node, int flag) { int ret, is_dir= 0, errno_copy= 0, local_attrs_set= 0, i, err_count; - int lfa_i_pushed= 0; + int lfa_ia_pushed= 0; mode_t mode; uid_t uid, disk_uid; gid_t gid, disk_gid; @@ -568,12 +584,13 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, int *errnos= NULL; uint64_t lfa_flags= 0, mask= 0, push_mask= 0; int max_bit, os_errno; - static uint64_t lfa_C= 0xffffffff, lfa_i= 0, lfa_F= 0; + static uint64_t lfa_C= 0xffffffff, lfa_i= 0, lfa_a= 0, lfa_F= 0; if(lfa_C == 0xffffffff) { lfa_C= Xorriso__lfa_bits("C"); lfa_F= Xorriso__lfa_bits("F"); lfa_i= Xorriso__lfa_bits("i"); + lfa_a= Xorriso__lfa_bits("a"); } ret= lstat(disk_path, &stbuf); @@ -670,9 +687,10 @@ cannot_set_xattr:; if(is_dir) mask&= ~lfa_F; push_mask= mask; - /* Do not set lfa_flag 'i' of a directory here. It would be too early. */ + /* Do not set lfa_flags 'i' or 'a' of a directory here. + It would be too early. */ if(is_dir) - mask&= ~lfa_i; + mask&= ~(lfa_i | lfa_a); } } @@ -682,7 +700,8 @@ cannot_set_xattr:; if(ret<=0) {ret= 0; goto ex;} ret= Permstack_push(&(xorriso->perm_stack), disk_path, &stbuf, - !!(lfa_flags & push_mask & lfa_i)); + (!!(lfa_flags & push_mask & lfa_i)) | + ((!!(lfa_flags & push_mask & lfa_a)) << 2)); if(ret<=0) { Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); strcpy(xorriso->info_text, @@ -690,7 +709,7 @@ cannot_set_xattr:; Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); {ret= -1; goto ex;} } - lfa_i_pushed= !!(lfa_flags & push_mask & lfa_i); + lfa_ia_pushed= !!(lfa_flags & push_mask & (lfa_i | lfa_a)); mode|= S_IRUSR|S_IWUSR|S_IXUSR; } ret= chmod(disk_path, mode); @@ -751,7 +770,7 @@ cannot_set_perm:; } } - ret= 1 + !!lfa_i_pushed; + ret= 1 + !!lfa_ia_pushed; ex:; iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,1 << 15); if(errnos != NULL) @@ -1954,7 +1973,7 @@ int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir, int dir_create= 0, node_register= 0, do_node_count= 0, normal_mode= 0; int target_was_no_dir, dir_is_new; struct stat *stack_stbufpt; - int lfa_i_pushed= 0, stack_immutable; + int lfa_ia_pushed= 0, stack_chattr; perm_stack_mem= xorriso->perm_stack; switch((flag >> 7) & 3) { @@ -2182,15 +2201,15 @@ much_too_long:; if(source_is_dir) { /* Restore exact access permissions of directory */ hret= Permstack_peek(&(xorriso->perm_stack), perm_stack_mem, xorriso, - disk_path, &stack_stbufpt, &stack_immutable, 0); - if(hret == 1 && (stack_immutable & 1)) - lfa_i_pushed= 1; + disk_path, &stack_stbufpt, &stack_chattr, 0); + if(hret == 1 && (stack_chattr & (1 | 4))) + lfa_ia_pushed= 1; hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64)); if(hret<=0 && hretperm_stack; @@ -2479,15 +2498,15 @@ attach_source:; So pop earlier than normal. */ hret= Permstack_peek(&(xorriso->perm_stack), perm_stack_mem, xorriso, - disk_path, &stack_stbufpt, &stack_immutable, 0); - if(hret == 1 && (stack_immutable & 1)) - lfa_i_pushed= 1; + disk_path, &stack_stbufpt, &stack_chattr, 0); + if(hret == 1 && (stack_chattr & (1 | 4))) + lfa_ia_pushed= 1; hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 2 | !!(flag&64)); if(hret <= 0 && hret < ret) ret= hret; - if(!lfa_i_pushed) { - hret= Xorriso_restore_chattr_i(xorriso, node, disk_path, 0); + if(!lfa_ia_pushed) { + hret= Xorriso_restore_chattr_ia(xorriso, node, disk_path, 0); if(hret <= 0 && hret < ret) ret= hret; if(ret <= 0) diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index e9bc3aa5..66eea943 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2024.09.08.192526" +#define Xorriso_timestamP "2024.09.09.134057" diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 632cc023..3d0ec083 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -714,8 +714,8 @@ int Xorriso_set_lfa_flags(struct XorrisO *xorriso, void *in_node, char *path, int Xorriso_remove_all_lfa_flags(struct XorrisO *xorriso, int flag); -int Xorriso_set_local_chattr_i(struct XorrisO *xorriso, char *disk_path, - int flag); +int Xorriso_set_local_chattr_ia(struct XorrisO *xorriso, char *disk_path, + int flag); #endif /* Xorrisoburn_includeD */