Proper handling of restore overwrite situations with directories and softlinks

This commit is contained in:
Thomas Schmitt 2008-06-11 13:15:43 +00:00
parent 75793b34ba
commit 0625c675be
3 changed files with 98 additions and 12 deletions

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH XORRISO 1 "Jun, 6, 2008" .TH XORRISO 1 "Jun, 11, 2008"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -15,6 +15,7 @@
.\" .br insert line break .\" .br insert line break
.\" .sp <n> insert n+1 empty lines .\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7) .\" for manpage-specific macros, see man(7)
.nh
.SH NAME .SH NAME
xorriso - creates, loads, manipulates and writes ISO 9660 filesystem images xorriso - creates, loads, manipulates and writes ISO 9660 filesystem images
with Rock Ridge extensions. with Rock Ridge extensions.
@ -1144,7 +1145,7 @@ Setting "on" allows automatic -rm_r. I.e. a non-directory can replace an
existing directory and all its subordinates. existing directory and all its subordinates.
.br .br
If restoring of files is enabled, then the overwrite rule applies to the If restoring of files is enabled, then the overwrite rule applies to the
target file objects on disk as well. target file objects on disk as well, but "on" is downgraded to "nondir".
.TP .TP
\fB\-split_size\fR number["k"|"m"] \fB\-split_size\fR number["k"|"m"]
Set the threshold for automatic splitting of regular files. Such splitting Set the threshold for automatic splitting of regular files. Such splitting
@ -1612,16 +1613,17 @@ from ISO images and to create, overwrite, or delete file objects on disk.
.br .br
Disk file exclusions by -not_mgt, -not_leaf, -not_paths apply. Disk file exclusions by -not_mgt, -not_leaf, -not_paths apply.
If disk file objects already exist then the settings of -overwrite and If disk file objects already exist then the settings of -overwrite and
-reassure apply. -reassure apply. But -overwrite "on" only triggers the behavior
of -overwrite "nondir". I.e. directories cannot be deleted.
.br
Access permissions of files in the ISO image do not restrict restoring.
The permissions on disk have to allow writing, of course.
.TP .TP
\fB\-osirrox\fR "on"|"device_files"|"off"[:option:...] \fB\-osirrox\fR "on"|"device_files"|"off"[:option:...]
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".
.br .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 To enable restoring of special files by "device_files" is potentially
dangerous. dangerous.
The meaning of the number st_rdev (see man 2 stat) depends much on the The meaning of the number st_rdev (see man 2 stat) depends much on the
@ -1644,7 +1646,7 @@ handled like any other ISO image directory.
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
the address given by disk_path. If more then one iso_rr_path is given then the address given by disk_path. If more then one iso_rr_path is given then
disk_path must be a directory or non-existent. In the latter case it gets 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. created and the extracted files get installed in it with the same leafnames.
.br .br
Missing directory components in disk_path will get created, if possible. Missing directory components in disk_path will get created, if possible.
.br .br
@ -1658,6 +1660,9 @@ ownership and group as in ISO image.
.TP .TP
\fB\-cp_rx\fR iso_rr_path [***] disk_path \fB\-cp_rx\fR iso_rr_path [***] disk_path
Like -cpx but also extracting whole directory trees from the ISO image. Like -cpx but also extracting whole directory trees from the ISO image.
.br
If disk_path is an existing directory then the trees will be inserted
underneath this directory and will keep their leaf names.
If directories do already exist under disk_path then their content If directories do already exist under disk_path then their content
eventually gets merged with the content of restored directories eventually gets merged with the content of restored directories
of the same name. Directory attributes get extracted only if the disk of the same name. Directory attributes get extracted only if the disk

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.06.10.100231" #define Xorriso_timestamP "2008.06.11.131607"

View File

