diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 1151c416..72763480 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -1746,13 +1746,6 @@ return: /* ---------------------------------- LstrinG --------------------------- */ -struct LstrinG { - char *text; - struct LstrinG *prev,*next; -}; - -int Lstring_destroy(struct LstrinG **lstring, int flag); - /* @param flag Bitfield for control purposes @@ -1875,6 +1868,7 @@ int Lstring_append_binary(struct LstrinG **entry, char *data, int data_len, #endif /* Xorriso_sregex_externaL */ + /* ------------------------------ LinkiteM -------------------------------- */ struct LinkiteM { @@ -2635,8 +2629,91 @@ int Exclusions_get_descrs(struct ExclusionS *o, /* ---------------------------- End ExclusionS ---------------------------- */ +/* ------------------------------ PermstacK ------------------------------- */ + + +struct PermiteM { + char *disk_path; + struct stat stbuf; + struct PermiteM *next; +}; + + +int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf, + int flag) +{ + struct PermiteM *m; + + m= TSOB_FELD(struct PermiteM,1); + if(m==NULL) + return(-1); + m->disk_path= NULL; + memcpy(&(m->stbuf), stbuf, sizeof(struct stat)); + m->next= *o; + + m->disk_path= strdup(disk_path); + if(m->disk_path==NULL) + goto failed; + + *o= m; + return(1); +failed:; + if(m->disk_path!=NULL) + free(m->disk_path); + free((char *) m); + return(-1); +} + + +/* @param flag bit0= minimal transfer: access permissions only +*/ +int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, + struct XorrisO *xorriso, int flag) +{ + int ret; + char sfe[5*SfileadrL]; + struct PermiteM *m, *m_next; + + if((*o)==stopper) + return(1); + for(m= *o; m!=NULL; m= m->next) + if(m->next==stopper) + break; + if(m==NULL) { + sprintf(xorriso->info_text, + "Program error: Permstack_pop() : cannot find stopper"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } + + for(m= *o; m!=stopper; m= m_next) { + ret= chmod(m->disk_path, m->stbuf.st_mode); + if(ret==-1) { + if(xorriso!=NULL) { + sprintf(xorriso->info_text, + "Cannot change access permissions of disk directory: chmod %o %s", + m->stbuf.st_mode & 07777, Text_shellsafe(m->disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", + 0); + } + } + if(!(flag&1)) + chown(m->disk_path, m->stbuf.st_uid, m->stbuf.st_gid); + /* don't complain if it fails */ + m_next= m->next; + free(m->disk_path); + free((char *) m); + *o= m_next; + } + return(1); +} + + +/* ---------------------------- End PermstacK ----------------------------- */ + /* ------------------------------- Xorriso -------------------------------- */ + /** The list of startup file names */ #define Xorriso_rc_nuM 4 @@ -2773,6 +2850,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->start_time= 0.0; m->last_update_time= 0.0; m->find_compare_result= 1; + m->perm_stack= NULL; m->result_line[0]= 0; m->result_line_counter= 0; m->result_page_counter= 0; diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index 46c1af45..da6ed5bb 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -45,8 +45,9 @@ /* <<< ??? */ typedef int (*Cleanup_app_handler_T)(); -struct LinkiteM; -struct ExclusionS; +struct LinkiteM; /* Trace of hops during symbolic link resolution */ +struct ExclusionS; /* List of -not_* conditions */ +struct PermiteM; /* Stack of temporarily altered access permissions */ /* maximum number of history lines to be reported with -status:long_history */ @@ -259,6 +260,8 @@ struct XorrisO { /* the global context of xorriso */ int find_compare_result; /* 1=everything matches , 0=mismatch , -1=error */ + struct PermiteM *perm_stack; /* Temporarily altered dir access permissions */ + /* result (stdout, R: ) */ char result_line[5*SfileadrL]; int result_line_counter; @@ -530,6 +533,40 @@ int Splitpart__parse(char *name, int *partno, int *total_parts, int Splitpart__compose(char *adr, int partno, int total_parts, off_t offset, off_t bytes, off_t total_bytes, int flag); +struct LstrinG { + char *text; + struct LstrinG *prev,*next; +}; + +int Lstring_destroy(struct LstrinG **lstring, int flag); + +int Lstring_destroy_all(struct LstrinG **lstring, int flag); + +/* + @param flag Bitfield for control purposes + bit0= insert before link rather than after it + bit1= do not copy data (e.g. because *data is invalid) +*/ +int Lstring_new_binary(struct LstrinG **lstring, char *data, int data_len, + struct LstrinG *link, int flag); + +/* + @param flag Bitfield for control purposes + bit0= insert before link rather than after it +*/ +int Lstring_new(struct LstrinG **lstring, char *text, struct LstrinG *link, + int flag); + +int Lstring_append_binary(struct LstrinG **entry, char *data, int data_len, + int flag); + + +int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf, + int flag); + +int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, + struct XorrisO *xorriso, int flag); + #endif /* Xorriso_private_includeD */ diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 9bc3caa0..ff86dde0 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.05.24.170109" +#define Xorriso_timestamP "2008.05.26.181210" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 0aeac1ca..24d568f5 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -1475,10 +1475,15 @@ int Xorriso_get_node_by_path(struct XorrisO *xorriso, /* <<< this is not safe -*/ -#define Xorriso_can_get_dev_T 1 #define Xorriso_get_dev_by_botcH 1 - +*/ +#if iso_lib_header_version_major > 0 || \ + ( iso_lib_header_version_major == 0 && \ + ( iso_lib_header_version_minor > 6 || \ + ( iso_lib_header_version_minor == 6 && \ + iso_lib_header_version_micro > 4))) +#define Xorriso_can_get_dev_T 1 +#endif #ifndef Xorriso_can_get_dev_T #ifdef Xorriso_standalonE @@ -1498,9 +1503,14 @@ int Xorriso_node_get_dev(struct XorrisO *xorriso, IsoNode *node, #ifdef Xorriso_can_get_dev_T /* >>> insert future API call here and remove botch below */ +#ifndef Xorriso_get_dev_by_botcH + + *dev= iso_special_get_dev((IsoSpecial *) node); + return(1); + +#else /* Xorriso_get_dev_by_botcH */ /* <<< */ -#ifdef Xorriso_get_dev_by_botcH /* Drilling a hole into libisofs-0.6.4 in order to substitute for the lack of an API call which returns the dev_t number of a IsoSpecial (block or character device). @@ -2053,7 +2063,7 @@ ex: /* @param flag bit0= cut_out mode : base on leaf parent directory */ -int Xorriso_copy_implict_properties(struct XorrisO *xorriso, IsoDir *dir, +int Xorriso_copy_implicit_properties(struct XorrisO *xorriso, IsoDir *dir, char *full_img_path, char *img_path, char *full_disk_path, int flag) { int ret, nfic, nic, nfdc, d, i; @@ -2303,7 +2313,7 @@ handle_path_node:; iso_node_set_gid((IsoNode *) dir, getegid()); if(disk_path!=NULL && !done) - Xorriso_copy_implict_properties(xorriso, dir, img_path, path, disk_path, + Xorriso_copy_implicit_properties(xorriso, dir, img_path, path, disk_path, !!(flag&8)); } @@ -2422,6 +2432,7 @@ unsupported_type:; /* @param flag bit0= minimal transfer: access permissions only + bit1= keep directory open: keep owner, allow rwx for owner */ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, IsoNode *node, int flag) @@ -2432,8 +2443,21 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, gid_t gid; struct utimbuf utime_buffer; char sfe[5*SfileadrL]; + struct stat stbuf; + + ret= lstat(disk_path, &stbuf); + if(ret==-1) { + sprintf(xorriso->info_text, + "Cannot obtain properties of disk file %s", + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + return(0); + } + uid= stbuf.st_uid; mode= iso_node_get_permissions(node); + if(S_ISDIR(stbuf.st_mode) && (flag&2)) + mode|= S_IRUSR|S_IWUSR|S_IXUSR; ret= chmod(disk_path, mode); if(ret==-1) { sprintf(xorriso->info_text, @@ -2444,8 +2468,10 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, } if(flag&1) return(1); - uid= iso_node_get_uid(node); + gid= iso_node_get_gid(node); + if(!(S_ISDIR(stbuf.st_mode) && (flag&2))) + uid= iso_node_get_uid(node); chown(disk_path, uid, gid); /* don't complain if it fails */ utime_buffer.actime= iso_node_get_atime(node); utime_buffer.modtime= iso_node_get_mtime(node); @@ -2461,17 +2487,18 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, } -#ifdef Osirrox_not_yeT - -/* @param flag bit0= cut_out mode : base on leaf parent directory +/* @param flag >>> bit0= cut_out mode : base on leaf parent directory + bit1= minimal transfer: access permissions only + bit2= keep directory open: keep owner, allow rwx for owner */ -int Xorriso_restore_implict_properties(struct XorrisO *xorriso, IsoDir *dir, +int Xorriso_restore_implicit_properties(struct XorrisO *xorriso, char *full_disk_path, char *disk_path, char *full_img_path, int flag) { int ret, nfic, ndc, nfdc, d, i; char nfi[SfileadrL], nd[SfileadrL], nfd[SfileadrL], *cpt; char sfe[5*SfileadrL]; struct stat stbuf; + IsoNode *node; ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd, 1|2|4); @@ -2487,7 +2514,10 @@ int Xorriso_restore_implict_properties(struct XorrisO *xorriso, IsoDir *dir, nfdc= Sfile_count_components(nfd, 0); ndc= Sfile_count_components(nd, 0); nfic= Sfile_count_components(nfi, 0); + + /* >>> ??? (flag&1) */ d= nfdc-(flag&1)-ndc; + if(d<0) return(-1); if(d>nfic) @@ -2500,27 +2530,24 @@ int Xorriso_restore_implict_properties(struct XorrisO *xorriso, IsoDir *dir, } if(nfi[0]==0) strcpy(nfi, "/"); - - -/* >>> CONSTRUCTION SITE */ - - - if(stat(nfi, &stbuf)==-1) + ret= Xorriso_fake_stbuf(xorriso, nfi, &stbuf, &node, 0); + if(ret<=0) return(0); - - Xorriso_transfer_properties(xorriso, &stbuf, (IsoNode *) dir, - ((flag&1) && d==0)); + ret= Xorriso_restore_properties(xorriso, nfd, node, !!(flag&2)); + if(ret<=0) + return(ret); sprintf(xorriso->info_text, - "Copied properties for %s", Text_shellsafe(ni, sfe, 0)); + "Restored properties for %s", Text_shellsafe(nd, sfe, 0)); sprintf(xorriso->info_text+strlen(xorriso->info_text), - " from %s", Text_shellsafe(nfd, sfe, 0)); + " from %s", Text_shellsafe(nfi, sfe, 0)); + + /* >>> ??? (flag&1) */ if(!((flag&1) && d==0)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); return(1); } -#endif /* Osirrox_not_yeT */ - /* @param flag bit0= Minimal transfer: access permissions only bit2= This is not a parameter. Do not report if ignored @@ -2693,6 +2720,9 @@ int Xorriso_restore(struct XorrisO *xorriso, int done= 0, is_dir= 0, ret, target_is_dir, source_is_dir, stbuf_ret; int target_is_split; struct stat stbuf, target_stbuf; + struct PermiteM *perm_stack_mem; + + perm_stack_mem= xorriso->perm_stack; ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4)); if(ret<0) @@ -2806,16 +2836,24 @@ handle_path_node:; Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); return(0); } + if(!done) { + ret= Permstack_push(&(xorriso->perm_stack), path, &stbuf, 0); + if(ret<=0) { + Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); + Xorriso_report_iso_error(xorriso, disk_path, ret, + "Cannot memorize permissions for disk directory", 0, "FATAL", 1); + return(-1); + } + /* keep rwx for the owner */ + Xorriso_restore_implicit_properties(xorriso, disk_path, path, + img_path, 4); + /* >>> ???(flag&8) */ + } + } else if(source_is_dir) { -#ifdef Osirrox_not_yeT - - if(disk_path!=NULL && !done) - Xorriso_restore_implict_properties(xorriso, dir, disk__path, path, - image_path, !!(flag&8)); -#endif /* Osirrox_not_yeT */ + /* >>> If owner: eventually try to obtain rwx-permssions, stack path */; } - if(done) { attach_source:; @@ -2826,6 +2864,9 @@ attach_source:; Xorriso_restore_properties(xorriso, disk_path, node, !!(flag&64)); #ifdef Osirrox_not_yeT + + /* >>> */ + if(!(flag&32)) { ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL, flag&2); @@ -2869,6 +2910,12 @@ attach_source:; *npt= '/'; } Xorriso_process_msg_queues(xorriso,0); + + /* restore exact access permissions of stacked paths */ + ret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, + !!(flag&64)); + if(ret<=0) + return(ret); return(1+!!is_dir); }