Implemented oncatenation of split files during -cpx

This commit is contained in:
2008-05-31 17:40:18 +00:00
parent c4568b11bc
commit 80feb22f04
6 changed files with 256 additions and 116 deletions

View File

@ -69,8 +69,6 @@ int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume,
off_t offset, off_t cut_size,
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_ISREG(node) (iso_node_get_type(node) == LIBISO_FILE)
@ -1949,7 +1947,7 @@ cannot_lstat:;
target_is_dir= LIBISO_ISDIR(node);
target_is_split= 0;
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)) {
Xorriso_process_msg_queues(xorriso,0);
@ -2264,7 +2262,7 @@ int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter,
target_is_split= 0;
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)) {
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
bit2= keep directory open: keep owner, allow rwx for owner
push to xorriso->perm_stack
*/
int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
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);
ndc= Sfile_count_components(nd, 0);
nfic= Sfile_count_components(nfi, 0);
/* >>> ??? (flag&1) */
d= nfdc-(flag&1)-ndc;
d= nfdc-ndc;
if(d<0)
return(-1);
if(d>nfic)
@ -2535,38 +2531,48 @@ int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
ret= Xorriso_fake_stbuf(xorriso, nfi, &stbuf, &node, 0);
if(ret<=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)
return(ret);
sprintf(xorriso->info_text,
"Restored properties for %s", Text_shellsafe(nd, sfe, 0));
sprintf(xorriso->info_text+strlen(xorriso->info_text),
" 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);
}
/* @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
bit3= do not restore properties
@return <0 severe error , 0 failure , 1 success ,
2 regularly not installed (disallowed device, UNIX domain socket)
*/
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 buf[32*1024];
char *link_target;
off_t todo, size;
off_t todo, size, seek_ret;
void *data_stream= NULL;
mode_t mode;
dev_t dev= 0;
struct stat stbuf;
if(LIBISO_ISDIR(node)) {
what= "directory";
@ -2577,13 +2583,38 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
/* >>> need to exploit node rather than img_path */
ret= Xorriso_iso_file_open(xorriso, img_path, &data_stream, 0);
if(ret<=0)
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)
goto cannot_restore;
todo= size= iso_file_get_size((IsoFile *) node);
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);
while(todo>0) {
wanted= sizeof(buf);
if(wanted>todo)
@ -2687,7 +2718,7 @@ cannot_restore:;
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= 0; goto ex;
}
if(LIBISO_ISLNK(node))
if((flag&8) || LIBISO_ISLNK(node))
ret= 1;
else
ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1);
@ -2717,23 +2748,26 @@ int Xorriso_restore(struct XorrisO *xorriso,
{
IsoImage *volume;
char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL], sfe2[5*SfileadrL];
char *img_path_pt;
IsoNode *node= NULL;
int done= 0, is_dir= 0, ret, target_is_dir, source_is_dir, stbuf_ret;
char *img_path_pt, *part_name;
IsoNode *node= NULL, *part_node, *first_part_node;
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 PermiteM *perm_stack_mem;
struct SplitparT *split_parts= NULL;
perm_stack_mem= xorriso->perm_stack;
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4));
if(ret<0)
return(ret);
goto ex;
if(ret>0)
return(3*!!(flag&16));
{ret= 3*!!(flag&16); goto ex;}
ret= Xorriso_get_volume(xorriso, &volume, 0);
if(ret<=0)
return(ret);
goto ex;
strncpy(path, disk_path, sizeof(path)-1);
path[sizeof(path)-1]= 0;
@ -2765,17 +2799,11 @@ int Xorriso_restore(struct XorrisO *xorriso,
"Cannot determine attributes of (ISO) source file %s",
Text_shellsafe(img_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
return(0);
ret= 0; goto ex;
}
#ifdef Osirrox_not_yeT
/* >>> */
int source_is_split= 0;
if(is_dir)
source_is_split= Xorriso_is_split(xorriso, node, 0);
#endif
if(is_dir && xorriso->do_concat_split)
leaf_is_split= Xorriso_identify_split(xorriso, img_path, node,
&split_parts, &split_count, &stbuf, 1|2);
}
for(npt= apt; !done; apt= npt+1) {
npt= strchr(apt, '/');
@ -2792,28 +2820,23 @@ int Xorriso_restore(struct XorrisO *xorriso,
continue;
}
source_is_dir= (is_dir || (flag&1) || !done);
source_is_split= done && leaf_is_split;
stbuf_ret= stat(path, &target_stbuf);
if(stbuf_ret!=-1) {
target_is_dir= S_ISDIR(target_stbuf.st_mode);
#ifdef Osirrox_not_yeT
/* >>> Take into respect source_is_split */
#endif
if((!target_is_dir) && source_is_dir) {
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)
return(ret);
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);
return(3*!!(flag&16));
{ret= 3*!!(flag&16); goto ex;}
}
stbuf_ret= -1;
goto handle_path_node;
@ -2823,12 +2846,13 @@ int Xorriso_restore(struct XorrisO *xorriso,
"While restoring '%s' : '%s' exists and may not be overwritten",
disk_path, path);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
{ret= 0; goto ex;}
}
}
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);
if(ret==-1) {
Xorriso_process_msg_queues(xorriso,0);
@ -2838,22 +2862,14 @@ handle_path_node:;
sprintf(xorriso->info_text,
"While restoring '%s' : could not insert '%s'", disk_path, path);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
{ret= 0; goto ex;}
}
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 */
Xorriso_restore_implicit_properties(xorriso, disk_path, path,
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 */;
@ -2864,7 +2880,7 @@ attach_source:;
if(flag&1) {
/* directory was created above */;
} else if(is_dir) {
} else if(is_dir && !source_is_split) {
Xorriso_restore_properties(xorriso, disk_path, node, !!(flag&64));
#ifdef Osirrox_not_yeT
@ -2872,38 +2888,68 @@ attach_source:;
/* >>> */
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);
if(ret<=0)
return(ret);
goto ex;
}
#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;
}
Xorriso_restore_properties(xorriso, path, first_part_node,
!!(flag&64));
break;
#ifdef Osirrox_not_yeT
if(resolve_link) {
} else if(resolve_link) {
ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
if(ret<=0)
return(ret);
goto ex;
disk_path_pt= resolved_disk_path;
} else
#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);
return(0);
{ret= 0; goto ex;}
}
if(ret==2)
return(3);
{ret= 3; goto ex;}
xorriso->pacifier_count++;
if(xorriso->pacifier_count%100 && !(flag&2))
Xorriso_pacifier_callback(xorriso, "files restored",
@ -2914,13 +2960,16 @@ attach_source:;
*npt= '/';
}
Xorriso_process_msg_queues(xorriso,0);
ret= 1 + (is_dir && !leaf_is_split);
ex:;
/* restore exact access permissions of stacked paths */
ret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
!!(flag&64));
if(ret<=0)
return(ret);
return(1+!!is_dir);
hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
!!(flag&64));
if(hret<=0 && hret<ret)
ret= hret;
if(split_parts!=NULL)
Splitparts_destroy(&split_parts, split_count, 0);
return(ret);
}
@ -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
bit1= insist in complete collection of part files
*/
int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr,
void *in_node,
struct SplitparT **parts, int *count,
struct stat *total_stbuf, int flag)
{
int ret, i;
int ret, i, incomplete= 0, overlapping= 0;
int partno, total_parts, first_total_parts= -1;
off_t offset, bytes, total_bytes, first_total_bytes= -1, first_bytes= -1;
off_t size;
off_t size, covered;
IsoImage *volume;
IsoDir *dir_node;
IsoDirIter *iter= NULL;
@ -5970,14 +6021,24 @@ cannot_iter:;
goto ex;
}
/* >>> ??? sort list ? */
for(i= 0; i<*count; i++) {
/* >>> check for disjointness */;
}
Splitparts_sort(*parts, *count, 0);
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));
total_stbuf->st_size= total_bytes;
ret= 1;
ret= !(overlapping || ((flag&2)&&incomplete));
ex:;
if(iter!=NULL)
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;
int split_count= 0, ret;
struct stat stbuf;
ret= Xorriso_identify_split(xorriso, "", (void *) node, &split_parts,
&split_count, &stbuf, 1);
ret= Xorriso_identify_split(xorriso, path, node, &split_parts,
&split_count, &stbuf, flag&1);
if(split_parts!=NULL)
Splitparts_destroy(&split_parts, split_count, 0);
return(ret>0);