New options -cpax, -cp_rx, cp_rax to restore files and trees from ISO to disk
This commit is contained in:
parent
440247dc98
commit
b595c7f836
@ -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
|
||||
|
@ -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;
|
||||
|
@ -1 +1 @@
|
||||
#define Xorriso_timestamP "2008.06.02.141334"
|
||||
#define Xorriso_timestamP "2008.06.05.165023"
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user