Implemented oncatenation of split files during -cpx

This commit is contained in:
Thomas Schmitt 2008-05-31 17:40:18 +00:00
parent b9f01ef512
commit 27f8339527
6 changed files with 256 additions and 116 deletions

View File

@ -1603,7 +1603,7 @@ pseudo-drives or as log files.
But its alter ego, osirrox, is able to extract file objects But its alter ego, osirrox, is able to extract file objects
from ISO images and to create, overwrite, or delete file objects on disk. from ISO images and to create, overwrite, or delete file objects on disk.
.TP .TP
\fB\-osirrox\fR "on"|"device_files"|"off" \fB\-osirrox\fR ["on"|"device_files"|"off"][:"concat_split_on"|"concat_split_off"]
Setting "off" disables disk filesystem manipulations. This is the default Setting "off" disables disk filesystem manipulations. This is the default
unless the program was started with leafname "osirrox". Elsewise unless the program was started with leafname "osirrox". Elsewise
the capability to restore files can be enabled explicitly by -osirrox "on". the capability to restore files can be enabled explicitly by -osirrox "on".
@ -1618,6 +1618,11 @@ are ignored during restore operations.
Due to a bug of previous versions, device files from previous sessions might Due to a bug of previous versions, device files from previous sessions might
have been altered to major=0, minor=1. So this combination does not get have been altered to major=0, minor=1. So this combination does not get
restored. restored.
.br
"concat_split_on" is default. It enables restoring of split file directories
as data files if the directory contains a complete collection of -cut_out
part files. With "concat_split_off" such directories are handled as any
other ISO image directory.
.TP .TP
\fB\-cpx\fR iso_rr_path [***] disk_path \fB\-cpx\fR iso_rr_path [***] disk_path
Extract single leaf file objects from the ISO image and store them under Extract single leaf file objects from the ISO image and store them under
@ -1628,6 +1633,10 @@ created. The extracted files get installed in it with the same leafnames.
Missing directory components in disk_path will get created, if possible. Missing directory components in disk_path will get created, if possible.
Disk file exclusions are in effect. If this is undesired then perform Disk file exclusions are in effect. If this is undesired then perform
-not_mgt "off" first. -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 .TP
.B Command compatibility emulations: .B Command compatibility emulations:
.PP .PP

View File