@ -2811,6 +2811,55 @@ ex:;
} }
/* @param flag bit0= source is a directory and not to be restored as split file
@return <=0 error , 1=collision handled , 2=no collision , 3=revoked by user
*/
int Xorriso_handle_collision(struct XorrisO *xorriso,
IsoNode *node, char *img_path,
char *disk_path, char *nominal_disk_path,
int *stbuf_ret, int flag)
{
int ret, target_is_dir= 0, target_is_link= 0, stat_ret;
struct stat target_stbuf, lt_stbuf;
/* does a disk file exist with this name ? */
*stbuf_ret= lstat(disk_path, &target_stbuf);
if(*stbuf_ret==-1)
return(2);
target_is_link= S_ISLNK(target_stbuf.st_mode);
if(target_is_link) {
stat_ret= stat(disk_path, &lt_stbuf);
if(stat_ret!=-1)
target_is_dir= S_ISDIR(lt_stbuf.st_mode);
} else {
target_is_dir= S_ISDIR(target_stbuf.st_mode);
}
if(target_is_dir && (!target_is_link) && !(flag&2)) {
strcpy(xorriso->info_text, "Attempt to replace DISK directory ");
Text_shellsafe(nominal_disk_path,
xorriso->info_text+strlen(xorriso->info_text), 0);
strcat(xorriso->info_text, " by ISO file ");
Text_shellsafe(img_path, xorriso->info_text+strlen(xorriso->info_text), 0);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
if(!(target_is_dir && (flag&1))) {
Xorriso_process_msg_queues(xorriso,0);
ret= Xorriso_restore_overwrite(xorriso, node, img_path, disk_path,
nominal_disk_path, &target_stbuf, 16);
if(ret==3)
return(3);
if(ret<=0)
return(ret);
*stbuf_ret= -1; /* It might still exist but will be handled properly */
}
return(1);
}
/* @param flag bit0= recursion is active /* @param flag bit0= recursion is active
bit1= do not report restored files bit1= do not report restored files
bit6= this is a copy action: do not fake times and ownership bit6= this is a copy action: do not fake times and ownership
@ -2825,15 +2874,20 @@ int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir,
IsoDirIter *iter= NULL; IsoDirIter *iter= NULL;
IsoNode **node_array= NULL; IsoNode **node_array= NULL;
int node_count, node_idx; int node_count, node_idx;
int ret, target_is_dir, source_is_dir, source_is_link, fret, was_failure= 0; int ret, 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; 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= ""; char *name, *disk_name, *leaf_name, *srcpt, *stbuf_src= "";
struct stat stbuf, target_stbuf;
struct LinkiteM *own_link_stack; struct LinkiteM *own_link_stack;
char *sfe= NULL, *sfe2= NULL; char *sfe= NULL, *sfe2= NULL;
char *disk_path= NULL, *img_path= NULL, *link_target= NULL; char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
off_t mem; off_t mem;
struct PermiteM *perm_stack_mem; struct PermiteM *perm_stack_mem;
struct stat stbuf;
#ifdef NIX
struct stat target_stbuf;
target_is_dir;
#endif
perm_stack_mem= xorriso->perm_stack; perm_stack_mem= xorriso->perm_stack;
@ -2984,6 +3038,7 @@ much_too_long:;
if(source_is_split) if(source_is_split)
do_not_dive= 1; do_not_dive= 1;
#ifdef NIX
/* >>> handle softlinks */; /* >>> handle softlinks */;
@ -3002,6 +3057,15 @@ much_too_long:;
} }
} }
#else /* NIX */
ret= Xorriso_handle_collision(xorriso, node, img_path, disk_path, disk_path,
&stbuf_ret, (source_is_dir && !source_is_split));
if(ret<=0 || ret==3)
goto was_problem;
#endif /* ! NIX */
if(stbuf_ret!=-1) { /* (Can only happen with directory) */ if(stbuf_ret!=-1) { /* (Can only happen with directory) */
/* ??? >>> eventually open access to existing directory ? */; /* ??? >>> eventually open access to existing directory ? */;
@ -3085,11 +3149,16 @@ int Xorriso_restore(struct XorrisO *xorriso,
IsoImage *volume; IsoImage *volume;
char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL]; char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL];
IsoNode *node= NULL; IsoNode *node= NULL;
int done= 0, is_dir= 0, ret, target_is_dir, source_is_dir, stbuf_ret, hret; int done= 0, is_dir= 0, ret, source_is_dir, stbuf_ret, hret;
int leaf_is_split= 0, source_is_split= 0, new_dir_made= 0; int leaf_is_split= 0, source_is_split= 0, new_dir_made= 0;
struct stat stbuf, target_stbuf; struct stat stbuf;
struct PermiteM *perm_stack_mem; struct PermiteM *perm_stack_mem;
#ifdef NIX
struct stat target_stbuf;
int target_is_dir;
#endif
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));
@ -3154,6 +3223,8 @@ int Xorriso_restore(struct XorrisO *xorriso,
source_is_dir= (is_dir || (flag&1) || !done); source_is_dir= (is_dir || (flag&1) || !done);
source_is_split= done && leaf_is_split; source_is_split= done && leaf_is_split;
#ifdef NIX
/* >>> handle softlinks */; /* >>> handle softlinks */;
stbuf_ret= stat(path, &target_stbuf); stbuf_ret= stat(path, &target_stbuf);
@ -3168,6 +3239,16 @@ int Xorriso_restore(struct XorrisO *xorriso,
stbuf_ret= -1; /* now it is removed (or can be handled properly) */ stbuf_ret= -1; /* now it is removed (or can be handled properly) */
} }
} }
#else /* NIX */
ret= Xorriso_handle_collision(xorriso, node, img_path, path, disk_path,
&stbuf_ret, (source_is_dir && !source_is_split));
if(ret<=0 || ret==3)
goto ex;
#endif /* ! NIX */
new_dir_made= 0; new_dir_made= 0;
if(stbuf_ret==-1 && (source_is_dir && !source_is_split)) { if(stbuf_ret==-1 && (source_is_dir && !source_is_split)) {
/* make a directory */ /* make a directory */