New options -cpax, -cp_rx, cp_rax to restore files and trees from ISO to disk

This commit is contained in:
Thomas Schmitt 2008-06-05 16:51:04 +00:00
parent 6ab1b7cd7d
commit 85eba6610a
4 changed files with 502 additions and 137 deletions

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1)
.TH XORRISO 1 "Jun, 02, 2008"
.TH XORRISO 1 "Jun, 5, 2008"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -146,7 +146,7 @@ There are two families of media in the MMC standard:
unformatted DVD-RW. These media provide a table of content which
describes their existing sessions. See option \fB-toc\fR.
.br
\fBOverwriteable\fR media are DVD-RAM, DVD+RW, and formatted DVD-RW.
\fBOverwriteable\fR media are DVD-RAM, DVD+RW, BD-RE, and formatted DVD-RW.
They allow random write access but do not provide information about their
session history. If they contain one or more ISO 9660 sessions and if the
first session was written by xorriso, then a table of content can
@ -181,7 +181,7 @@ Appendable is the state after writing a session with option -close off.
for xorriso.
.br
Closed is the state of DVD-ROM media and of multi-session media which were
written with option -close on. If the drive is incapable of writing it will
written with option -close on. If the drive is read-only hardware then it will
probably show any media as closed CD-ROM resp. DVD-ROM.
.br
Overwriteable media assume this state in such read-only drives or if they
@ -1140,6 +1140,9 @@ With setting "nondir", only directories are protected by such events, other
existing file types get treated with -rm before the new file gets added.
Setting "on" allows automatic -rm_r. I.e. a non-directory can replace an
existing directory and all its subordinates.
.br
If restoring of files is enabled, then the overwrite rule applies to the
target file objects on disk as well.
.TP
\fB\-split_size\fR number["k"|"m"]
Set the threshold for automatic splitting of regular files. Such splitting
@ -1385,6 +1388,8 @@ If "on" then ask the user for "y" or "n":
.br
before deleting or overwriting any file in the ISO image,
.br
before overwriting any disk file during restore operations,
.br
before rolling back pending image changes,
.br
before committing image changes to media,
@ -1602,12 +1607,19 @@ Normally xorriso only writes to disk files which were given as stdio:
pseudo-drives or as log files.
But its alter ego, osirrox, is able to extract file objects
from ISO images and to create, overwrite, or delete file objects on disk.
.br
Disk file exclusions by -not_mgt, -not_leaf, -not_paths apply.
If disk file objects already exist then the settings of -overwrite and
-reassure apply.
.TP
\fB\-osirrox\fR "on"|"device_files"|"off"[:option:...]
Setting "off" disables disk filesystem manipulations. This is the default
unless the program was started with leafname "osirrox". Elsewise
the capability to restore files can be enabled explicitly by -osirrox "on".
.br
Access permissions of files in the ISO image do not restrict restoring.
The permissions on disk have to allow writing, of course.
.br
To enable restoring of special files by "device_files" is potentially
dangerous.
The meaning of the number st_rdev (see man 2 stat) depends much on the
@ -1624,7 +1636,7 @@ directories as data files if the directory contains a complete collection
of -cut_out part files.
.br
With option "concat_split_off" such directories are
handled as any other ISO image directory.
handled like any other ISO image directory.
.TP
\fB\-cpx\fR iso_rr_path [***] disk_path
Extract single leaf file objects from the ISO image and store them under
@ -1633,13 +1645,26 @@ disk_path must be a directory or non-existent. In the latter case it gets
created. The extracted files get installed in it with the same leafnames.
.br
Missing directory components in disk_path will get created, if possible.
Disk file exclusions are in effect. If this is undesired then perform
-not_mgt "off" first.
.br
Directories are allowed as iso_rr_path only with -osirrox "concat_split_on"
and only if they actually represent a complete collection of -cut_out split
file parts.
.TP
\fB\-cpax\fR iso_rr_path [***] disk_path
Like -cpx but restoring mtime, atime as in ISO image and trying to set
ownership and group as in ISO image.
.TP
\fB\-cp_rx\fR iso_rr_path [***] disk_path
Like -cpx but also extracting whole directory trees from the ISO image.
If directories do already exist under disk_path then their content
eventually gets merged with the content of restored directories
of the same name. Disk files get removed only if they are to be replaced
by file objects from the ISO image.
.TP
\fB\-cp_rax\fR iso_rr_path [***] disk_path
Like -cp_rx but restoring mtime, atime as in ISO image and trying to set
ownership and group as in ISO image.
.TP
.B Command compatibility emulations:
.PP
Writing of ISO 9660 on CD is traditionally done by program mkisofs

View File

