diff --git a/xorriso/aux_objects.c b/xorriso/aux_objects.c index 62bd9f91..ee1e9135 100644 --- a/xorriso/aux_objects.c +++ b/xorriso/aux_objects.c @@ -1046,5 +1046,36 @@ 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 +*/ +int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper, + struct XorrisO *xorriso, + char *disk_path, struct stat **stbuf, int *immutable, + int flag) +{ + struct PermiteM *m; + + if((*o) == stopper) + return(0); + for(m= *o; m != NULL; m= m->next) { + if(strcmp(m->disk_path, disk_path) == 0) { + *stbuf= &(m->stbuf); + *immutable= m->immutable; + return(1); + } + if(m->next == stopper) + break; + } + if(m == NULL) { + sprintf(xorriso->info_text, + "Program error: Permstack_peek() : cannot find stopper"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } + return(0); +} + + /* ---------------------------- End PermstacK ----------------------------- */ diff --git a/xorriso/aux_objects.h b/xorriso/aux_objects.h index 3841a787..d979b06b 100644 --- a/xorriso/aux_objects.h +++ b/xorriso/aux_objects.h @@ -180,6 +180,15 @@ int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf, 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 +*/ +int Permstack_peek(struct PermiteM **o, struct PermiteM *stopper, + struct XorrisO *xorriso, + char *disk_path, struct stat **stbuf, int *immutable, + int flag); #endif /* ! Xorriso_pvt_auxobj_includeD */ diff --git a/xorriso/read_run.c b/xorriso/read_run.c index 33678770..2a1938f0 100644 --- a/xorriso/read_run.c +++ b/xorriso/read_run.c @@ -529,18 +529,39 @@ int Xorriso_early_chattr_CF(struct XorrisO *xorriso, IsoNode *node, } +int Xorriso_restore_timestamps(struct XorrisO *xorriso, char *disk_path, + IsoNode *node, int flag) +{ + int ret; + struct utimbuf utime_buffer; + + utime_buffer.actime= iso_node_get_atime(node); + utime_buffer.modtime= iso_node_get_mtime(node); + ret= utime(disk_path, &utime_buffer); + if(ret == -1) { + sprintf(xorriso->info_text, + "Cannot change atime, mtime of disk file "); + Text_shellsafe(disk_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + return(0); + } + return(1); +} + + /* @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 */ 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; mode_t mode; uid_t uid, disk_uid; gid_t gid, disk_gid; - struct utimbuf utime_buffer; struct stat stbuf; size_t num_attrs= 0, *value_lengths= NULL; char **names= NULL, **values= NULL; @@ -669,6 +690,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); mode|= S_IRUSR|S_IWUSR|S_IXUSR; } ret= chmod(disk_path, mode); @@ -684,16 +706,9 @@ cannot_set_perm:; if(flag&1) {ret= 1; goto ex;} - utime_buffer.actime= iso_node_get_atime(node); - utime_buffer.modtime= iso_node_get_mtime(node); - ret= utime(disk_path,&utime_buffer); - if(ret==-1) { - sprintf(xorriso->info_text, - "Cannot change atime, mtime of disk file "); - Text_shellsafe(disk_path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - {ret= 0; goto ex;} - } + ret= Xorriso_restore_timestamps(xorriso, disk_path, node, 0); + if(ret <= 0) + goto ex; gid= iso_node_get_gid(node); if(!(S_ISDIR(stbuf.st_mode) && (flag&2))) @@ -736,7 +751,7 @@ cannot_set_perm:; } } - ret= 1; + ret= 1 + !!lfa_i_pushed; ex:; iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,1 << 15); if(errnos != NULL) @@ -1938,6 +1953,8 @@ int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir, struct stat stbuf, disk_stbuf; 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; perm_stack_mem= xorriso->perm_stack; switch((flag >> 7) & 3) { @@ -2164,11 +2181,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; hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64)); if(hret<=0 && hretperm_stack; @@ -2420,7 +2443,7 @@ attach_source:; } if(new_dir_made && !(flag&64)) { /* set timestamps which Permstack_pop() will not set */ - ret= Xorriso_restore_properties(xorriso, disk_path, node, 2); + ret= Xorriso_restore_timestamps(xorriso, disk_path, node, 0); if(ret <= 0) { hret= Xorriso_eval_problem_status(xorriso, ret, 1 | 2); if(hret < 0) @@ -2455,15 +2478,21 @@ attach_source:; /* Need to set any properties before possibly setting immutable bit. 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; hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 2 | !!(flag&64)); if(hret <= 0 && hret < ret) ret= hret; - hret= Xorriso_restore_chattr_i(xorriso, node, disk_path, 0); - if(hret <= 0 && hret < ret) - ret= hret; - if(ret <= 0) - goto ex; + if(!lfa_i_pushed) { + hret= Xorriso_restore_chattr_i(xorriso, node, disk_path, 0); + if(hret <= 0 && hret < ret) + ret= hret; + if(ret <= 0) + goto ex; + } } Xorriso_process_msg_queues(xorriso,0); diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 4215a49c..e9bc3aa5 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2024.09.08.102135" +#define Xorriso_timestamP "2024.09.08.192526"