First experiments of osirrox ISO-to-disk copying

This commit is contained in:
2008-05-22 19:25:59 +00:00
parent ad33b43f99
commit 53f462b406
6 changed files with 935 additions and 105 deletions

View File

@ -2652,6 +2652,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
{
int i, ret;
struct XorrisO *m;
char leafname[SfileadrL];
*xorriso= m= TSOB_FELD(struct XorrisO,1);
if(m==NULL)
@ -2715,6 +2716,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->keep_boot_image= 0;
m->patch_isolinux_image= 0;
m->allow_graft_points= 0;
m->allow_restore= 0;
m->dialog= 0;
m->search_mode= 0;
m->structured_search= 1;
@ -2777,6 +2779,11 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->result_open_line_len= 0;
m->info_text[0]= 0;
ret= Sfile_leafname(progname, leafname, 0);
if(ret<=0)
goto failure;
if(strcmp(leafname, "osirrox")==0)
m->allow_restore= 1;
ret= Exclusions_new(&(m->disk_exclusions), 0);
if(ret<=0)
goto failure;
@ -3816,6 +3823,11 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
Xorriso_status_result(xorriso,filter,fp,flag&2);
}
is_default= !(xorriso->allow_restore);
sprintf(line,"-osirrox %s\n", xorriso->allow_restore ? "on" : "off");
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default= (xorriso->keep_boot_image==0 && xorriso->patch_isolinux_image==0);
form= "any";
treatment= "discard";
@ -5100,7 +5112,7 @@ int Xorriso_end_idx(struct XorrisO *xorriso,
bit3= do not expand last argument
bit4= ignore last argument
bit5= demand exactly one match
bit6= with bit allow 0 matches if pattern is a constant
bit6= with bit5 allow 0 matches if pattern is a constant
bit8= free the eventually allocated sub_vector
*/
int Xorriso_opt_args(struct XorrisO *xorriso, char *cmd,
@ -6213,6 +6225,210 @@ int Xorriso_lsx_filev(struct XorrisO *xorriso, char *wd,
}
/*
@param flag >>> bit0= remove whole sub tree: rm -r
bit1= remove empty directory: rmdir
bit2= recursion: do not reassure in mode 2 "tree"
bit3= this is for overwriting and not for plain removal
bit4= count deleted files in xorriso->pacifier_count
bit5= with bit0 only remove directory content, not the directory
@return <=0 = error
1 = removed leaf file object
2 = removed directory or tree
3 = did not remove on user revocation
*/
int Xorriso_rmx(struct XorrisO *xorriso, off_t boss_mem, char *path, int flag)
{
int ret, is_dir= 0;
struct stat victim_stbuf, *victim_node= NULL;
struct DirseQ *dirseq= NULL;
char *sfe= NULL, *sub_path= NULL;
/* Avoiding large local memory objects in order to save stack space */
sfe= malloc(5*SfileadrL);
sub_path= malloc(2*SfileadrL);
if(sfe==NULL || sub_path==NULL) {
Xorriso_no_malloc_memory(xorriso, &sfe, 0);
{ret= -1; goto ex;}
}
if(Xorriso_much_too_long(xorriso, strlen(path), 0)<=0)
{ret= 0; goto ex;}
ret= lstat(path, &victim_stbuf);
if(ret==-1) {
sprintf(xorriso->info_text, "Cannot lstat(%s)",
Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
{ret= 0; goto ex;}
}
if(strcmp(path, "/")==0) {
sprintf(xorriso->info_text, "May not delete root directory");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
victim_node= &victim_stbuf;
if(S_ISDIR(victim_stbuf.st_mode))
is_dir= 1;
if(!is_dir) {
if(flag&2) { /* rmdir */
sprintf(xorriso->info_text, "%s in disk filesystem is not a directory",
Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else {
if(flag&1) { /* rm -r */
#ifdef Osirrox_not_yeT
/* >>> */
if((xorriso->do_reassure==1 && !xorriso->request_not_to_ask) ||
(flag&32)) {
/* Iterate over subordinates and delete them */
mem= boss_mem;
ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem,
&iter, &node_array, &node_count, &node_idx,
&node, 1|2);
if(ret<=0) {
cannot_create_iter:;
Xorriso_cannot_create_iter(xorriso, ret, 0);
ret= -1; goto ex;
}
pl= strlen(path);
strcpy(sub_path, path);
if(pl==0 || sub_path[pl-1]!='/') {
sub_path[pl++]= '/';
sub_path[pl]= 0;
}
sub_name= sub_path+pl;
while(1) {
ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter,
&node_array, &node_count, &node_idx, &node, 0);
if(ret<0)
goto ex;
if(ret==0 || xorriso->request_to_abort)
break;
name= (char *) iso_node_get_name(node);
if(Xorriso_much_too_long(xorriso, pl+1+strlen(name), 0)<=0)
{ret= 0; goto rm_r_problem_handler;}
strcpy(sub_name, name);
ret= Xorriso_rmi(xorriso, iter, mem, sub_path, (flag&(1|2|8|16))|4);
if(ret==3 || ret<=0 || xorriso->request_to_abort) {
rm_r_problem_handler:;
not_removed= 1;
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
if(fret<0)
goto dir_not_removed;
}
}
if(flag&32)
{ret= 2; goto ex;}
if(not_removed) {
dir_not_removed:;
sprintf(xorriso->info_text, "Directory not removed: %s",
Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
if(ret>0)
ret= 3;
goto ex;
}
}
#else /* Osirrox_not_yeT */
sprintf(xorriso->info_text, "-rm_rx is not implemented yet");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
#endif /* !Osirrox_not_yeT */
} else {
if(!(flag&2)) { /* not rmdir */
sprintf(xorriso->info_text, "%s in disk filesystem is a directory",
Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= Dirseq_new(&dirseq, path, 1);
if(ret>0) {
ret= Dirseq_next_adr(dirseq, sfe, 0);
if(ret>0) {
sprintf(xorriso->info_text,
"Directory not empty on attempt to delete: %s",
Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
}
}
if(xorriso->request_to_abort)
{ret= 3; goto ex;}
while((xorriso->do_reassure==1 || (xorriso->do_reassure==2 && !(flag&4)))
&& !xorriso->request_not_to_ask) {
/* ls -ld */
Xorriso_lsx_filev(xorriso, xorriso->wdx, 1, &path, (off_t) 0, 1|2|8);
if(is_dir) /* du -s */
Xorriso_lsx_filev(xorriso, xorriso->wdx, 1, &path, (off_t) 0, 2|4);
if(flag&8)
sprintf(xorriso->info_text,
"File exists. Remove ? n= keep old, y= remove, x= abort, @= stop asking\n");
else
sprintf(xorriso->info_text,
"Remove above file ? n= keep it, y= remove it, x= abort, @= stop asking\n");
Xorriso_info(xorriso, 4);
ret= Xorriso_request_confirmation(xorriso, 1|2|4|16);
if(ret<=0)
goto ex;
if(xorriso->request_to_abort) {
sprintf(xorriso->info_text,
"Removal operation aborted by user before file: %s",
Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
ret= 3; goto ex;
}
if(ret==3)
continue;
if(ret==6) /* yes */
break;
if(ret==4) { /* yes, do not ask again */
xorriso->request_not_to_ask= 1;
break;
}
if(ret==1) { /* no */
sprintf(xorriso->info_text, "Kept in existing state: %s",
Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
ret= 3; goto ex;
}
}
if(is_dir)
ret= rmdir(path);
else
ret= unlink(path);
if(ret==-1) {
sprintf(xorriso->info_text, "Cannot delete from disk filesystem %s",
Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= -1; goto ex;
}
if(flag&16)
xorriso->pacifier_count++;
ret= 1+!!is_dir;
ex:;
if(sfe!=NULL)
free(sfe);
if(sub_path!=NULL)
free(sub_path);
Dirseq_destroy(&dirseq, 0);
return(ret);
}
/* @param flag bit0= recursion
*/
int Xorriso_findx_action(struct XorrisO *xorriso, struct FindjoB *job,
@ -6486,7 +6702,8 @@ ex:;
/* @param flag bit0= a non-existing target of multiple sources is a directory
bit1= all paths except the last one are disk_paths
@return <=0 iis error, 1= leaf file object, 2= directory
bit2= the last path is a disk_path
@return <=0 is error, 1= leaf file object, 2= directory
*/
int Xorriso_cpmv_args(struct XorrisO *xorriso, char *cmd,
int argc, char **argv, int *idx,
@ -6511,12 +6728,17 @@ int Xorriso_cpmv_args(struct XorrisO *xorriso, char *cmd,
goto ex;
/* demand one match, or 0 with a constant */
ret= Xorriso_opt_args(xorriso, cmd, argc, argv, end_idx, &end_idx, &destc,
&destv, 32|64);
&destv, ((flag&4)>>1) | 32 | 64);
if(ret<=0)
goto ex;
/* Evaluate target address */
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest, 1);
if(flag&4)
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, destv[0], eff_dest,
2|4|16);
else
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest,
1);
if(ret<0)
{ret= 0; goto ex;}
if(ret==2 || ((flag&1) && *optc > 1 && ret==0)) {
@ -6531,7 +6753,8 @@ int Xorriso_cpmv_args(struct XorrisO *xorriso, char *cmd,
{ret= 0; goto ex;}
}
if(ret==0) { /* compute complete eff_dest */
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0],eff_dest,2);
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest,
2 | (flag&4));
if(ret<0)
{ret= 0; goto ex;}
}
@ -8334,8 +8557,8 @@ int Xorriso_option_cpri(struct XorrisO *xorriso, int argc, char **argv,
strcpy(eff_dest, dest_dir);
ret= Sfile_add_to_path(eff_dest, leafname, 0);
if(ret<=0) {
printf(xorriso->info_text, "Effective path gets much too long (%d)",
strlen(eff_dest)+strlen(leafname)+1);
sprintf(xorriso->info_text, "Effective path gets much too long (%d)",
(int) (strlen(eff_dest)+ strlen(leafname)+1));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto problem_handler;
}
@ -8366,6 +8589,96 @@ ex:;
}
/* Option -cpx */
int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag)
{
int i, ret, is_dir= 0, was_failure= 0, fret, end_idx_dummy;
char eff_origin[SfileadrL], eff_dest[SfileadrL];
char dest_dir[SfileadrL], leafname[SfileadrL], sfe[5*SfileadrL];
int optc= 0;
char **optv= NULL;
struct stat stbuf;
if(!xorriso->allow_restore) {
sprintf(xorriso->info_text,
"-cpx: image-to-disk copies are not enabled by option -osirrox");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(xorriso->volset_change_pending) {
sprintf(xorriso->info_text,
"-cpx: Image changes pending. May not copy from image to disk.\n");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
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 */
Xorriso_pacifier_reset(xorriso, 0);
for(i= 0; i<optc && !xorriso->request_to_abort; i++) {
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, optv[i], eff_origin,
2);
if(ret<=0 || xorriso->request_to_abort)
goto problem_handler;
ret= Xorriso_iso_lstat(xorriso, eff_origin, &stbuf, 2);
if(ret==-1)
goto problem_handler;
if(S_ISDIR(stbuf.st_mode)) {
sprintf(xorriso->info_text, "-cpx: May not copy directory %s",
Text_shellsafe(eff_origin, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto problem_handler;
}
if(is_dir) {
ret= Sfile_leafname(eff_origin, leafname, 0);
if(ret<=0)
goto problem_handler;
strcpy(eff_dest, dest_dir);
ret= Sfile_add_to_path(eff_dest, leafname, 0);
if(ret<=0) {
sprintf(xorriso->info_text, "Effective path gets much too long (%d)",
(int) (strlen(eff_dest)+strlen(leafname)+1i));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto problem_handler;
}
}
ret= Xorriso_restore(xorriso, eff_origin, eff_dest, 16|64);
if(ret<=0 || xorriso->request_to_abort)
goto problem_handler;
if(ret==3 || (flag&1))
continue;
sprintf(xorriso->info_text,
"Copied from ISO image to disk: %s '%s'='%s'\n",
(ret>1 ? "directory" : "file"), eff_origin, eff_dest);
Xorriso_info(xorriso, 0);
continue; /* regular bottom of loop */
problem_handler:;
was_failure= 1;
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
if(fret>=0)
continue;
goto ex;
}
Xorriso_pacifier_callback(xorriso, "files copied", xorriso->pacifier_count,
xorriso->pacifier_total, "", 1);
ret= !was_failure;
ex:;
Xorriso_opt_args(xorriso, "-cpx",
argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256);
return(ret);
}
/* SPLIT : proposed target format
part_{partno}_of_{total_parts}_at_{offset}_with_{bytes}_of_{total_bytes}
*/
@ -9827,8 +10140,8 @@ int Xorriso_option_mvi(struct XorrisO *xorriso, int argc, char **argv,
strcpy(eff_dest, dest_dir);
ret= Sfile_add_to_path(eff_dest, leafname, 0);
if(ret<=0) {
printf(xorriso->info_text, "Effective path gets much too long (%d)",
strlen(eff_dest)+strlen(leafname)+1);
sprintf(xorriso->info_text, "Effective path gets much too long (%d)",
(int) (strlen(eff_dest)+strlen(leafname)+1));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto problem_handler;
}
@ -10147,6 +10460,26 @@ ex:;
}
/* Option -osirrox "on"|"off" */
int Xorriso_option_osirrox(struct XorrisO *xorriso, char *mode, int flag)
{
if(strcmp(mode, "off")==0)
xorriso->allow_restore= 0;
else if(strcmp(mode, "on")==0 || mode[0]==0)
xorriso->allow_restore= 1;
else {
sprintf(xorriso->info_text, "-osirrox: unknown mode '%s'", mode);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
sprintf(xorriso->info_text,
"%s copying of file objects from ISO image to disk filesystem\n",
xorriso->allow_restore ? "Enabled" : "Disabled");
Xorriso_info(xorriso, 0);
return(1);
}
/* Option -overwrite "on"|"nondir"|"off" */
int Xorriso_option_overwrite(struct XorrisO *xorriso, char *mode, int flag)
{
@ -11060,17 +11393,19 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
static char arg0_commands[][40]= {
"ban_stdio_write","commit","commit_eject","devices","end","help",
"list_formats","no_rc","print_size","pwd","pwdi","pwdx",
"rollback","rollback_end","tell_media_space","toc","version","--",""
"rollback","rollback_end","tell_media_space","toc","version","--",
""
};
static char arg1_commands[][40]= {
"abort_on","add_plainly","blank","cd","cdi","cdx","close","dev",
"dummy","dialog","disk_pattern","eject","iso_rr_pattern","follow",
"format","fs","gid","history","indev","joliet","mark","not_leaf",
"not_list","not_mgt","options_from_file","overwrite","outdev",
"not_list","not_mgt","options_from_file","osirrox","outdev","overwrite",
"padding","path_list","pathspecs","pkt_output","print","prompt",
"prog","publisher","reassure","report_about","rom_toc_scan",
"session_log","speed","split_size","status","status_history_max",
"temp_mem_limit","uid","volid","use_readline",""
"temp_mem_limit","uid","volid","use_readline",
""
};
static char arg2_commands[][40]= {
"alter_date","alter_date_r","boot_image","compare","compare_r",
@ -11079,12 +11414,14 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
""
};
static char arg4_commands[][40]= {
"cut_out",""
"cut_out",
""
};
static char argn_commands[][40]= {
"add","as","chgrp","chgrpi","chgrp_r","chgrp_ri","chmod","chmodi",
"chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri",
"cpr","cpri","du","dui","dus","dusi","dux","dusx","find","findi","findx",
"cpr","cpri","cpx",
"du","dui","dus","dusi","dux","dusx","find","findi","findx",
"ls","lsi","lsl","lsli","lsd","lsdi","lsdl","lsdli",
"lsx","lslx","lsdx","lsdlx","mv","mvi","mkdir","mkdiri",
"not_paths","rm","rmi","rm_r","rm_ri","rmdir","rmdiri",
@ -11300,6 +11637,9 @@ next_command:;
} else if(strcmp(cmd,"cpr")==0 || strcmp(cmd,"cpri")==0) {
ret= Xorriso_option_cpri(xorriso, argc, argv, idx, 0);
} else if(strcmp(cmd,"cpx")==0) {
ret= Xorriso_option_cpx(xorriso, argc, argv, idx, 0);
} else if(strcmp(cmd,"cut_out")==0) {
(*idx)+= 4;
if((*idx)>argc) {
@ -11466,14 +11806,18 @@ next_command:;
if(ret==3)
goto ex;
} else if(strcmp(cmd,"overwrite")==0) {
(*idx)++;
ret= Xorriso_option_overwrite(xorriso,arg1,0);
} else if(strcmp(cmd,"outdev")==0) {
(*idx)++;
ret= Xorriso_option_dev(xorriso, arg1, 2);
} else if(strcmp(cmd,"osirrox")==0) {
(*idx)++;
ret= Xorriso_option_osirrox(xorriso,arg1,0);
} else if(strcmp(cmd,"overwrite")==0) {
(*idx)++;
ret= Xorriso_option_overwrite(xorriso,arg1,0);
} else if(strcmp(cmd,"padding")==0) {
(*idx)++;
ret= Xorriso_option_padding(xorriso, arg1, 0);