New -findx -exec action "empty_iso_dir", workaround for ticket 132

This commit is contained in:
Thomas Schmitt 2008-03-07 18:24:26 +00:00
parent a5ea9f79a0
commit 955d08c735
5 changed files with 294 additions and 173 deletions

View File

@ -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

View File

@ -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) {

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.03.07.075325"
#define Xorriso_timestamP "2008.03.07.182411"

View File

@ -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)

View File

@ -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