@ -2692,12 +2692,14 @@ failed:;
/* @param flag bit0= minimal transfer: access permissions only
bit1= do not set timestamps
*/
int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
struct XorrisO *xorriso, int flag)
{
int ret;
char sfe[5*SfileadrL];
struct utimbuf utime_buffer;
struct PermiteM *m, *m_next;
if((*o)==stopper)
@ -2723,9 +2725,22 @@ int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
0);
}
}
if(!(flag&1))
if(!(flag&1)) {
chown(m->disk_path, m->stbuf.st_uid, m->stbuf.st_gid);
/* don't complain if it fails */
if(!(flag&2)) {
utime_buffer.actime= m->stbuf.st_atime;
utime_buffer.modtime= m->stbuf.st_mtime;;
ret= utime(m->disk_path,&utime_buffer);
if(ret==-1 && xorriso!=NULL) {
sprintf(xorriso->info_text,
"Cannot change timestamps of disk directory: %s",
Text_shellsafe(m->disk_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",
0);
}
}
}
m_next= m->next;
free(m->disk_path);
free((char *) m);
@ -8711,7 +8726,10 @@ ex:;
}
/* Option -cpx */
/* Options -cpx , -cpax, -cp_rx , -cp_rax */
/* @param flag bit0= recursive (-cp_rx, -cp_rax)
bit1= full property restore (-cpax, -cp_rax)
*/
int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag)
{
@ -8722,7 +8740,7 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
char **optv= NULL;
struct stat stbuf;
ret= Xorriso_cpmv_args(xorriso, "-cpx", argc, argv, idx,
ret= Xorriso_cpmv_args(xorriso, "-cp*x", argc, argv, idx,
&optc, &optv, eff_dest, 1|4);
if(ret<=0)
goto ex;
@ -8738,7 +8756,7 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
}
if(xorriso->volset_change_pending) {
sprintf(xorriso->info_text,
"-cpx: Image changes pending. May not copy from image to disk.\n");
"-cp*x: Image changes pending. May not copy from image to disk.\n");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
@ -8754,7 +8772,7 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
ret= Xorriso_iso_lstat(xorriso, eff_origin, &stbuf, 2|4);
if(ret==-1)
goto problem_handler;
if(S_ISDIR(stbuf.st_mode)) {
if(S_ISDIR(stbuf.st_mode) && !(flag&1)) {
/* only allow directories if they actually represent split data files */
ret= 0;
if(xorriso->do_concat_split)
@ -8782,7 +8800,7 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
goto problem_handler;
}
}
ret= Xorriso_restore(xorriso, eff_origin, eff_dest, 16|64);
ret= Xorriso_restore(xorriso, eff_origin, eff_dest, 16 | (!(flag&2)<<6));
if(ret<=0 || xorriso->request_to_abort)
goto problem_handler;
if(ret==3 || (flag&1))
@ -8804,7 +8822,7 @@ problem_handler:;
xorriso->pacifier_total, "", 1);
ret= !was_failure;
ex:;
Xorriso_opt_args(xorriso, "-cpx",
Xorriso_opt_args(xorriso, "-cp*x",
argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256);
return(ret);
}
@ -9728,9 +9746,15 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" to create, overwrite, delete files in the disk filesystem.",
" -cpx iso_rr_path [***] disk_path",
" Copy leaf file objects from ISO image to disk filesystem.",
" -cpax iso_rr_path [***] disk_path",
" Like -cpx but trying to restore timestamps and ownership.",
" -cp_rx iso_rr_path [***] disk_path",
" Copy directory trees from ISO image to disk filesystem.",
" -cp_rax iso_rr_path [***] disk_path",
" Like -cp_rx but trying to restore timestamps and ownership.",
"",
"Compatibility emulation (argument list may be ended by --):",
" -as mkisofs [-help|-o|-R|-J|-V|-P|-f|-graft-points|-path-list|pathspecs]",
" -as mkisofs [-help|-o|-R|-J|-V|-P|-f|-m|-graft-points|-path-list|pathspecs]",
" Perform some mkisofs gestures, understand pathspecs as mkisofs",
" does. Commit happens outside emulation at usual occasions.",
" -as cdrecord [-help|-v|dev=|speed=|blank=|fs=|-eject|-atip|padsize=|path|-]",
@ -11593,7 +11617,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
static char argn_commands[][40]= {
"add","as","chgrp","chgrpi","chgrp_r","chgrp_ri","chmod","chmodi",
"chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri",
"cpr","cpri","cpx",
"cpr","cpri","cp_rax","cp_rx","cpax","cpx",
"du","dui","dus","dusi","dux","dusx","find","findi","findx",
"ls","lsi","lsl","lsli","lsd","lsdi","lsdl","lsdli",
"lsx","lslx","lsdx","lsdlx","mv","mvi","mkdir","mkdiri",
@ -11810,8 +11834,13 @@ next_command:;
} else if(strcmp(cmd,"cpr")==0 || strcmp(cmd,"cpri")==0) {
ret= Xorriso_option_cpri(xorriso, argc, argv, idx, 0);
} else if(strcmp(cmd,"cpx")==0) {
ret= Xorriso_option_cpx(xorriso, argc, argv, idx, 0);
} else if(strcmp(cmd,"cp_rx")==0 || strcmp(cmd,"cp_rax")==0) {
ret= Xorriso_option_cpx(xorriso, argc, argv, idx,
1|((strcmp(cmd,"cp_rax")==0)<<1));
} else if(strcmp(cmd,"cpx")==0 || strcmp(cmd,"cpax")==0) {
ret= Xorriso_option_cpx(xorriso, argc, argv, idx,
(strcmp(cmd,"cpax")==0)<<1);
} else if(strcmp(cmd,"cut_out")==0) {
(*idx)+= 4;

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.06.02.141334"
#define Xorriso_timestamP "2008.06.05.165023"

View File

@ -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)
ret= Xorriso_restore_overwrite(xorriso, img_path, path, disk_path,
&target_stbuf, flag&16);
if(ret<=0 || ret==3)
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;}
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);
ret= Xorriso_restore_disk_object(xorriso, img_path, node, path,
flag & (2|4|64));
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);
}
} 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);