@ -2460,6 +2460,32 @@ int Splitpart__compose(char *adr, int partno, int total_parts,
} }
int Splitparts_cmp(const void *v1, const void *v2)
{
struct SplitparT *p1, *p2;
p1= (struct SplitparT *) v1;
p2= (struct SplitparT *) v2;
if(p1->partno>p2->partno)
return(1);
if(p1->partno<p2->partno)
return(-1);
if(p1->offset>p2->offset)
return(1);
if(p1->offset<p2->offset)
return(-1);
return(0);
}
int Splitparts_sort(struct SplitparT *o, int count, int flag)
{
qsort(o, (size_t) count, sizeof(struct SplitparT), Splitparts_cmp);
return(1);
}
/* ---------------------------- End SplitparT ------------------------- */ /* ---------------------------- End SplitparT ------------------------- */
/* ------------------------------ ExclusionS ------------------------------ */ /* ------------------------------ ExclusionS ------------------------------ */
@ -2795,6 +2821,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->patch_isolinux_image= 0; m->patch_isolinux_image= 0;
m->allow_graft_points= 0; m->allow_graft_points= 0;
m->allow_restore= 0; m->allow_restore= 0;
m->do_concat_split= 1;
m->dialog= 0; m->dialog= 0;
m->search_mode= 0; m->search_mode= 0;
m->structured_search= 1; m->structured_search= 1;
@ -3902,10 +3929,12 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
Xorriso_status_result(xorriso,filter,fp,flag&2); Xorriso_status_result(xorriso,filter,fp,flag&2);
} }
is_default= (xorriso->allow_restore==0); is_default= (xorriso->allow_restore==0 && xorriso->do_concat_split==1);
sprintf(line,"-osirrox %s\n", sprintf(line,"-osirrox %s:%s\n",
xorriso->allow_restore ? xorriso->allow_restore==2 ? "device_files" : "on" xorriso->allow_restore ? xorriso->allow_restore==2 ?
: "off"); "device_files" : "on" : "off",
xorriso->do_concat_split ? "concat_split_on" : "concat_split_off");
if(!(is_default && no_defaults)) if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2); Xorriso_status_result(xorriso,filter,fp,flag&2);
@ -4644,7 +4673,7 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
&offset, &bytes, &total_bytes, 0); &offset, &bytes, &total_bytes, 0);
strcpy(part_path, iso_adr); strcpy(part_path, iso_adr);
if(Sfile_add_to_path(part_path, part_name, 0)<=0) { if(Sfile_add_to_path(part_path, part_name, 0)<=0) {
Xorriso_much_too_long(xorriso, strlen(iso_adr)+strlen(part_path)+1, Xorriso_much_too_long(xorriso, strlen(iso_adr)+strlen(part_name)+1,
2); 2);
{ret= -1; goto ex;} {ret= -1; goto ex;}
} }
@ -8693,6 +8722,14 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
char **optv= NULL; char **optv= NULL;
struct stat stbuf; struct stat stbuf;
ret= Xorriso_cpmv_args(xorriso, "-cpx", argc, argv, idx,
&optc, &optv, eff_dest, 1|4);
if(ret<=0)
goto ex;
if(ret==2) {
is_dir= 1;
strcpy(dest_dir, eff_dest);
}
if(!xorriso->allow_restore) { if(!xorriso->allow_restore) {
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"-cpx: image-to-disk copies are not enabled by option -osirrox"); "-cpx: image-to-disk copies are not enabled by option -osirrox");
@ -8705,14 +8742,6 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex; ret= 0; goto ex;
} }
ret= Xorriso_cpmv_args(xorriso, "-cpx", argc, argv, idx,
&optc, &optv, eff_dest, 1|4);
if(ret<=0)
goto ex;
if(ret==2) {
is_dir= 1;
strcpy(dest_dir, eff_dest);
}
/* Perform copying */ /* Perform copying */
Xorriso_pacifier_reset(xorriso, 0); Xorriso_pacifier_reset(xorriso, 0);
@ -8726,11 +8755,19 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
if(ret==-1) if(ret==-1)
goto problem_handler; goto problem_handler;
if(S_ISDIR(stbuf.st_mode)) { if(S_ISDIR(stbuf.st_mode)) {
/* only allow directories if they actually represent split data files */
ret= 0;
if(xorriso->do_concat_split)
ret= Xorriso_is_split(xorriso, eff_origin, NULL, 2);
if(ret<0)
goto problem_handler;
if(ret==0) {
sprintf(xorriso->info_text, "-cpx: May not copy directory %s", sprintf(xorriso->info_text, "-cpx: May not copy directory %s",
Text_shellsafe(eff_origin, sfe, 0)); Text_shellsafe(eff_origin, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto problem_handler; ret= 0; goto problem_handler;
} }
}
if(is_dir) { if(is_dir) {
ret= Sfile_leafname(eff_origin, leafname, 0); ret= Sfile_leafname(eff_origin, leafname, 0);
@ -9684,8 +9721,8 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" -compare_r disk_path iso_rr_path ", " -compare_r disk_path iso_rr_path ",
" Like -compare but affecting all files below directories.", " Like -compare but affecting all files below directories.",
"", "",
"Restore options (copying file objects from ISO image to disk filesystem):", "Restore options which copy file objects from ISO image to disk filesystem:",
" -osirrox \"on\"|\"device_files\"|\"off\"", " -osirrox \"on\"|\"device_files\"|\"off\":\"concat_split_on\"|\"concat_split_off\"",
" By default \"off\" the inverse operation of xorriso from ISO", " By default \"off\" the inverse operation of xorriso from ISO",
" image to disk filesystem is disabled. \"on\" allows xorriso", " image to disk filesystem is disabled. \"on\" allows xorriso",
" to create, overwrite, delete files in the disk filesystem.", " to create, overwrite, delete files in the disk filesystem.",
@ -10567,17 +10604,35 @@ ex:;
/* Option -osirrox "on"|"off" */ /* Option -osirrox "on"|"off" */
int Xorriso_option_osirrox(struct XorrisO *xorriso, char *mode, int flag) int Xorriso_option_osirrox(struct XorrisO *xorriso, char *mode, int flag)
{ {
if(strcmp(mode, "off")==0) int l;
char *npt, *cpt;
npt= cpt= mode;
for(cpt= mode; npt!=NULL; cpt= npt+1) {
npt= strchr(cpt,':');
if(npt==NULL)
l= strlen(cpt);
else
l= npt-cpt;
if(l==0 && mode[0]!=0)
goto unknown_mode;
if(strncmp(cpt, "off", l)==0)
xorriso->allow_restore= 0; xorriso->allow_restore= 0;
else if(strcmp(mode, "device_files")==0) else if(strncmp(cpt, "device_files", l)==0)
xorriso->allow_restore= 2; xorriso->allow_restore= 2;
else if(strcmp(mode, "on")==0 || mode[0]==0) else if(strncmp(cpt, "on", l)==0 || mode[0]==0)
xorriso->allow_restore= 1; xorriso->allow_restore= 1;
else if(strncmp(cpt, "concat_split_on", l)==0)
xorriso->do_concat_split= 1;
else if(strncmp(cpt, "concat_split_off", l)==0)
xorriso->do_concat_split= 0;
else { else {
sprintf(xorriso->info_text, "-osirrox: unknown mode '%s'", mode); unknown_mode:;
sprintf(xorriso->info_text, "-osirrox: unknown mode '%s'", cpt);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0); return(0);
} }
}
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"%s copying of file objects from ISO image to disk filesystem\n", "%s copying of file objects from ISO image to disk filesystem\n",
xorriso->allow_restore ? "Enabled" : "Disabled"); xorriso->allow_restore ? "Enabled" : "Disabled");

View File

@ -161,6 +161,9 @@ struct XorrisO { /* the global context of xorriso */
int allow_graft_points; int allow_graft_points;
int allow_restore; /* 0= disallowed, 1=allowed, 2=device files allowed */ int allow_restore; /* 0= disallowed, 1=allowed, 2=device files allowed */
int do_concat_split; /* 1= restore complete split file directories as
regular files
*/
int dialog; int dialog;
@ -534,6 +537,8 @@ int Splitpart__parse(char *name, int *partno, int *total_parts,
int Splitpart__compose(char *adr, int partno, int total_parts, int Splitpart__compose(char *adr, int partno, int total_parts,
off_t offset, off_t bytes, off_t total_bytes, int flag); off_t offset, off_t bytes, off_t total_bytes, int flag);
int Splitparts_sort(struct SplitparT *o, int count, int flag);
struct LstrinG { struct LstrinG {
char *text; char *text;
struct LstrinG *prev,*next; struct LstrinG *prev,*next;

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.05.27.201513" #define Xorriso_timestamP "2008.05.31.174045"

View File

@ -69,8 +69,6 @@ int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume,
off_t offset, off_t cut_size, off_t offset, off_t cut_size,
IsoNode **node, int flag); IsoNode **node, int flag);
int Xorriso_is_split(struct XorrisO *xorriso, IsoNode *node, int flag);
#define LIBISO_ISDIR(node) (iso_node_get_type(node) == LIBISO_DIR) #define LIBISO_ISDIR(node) (iso_node_get_type(node) == LIBISO_DIR)
#define LIBISO_ISREG(node) (iso_node_get_type(node) == LIBISO_FILE) #define LIBISO_ISREG(node) (iso_node_get_type(node) == LIBISO_FILE)
@ -1949,7 +1947,7 @@ cannot_lstat:;
target_is_dir= LIBISO_ISDIR(node); target_is_dir= LIBISO_ISDIR(node);
target_is_split= 0; target_is_split= 0;
if(target_is_dir) if(target_is_dir)
target_is_split= Xorriso_is_split(xorriso, node, 0); target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1);
if(!((target_is_dir && !target_is_split) && source_is_dir)) { if(!((target_is_dir && !target_is_split) && source_is_dir)) {
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
@ -2264,7 +2262,7 @@ int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter,
target_is_split= 0; target_is_split= 0;
if(target_is_dir) if(target_is_dir)
target_is_split= Xorriso_is_split(xorriso, node, 0); target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1);
if(!((target_is_dir && !target_is_split) && source_is_dir)) { if(!((target_is_dir && !target_is_split) && source_is_dir)) {
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
@ -2489,9 +2487,10 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
} }
/* @param flag >>> bit0= cut_out mode : base on leaf parent directory /* @param flag
bit1= minimal transfer: access permissions only bit1= minimal transfer: access permissions only
bit2= keep directory open: keep owner, allow rwx for owner bit2= keep directory open: keep owner, allow rwx for owner
push to xorriso->perm_stack
*/ */
int Xorriso_restore_implicit_properties(struct XorrisO *xorriso, int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
char *full_disk_path, char *disk_path, char *full_img_path, int flag) char *full_disk_path, char *disk_path, char *full_img_path, int flag)
@ -2516,10 +2515,7 @@ int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
nfdc= Sfile_count_components(nfd, 0); nfdc= Sfile_count_components(nfd, 0);
ndc= Sfile_count_components(nd, 0); ndc= Sfile_count_components(nd, 0);
nfic= Sfile_count_components(nfi, 0); nfic= Sfile_count_components(nfi, 0);
d= nfdc-ndc;
/* >>> ??? (flag&1) */
d= nfdc-(flag&1)-ndc;
if(d<0) if(d<0)
return(-1); return(-1);
if(d>nfic) if(d>nfic)
@ -2535,38 +2531,48 @@ int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
ret= Xorriso_fake_stbuf(xorriso, nfi, &stbuf, &node, 0); ret= Xorriso_fake_stbuf(xorriso, nfi, &stbuf, &node, 0);
if(ret<=0) if(ret<=0)
return(0); return(0);
ret= Xorriso_restore_properties(xorriso, nfd, node, !!(flag&2)); 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));
if(ret<=0) if(ret<=0)
return(ret); return(ret);
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"Restored properties for %s", Text_shellsafe(nd, sfe, 0)); "Restored properties for %s", Text_shellsafe(nd, sfe, 0));
sprintf(xorriso->info_text+strlen(xorriso->info_text), sprintf(xorriso->info_text+strlen(xorriso->info_text),
" from %s", Text_shellsafe(nfi, sfe, 0)); " from %s", Text_shellsafe(nfi, sfe, 0));
/* >>> ??? (flag&1) */
if(!((flag&1) && d==0))
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
return(1); return(1);
} }
/* @param flag bit0= Minimal transfer: access permissions only /* @param flag bit0= Minimal transfer: access permissions only
bit1= offset and bytes is valid for writing to regular file
bit2= This is not a parameter. Do not report if ignored bit2= This is not a parameter. Do not report if ignored
bit3= do not restore properties
@return <0 severe error , 0 failure , 1 success , @return <0 severe error , 0 failure , 1 success ,
2 regularly not installed (disallowed device, UNIX domain socket) 2 regularly not installed (disallowed device, UNIX domain socket)
*/ */
int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node, int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
char *img_path, char *disk_path, int flag) char *img_path, char *disk_path,
off_t offset, off_t bytes, int flag)
{ {
int ret= 0, write_fd= -1, wanted, wret; int ret= 0, write_fd= -1, wanted, wret, open_flags;
char *what= "[unknown filetype]", sfe[5*SfileadrL], sfe2[5*SfileadrL]; char *what= "[unknown filetype]", sfe[5*SfileadrL], sfe2[5*SfileadrL];
char buf[32*1024]; char buf[32*1024];
char *link_target; char *link_target;
off_t todo, size; off_t todo, size, seek_ret;
void *data_stream= NULL; void *data_stream= NULL;
mode_t mode; mode_t mode;
dev_t dev= 0; dev_t dev= 0;
struct stat stbuf;
if(LIBISO_ISDIR(node)) { if(LIBISO_ISDIR(node)) {
what= "directory"; what= "directory";
@ -2577,12 +2583,37 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
/* >>> need to exploit node rather than img_path */ /* >>> need to exploit node rather than img_path */
ret= Xorriso_iso_file_open(xorriso, img_path, &data_stream, 0); ret= Xorriso_iso_file_open(xorriso, img_path, &data_stream, 0);
if(ret<=0) if(ret<=0)
goto ex; goto ex;
write_fd= open(disk_path,O_WRONLY|O_EXCL|O_CREAT);
open_flags= O_WRONLY|O_CREAT;
if(flag&2) {
ret= stat(disk_path, &stbuf);
if(ret!=-1 && !S_ISREG(stbuf.st_mode)) {
sprintf(xorriso->info_text,
"Restore offset demanded. But filesystem path leads to non-data file %s",
Text_shellsafe(disk_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
goto cannot_restore;
}
}
if(offset==0 || !(flag&2))
open_flags|= O_EXCL;
write_fd= open(disk_path, open_flags, S_IRUSR|S_IWUSR);
if(write_fd==-1) if(write_fd==-1)
goto cannot_restore; goto cannot_restore;
if(flag&2) {
todo= size= bytes;
seek_ret= lseek(write_fd, offset, SEEK_SET);
if(seek_ret == -1) {
sprintf(xorriso->info_text,
"Cannot address byte %.f in filesystem path %s",
(double) offset, Text_shellsafe(disk_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
goto cannot_restore;
}
} else
todo= size= iso_file_get_size((IsoFile *) node); todo= size= iso_file_get_size((IsoFile *) node);
while(todo>0) { while(todo>0) {
wanted= sizeof(buf); wanted= sizeof(buf);
@ -2687,7 +2718,7 @@ cannot_restore:;
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= 0; goto ex; ret= 0; goto ex;
} }
if(LIBISO_ISLNK(node)) if((flag&8) || LIBISO_ISLNK(node))
ret= 1; ret= 1;
else else
ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1); ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1);
@ -2717,23 +2748,26 @@ int Xorriso_restore(struct XorrisO *xorriso,
{ {
IsoImage *volume; IsoImage *volume;
char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL], sfe2[5*SfileadrL]; char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL], sfe2[5*SfileadrL];
char *img_path_pt; char *img_path_pt, *part_name;
IsoNode *node= NULL; IsoNode *node= NULL, *part_node, *first_part_node;
int done= 0, is_dir= 0, ret, target_is_dir, source_is_dir, stbuf_ret; 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;
struct stat stbuf, target_stbuf; struct stat stbuf, target_stbuf;
struct PermiteM *perm_stack_mem; struct PermiteM *perm_stack_mem;
struct SplitparT *split_parts= NULL;
perm_stack_mem= xorriso->perm_stack; perm_stack_mem= xorriso->perm_stack;
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4)); ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4));
if(ret<0) if(ret<0)
return(ret); goto ex;
if(ret>0) if(ret>0)
return(3*!!(flag&16)); {ret= 3*!!(flag&16); goto ex;}
ret= Xorriso_get_volume(xorriso, &volume, 0); ret= Xorriso_get_volume(xorriso, &volume, 0);
if(ret<=0) if(ret<=0)
return(ret); goto ex;
strncpy(path, disk_path, sizeof(path)-1); strncpy(path, disk_path, sizeof(path)-1);
path[sizeof(path)-1]= 0; path[sizeof(path)-1]= 0;
@ -2765,17 +2799,11 @@ int Xorriso_restore(struct XorrisO *xorriso,
"Cannot determine attributes of (ISO) source file %s", "Cannot determine attributes of (ISO) source file %s",
Text_shellsafe(img_path, sfe, 0)); Text_shellsafe(img_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
return(0); ret= 0; goto ex;
} }
if(is_dir && xorriso->do_concat_split)
#ifdef Osirrox_not_yeT leaf_is_split= Xorriso_identify_split(xorriso, img_path, node,
/* >>> */ &split_parts, &split_count, &stbuf, 1|2);
int source_is_split= 0;
if(is_dir)
source_is_split= Xorriso_is_split(xorriso, node, 0);
#endif
} }
for(npt= apt; !done; apt= npt+1) { for(npt= apt; !done; apt= npt+1) {
npt= strchr(apt, '/'); npt= strchr(apt, '/');
@ -2792,28 +2820,23 @@ int Xorriso_restore(struct XorrisO *xorriso,
continue; continue;
} }
source_is_dir= (is_dir || (flag&1) || !done); source_is_dir= (is_dir || (flag&1) || !done);
source_is_split= done && leaf_is_split;
stbuf_ret= stat(path, &target_stbuf); stbuf_ret= stat(path, &target_stbuf);
if(stbuf_ret!=-1) { if(stbuf_ret!=-1) {
target_is_dir= S_ISDIR(target_stbuf.st_mode); target_is_dir= S_ISDIR(target_stbuf.st_mode);
if(!(target_is_dir && (source_is_dir && !source_is_split))) {
#ifdef Osirrox_not_yeT
/* >>> Take into respect source_is_split */
#endif
if((!target_is_dir) && source_is_dir) {
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
/* handle overwrite situation */ /* handle overwrite situation */
if(xorriso->do_overwrite==1 || if(xorriso->do_overwrite==1 ||
(xorriso->do_overwrite==2 && !target_is_dir)) { (xorriso->do_overwrite==2 && !target_is_dir)) {
ret= Xorriso_rmx(xorriso, (off_t) 0, path, 1|8); ret= Xorriso_rmx(xorriso, (off_t) 0, path, 1|8);
if(ret<=0) if(ret<=0)
return(ret); goto ex;
if(ret==3) { if(ret==3) {
sprintf(xorriso->info_text, "User revoked restoring of: %s", sprintf(xorriso->info_text, "User revoked restoring of: %s",
Text_shellsafe(disk_path, sfe, 0)); Text_shellsafe(disk_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
return(3*!!(flag&16)); {ret= 3*!!(flag&16); goto ex;}
} }
stbuf_ret= -1; stbuf_ret= -1;
goto handle_path_node; goto handle_path_node;
@ -2823,12 +2846,13 @@ int Xorriso_restore(struct XorrisO *xorriso,
"While restoring '%s' : '%s' exists and may not be overwritten", "While restoring '%s' : '%s' exists and may not be overwritten",
disk_path, path); disk_path, path);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0); {ret= 0; goto ex;}
} }
} }
handle_path_node:; handle_path_node:;
if(stbuf_ret==-1 && source_is_dir) { /* make a directory */ if(stbuf_ret==-1 && (source_is_dir && !source_is_split)) {
/* make a directory */
ret= mkdir(path, 0777); ret= mkdir(path, 0777);
if(ret==-1) { if(ret==-1) {
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
@ -2838,22 +2862,14 @@ handle_path_node:;
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"While restoring '%s' : could not insert '%s'", disk_path, path); "While restoring '%s' : could not insert '%s'", disk_path, path);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0); {ret= 0; goto ex;}
} }
if(!done) { if(!done) {
ret= Permstack_push(&(xorriso->perm_stack), path, &stbuf, 0);
if(ret<=0) {
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
Xorriso_report_iso_error(xorriso, disk_path, ret,
"Cannot memorize permissions for disk directory", 0, "FATAL", 1);
return(-1);
}
/* keep rwx for the owner */ /* keep rwx for the owner */
Xorriso_restore_implicit_properties(xorriso, disk_path, path, Xorriso_restore_implicit_properties(xorriso, disk_path, path,
img_path, 4); img_path, 4);
/* >>> ???(flag&8) */
} }
} else if(source_is_dir) { } else if(source_is_dir && !source_is_split) {
/* >>> If owner: eventually try to obtain rwx-permssions, stack path */; /* >>> If owner: eventually try to obtain rwx-permssions, stack path */;
@ -2864,7 +2880,7 @@ attach_source:;
if(flag&1) { if(flag&1) {
/* directory was created above */; /* directory was created above */;
} else if(is_dir) { } else if(is_dir && !source_is_split) {
Xorriso_restore_properties(xorriso, disk_path, node, !!(flag&64)); Xorriso_restore_properties(xorriso, disk_path, node, !!(flag&64));
#ifdef Osirrox_not_yeT #ifdef Osirrox_not_yeT
@ -2872,38 +2888,68 @@ attach_source:;
/* >>> */ /* >>> */
if(!(flag&32)) { if(!(flag&32)) {
ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL, ret= Xorriso_add_tree(xorriso, dir, img_path, path, NULL,
flag&2); flag&2);
if(ret<=0) if(ret<=0)
return(ret); goto ex;
} }
#endif #endif
} else { } 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;
}
Xorriso_restore_properties(xorriso, path, first_part_node,
!!(flag&64));
break;
#ifdef Osirrox_not_yeT #ifdef Osirrox_not_yeT
if(resolve_link) { } else if(resolve_link) {
ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0); ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
if(ret<=0) if(ret<=0)
return(ret); goto ex;
disk_path_pt= resolved_disk_path; disk_path_pt= resolved_disk_path;
} else
#endif /* Osirrox_not_yeT */ #endif /* Osirrox_not_yeT */
} else
img_path_pt= img_path; img_path_pt= img_path;
ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, path, ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, path,
(off_t) 0, (off_t) 0,
(flag&4) | !!(flag&64)); (flag&4) | !!(flag&64));
if(ret<=0) { if(ret<=0) {
restoring_failed:;
sprintf(xorriso->info_text, "Restoring failed: %s = %s", sprintf(xorriso->info_text, "Restoring failed: %s = %s",
Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0)); Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0); {ret= 0; goto ex;}
} }
if(ret==2) if(ret==2)
return(3); {ret= 3; goto ex;}
xorriso->pacifier_count++; xorriso->pacifier_count++;
if(xorriso->pacifier_count%100 && !(flag&2)) if(xorriso->pacifier_count%100 && !(flag&2))
Xorriso_pacifier_callback(xorriso, "files restored", Xorriso_pacifier_callback(xorriso, "files restored",
@ -2914,13 +2960,16 @@ attach_source:;
*npt= '/'; *npt= '/';
} }
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
ret= 1 + (is_dir && !leaf_is_split);
ex:;
/* restore exact access permissions of stacked paths */ /* restore exact access permissions of stacked paths */
ret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
!!(flag&64)); !!(flag&64));
if(ret<=0) if(hret<=0 && hret<ret)
ret= hret;
if(split_parts!=NULL)
Splitparts_destroy(&split_parts, split_count, 0);
return(ret); return(ret);
return(1+!!is_dir);
} }
@ -5872,16 +5921,18 @@ int Xorriso_iso_file_close(struct XorrisO *xorriso, void **stream, int flag)
/* @param flag bit0= in_node is valid, do not resolve iso_adr /* @param flag bit0= in_node is valid, do not resolve iso_adr
bit1= insist in complete collection of part files
*/ */
int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr, int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr,
void *in_node, void *in_node,
struct SplitparT **parts, int *count, struct SplitparT **parts, int *count,
struct stat *total_stbuf, int flag) struct stat *total_stbuf, int flag)
{ {
int ret, i; int ret, i, incomplete= 0, overlapping= 0;
int partno, total_parts, first_total_parts= -1; int partno, total_parts, first_total_parts= -1;
off_t offset, bytes, total_bytes, first_total_bytes= -1, first_bytes= -1; off_t offset, bytes, total_bytes, first_total_bytes= -1, first_bytes= -1;
off_t size; off_t size, covered;
IsoImage *volume; IsoImage *volume;
IsoDir *dir_node; IsoDir *dir_node;
IsoDirIter *iter= NULL; IsoDirIter *iter= NULL;
@ -5970,14 +6021,24 @@ cannot_iter:;
goto ex; goto ex;
} }
/* >>> ??? sort list ? */ Splitparts_sort(*parts, *count, 0);
for(i= 0; i<*count; i++) {
/* >>> check for disjointness */;
}
covered= 0;
for(i= 0; i<*count; i++) {
Splitparts_get(*parts, i, &name, &partno, &total_parts, &offset, &bytes,
&total_bytes, 0);
if(offset>covered)
incomplete= 1;
else if(offset<covered)
overlapping= 1;
if(offset+bytes > covered)
covered= offset+bytes;
}
if(total_bytes>covered)
incomplete= 1;
memcpy(total_stbuf, &first_stbuf, sizeof(struct stat)); memcpy(total_stbuf, &first_stbuf, sizeof(struct stat));
total_stbuf->st_size= total_bytes; total_stbuf->st_size= total_bytes;
ret= 1; ret= !(overlapping || ((flag&2)&&incomplete));
ex:; ex:;
if(iter!=NULL) if(iter!=NULL)
iso_dir_iter_free(iter); iso_dir_iter_free(iter);
@ -5985,14 +6046,18 @@ ex:;
} }
int Xorriso_is_split(struct XorrisO *xorriso, IsoNode *node, int flag) /* @param flag bit0= node is valid, do not resolve path
bit1= insist in complete collection of part files
*/
int Xorriso_is_split(struct XorrisO *xorriso, char *path, void *node,
int flag)
{ {
struct SplitparT *split_parts= NULL; struct SplitparT *split_parts= NULL;
int split_count= 0, ret; int split_count= 0, ret;
struct stat stbuf; struct stat stbuf;
ret= Xorriso_identify_split(xorriso, "", (void *) node, &split_parts, ret= Xorriso_identify_split(xorriso, path, node, &split_parts,
&split_count, &stbuf, 1); &split_count, &stbuf, flag&1);
if(split_parts!=NULL) if(split_parts!=NULL)
Splitparts_destroy(&split_parts, split_count, 0); Splitparts_destroy(&split_parts, split_count, 0);
return(ret>0); return(ret>0);

View File

@ -225,8 +225,14 @@ int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr,
struct SplitparT **parts, int *count, struct SplitparT **parts, int *count,
struct stat *total_stbuf, int flag); struct stat *total_stbuf, int flag);
/* /* @param flag bit0= node is valid, do not resolve path
@param flag bit1= insist in complete collection of part files
*/
int Xorriso_is_split(struct XorrisO *xorriso, char *path, void *node,
int flag);
/* @param flag
>>> bit0= mkdir: graft in as empty directory, not as copy from iso >>> bit0= mkdir: graft in as empty directory, not as copy from iso
bit1= do not report copied files bit1= do not report copied files
bit2= -follow, -not_*: this is not a command parameter bit2= -follow, -not_*: this is not a command parameter