Implemented -overwrite control

This commit is contained in:
Thomas Schmitt 2007-11-06 16:32:39 +00:00
parent 6be36c8726
commit dd4ebdbe17
6 changed files with 244 additions and 58 deletions

View File

@ -264,10 +264,10 @@ operations. They are intended to be in effect with the read-only mounted image.
.PP
If the iso_rr_path of a newly inserted or renamed file leads to an existing
file object in the ISO image, then the following collision handling happens:
.br
If both objects are directories then they get merged by recursively inserting
the subobjects from filesystem into ISO image.
> If other file types collide then the setting of command -overwrite decides.
> Directories may only be deleted by commands -rmdir or -rm_r.
If other file types collide then the setting of command -overwrite decides.
.PP
The commands in this section alter the ISO image and not the local filesystem.
.TP
@ -487,13 +487,20 @@ Set the threshhold for events to be reported.
Events are the same as with -abort_on. Regardless what is
set by -report_about, messages get always reported if they
reach the severity threshhold of -abort_on .
.TP
> \fB\-overwrite\fR "on"|"off"
Allow or disallow to overwrite existing files in the
ISO image by files with the same user defined name. This is
the RockRidge name and not the plain ISO name.
.br
With setting "off", RR name collisions cause SORRY-events.
Event messages are sent to the info channel "I" which is usually stderr
but may be influenced by command -pkt_output.
Info messages which belong to no event get attributed severity "NOTE".
.TP
\fB\-overwrite\fR "on"|"nondir"|"off"
Allow or disallow to overwrite existing files in the
ISO image by files with the same user defined name.
.br
With setting "off", name collisions cause SORRY-events.
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.
.TP
.B Dialog mode control:
.TP

View File

@ -1669,7 +1669,7 @@ return:
/* >>> how to distinguish error from EOF , do i need a (FILE *) ? */
return(0);
}
if(strlen(entry->d_name)>4095) {
if(strlen(entry->d_name)>=SfileadrL) {
fprintf(stderr,"--- oversized directory entry (number %d) :\n %s",
o->count+1,entry->d_name);
return(-1);
@ -1769,7 +1769,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->global_uid= 0;
m->volid[0]= 0;
m->do_global_gid= 0;
m->do_overwrite= 1;
m->do_overwrite= 2;
m->do_reassure= 0;
m->global_gid= 0;
m->indev[0]= 0;
@ -2818,8 +2818,9 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
Xorriso_status_result(xorriso,filter,fp,flag&2);
}
is_default= !!xorriso->do_overwrite;
sprintf(line,"-overwrite %s\n",(xorriso->do_overwrite ? "on" : "off"));
is_default= (xorriso->do_overwrite==2);
sprintf(line,"-overwrite %s\n",(xorriso->do_overwrite == 1 ? "on" :
(xorriso->do_overwrite == 2 ? "nondir" : "off")));
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
@ -3095,7 +3096,7 @@ int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag)
if(xorriso->problem_status < xorriso->abort_on_severity &&
xorriso->problem_status > 0) {
if(xorriso->problem_status >= sev) {
if(xorriso->problem_status >= sev && !(flag&1)) {
sprintf(xorriso->info_text,
"xorriso : NOTE : Tolerated problem event of severity '%s'\n",
xorriso->problem_status_text);
@ -3106,6 +3107,7 @@ int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag)
sprintf(xorriso->info_text,
"xorriso : ABORT : -abort_on '%s' encountered '%s'",
xorriso->abort_on_text, xorriso->problem_status_text);
if(!(flag&1))
Xorriso_info(xorriso, 0);/* submit not as problem event */
ret= -1;
} else if(ret>0)
@ -4359,10 +4361,20 @@ ex:;
}
/* Option -overwrite "on"|"off" */
/* Option -overwrite "on"|"nondir"|"off" */
int Xorriso_option_overwrite(struct XorrisO *xorriso, char *mode, int flag)
{
xorriso->do_overwrite= !!strcmp(mode, "off");
if(strcmp(mode, "off")==0)
xorriso->do_overwrite= 0;
else if(strcmp(mode, "on")==0)
xorriso->do_overwrite= 0;
else if(strcmp(mode, "nondir")==0)
xorriso->do_overwrite= 2;
else {
sprintf(xorriso->info_text, "-overwrite: unknown mode '%s'", mode);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
return(0);
}
return(1);
}

View File

