diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 71c443e1..e8d561e8 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -684,8 +684,8 @@ the particular file names of the eventual directory tree underneath iso_rr_path. If no -name pattern is given, then any file name matches. .br The optional -type test restricts matching to files of the given type: -"block", "char", "dir", "pipe", "file", "link", "socket", "Xotic", -where "X" eventually matches what is not matched by the other types. +"block", "char", "dir", "pipe", "file", "link", "socket", +"Xotic" which eventually matches what is not matched by the other types. .br Only the first letter is interpreted. E.g.: -find / -type d .br @@ -1299,6 +1299,11 @@ Similar to shell command du -sk. Like -find but operating on local filesystem and not on the ISO image. This is subject to the settings of -follow. .br +Find accepts the same -type arguments as -find. Additionally it recognizes +type "mountpoint" (or "m"). It matches subdirectories which reside on a +different device than their parent. It never matches the disk_path +given as start address for -findx. +.br -findx accepts the -exec actions as does -find. But except the following few actions it will allways perform action "echo". .br diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 89b2dbaf..838a4b16 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -2379,7 +2379,7 @@ struct FindjoB { f = reg - = reg s = socket ->>> m = subordinate mountpoint (does never match find start directory) + m = subordinate mountpoint (does never match find start directory) X = other 0x0 = test inactive */ @@ -2387,8 +2387,8 @@ struct FindjoB { /* 0= echo ->>> 1= rm (also rmdir) ->>> 2= rm_r + 1= rm (also rmdir) + 2= rm_r >>> 3= mv target 4= chown user 5= chgrp group @@ -2405,6 +2405,7 @@ struct FindjoB { 16= not_in_iso 17= update 18= add_missing +>>>19= empty_iso_dir */ int action; char *target; @@ -6142,7 +6143,7 @@ int Xorriso_findx_action(struct XorrisO *xorriso, struct FindjoB *job, action= 0; if(action<0) action= 0; - if(action==15 || action==16 || action==18) { + if(action==15 || action==16 || action==18 || action==19) { /* in_iso , not_in_iso, add_missing */ Findjob_get_start_path(job, &disk_prefix, 0); if(strncmp(abs_path, disk_prefix, strlen(disk_prefix))!=0) @@ -6184,6 +6185,18 @@ int Xorriso_findx_action(struct XorrisO *xorriso, struct FindjoB *job, } if(ret>=0) ret= 1; + } else if(action==19) { /* empty_iso_dir */ + ret= Xorriso_iso_lstat(xorriso, iso_path, &stbuf, 0); + if(ret==-1) + return(1); + if(!S_ISDIR(stbuf.st_mode)) + return(1); + ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, iso_path, 1|32); + if(ret>0) { + sprintf(xorriso->info_text, "Emptied directory %s", + Text_shellsafe(iso_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); + } } else { sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); Xorriso_result(xorriso, 0); @@ -7124,7 +7137,7 @@ int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter, if(compare_result&(8|64)) { /* file type, minor+major with device file */ - ret= Xorriso_rmi(xorriso, boss_iter, iso_rr_path, 1); /* rm_r */ + ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1); /* rm_r */ if(ret>0) { deleted= 1; ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, iso_rr_path, @@ -7134,7 +7147,7 @@ int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter, } else if(compare_result&(1)) { /* disk_adr not existing */ - ret= Xorriso_rmi(xorriso, boss_iter, iso_rr_path, 1); + ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1); deleted= 1; sprintf(xorriso->info_text, "Deleted "); @@ -8545,8 +8558,10 @@ not_enough_arguments:; Xorriso_pacifier_reset(xorriso, 0); mem_lut= xorriso->last_update_time; } - } else if(strcmp(cpt, "in_iso")==0 || strcmp(cpt, "not_in_iso")==0 || - strcmp(cpt, "add_missing")==0) { + } else if(strcmp(cpt, "in_iso")==0 || + strcmp(cpt, "not_in_iso")==0 || + strcmp(cpt, "add_missing")==0 || + strcmp(cpt, "empty_iso_dir")==0) { if(i+1>=end_idx) goto not_enough_arguments; i++; @@ -8558,6 +8573,8 @@ not_enough_arguments:; action= 15; else if(strcmp(cpt, "add_missing")==0) action= 18; + else if(strcmp(cpt, "empty_iso_dir")==0) + action= 19; else action= 16; Findjob_set_action_target(job, action, other_path_start, 0); @@ -9797,7 +9814,7 @@ int Xorriso_option_rmi(struct XorrisO *xorriso, int argc, char **argv, } strcpy(path, eff_path); - ret= Xorriso_rmi(xorriso, NULL, path, flag&(1|2)); + ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, path, flag&(1|2)); if(ret<=0 || xorriso->request_to_abort) goto problem_handler; if(ret<3) { diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 1784c8cd..545895cb 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.03.07.075325" +#define Xorriso_timestamP "2008.03.07.182411" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 4c4ef92f..96114593 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -1433,6 +1433,49 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf, } +/* Ticket 132 : Workaround for missing feature */ +int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume, + IsoDir *dir, char *disk_path, char *img_name, + char *nominal_source, char *nominal_target, + IsoNode **node, int flag) +{ + int ret, wa_ret, i; + char wa_name[256]; + IsoDir *hdir; + + ret= iso_tree_add_node(volume, dir, disk_path, node); + if(ret==ISO_NODE_NAME_NOT_UNIQUE) { + wa_ret= ISO_NODE_NAME_NOT_UNIQUE; + for(i= 0; wa_ret==ISO_NODE_NAME_NOT_UNIQUE && i<2000000000; i++) { + sprintf(wa_name, "xorriso_works_around_what_is_not_a_bug_try_%d", i); + wa_ret= iso_tree_add_new_dir(dir, wa_name, &hdir); + } + if(wa_ret<0) + goto cannot_add; + ret= iso_tree_add_node(volume, hdir, disk_path, node); + if(ret>0) { + ret= iso_node_set_name(*node, img_name); + if(ret<0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, nominal_target, 0, + "Cannot set name", 0, "FAILURE", 1); + return(ret); + } + iso_node_take(*node); + ret= iso_dir_add_node(dir, *node, 0); + } + iso_node_remove((IsoNode *) hdir); + } + if(ret<0) { +cannot_add:; + Xorriso_report_iso_error(xorriso, nominal_source, ret, + "Cannot add node to tree", 0, "FAILURE", 1|2); + return(ret); + } + return(1); +} + + /* @param flag bit0= recursion is active bit1= do not report added files */ @@ -1576,17 +1619,6 @@ cannot_lstat:; source_is_dir= 1; if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount) do_not_dive= 1; - -#ifdef NIX - } else if(!(S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))) { - Xorriso_msgs_submit(xorriso, 0, stbuf_src, 0, "ERRFILE", 0); - sprintf(xorriso->info_text,"Source file %s %s non-supported file type", - Text_shellsafe(srcpt, sfe, 0), - source_is_link ? "leads to" : "is of"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto was_problem; -#endif /* NIX */ - } /* does a node exist with this name ? */ @@ -1600,7 +1632,7 @@ cannot_lstat:; /* handle overwrite situation */; if(xorriso->do_overwrite==1 || (xorriso->do_overwrite==2 && !target_is_dir)) { - ret= Xorriso_rmi(xorriso, NULL, img_path, 1|8); + ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, img_path, 1|8); if(ret<=0) goto was_problem; if(ret==3) { @@ -1640,7 +1672,13 @@ cannot_lstat:; {ret= 0; goto was_problem;} } } else { +#ifdef NIX ret= iso_tree_add_node(volume, dir, srcpt, &node); +#else + ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name, + stbuf_src, img_path, + &node, 0); +#endif if(ret<0) { Xorriso_report_iso_error(xorriso, stbuf_src, ret, "Cannot add node to tree", 0, "FAILURE", 1|2); @@ -1911,7 +1949,7 @@ int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter, /* handle overwrite situation */; if(xorriso->do_overwrite==1 || (xorriso->do_overwrite==2 && !target_is_dir)) { - ret= Xorriso_rmi(xorriso, boss_iter, path, 1|8); + ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, path, 1|8); if(ret<=0) return(ret); if(ret==3) { @@ -1953,7 +1991,7 @@ handle_path_node:; iso_node_set_uid((IsoNode *) dir, geteuid()); iso_node_set_gid((IsoNode *) dir, getegid()); - if(!done) + if(disk_path!=NULL && !done) Xorriso_copy_implict_properties(xorriso, dir, img_path, path, disk_path, 0); @@ -1982,6 +2020,8 @@ attach_source:; disk_path_pt= resolved_disk_path; } else disk_path_pt= disk_path; + +#ifdef NIX ret= iso_tree_add_node(volume, dir, disk_path_pt, &node); if(ret<0) { Xorriso_process_msg_queues(xorriso,0); @@ -1993,6 +2033,16 @@ attach_source:; Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); return(0); } +#else + ret= Xorriso_tree_graft_node(xorriso, volume, dir, disk_path_pt, apt, + disk_path, img_path, &node, 0); + if(ret<0) { + sprintf(xorriso->info_text, "Grafting failed: %s = %s", + Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } +#endif xorriso->volset_change_pending= 1; iso_node_set_name(node, apt); } @@ -2471,6 +2521,131 @@ int Xorriso_cannot_create_iter(struct XorrisO *xorriso, int iso_error,int flag) } +int Xorriso__node_lba_cmp(const void *node1, const void *node2) +{ + uint32_t lba1= 0, lba2= 0; + int ret; + + ret = iso_node_get_old_image_lba(*((IsoNode **) node1), &lba1, 0); + if(ret!=1) + lba1= 0; + ret = iso_node_get_old_image_lba(*((IsoNode **) node2), &lba2, 0); + if(ret!=1) + lba1= 0; + return(lba1-lba2); +} + +/* The caller shall make no assumptions about the meaning of iter, node_array, + node_count, node_idx ! They are just opaque handles for which the caller + provides the memory of proper type. + @param flag bit0= initialize iteration + bit1= action needs full freedom of object manipulation + bit2= action needs LBA sorted iteration + bit31= end iteration (mandatory !) +*/ +int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem, + IsoDirIter **iter, + IsoNode ***node_array, int *node_count, int *node_idx, + IsoNode **iterated_node, int flag) +{ + int ret, i; + IsoNode *node; + off_t new_mem= 0; + char mem_text[80], limit_text[80]; + + if(flag&1) { + *node_array= NULL; + *node_count= -1; + *node_idx= 0; + *iter= NULL; + ret= iso_dir_get_children(dir_node, iter); + if(ret<0) { +cannot_iter:; + Xorriso_cannot_create_iter(xorriso, ret, 0); + return(-1); + } + if((flag&2)|(flag&4)) { + /* copy list of nodes and prepare soft iterator */ + *node_count= 0; + while(iso_dir_iter_next(*iter, &node) == 1) + (*node_count)++; + iso_dir_iter_free(*iter); + *iter= NULL; + + new_mem= ((*node_count)+1) * sizeof(IsoNode *); + if(new_mem > xorriso->temp_mem_limit) { + Sfile_scale((double) new_mem, mem_text, 5,1e4, 0); + Sfile_scale((double) xorriso->temp_mem_limit, limit_text, 5,1e4, 0); + sprintf(xorriso->info_text, + "Stacked directory snapshots exceed -temp_mem_limit (%s > %s)", + mem_text, limit_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + *node_count= -1; + return(-1); + } + (*node_array)= (IsoNode **) calloc((*node_count)+1, sizeof(IsoNode *)); + if(*node_array == NULL) { + sprintf(xorriso->info_text, + "Could not allocate inode list of %.f bytes", + ((double) (*node_count)+1) * (double) sizeof(IsoNode *)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + *node_count= -1; + return(-1); + } + *mem= new_mem; + ret= iso_dir_get_children(dir_node, iter); + if(ret<0) + goto cannot_iter; + while(iso_dir_iter_next(*iter, &node) == 1 && *node_idx < *node_count) { + (*node_array)[*node_idx]= node; + iso_node_ref(node); + (*node_idx)++; + } + iso_dir_iter_free(*iter); + *iter= NULL; + *node_count= *node_idx; + *node_idx= 0; + if((flag&4) && *node_count>1) + qsort(*node_array, *node_count, sizeof(IsoNode *), + Xorriso__node_lba_cmp); + } + } + + if(flag&(1<<31)) { + if(*node_count>=0 && *node_array!=NULL) { + for(i= 0; i<*node_count; i++) + iso_node_unref((*node_array)[i]); + free(*node_array); + *node_array= NULL; + *node_count= -1; + *node_idx= 0; + } else { + if(*iter!=NULL) + iso_dir_iter_free(*iter); + *iter= NULL; + } + } + + if(flag&(1|(1<<31))) + return(1); + if(*node_count>=0) { + /* return next node_array element */ + if(*node_idx>=*node_count) + return(0); + *iterated_node= (*node_array)[*node_idx]; + (*node_idx)++; + } else { + ret= iso_dir_iter_next(*iter, iterated_node); + return(ret == 1); + } + return(1); +} + + +/* +*/ +#define Xorriso_rmi_findi_iteR yes + /* @param boss_iter If not NULL then this is an iterator suitable for iso_dir_iter_remove() which is then to be used instead of iso_node_remove(). @@ -2479,12 +2654,13 @@ int Xorriso_cannot_create_iter(struct XorrisO *xorriso, int iso_error,int flag) bit2= recursion: do not reassure in mode 2 "tree" bit3= this is for overwriting and not for plain removal bit4= count deleted files in xorriso->pacifier_count + bit5= with bit0 only remove directory content, not the directory @return <=0 = error 1 = removed simple node 2 = removed directory or tree 3 = did not remove on user revocation */ -int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, +int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, off_t boss_mem, char *path, int flag) { int ret, is_dir= 0, pl, not_removed= 0, fret; @@ -2497,7 +2673,14 @@ int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, #ifdef Xorriso_fat_local_meM char sfe[5*SfileadrL], sub_path[2*SfileadrL]; #else + char *sfe= NULL, *sub_path= NULL; + off_t mem; + +#ifdef Xorriso_rmi_findi_iteR + IsoNode **node_array= NULL; + int node_count, node_idx; +#endif /* ! Xorriso_rmi_findi_iteR */ /* Avoiding large local memory objects in order to save stack space */ sfe= malloc(5*SfileadrL); @@ -2550,12 +2733,22 @@ int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, } } else { if(flag&1) { /* rm -r */ - if(xorriso->do_reassure==1 && !xorriso->request_not_to_ask) { + if((xorriso->do_reassure==1 && !xorriso->request_not_to_ask) || + (flag&32)) { /* Iterate over subordinates and delete them */ + mem= boss_mem; +#ifdef Xorriso_rmi_findi_iteR + ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, + &iter, &node_array, &node_count, &node_idx, + &node, 1|2); + if(ret<=0) { +#else ret= iso_dir_get_children((IsoDir *) victim_node, &iter); Xorriso_process_msg_queues(xorriso,0); if(ret<0) { +#endif /* ! Xorriso_rmi_findi_iteR */ + cannot_create_iter:; Xorriso_cannot_create_iter(xorriso, ret, 0); ret= -1; goto ex; @@ -2567,13 +2760,25 @@ cannot_create_iter:; sub_path[pl]= 0; } sub_name= sub_path+pl; + +#ifdef Xorriso_rmi_findi_iteR + while(1) { + ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter, + &node_array, &node_count, &node_idx, &node, 0); + if(ret<0) + goto ex; + if(ret==0 || xorriso->request_to_abort) + break; +#else while(iso_dir_iter_next(iter, &node) == 1 && !xorriso->request_to_abort) { +#endif + name= (char *) iso_node_get_name(node); if(Xorriso_much_too_long(xorriso, pl+1+strlen(name), 0)<=0) {ret= 0; goto rm_r_problem_handler;} strcpy(sub_name, name); - ret= Xorriso_rmi(xorriso, iter, sub_path, (flag&(1|2|8|16))|4); + ret= Xorriso_rmi(xorriso, iter, mem, sub_path, (flag&(1|2|8|16))|4); if(ret==3 || ret<=0 || xorriso->request_to_abort) { rm_r_problem_handler:; not_removed= 1; @@ -2582,6 +2787,9 @@ rm_r_problem_handler:; goto dir_not_removed; } } + if(flag&32) + {ret= 2; goto ex;} + if(not_removed) { dir_not_removed:; sprintf(xorriso->info_text, "Directory not removed: %s", @@ -2705,8 +2913,14 @@ ex:; free(sub_path); #endif /* ! Xorriso_fat_local_meM */ +#ifdef Xorriso_rmi_findi_iteR + Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter, + &node_array, &node_count, &node_idx, &node, (1<<31)); +#else if(iter!=NULL) iso_dir_iter_free(iter); +#endif /* ! Xorriso_rmi_findi_iteR */ + return(ret); } @@ -3332,6 +3546,21 @@ int Xorriso_rename(struct XorrisO *xorriso, void *boss_iter, IsoDir *origin_dir, *dest_dir; IsoNode *node, *iso_node; +#ifndef Libisofs_iso_dir_iter_sufficienT + /* Ticket 127: A80301 - A80302 + I do not not deem IsoDirIter safe for node list manipulations. + The parameter boss_iter once was intended to allow such but + has now been downgraded to a mere check for eventual programming bugs. + */ + if(boss_iter!=NULL) { + sprintf(xorriso->info_text, + "Program error: Xorriso_rename() was requested to delete iterated node %s", + Text_shellsafe(origin, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } +#endif /* Libisofs_iso_dir_iter_sufficienT */ + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, origin, eff_origin, 0); if(ret<=0) return(ret); @@ -3377,7 +3606,7 @@ int Xorriso_rename(struct XorrisO *xorriso, void *boss_iter, Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); return(0); } else if(dest_ret>0) { - ret= Xorriso_rmi(xorriso, boss_iter, eff_dest, 1|8); + ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, eff_dest, 1|8); if(ret<=0) return(0); if(ret==3) { @@ -3430,15 +3659,6 @@ int Xorriso_rename(struct XorrisO *xorriso, void *boss_iter, Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); return(-1); } - ret= iso_dir_add_node(dest_dir, node, 0); - if(ret<0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot add", 0, "FATAL", 1); - sprintf(xorriso->info_text, - "Internal error on rename: failed to insert node"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - return(-1); - } leafname= strrchr(eff_dest, '/'); if(leafname==NULL) leafname= eff_dest; @@ -3453,12 +3673,19 @@ int Xorriso_rename(struct XorrisO *xorriso, void *boss_iter, if(ret<0) { Xorriso_process_msg_queues(xorriso,0); Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot set name", 0, - "FATAL", 1); - sprintf(xorriso->info_text, "Internal error on rename: failed to set name"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + "FAILURE", 1); return(-1); } Xorriso_process_msg_queues(xorriso,0); + ret= iso_dir_add_node(dest_dir, node, 0); + if(ret<0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot add", 0, "FATAL", 1); + sprintf(xorriso->info_text, + "Internal error on rename: failed to insert node"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } return(1); } @@ -3813,11 +4040,11 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, if(ret>0) { if(S_ISDIR(dir_stbuf.st_mode)) hflag= 2; - ret= Xorriso_rmi(xorriso, boss_iter, abs_path, hflag); + ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, hflag); deleted= 1; } } else if(action==2) { /* rm_r */ - ret= Xorriso_rmi(xorriso, boss_iter, abs_path, 1|hflag); + ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, 1|hflag); deleted= 1; } else if(action==3) { @@ -3860,129 +4087,6 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, } -int Xorriso__node_lba_cmp(const void *node1, const void *node2) -{ - uint32_t lba1= 0, lba2= 0; - int ret; - - ret = iso_node_get_old_image_lba(*((IsoNode **) node1), &lba1, 0); - if(ret!=1) - lba1= 0; - ret = iso_node_get_old_image_lba(*((IsoNode **) node2), &lba2, 0); - if(ret!=1) - lba1= 0; - return(lba1-lba2); -} - - - -/* The caller shall make no assumptions about the meaning of iter, node_array, - node_count, node_idx ! They are just opaque handles for which the caller - provides the memory of proper type. - @param flag bit0= initialize iteration - bit1= action needs full freedom of object manipulation - bit2= action needs LBA sorted iteration - bit31= end iteration (mandatory !) -*/ -int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem, - IsoDirIter **iter, - IsoNode ***node_array, int *node_count, int *node_idx, - IsoNode **iterated_node, int flag) -{ - int ret, i; - IsoNode *node; - off_t new_mem= 0; - char mem_text[80], limit_text[80]; - - if(flag&1) { - *node_array= NULL; - *node_count= -1; - *node_idx= 0; - *iter= NULL; - ret= iso_dir_get_children(dir_node, iter); - if(ret<0) { -cannot_iter:; - Xorriso_cannot_create_iter(xorriso, ret, 0); - return(-1); - } - if((flag&2)|(flag&4)) { - /* copy list of nodes and prepare soft iterator */ - *node_count= 0; - while(iso_dir_iter_next(*iter, &node) == 1) - (*node_count)++; - iso_dir_iter_free(*iter); - *iter= NULL; - - new_mem= ((*node_count)+1) * sizeof(IsoNode *); - if(new_mem > xorriso->temp_mem_limit) { - Sfile_scale((double) new_mem, mem_text, 5,1e4, 0); - Sfile_scale((double) xorriso->temp_mem_limit, limit_text, 5,1e4, 0); - sprintf(xorriso->info_text, - "Stacked directory snapshots exceed -temp_mem_limit (%s > %s)", - mem_text, limit_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - *node_count= -1; - return(-1); - } - (*node_array)= (IsoNode **) calloc((*node_count)+1, sizeof(IsoNode *)); - if(*node_array == NULL) { - sprintf(xorriso->info_text, - "Could not allocate inode list of %.f bytes", - ((double) (*node_count)+1) * (double) sizeof(IsoNode *)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - *node_count= -1; - return(-1); - } - *mem= new_mem; - ret= iso_dir_get_children(dir_node, iter); - if(ret<0) - goto cannot_iter; - while(iso_dir_iter_next(*iter, &node) == 1 && *node_idx < *node_count) { - (*node_array)[*node_idx]= node; - iso_node_ref(node); - (*node_idx)++; - } - iso_dir_iter_free(*iter); - *iter= NULL; - *node_count= *node_idx; - *node_idx= 0; - if((flag&4) && *node_count>1) - qsort(*node_array, *node_count, sizeof(IsoNode *), - Xorriso__node_lba_cmp); - } - } - - if(flag&(1<<31)) { - if(*node_count>=0 && *node_array!=NULL) { - for(i= 0; i<*node_count; i++) - iso_node_unref((*node_array)[i]); - free(*node_array); - *node_array= NULL; - *node_count= -1; - *node_idx= 0; - } else { - if(*iter!=NULL) - iso_dir_iter_free(*iter); - *iter= NULL; - } - } - - if(flag&(1|(1<<31))) - return(1); - if(*node_count>=0) { - /* return next node_array element */ - if(*node_idx>=*node_count) - return(0); - *iterated_node= (*node_array)[*node_idx]; - (*node_idx)++; - } else { - ret= iso_dir_iter_next(*iter, iterated_node); - return(ret == 1); - } - return(1); -} - - /* @param flag bit0= recursion bit1= do not count deleted files with rm and rm_r @return <=0 error, 1= ok , 2= dir node and path has been deleted @@ -4131,13 +4235,8 @@ ex:; Xorriso_process_msg_queues(xorriso,0); -#ifdef Xorriso_findi_new_iteR Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, &node_array, &node_count, &node_idx, &node, (1<<31)); -#else - if(iter!=NULL) - iso_dir_iter_free(iter); -#endif if(ret<=0) return(ret); if(deleted) diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 7f259291..f9f0fc42 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -78,7 +78,7 @@ int Xorriso_format_media(struct XorrisO *xorriso, int flag); 2 = removed directory or tree 3 = did not remove on user revocation */ -int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, +int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, off_t boss_mem, char *path, int flag); /* @param flag bit0= long format