Proper handling of restore overwrite situations with directories and softlinks

This commit is contained in:
2008-06-11 13:15:43 +00:00
parent d784d8f2e9
commit 24ad7e5abe
3 changed files with 98 additions and 12 deletions

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
bit1= do not report restored files
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;
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 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;
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;
struct stat stbuf;
#ifdef NIX
struct stat target_stbuf;
target_is_dir;
#endif
perm_stack_mem= xorriso->perm_stack;
@ -2984,6 +3038,7 @@ much_too_long:;
if(source_is_split)
do_not_dive= 1;
#ifdef NIX
/* >>> 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) */
/* ??? >>> eventually open access to existing directory ? */;
@ -3085,11 +3149,16 @@ int Xorriso_restore(struct XorrisO *xorriso,
IsoImage *volume;
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 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;
struct stat stbuf, target_stbuf;
struct stat stbuf;
struct PermiteM *perm_stack_mem;
#ifdef NIX
struct stat target_stbuf;
int target_is_dir;
#endif
perm_stack_mem= xorriso->perm_stack;
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_split= done && leaf_is_split;
#ifdef NIX
/* >>> handle softlinks */;
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) */
}
}
#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;
if(stbuf_ret==-1 && (source_is_dir && !source_is_split)) {
/* make a directory */