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