New -findx -exec action "empty_iso_dir", workaround for ticket 132
This commit is contained in:
parent
a5ea9f79a0
commit
955d08c735
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -1 +1 @@
|
||||
#define Xorriso_timestamP "2008.03.07.075325"
|
||||
#define Xorriso_timestamP "2008.03.07.182411"
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user