@ -57,7 +57,7 @@ int Xorriso_msgs_submit(struct XorrisO *xorriso,
option function to evaluate the situation.
@param xorriso The environment handle
@param ret The return value of the prviously called option function
@param flag Unused yet. Submit 0.
@param flag bit0= do not issue own event messages
@return Gives the advice:
2= pardon was given, go on
1= no problem, go on
@ -249,7 +249,7 @@ int Xorriso_option_no_rc(struct XorrisO *xorriso, int flag);
int Xorriso_option_options_from_file(struct XorrisO *xorriso, char *adr,
int flag);
/* Option -overwrite "on"|"off" */
/* Option -overwrite "on"|"nondir"|"off" */
int Xorriso_option_overwrite(struct XorrisO *xorriso, char *mode, int flag);
/* Option -page */

View File

@ -72,8 +72,7 @@ struct XorrisO { /* the global context of xorriso */
int do_global_gid;
gid_t global_gid;
/* >>> put overwrite_mode here */
int do_overwrite;
int do_overwrite; /* 0=off, 1=on, 2=nondir */
int do_reassure;
char volid[SfileadrL];
@ -202,6 +201,15 @@ char *Text_shellsafe(char *in_text, char *out_text, int flag);
int Sort_argv(int argc, char **argv, int flag);
struct DirseQ;
int Dirseq_new(struct DirseQ **o, char *dir, int flag);
int Dirseq_destroy(struct DirseQ **o, int flag);
int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag);
#endif /* Xorriso_private_includeD */

View File

@ -1 +1 @@
#define Xorriso_timestamP "2007.11.02.184705"
#define Xorriso_timestamP "2007.11.06.163305"

View File

@ -97,6 +97,20 @@ int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag)
}
/* @param flag bit0=path is in source filesystem , bit1= unconditionally */
int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag)
{
if(len>=SfileadrL || (flag&2)) {
sprintf(xorriso->info_text,
"Path given for %s is much too long (%d)",
((flag&1) ? "local filesystem" : "ISO image"), len);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
return(0);
}
return(1);
}
/* @param flag bit1= obtain outdrive, else indrive */
int Xorriso_get_drive_handles(struct XorrisO *xorriso,
struct burn_drive_info **dinfo,
@ -562,17 +576,149 @@ much_too_long:;
}
/* @param flag bit0= recursion is active */
int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir,
char *img_dir_path, char *disk_dir_path, int flag)
{
struct iso_volume *volume;
struct iso_tree_node *node;
int ret, target_is_dir, source_is_dir;
struct DirseQ *dirseq= NULL;
char sfe[4*SfileadrL], sfe2[4*SfileadrL];
char disk_path[2*SfileadrL], img_path[2*SfileadrL];
char *name, *img_name;
struct stat stbuf;
ret= Xorriso_get_volume(xorriso, &volume, 0);
if(ret<=0)
return(ret);
ret= Dirseq_new(&dirseq, disk_dir_path, 1);
if(ret<0) {
sprintf(xorriso->info_text,"Failed to create source filesystem iterator");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
{ret= -1; goto ex;}
}
if(ret==0) {
sprintf(xorriso->info_text,"Cannot open as source directory: %s",
Text_shellsafe(disk_dir_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
{ret= 0; goto ex;}
}
if(Sfile_str(disk_path, disk_dir_path,0)<=0)
{ret= -1; goto ex;}
if(disk_path[strlen(disk_path)-1]!='/')
strcat(disk_path,"/");
name= disk_path+strlen(disk_path);
if(Sfile_str(img_path, img_dir_path, 0)<=0)
{ret= -1; goto ex;}
if(img_path[strlen(img_path)-1]!='/')
strcat(img_path,"/");
img_name= img_path+strlen(img_path);
while(1) { /* loop over directory content */
Xorriso_process_msg_queues(xorriso,0);
ret= Dirseq_next_adr(dirseq,name,0);
if(ret==0)
break;
if(ret<0) {
sprintf(xorriso->info_text,"Failed to obtain next directory entry");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
{ret= -1; goto ex;}
}
strcpy(img_name, name);
if(Xorriso_much_too_long(xorriso, strlen(img_path), 0)<=0)
goto was_problem;
if(Xorriso_much_too_long(xorriso, strlen(disk_path), 0)<=0)
goto was_problem;
if(lstat(disk_path, &stbuf)==-1) {
sprintf(xorriso->info_text,
"Cannot determine attributes of source file %s",
Text_shellsafe(disk_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0);
goto was_problem;
}
source_is_dir= 0;
if(S_ISDIR(stbuf.st_mode)) {
source_is_dir= 1;
} else if(!(S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))) {
sprintf(xorriso->info_text,"Source file %s is of non-supported file type",
Text_shellsafe(disk_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
goto was_problem;
}
/* does a node exist with this name ? */
node= iso_tree_volume_path_to_node(volume,img_path);
if(node!=NULL) {
target_is_dir= (iso_tree_node_get_type(node)==LIBISO_NODE_DIR);
if(!(target_is_dir && source_is_dir)) {
Xorriso_process_msg_queues(xorriso,0);
/* handle overwrite situation */;
if(xorriso->do_overwrite==1 ||
(xorriso->do_overwrite==2 && !target_is_dir)) {
ret= Xorriso_rmi(xorriso, img_path, 1);
if(ret<=0)
goto was_problem;
node= NULL;
} else {
sprintf(xorriso->info_text,
"While grafting %s : file object exists and may not be overwritten",
Text_shellsafe(img_path,sfe,0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
goto was_problem;
}
}
}
if(node==NULL)
node= iso_tree_add_node(dir, disk_path);
if(node == NULL) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,
"While grafting %s=%s : libisofs_errno = %d",
Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0),
libisofs_errno);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
goto was_problem;
}
/* name always equal to disk. Obsolete: iso_tree_node_set_name(node,name);*/
if(source_is_dir) {
ret= Xorriso_add_tree(xorriso, (struct iso_tree_node_dir *) node,
img_path, disk_path, 1);
if(ret<0)
{ret= -1; goto ex;}
if(ret==0)
goto was_problem;
}
continue;
was_problem:;
ret= Xorriso_eval_problem_status(xorriso, 0, 1);
if(ret<0)
{ret= 0; goto ex;}
}
ret= 1;
ex:
Xorriso_process_msg_queues(xorriso,0);
Dirseq_destroy(&dirseq, 0);
return(ret);
}
/** @param flag bit0= mkdir: graft in as empty directory, not as copy from disk
@return <=0 = error , 1 = added simple node , 2 = added directory */
int Xorriso_graft_in(struct XorrisO *xorriso, char *disk_path, char *img_path,
int flag)
{
struct iso_volume *volume;
struct iso_tree_radd_dir_behavior behav= {NULL, 0, 0};
char path[SfileadrL], *apt, *npt, *cpt;
struct iso_tree_node_dir *dir;
struct iso_tree_node *node;
int done= 0, is_dir= 0, l, ret;
int done= 0, is_dir= 0, l, ret, target_is_dir, source_is_dir;
struct stat stbuf;
for(cpt= img_path; 1; cpt++) {
@ -654,24 +800,34 @@ int Xorriso_graft_in(struct XorrisO *xorriso, char *disk_path, char *img_path,
goto attach_source;
continue;
}
source_is_dir= (is_dir || (flag&1) || !done);
node= iso_tree_volume_path_to_node(volume,path);
if(node!=NULL) {
if(iso_tree_node_get_type(node)!=LIBISO_NODE_DIR) {
target_is_dir= (iso_tree_node_get_type(node)==LIBISO_NODE_DIR);
if(!(target_is_dir && source_is_dir)) {
Xorriso_process_msg_queues(xorriso,0);
if(done) {
/* >>> handle overwrite situation */;
/* handle overwrite situation */;
if(xorriso->do_overwrite==1 ||
(xorriso->do_overwrite==2 && !target_is_dir)) {
ret= Xorriso_rmi(xorriso, path, 1);
if(ret<=0)
return(ret);
node= NULL;
goto handle_path_node;
}
sprintf(xorriso->info_text,
"While grafting '%s' : '%s' exists and is not a directory",
"While grafting '%s' : '%s' exists and may not be overwritten",
img_path, path);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
return(0);
}
dir= (struct iso_tree_node_dir *) node;
} else if(is_dir || (flag&1) || !done) {
}
handle_path_node:;
if(node==NULL && source_is_dir) { /* make a directory */
dir= iso_tree_add_dir(dir, apt);
if(dir==NULL) {
Xorriso_process_msg_queues(xorriso,0);
@ -692,11 +848,19 @@ attach_source:;
} else if(is_dir) {
/* >>> do this by own recursive operation in order to gain
full control with overwriting */;
#ifdef Xorriso_on_its_way_ouT
/* <<< */
{ struct iso_tree_radd_dir_behavior behav= {NULL, 0, 0};
iso_tree_radd_dir(dir, disk_path, &behav);
}
#else
ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, 0);
if(ret<=0)
return(ret);
#endif /* ! Xorriso_on_its_way_ouT */
} else {
node= iso_tree_add_node(dir, disk_path);
@ -820,6 +984,9 @@ int Xorriso_toc(struct XorrisO *xorriso, int flag)
if(s != BURN_DISC_FULL && s != BURN_DISC_APPENDABLE)
return(1);
if(xorriso->request_to_abort)
return(1);
disc= burn_drive_get_disc(drive);
if (disc==NULL) {
Xorriso_process_msg_queues(xorriso,0);
@ -856,11 +1023,13 @@ int Xorriso_toc(struct XorrisO *xorriso, int flag)
num_sessions= 1;
} else {
sessions= burn_disc_get_sessions(disc, &num_sessions);
for (session_no= 0; session_no<num_sessions; session_no++) {
for (session_no= 0; session_no<num_sessions && !(xorriso->request_to_abort);
session_no++) {
tracks = burn_session_get_tracks(sessions[session_no], &num_tracks);
if (tracks==NULL)
continue;
for(track_no= 0; track_no<num_tracks; track_no++) {
for(track_no= 0; track_no<num_tracks && !(xorriso->request_to_abort);
track_no++) {
track_count++;
is_data= 0;
burn_track_get_entry(tracks[track_no], &toc_entry);
@ -896,6 +1065,8 @@ int Xorriso_toc(struct XorrisO *xorriso, int flag)
num_data+= last_track_size;
}
}
if(xorriso->request_to_abort)
return(1);
sprintf(respt, "Media summary: %d session%s, %d data blocks\n",
num_sessions, (num_sessions==1 ? "" : "s"), num_data);
Xorriso_result(xorriso,0);
@ -947,7 +1118,7 @@ int Xorriso_show_devices(struct XorrisO *xorriso, int flag)
Xorriso_info(xorriso,0);
respt= xorriso->result_line;
for(i= 0; i < drive_count; i++) {
for(i= 0; i < drive_count && !(xorriso->request_to_abort); i++) {
if(burn_drive_get_adr(&(drive_list[i]), adr)<=0)
strcpy(adr, "-get_adr_failed-");
Xorriso_process_msg_queues(xorriso,0);
@ -1196,7 +1367,7 @@ int Xorriso_node_from_path(struct XorrisO *xorriso, struct iso_volume *volume,
/* @param flag bit0= remove whole sub tree: rm -r
bit1=remove empty directory: rmdir
bit1= remove empty directory: rmdir
@return <=0 = error
1 = removed simple node
2 = removed directory or tree
@ -1213,12 +1384,8 @@ int Xorriso_rmi(struct XorrisO *xorriso, char *path, int flag)
if(ret<=0)
return(ret);
if(strlen(path)>=SfileadrL) {
sprintf(xorriso->info_text,
"Path given for ISO image is much too long (%d)", strlen(path));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
if(Xorriso_much_too_long(xorriso, strlen(path), 0)<=0)
return(0);
}
ret= Xorriso_node_from_path(xorriso, volume, path, &victim_node, 0);
if(ret<=0)
return(ret);
@ -1253,16 +1420,11 @@ int Xorriso_rmi(struct XorrisO *xorriso, char *path, int flag)
return(0);
}
#ifdef Not_yeT
char boss_adr[SfiladrL], *spt;
struct *check_node;
int l;
if(xorriso->do_reassure) {
/* >>> derive boss_path as dirname from victim_path ... */
check_node= iso_tree_volume_path_to_node(volume, boss_path);
/* >>> compare boss_node and check_node */
/* >>> ask user */;
#endif /* Not_yeT */
}
ret= iso_tree_node_remove(boss_node, victim_node);
Xorriso_process_msg_queues(xorriso,0);
@ -1379,10 +1541,7 @@ int Xorriso_show_du_subs(struct XorrisO *xorriso,
strcpy(path, abs_path);
if(Sfile_add_to_path(path, name, 0)<=0) {
much_too_long:;
sprintf(xorriso->info_text,
"Path for subdirectory gets much too long (%d)",
strlen(path)+strlen(name)+1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2);
{ret= -1; goto ex;}
}
filec++;
@ -1419,7 +1578,7 @@ much_too_long:;
iter= iso_tree_node_children(dir_node);
}
for(i= 0; i<filec; i++) {
for(i= 0; i<filec && !(xorriso->request_to_abort); i++) {
if(no_sort) {
node= iso_tree_iter_next(iter);
if(node==NULL)
@ -1519,7 +1678,7 @@ much_too_long:;
return(!was_error);
}
for(i= 0; i<filec; i++) {
for(i= 0; i<filec && !(xorriso->request_to_abort); i++) {
if(filev[i][0]!='/') {
strcpy(path, xorriso->wdi);
if(Sfile_add_to_path(path, filev[i], 0)<=0)
@ -1667,7 +1826,7 @@ wdi_is_not_a_dir:;
iter= iso_tree_node_children(dir_node);
}
for(i= 0; i<filec; i++) {
for(i= 0; i<filec && !(xorriso->request_to_abort); i++) {
if(no_sort) {
node= iso_tree_iter_next(iter);
if(node==NULL)