|
|
|
@ -69,6 +69,11 @@ int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume,
|
|
|
|
|
off_t offset, off_t cut_size,
|
|
|
|
|
IsoNode **node, int flag);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define LIBISO_ISDIR(node) (iso_node_get_type(node) == LIBISO_DIR)
|
|
|
|
|
#define LIBISO_ISREG(node) (iso_node_get_type(node) == LIBISO_FILE)
|
|
|
|
@ -2433,11 +2438,12 @@ unsupported_type:;
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= minimal transfer: access permissions only
|
|
|
|
|
bit1= keep directory open: keep owner, allow rwx for owner
|
|
|
|
|
and push directory onto xorriso->perm_stack
|
|
|
|
|
*/
|
|
|
|
|
int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
|
|
|
|
|
IsoNode *node, int flag)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
int ret, is_dir= 0;
|
|
|
|
|
mode_t mode;
|
|
|
|
|
uid_t uid;
|
|
|
|
|
gid_t gid;
|
|
|
|
@ -2455,9 +2461,22 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
|
|
|
|
|
}
|
|
|
|
|
uid= stbuf.st_uid;
|
|
|
|
|
|
|
|
|
|
is_dir= S_ISDIR(stbuf.st_mode);
|
|
|
|
|
mode= iso_node_get_permissions(node);
|
|
|
|
|
if(S_ISDIR(stbuf.st_mode) && (flag&2))
|
|
|
|
|
if(is_dir && (flag&2)) {
|
|
|
|
|
ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
return(0);
|
|
|
|
|
ret= Permstack_push(&(xorriso->perm_stack), disk_path, &stbuf, 0);
|
|
|
|
|
if(ret<=0) {
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
|
|
|
|
|
strcpy(xorriso->info_text,
|
|
|
|
|
"Cannot memorize permissions for disk directory");
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
|
|
|
|
|
return(-1);
|
|
|
|
|
}
|
|
|
|
|
mode|= S_IRUSR|S_IWUSR|S_IXUSR;
|
|
|
|
|
}
|
|
|
|
|
ret= chmod(disk_path, mode);
|
|
|
|
|
if(ret==-1) {
|
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
@ -2531,17 +2550,7 @@ int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
|
|
|
|
|
ret= Xorriso_fake_stbuf(xorriso, nfi, &stbuf, &node, 0);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
return(0);
|
|
|
|
|
if(flag&4) {
|
|
|
|
|
ret= Permstack_push(&(xorriso->perm_stack), nd, &stbuf, 0);
|
|
|
|
|
if(ret<=0) {
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, nfd, 0, "ERRFILE", 0);
|
|
|
|
|
strcpy(xorriso->info_text,
|
|
|
|
|
"Cannot memorize permissions for disk directory");
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
|
|
|
|
|
return(-1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ret= Xorriso_restore_properties(xorriso, nd, node, !!(flag&2));
|
|
|
|
|
ret= Xorriso_restore_properties(xorriso, nd, node, ((flag>>1)&3));
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
return(ret);
|
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
@ -2731,6 +2740,394 @@ ex:;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle overwrite situation in disk filesystem.
|
|
|
|
|
@param flag
|
|
|
|
|
bit4= return 3 on rejection by exclusion or user
|
|
|
|
|
*/
|
|
|
|
|
int Xorriso_restore_overwrite(struct XorrisO *xorriso, char *img_path,
|
|
|
|
|
char *path, char *nominal_path,
|
|
|
|
|
struct stat *stbuf, int flag)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
char sfe[5*SfileadrL], sfe2[5*SfileadrL];
|
|
|
|
|
|
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
|
if(xorriso->do_overwrite==1 ||
|
|
|
|
|
(xorriso->do_overwrite==2 && !S_ISDIR(stbuf->st_mode))) {
|
|
|
|
|
ret= Xorriso_rmx(xorriso, (off_t) 0, path, 1|8);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
return(ret);
|
|
|
|
|
if(ret==3) {
|
|
|
|
|
sprintf(xorriso->info_text, "User revoked restoring of (ISO) file: %s",
|
|
|
|
|
Text_shellsafe(img_path, sfe, 0));
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
|
return(3*!!(flag&16));
|
|
|
|
|
}
|
|
|
|
|
return(1);
|
|
|
|
|
}
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, nominal_path, 0, "ERRFILE", 0);
|
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
|
"While restoring %s : %s exists and may not be overwritten",
|
|
|
|
|
Text_shellsafe(nominal_path, sfe, 0), strcmp(nominal_path, path)==0 ?
|
|
|
|
|
"file object" : Text_shellsafe(path, sfe2, 0));
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
@param flag
|
|
|
|
|
bit1= do not report copied files
|
|
|
|
|
bit2= -follow, -not_*: this is not a command parameter
|
|
|
|
|
bit3= keep directory open: keep owner, allow rwx for owner
|
|
|
|
|
bit6= this is a copy action: do not fake times and ownership
|
|
|
|
|
@return <=0 = error , 1 = added leaf file object , 2 = added directory ,
|
|
|
|
|
*/
|
|
|
|
|
int Xorriso_restore_disk_object(struct XorrisO *xorriso,
|
|
|
|
|
char *img_path, IsoNode *node,
|
|
|
|
|
char *disk_path,
|
|
|
|
|
int flag)
|
|
|
|
|
{
|
|
|
|
|
int ret, i, split_count= 0, partno, total_parts, leaf_is_split= 0;
|
|
|
|
|
off_t offset, bytes, total_bytes;
|
|
|
|
|
char *part_name, part_path[SfileadrL], *img_path_pt;
|
|
|
|
|
char sfe[5*SfileadrL], sfe2[5*SfileadrL];
|
|
|
|
|
IsoImage *volume;
|
|
|
|
|
IsoNode *part_node, *first_part_node= NULL;
|
|
|
|
|
struct SplitparT *split_parts= NULL;
|
|
|
|
|
struct stat stbuf;
|
|
|
|
|
|
|
|
|
|
ret= Xorriso_get_volume(xorriso, &volume, 0);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto ex;
|
|
|
|
|
|
|
|
|
|
if(LIBISO_ISDIR(node) && xorriso->do_concat_split)
|
|
|
|
|
leaf_is_split= Xorriso_identify_split(xorriso, img_path, node,
|
|
|
|
|
&split_parts, &split_count, &stbuf, 1|2);
|
|
|
|
|
if(leaf_is_split) {
|
|
|
|
|
/* map all files in directory img_path into regular file disk_path */
|
|
|
|
|
|
|
|
|
|
for(i=0 ; i<split_count; i++) {
|
|
|
|
|
Splitparts_get(split_parts, i, &part_name, &partno, &total_parts,
|
|
|
|
|
&offset, &bytes, &total_bytes, 0);
|
|
|
|
|
|
|
|
|
|
strcpy(part_path, img_path);
|
|
|
|
|
if(Sfile_add_to_path(part_path, part_name, 0)<=0) {
|
|
|
|
|
Xorriso_much_too_long(xorriso, strlen(img_path)+strlen(part_name)+1, 2);
|
|
|
|
|
goto restoring_failed;
|
|
|
|
|
}
|
|
|
|
|
ret= Xorriso_node_from_path(xorriso, volume, part_path, &part_node, 0);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto restoring_failed;
|
|
|
|
|
if(i==0)
|
|
|
|
|
first_part_node= part_node;
|
|
|
|
|
if(offset+bytes>total_bytes)
|
|
|
|
|
bytes= total_bytes-offset;
|
|
|
|
|
ret= Xorriso_tree_restore_node(xorriso, part_node, part_path, disk_path,
|
|
|
|
|
offset, bytes,
|
|
|
|
|
(!!(flag&64)) | 2 | (flag&4) | 8);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto restoring_failed;
|
|
|
|
|
}
|
|
|
|
|
if(first_part_node!=NULL)
|
|
|
|
|
Xorriso_restore_properties(xorriso, disk_path, first_part_node,
|
|
|
|
|
!!(flag&64));
|
|
|
|
|
goto went_well;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef Osirrox_not_yeT
|
|
|
|
|
|
|
|
|
|
if(resolve_link) {
|
|
|
|
|
ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto ex;
|
|
|
|
|
disk_path_pt= resolved_disk_path;
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
|
|
#endif /* Osirrox_not_yeT */
|
|
|
|
|
|
|
|
|
|
img_path_pt= img_path;
|
|
|
|
|
|
|
|
|
|
ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, disk_path,
|
|
|
|
|
(off_t) 0, (off_t) 0,
|
|
|
|
|
(flag&(4|8)) | !!(flag&64));
|
|
|
|
|
if(ret>0 && (flag&8))
|
|
|
|
|
ret= Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64));
|
|
|
|
|
if(ret<=0) {
|
|
|
|
|
restoring_failed:;
|
|
|
|
|
sprintf(xorriso->info_text, "Restoring 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);
|
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
|
}
|
|
|
|
|
if(ret==2)
|
|
|
|
|
{ret= 3; goto ex;}
|
|
|
|
|
went_well:;
|
|
|
|
|
xorriso->pacifier_count++;
|
|
|
|
|
if(xorriso->pacifier_count%100 && !(flag&2))
|
|
|
|
|
Xorriso_pacifier_callback(xorriso, "files restored",
|
|
|
|
|
xorriso->pacifier_count,
|
|
|
|
|
xorriso->pacifier_total, "", 0);
|
|
|
|
|
ret= 1;
|
|
|
|
|
ex:;
|
|
|
|
|
if(split_parts!=NULL)
|
|
|
|
|
Splitparts_destroy(&split_parts, split_count, 0);
|
|
|
|
|
return(ret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* @param flag bit0= recursion is active
|
|
|
|
|
bit1= do not report restored files
|
|
|
|
|
bit6= this is a copy action: do not fake times and ownership
|
|
|
|
|
*/
|
|
|
|
|
int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir,
|
|
|
|
|
char *img_dir_path, char *disk_dir_path,
|
|
|
|
|
off_t boss_mem,
|
|
|
|
|
struct LinkiteM *link_stack, int flag)
|
|
|
|
|
{
|
|
|
|
|
IsoImage *volume;
|
|
|
|
|
IsoNode *node;
|
|
|
|
|
IsoDirIter *iter= NULL;
|
|
|
|
|
IsoNode **node_array= NULL;
|
|
|
|
|
int node_count, node_idx;
|
|
|
|
|
int ret, target_is_dir, source_is_dir, source_is_link, fret, was_failure= 0;
|
|
|
|
|
int do_not_dive, source_is_split= 0, len_dp, len_ip, stbuf_ret, hflag, hret;
|
|
|
|
|
char *name, *disk_name, *leaf_name, *srcpt, *stbuf_src= "";
|
|
|
|
|
struct stat stbuf, target_stbuf;
|
|
|
|
|
struct LinkiteM *own_link_stack;
|
|
|
|
|
char *sfe= NULL, *sfe2= NULL;
|
|
|
|
|
char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
|
|
|
|
|
off_t mem;
|
|
|
|
|
struct PermiteM *perm_stack_mem;
|
|
|
|
|
|
|
|
|
|
perm_stack_mem= xorriso->perm_stack;
|
|
|
|
|
|
|
|
|
|
/* Avoiding large local memory objects in order to save stack space */
|
|
|
|
|
sfe= malloc(5*SfileadrL);
|
|
|
|
|
sfe2= malloc(5*SfileadrL);
|
|
|
|
|
disk_path= malloc(2*SfileadrL);
|
|
|
|
|
img_path= malloc(2*SfileadrL);
|
|
|
|
|
link_target= malloc(SfileadrL);
|
|
|
|
|
if(sfe==NULL || sfe2==NULL || disk_path==NULL || img_path==NULL ||
|
|
|
|
|
link_target==NULL) {
|
|
|
|
|
Xorriso_no_malloc_memory(xorriso, &sfe, 0);
|
|
|
|
|
{ret= -1; goto ex;}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
own_link_stack= link_stack;
|
|
|
|
|
|
|
|
|
|
ret= Xorriso_get_volume(xorriso, &volume, 0);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto ex;
|
|
|
|
|
|
|
|
|
|
stbuf_src= img_dir_path;
|
|
|
|
|
node= (IsoNode *) dir;
|
|
|
|
|
ret= Xorriso_fake_stbuf(xorriso, stbuf_src, &stbuf, &node, 1);
|
|
|
|
|
if(ret<=0) {
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0);
|
|
|
|
|
sprintf(xorriso->info_text,"Cannot open as (ISO) source directory: %s",
|
|
|
|
|
Text_shellsafe(img_dir_path, sfe, 0));
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef Osirrox_not_yeT
|
|
|
|
|
|
|
|
|
|
dev_t dir_dev;
|
|
|
|
|
dir_dev= stbuf.st_dev;
|
|
|
|
|
|
|
|
|
|
if(S_ISLNK(stbuf.st_mode)) {
|
|
|
|
|
if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
|
|
|
|
|
{ret= 2; goto ex;}
|
|
|
|
|
stbuf_src= disk_dir_path;
|
|
|
|
|
if(stat(disk_dir_path, &stbuf)==-1)
|
|
|
|
|
goto cannot_open_dir;
|
|
|
|
|
if(dir_dev != stbuf.st_dev &&
|
|
|
|
|
!(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1))))
|
|
|
|
|
{ret= 2; goto ex;}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* Osirrox_not_yeT */
|
|
|
|
|
|
|
|
|
|
if(!S_ISDIR(stbuf.st_mode)) {
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0);
|
|
|
|
|
sprintf(xorriso->info_text,"Is not a directory in ISO image: %s",
|
|
|
|
|
Text_shellsafe(img_dir_path, sfe, 0));
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mem= boss_mem;
|
|
|
|
|
ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
|
|
|
|
|
&node_idx, &node, 1|4);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto ex;
|
|
|
|
|
|
|
|
|
|
if(Sfile_str(img_path, img_dir_path,0)<=0) {
|
|
|
|
|
much_too_long:;
|
|
|
|
|
Xorriso_much_too_long(xorriso, SfileadrL, 2);
|
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
|
}
|
|
|
|
|
if(img_path[0]==0 || img_path[strlen(img_path)-1]!='/')
|
|
|
|
|
strcat(img_path,"/");
|
|
|
|
|
name= img_path+strlen(img_path);
|
|
|
|
|
if(Sfile_str(disk_path, disk_dir_path, 0)<=0)
|
|
|
|
|
goto much_too_long;
|
|
|
|
|
if(disk_path[0] || disk_path[strlen(disk_path)-1]!='/')
|
|
|
|
|
strcat(disk_path,"/");
|
|
|
|
|
disk_name= disk_path+strlen(disk_path);
|
|
|
|
|
|
|
|
|
|
len_dp= strlen(disk_path);
|
|
|
|
|
len_ip= strlen(img_path);
|
|
|
|
|
|
|
|
|
|
while(1) { /* loop over ISO directory content */
|
|
|
|
|
stbuf_src= "";
|
|
|
|
|
|
|
|
|
|
#ifdef Osirrox_not_yeT
|
|
|
|
|
|
|
|
|
|
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
srcpt= img_path;
|
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
|
ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
|
|
|
|
|
&node_idx, &node, 0);
|
|
|
|
|
if(ret<0)
|
|
|
|
|
goto ex;
|
|
|
|
|
if(ret==0 || xorriso->request_to_abort)
|
|
|
|
|
break;
|
|
|
|
|
leaf_name= (char *) iso_node_get_name(node);
|
|
|
|
|
if(Xorriso_much_too_long(xorriso, len_dp + strlen(leaf_name)+1, 0)<=0)
|
|
|
|
|
{ret= 0; goto was_problem;}
|
|
|
|
|
if(Xorriso_much_too_long(xorriso, len_ip + strlen(leaf_name)+1, 0)<=0)
|
|
|
|
|
{ret= 0; goto was_problem;}
|
|
|
|
|
/* name is a pointer into img_path */
|
|
|
|
|
strcpy(name, leaf_name);
|
|
|
|
|
strcpy(disk_name, leaf_name);
|
|
|
|
|
|
|
|
|
|
stbuf_src= srcpt;
|
|
|
|
|
ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 1);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto was_problem;
|
|
|
|
|
source_is_dir= 0;
|
|
|
|
|
source_is_link= S_ISLNK(stbuf.st_mode);
|
|
|
|
|
|
|
|
|
|
#ifdef Osirrox_not_yeT
|
|
|
|
|
|
|
|
|
|
if(xorriso->do_follow_links && source_is_link) {
|
|
|
|
|
/* Xorriso_hop_link checks for wide link loops */
|
|
|
|
|
ret= Xorriso_hop_link(xorriso, srcpt, &own_link_stack, &hstbuf, 0);
|
|
|
|
|
if(ret<0)
|
|
|
|
|
goto was_problem;
|
|
|
|
|
if(ret==1) {
|
|
|
|
|
ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto was_problem;
|
|
|
|
|
srcpt= link_target;
|
|
|
|
|
stbuf_src= srcpt;
|
|
|
|
|
if(lstat(srcpt, &stbuf)==-1)
|
|
|
|
|
goto cannot_lstat;
|
|
|
|
|
} else {
|
|
|
|
|
if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0)
|
|
|
|
|
{ret= 0; goto was_problem;}
|
|
|
|
|
}
|
|
|
|
|
} else if (S_ISLNK(stbuf.st_mode)) {
|
|
|
|
|
ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto was_problem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* Osirrox_not_yeT */
|
|
|
|
|
|
|
|
|
|
do_not_dive= 0;
|
|
|
|
|
if(S_ISDIR(stbuf.st_mode))
|
|
|
|
|
source_is_dir= 1;
|
|
|
|
|
source_is_split= 0;
|
|
|
|
|
if(source_is_dir)
|
|
|
|
|
source_is_split= Xorriso_is_split(xorriso, img_path, node, 1|2);
|
|
|
|
|
if(source_is_split)
|
|
|
|
|
do_not_dive= 1;
|
|
|
|
|
|
|
|
|
|
/* does a disk file exist with this name ? */
|
|
|
|
|
stbuf_ret= lstat(disk_path, &target_stbuf);
|
|
|
|
|
if(stbuf_ret!=-1) {
|
|
|
|
|
target_is_dir= S_ISDIR(target_stbuf.st_mode);
|
|
|
|
|
if(!(target_is_dir && (source_is_dir && !source_is_split))) {
|
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
|
ret= Xorriso_restore_overwrite(xorriso, img_path, disk_path, disk_path,
|
|
|
|
|
&target_stbuf, 0);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto was_problem;
|
|
|
|
|
stbuf_ret= -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(stbuf_ret!=-1) { /* (Can only happen with directory) */
|
|
|
|
|
|
|
|
|
|
/* ??? >>> eventually open access to existing directory ? */;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
hflag= 4 | (flag & (2|64));
|
|
|
|
|
if(source_is_dir && !do_not_dive)
|
|
|
|
|
hflag|= 8; /* keep directory open for user */
|
|
|
|
|
ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
|
|
|
|
|
hflag);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto was_problem;
|
|
|
|
|
}
|
|
|
|
|
if(source_is_dir && !do_not_dive) {
|
|
|
|
|
ret= Xorriso_restore_tree(xorriso, (IsoDir *) node,
|
|
|
|
|
img_path, disk_path, mem,
|
|
|
|
|
own_link_stack, 1|(flag&2));
|
|
|
|
|
/* eventually restore exact access permissions of directory */
|
|
|
|
|
hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
|
|
|
|
|
!!(flag&64));
|
|
|
|
|
if(hret<=0 && hret<ret)
|
|
|
|
|
ret= hret;
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto was_problem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
continue; /* regular bottom of loop */
|
|
|
|
|
was_problem:;
|
|
|
|
|
was_failure= 1;
|
|
|
|
|
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
|
|
|
|
|
if(fret<0)
|
|
|
|
|
goto ex;
|
|
|
|
|
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret= 1;
|
|
|
|
|
ex:
|
|
|
|
|
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64));
|
|
|
|
|
if(sfe!=NULL)
|
|
|
|
|
free(sfe);
|
|
|
|
|
if(sfe2!=NULL)
|
|
|
|
|
free(sfe2);
|
|
|
|
|
if(disk_path!=NULL)
|
|
|
|
|
free(disk_path);
|
|
|
|
|
if(img_path!=NULL)
|
|
|
|
|
free(img_path);
|
|
|
|
|
if(link_target!=NULL)
|
|
|
|
|
free(link_target);
|
|
|
|
|
Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
|
|
|
|
|
&node_idx, &node, (1<<31));
|
|
|
|
|
|
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
|
|
|
|
|
|
#ifdef Osirrox_not_yeT
|
|
|
|
|
|
|
|
|
|
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
return(ret);
|
|
|
|
|
return(!was_failure);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
@param flag
|
|
|
|
|
>>> bit0= mkdir: graft in as empty directory, not as copy from iso
|
|
|
|
@ -2747,15 +3144,12 @@ int Xorriso_restore(struct XorrisO *xorriso,
|
|
|
|
|
char *img_path, char *disk_path, int flag)
|
|
|
|
|
{
|
|
|
|
|
IsoImage *volume;
|
|
|
|
|
char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL], sfe2[5*SfileadrL];
|
|
|
|
|
char *img_path_pt, *part_name;
|
|
|
|
|
IsoNode *node= NULL, *part_node, *first_part_node= NULL;
|
|
|
|
|
char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL];
|
|
|
|
|
IsoNode *node= NULL;
|
|
|
|
|
int done= 0, is_dir= 0, ret, target_is_dir, source_is_dir, stbuf_ret, hret;
|
|
|
|
|
int leaf_is_split= 0, source_is_split= 0, split_count, partno, total_parts, i;
|
|
|
|
|
off_t offset, bytes, total_bytes;
|
|
|
|
|
int leaf_is_split= 0, source_is_split= 0;
|
|
|
|
|
struct stat stbuf, target_stbuf;
|
|
|
|
|
struct PermiteM *perm_stack_mem;
|
|
|
|
|
struct SplitparT *split_parts= NULL;
|
|
|
|
|
|
|
|
|
|
perm_stack_mem= xorriso->perm_stack;
|
|
|
|
|
|
|
|
|
@ -2802,8 +3196,7 @@ int Xorriso_restore(struct XorrisO *xorriso,
|
|
|
|
|
ret= 0; goto ex;
|
|
|
|
|
}
|
|
|
|
|
if(is_dir && xorriso->do_concat_split)
|
|
|
|
|
leaf_is_split= Xorriso_identify_split(xorriso, img_path, node,
|
|
|
|
|
&split_parts, &split_count, &stbuf, 1|2);
|
|
|
|
|
leaf_is_split= Xorriso_is_split(xorriso, img_path, node, 1|2);
|
|
|
|
|
}
|
|
|
|
|
for(npt= apt; !done; apt= npt+1) {
|
|
|
|
|
npt= strchr(apt, '/');
|
|
|
|
@ -2825,32 +3218,13 @@ int Xorriso_restore(struct XorrisO *xorriso,
|
|
|
|
|
if(stbuf_ret!=-1) {
|
|
|
|
|
target_is_dir= S_ISDIR(target_stbuf.st_mode);
|
|
|
|
|
if(!(target_is_dir && (source_is_dir && !source_is_split))) {
|
|
|
|
|
Xorriso_process_msg_queues(xorriso,0);
|
|
|
|
|
/* handle overwrite situation */
|
|
|
|
|
if(xorriso->do_overwrite==1 ||
|
|
|
|
|
(xorriso->do_overwrite==2 && !target_is_dir)) {
|
|
|
|
|
ret= Xorriso_rmx(xorriso, (off_t) 0, path, 1|8);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto ex;
|
|
|
|
|
if(ret==3) {
|
|
|
|
|
sprintf(xorriso->info_text, "User revoked restoring of: %s",
|
|
|
|
|
Text_shellsafe(disk_path, sfe, 0));
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
|
|
|
|
{ret= 3*!!(flag&16); goto ex;}
|
|
|
|
|
}
|
|
|
|
|
stbuf_ret= -1;
|
|
|
|
|
goto handle_path_node;
|
|
|
|
|
}
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
|
|
|
|
|
sprintf(xorriso->info_text,
|
|
|
|
|
"While restoring '%s' : '%s' exists and may not be overwritten",
|
|
|
|
|
disk_path, path);
|
|
|
|
|
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
|
ret= Xorriso_restore_overwrite(xorriso, img_path, path, disk_path,
|
|
|
|
|
&target_stbuf, flag&16);
|
|
|
|
|
if(ret<=0 || ret==3)
|
|
|
|
|
goto ex;
|
|
|
|
|
stbuf_ret= -1; /* now it is removed */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handle_path_node:;
|
|
|
|
|
if(stbuf_ret==-1 && (source_is_dir && !source_is_split)) {
|
|
|
|
|
/* make a directory */
|
|
|
|
|
ret= mkdir(path, 0777);
|
|
|
|
@ -2881,81 +3255,20 @@ attach_source:;
|
|
|
|
|
/* directory was created above */;
|
|
|
|
|
|
|
|
|
|
} else if(is_dir && !source_is_split) {
|
|
|
|
|
Xorriso_restore_properties(xorriso, disk_path, node, !!(flag&64));
|
|
|
|
|
|
|
|
|
|
#ifdef Osirrox_not_yeT
|
|
|
|
|
|
|
|
|
|
/* >>> */
|
|
|
|
|
|
|
|
|
|
Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64));
|
|
|
|
|
if(!(flag&32)) {
|
|
|
|
|
ret= Xorriso_add_tree(xorriso, dir, img_path, path, NULL,
|
|
|
|
|
flag&2);
|
|
|
|
|
ret= Xorriso_restore_tree(xorriso, (IsoDir *) node, img_path, path,
|
|
|
|
|
(off_t) 0, NULL, flag&(2|64));
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto ex;
|
|
|
|
|
if(!(flag&64)) /* set timestamps which Permstack_pop() will not set */
|
|
|
|
|
Xorriso_restore_properties(xorriso, disk_path, node, 2);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
if(source_is_split) {
|
|
|
|
|
/* map all files in directory img_path into regular file disk_path */
|
|
|
|
|
|
|
|
|
|
for(i=0 ; i<split_count; i++) {
|
|
|
|
|
Splitparts_get(split_parts, i, &part_name, &partno, &total_parts,
|
|
|
|
|
&offset, &bytes, &total_bytes, 0);
|
|
|
|
|
strcpy(sfe2, img_path);
|
|
|
|
|
if(Sfile_add_to_path(sfe2, part_name, 0)<=0) {
|
|
|
|
|
Xorriso_much_too_long(xorriso,
|
|
|
|
|
strlen(img_path)+strlen(part_name)+1, 2);
|
|
|
|
|
goto restoring_failed;
|
|
|
|
|
}
|
|
|
|
|
ret= Xorriso_node_from_path(xorriso, volume, sfe2, &part_node, 0);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto restoring_failed;
|
|
|
|
|
if(i==0)
|
|
|
|
|
first_part_node= part_node;
|
|
|
|
|
if(offset+bytes>total_bytes)
|
|
|
|
|
bytes= total_bytes-offset;
|
|
|
|
|
ret= Xorriso_tree_restore_node(xorriso, part_node, sfe2, path,
|
|
|
|
|
offset, bytes,
|
|
|
|
|
(!!(flag&64)) | 2 | (flag&4) | 8);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto restoring_failed;
|
|
|
|
|
}
|
|
|
|
|
if(first_part_node!=NULL)
|
|
|
|
|
Xorriso_restore_properties(xorriso, path, first_part_node,
|
|
|
|
|
!!(flag&64));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
#ifdef Osirrox_not_yeT
|
|
|
|
|
|
|
|
|
|
} else if(resolve_link) {
|
|
|
|
|
ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto ex;
|
|
|
|
|
disk_path_pt= resolved_disk_path;
|
|
|
|
|
|
|
|
|
|
#endif /* Osirrox_not_yeT */
|
|
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
img_path_pt= img_path;
|
|
|
|
|
|
|
|
|
|
ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, path,
|
|
|
|
|
(off_t) 0, (off_t) 0,
|
|
|
|
|
(flag&4) | !!(flag&64));
|
|
|
|
|
if(ret<=0) {
|
|
|
|
|
restoring_failed:;
|
|
|
|
|
sprintf(xorriso->info_text, "Restoring 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);
|
|
|
|
|
{ret= 0; goto ex;}
|
|
|
|
|
}
|
|
|
|
|
if(ret==2)
|
|
|
|
|
{ret= 3; goto ex;}
|
|
|
|
|
xorriso->pacifier_count++;
|
|
|
|
|
if(xorriso->pacifier_count%100 && !(flag&2))
|
|
|
|
|
Xorriso_pacifier_callback(xorriso, "files restored",
|
|
|
|
|
xorriso->pacifier_count,
|
|
|
|
|
xorriso->pacifier_total, "", 0);
|
|
|
|
|
ret= Xorriso_restore_disk_object(xorriso, img_path, node, path,
|
|
|
|
|
flag & (2|4|64));
|
|
|
|
|
if(ret<=0)
|
|
|
|
|
goto ex;
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
*npt= '/';
|
|
|
|
@ -2965,11 +3278,9 @@ restoring_failed:;
|
|
|
|
|
ex:;
|
|
|
|
|
/* restore exact access permissions of stacked paths */
|
|
|
|
|
hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
|
|
|
|
|
!!(flag&64));
|
|
|
|
|
2 | !!(flag&64));
|
|
|
|
|
if(hret<=0 && hret<ret)
|
|
|
|
|
ret= hret;
|
|
|
|
|
if(split_parts!=NULL)
|
|
|
|
|
Splitparts_destroy(&split_parts, split_count, 0);
|
|
|
|
|
return(ret);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -6058,7 +6369,7 @@ int Xorriso_is_split(struct XorrisO *xorriso, char *path, void *node,
|
|
|
|
|
struct stat stbuf;
|
|
|
|
|
|
|
|
|
|
ret= Xorriso_identify_split(xorriso, path, node, &split_parts,
|
|
|
|
|
&split_count, &stbuf, flag&1);
|
|
|
|
|
&split_count, &stbuf, flag & 3);
|
|
|
|
|
if(split_parts!=NULL)
|
|
|
|
|
Splitparts_destroy(&split_parts, split_count, 0);
|
|
|
|
|
return(ret>0);
|
|
|
|
|