diff --git a/libisoburn/libisoburn.ver b/libisoburn/libisoburn.ver index b1f38afa..b66ee690 100644 --- a/libisoburn/libisoburn.ver +++ b/libisoburn/libisoburn.ver @@ -148,6 +148,7 @@ Xorriso_option_commit_eject; Xorriso_option_compare; Xorriso_option_compliance; Xorriso_option_copyright_file; +Xorriso_option_cp_clone; Xorriso_option_cpri; Xorriso_option_cpx; Xorriso_option_cut_out; diff --git a/xorriso/iso_manip.c b/xorriso/iso_manip.c index 107fe607..6c9983b0 100644 --- a/xorriso/iso_manip.c +++ b/xorriso/iso_manip.c @@ -916,6 +916,7 @@ unsupported_type:; /* @param flag bit0= do not produce info message on success + bit1= do not raise protest if directory already exists @return 1=success, 0=was already directory, -1=was other type, -2=other error */ @@ -928,8 +929,10 @@ int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag) if(ret<0) return(-2); if(ret>0) { + if(ret == 2 && (flag & 2)) + return(0); sprintf(xorriso->info_text,"-mkdir: Address already existing %s", - Text_shellsafe(eff_path, sfe, 0)); + Text_shellsafe(eff_path, sfe, 0)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, (ret==2 ? "WARNING" : "FAILURE"), 0); return(-1+(ret==2)); @@ -1405,7 +1408,7 @@ int Xorriso_clone_tree(struct XorrisO *xorriso, void *boss_iter, if(eff_dest[0] == 0) strcpy(eff_dest, "/"); sprintf(xorriso->info_text, - "Cloning: Copy address already exists : "); + "Cloning: Copy address already exists: "); Text_shellsafe(eff_dest, xorriso->info_text, 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); return(0); diff --git a/xorriso/opts_a_c.c b/xorriso/opts_a_c.c index 9be51e86..881d42bf 100644 --- a/xorriso/opts_a_c.c +++ b/xorriso/opts_a_c.c @@ -94,6 +94,7 @@ int Xorriso_option_acl(struct XorrisO *xorriso, char *mode, int flag) /* Option -add */ /* @param flag bit0=do not report the added item bit1=do not reset pacifier, no final pacifier message + bit2= prepend ISO working directory in any case */ int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) @@ -134,12 +135,16 @@ int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv, } *wpt= 0; } - if(split==0) { + if(split==0) strcpy(target, source); - } else if(target[0]!='/') { + if(flag & 4) { ret= Sfile_prepend_path(xorriso->wdi, target, 0); - if(ret<=0) + if(ret<=0) { + sprintf(xorriso->info_text, "Effective path gets much too long (%d)", + (int) (strlen(xorriso->wdi)+strlen(target)+1)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); goto problem_handler; + } } ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, target, eff_path, 2); @@ -1887,6 +1892,102 @@ int Xorriso_option_copyright_file(struct XorrisO *xorriso, char *name, int flag) } +/* Option -cp_clone */ +int Xorriso_option_cp_clone(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, end_idx_dummy, ret, is_dir= 0, was_failure= 0, fret, pass; + char eff_origin[SfileadrL], eff_dest[SfileadrL], dest_dir[SfileadrL]; + char leafname[SfileadrL]; + int optc= 0; + char **optv= NULL; + struct stat stbuf; + + ret= Xorriso_cpmv_args(xorriso, "-cp_clone", argc, argv, idx, + &optc, &optv, eff_dest, 1); + if(ret<=0) + goto ex; + if(ret == 1 && optc > 1) { +nondir_exists:; + sprintf(xorriso->info_text, + "-cp_clone: Copy address already exists and is not a directory: "); + Text_shellsafe(eff_dest, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + strcpy(dest_dir, eff_dest); + if(optc == 1) { + ret= Xorriso_iso_lstat(xorriso, eff_dest, &stbuf, 0); + if(ret >= 0) { + if(S_ISDIR(stbuf.st_mode))/* target directory exists */ + is_dir= 1; + else + goto nondir_exists; + } + } else { + is_dir= 1; + ret= Xorriso_mkdir(xorriso, dest_dir, 1 | 2); + if(ret < 0) + {ret= -(ret != -1); goto ex;} + } + + /* Pass 0 checks whether the way is clear, pass 1 does the cloning */ + for(pass= 0; pass < 2; pass++) { + for(i= 0; iwdi, + optv[i], eff_origin, !!pass); + if(ret<=0 || xorriso->request_to_abort) + 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)+1)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto problem_handler; + } + } + ret= Xorriso_iso_lstat(xorriso, eff_dest, &stbuf, 0); + if(pass == 0) { + if(ret >= 0) { + sprintf(xorriso->info_text, "Cloning: Copy address already exists: "); + Text_shellsafe(eff_dest, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto problem_handler; + } + } else if(ret == -1) { + ret= Xorriso_clone_tree(xorriso, NULL, eff_origin, eff_dest, 0); + if(ret <= 0) + goto problem_handler; + sprintf(xorriso->info_text, "Cloned in ISO image: "); + Text_shellsafe(eff_origin, xorriso->info_text, 1); + strcat(xorriso->info_text, " to "); + Text_shellsafe(eff_dest, xorriso->info_text, 1); + strcat(xorriso->info_text, "\n"); + 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; + } + } + ret= !was_failure; +ex:; + Xorriso_opt_args(xorriso, "-cp_clone", + argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256); + return(ret); +} + + /* Option -cpr alias -cpri */ int Xorriso_option_cpri(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) diff --git a/xorriso/opts_d_h.c b/xorriso/opts_d_h.c index 1c9bc18b..4dced9b9 100644 --- a/xorriso/opts_d_h.c +++ b/xorriso/opts_d_h.c @@ -1600,7 +1600,9 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " -rmdir iso_rr_path [***]", " Delete empty directories.", " -clone iso_rr_path_original iso_rr_path_copy", -" Create a copy of an ISO directory tree. I.e. ISO to ISO.", +" Create an ISO copy of an ISO file or ISO directory tree.", +" -cp_clone iso_rr_path_original [***] iso_rr_path_dest", +" Create ISO to ISO copies according to the rules of cp -r.", "", " -- Default list delimiter marking the end of action argument", " list. It may be changed by option -list_delimiter.", diff --git a/xorriso/parse_exec.c b/xorriso/parse_exec.c index 246ceb28..08065a7f 100644 --- a/xorriso/parse_exec.c +++ b/xorriso/parse_exec.c @@ -314,8 +314,9 @@ int Xorriso_cpmv_args(struct XorrisO *xorriso, char *cmd, if(ret==2 || ((flag&1) && *optc > 1 && ret==0)) { is_dir= 1; } else if(*optc > 1) { - for(i= 0; i<*optc; i++) - Xorriso_msgs_submit(xorriso, 0, (*optv)[i], 0, "ERRFILE", 0); + if(flag & 2) + for(i= 0; i<*optc; i++) + Xorriso_msgs_submit(xorriso, 0, (*optv)[i], 0, "ERRFILE", 0); sprintf(xorriso->info_text, "%s: more than one origin given, destination is a non-directory: %s", cmd, Text_shellsafe(destv[0], sfe, 0)); @@ -497,7 +498,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, "check_md5","check_md5_r","check_media","check_media_defaults", "chgrp","chgrpi","chgrp_r","chgrp_ri","chmod","chmodi", "chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri", - "compare_l","cpr","cpri","cp_rax","cp_rx","cpax","cpx", + "compare_l","cp_clone","cp_rax","cp_rx","cpr","cpri", "cpax","cpx", "du","dui","dus","dusi","dux","dusx","external_filter","extract_l", "file_size_limit","find","findi","finds","findx", "getfacl","getfacli","getfacl_r","getfacl_ri", @@ -785,13 +786,16 @@ next_command:; (*idx)++; Xorriso_option_copyright_file(xorriso, arg1, 0); - } else if(strcmp(cmd,"cpr")==0 || strcmp(cmd,"cpri")==0) { - ret= Xorriso_option_cpri(xorriso, argc, argv, idx, 0); + } else if(strcmp(cmd,"cp_clone") == 0) { + ret= Xorriso_option_cp_clone(xorriso, argc, argv, idx, 0); } else if(strcmp(cmd,"cp_rx")==0 || strcmp(cmd,"cp_rax")==0) { ret= Xorriso_option_cpx(xorriso, argc, argv, idx, 1|((strcmp(cmd,"cp_rax")==0)<<1)); + } 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 || strcmp(cmd,"cpax")==0) { ret= Xorriso_option_cpx(xorriso, argc, argv, idx, (strcmp(cmd,"cpax")==0)<<1); @@ -1316,7 +1320,6 @@ next_command:; ret= Xorriso_option_temp_mem_limit(xorriso, arg1, 0); } else if(strcmp(cmd,"test")==0) { /* This option does not exist. */ - /* install temporary test code here */; } else if(strcmp(cmd,"toc")==0) { diff --git a/xorriso/sfile.c b/xorriso/sfile.c index f2b7280e..ef3aadf4 100644 --- a/xorriso/sfile.c +++ b/xorriso/sfile.c @@ -148,9 +148,24 @@ int Sfile_add_to_path(char path[SfileadrL], char *addon, int flag) int Sfile_prepend_path(char *prefix, char path[SfileadrL], int flag) { - int l, i; + int l, i, slashes, prefix_len, path_len; - l= strlen(path)+strlen(prefix)+1; + l= strlen(prefix); + if(l == 0) + return(1); + + /* Do not copy slashes between both parts */ + for(prefix_len= l; prefix_len > 0; prefix_len--) + if(prefix[prefix_len - 1] != '/') + break; + if(prefix_len == 0) + prefix_len= strlen(prefix) - 1; + path_len= strlen(path); + for(slashes= 0; slashes < path_len; slashes++) + if(path[slashes] != '/') + break; + + l= (strlen(path) - slashes) + prefix_len + 1; if(l>=SfileadrL) { #ifdef Not_yeT @@ -164,10 +179,16 @@ int Sfile_prepend_path(char *prefix, char path[SfileadrL], int flag) return(-1); } l-= strlen(path); - for(i= strlen(path)+1; i>=0; i--) - path[i+l]= path[i]; - strcpy(path,prefix); - path[l-1]= '/'; + if(l < 0) { + for(i= slashes; i <= path_len + 1; i++) + path[i+l]= path[i]; + } else if(l > 0) { + for(i= path_len + 1; i >= slashes; i--) + path[i+l]= path[i]; + } + if(prefix_len > 0) + memcpy(path, prefix, prefix_len); + path[l - 1 + slashes]= '/'; return(1); } diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 71a89ec2..51bcf167 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -9,7 +9,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "Feb 02, 2011" +.TH XORRISO 1 "Feb 04, 2011" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -1063,6 +1063,17 @@ The copies may then be manipulated independendly of their originals. This command will refuse execution if the address iso_rr_path_copy already exists in the ISO tree. .TP +\fB\-cp_clone\fR iso_rr_path_original [***] iso_rr_path_dest +Create copies of one or more ISO file objects as with command -clone. +Do not not overwrite existing ISO file objects. +.br +The rules for generating the copy addresses are the same as with +command -cpr (see above) resp. shell command cp -r. Other than with -cpr, +relative iso_rr_path_original will get prepended the -cd path and not +the -cdx path. Consider to -mkdir iso_rr_path_dest before -cp_clone +so the copy address does not depend on the number of iso_rr_path_original +arguments. +.TP .B Settings for file insertion: .TP \fB\-file_size_limit\fR value [value [...]] -- diff --git a/xorriso/xorriso.h b/xorriso/xorriso.h index 20343c09..8baa67b4 100644 --- a/xorriso/xorriso.h +++ b/xorriso/xorriso.h @@ -742,6 +742,10 @@ int Xorriso_option_compliance(struct XorrisO *xorriso, char *mode, int flag); int Xorriso_option_copyright_file(struct XorrisO *xorriso, char *name, int flag); +/* Option -cp_clone */ +int Xorriso_option_cp_clone(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag); + /* Option -cpr alias -cpri */ int Xorriso_option_cpri( struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag); diff --git a/xorriso/xorriso.info b/xorriso/xorriso.info index a7bcc73d..38cfa97b 100644 --- a/xorriso/xorriso.info +++ b/xorriso/xorriso.info @@ -998,6 +998,16 @@ filesystem. This command will refuse execution if the address iso_rr_path_copy already exists in the ISO tree. +-cp_clone iso_rr_path_original [***] iso_rr_path_dest + Create copies of one or more ISO file objects as with command + -clone. Do not not overwrite existing ISO file objects. + The rules for generating the copy addresses are the same as with + command -cpr (see above) resp. shell command cp -r. Other than + with -cpr, relative iso_rr_path_original will get prepended the + -cd path and not the -cdx path. Consider to -mkdir + iso_rr_path_dest before -cp_clone so the copy address does not + depend on the number of iso_rr_path_original arguments. +  File: xorriso.info, Node: SetInsert, Next: Manip, Prev: Insert, Up: Options @@ -4039,6 +4049,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top * -compare_r reports ISO/disk differences: Navigate. (line 152) * -compliance controls standard compliance: SetWrite. (line 14) * -copyright_file sets copyright file name: SetWrite. (line 152) +* -cp_clone copies ISO directory tree: Insert. (line 182) * -cp_rx copies file trees to disk: Restore. (line 104) * -cpax copies files to disk: Restore. (line 100) * -cpr inserts like with cp -r: Insert. (line 152) @@ -4234,6 +4245,7 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top * Dialog, enable dialog mode, -dialog: DialogCtl. (line 7) * Dialog, line editing, -use_readline: DialogCtl. (line 28) * Dialog, terminal geometry, -page: DialogCtl. (line 19) +* Directories, copy, -cp_clone: Insert. (line 182) * Directory, copy, -clone: Insert. (line 171) * Directory, create, -mkdir: Insert. (line 166) * Directory, delete, -rmdir: Manip. (line 32) @@ -4453,45 +4465,45 @@ Node: Options23227 Node: AqDrive24835 Node: Loading27741 Node: Insert40885 -Node: SetInsert49874 -Node: Manip58441 -Node: CmdFind67122 -Node: Filter77546 -Node: Writing81895 -Node: SetWrite88184 -Node: Bootable101794 -Node: Jigdo114101 -Node: Charset118359 -Node: Exception121110 -Node: DialogCtl125625 -Node: Inquiry128212 -Node: Navigate132545 -Node: Verify140440 -Node: Restore149029 -Node: Emulation155685 -Node: Scripting164728 -Node: Frontend170290 -Node: Examples171585 -Node: ExDevices172754 -Node: ExCreate173388 -Node: ExDialog174662 -Node: ExGrowing175924 -Node: ExModifying176726 -Node: ExBootable177227 -Node: ExCharset177774 -Node: ExPseudo178602 -Node: ExCdrecord179496 -Node: ExMkisofs179811 -Node: ExGrowisofs180814 -Node: ExException181938 -Node: ExTime182392 -Node: ExIncBackup182851 -Node: ExRestore186419 -Node: ExRecovery187388 -Node: Files187954 -Node: Seealso189182 -Node: Legal189706 -Node: CommandIdx190628 -Node: ConceptIdx204927 +Node: SetInsert50450 +Node: Manip59017 +Node: CmdFind67698 +Node: Filter78122 +Node: Writing82471 +Node: SetWrite88760 +Node: Bootable102370 +Node: Jigdo114677 +Node: Charset118935 +Node: Exception121686 +Node: DialogCtl126201 +Node: Inquiry128788 +Node: Navigate133121 +Node: Verify141016 +Node: Restore149605 +Node: Emulation156261 +Node: Scripting165304 +Node: Frontend170866 +Node: Examples172161 +Node: ExDevices173330 +Node: ExCreate173964 +Node: ExDialog175238 +Node: ExGrowing176500 +Node: ExModifying177302 +Node: ExBootable177803 +Node: ExCharset178350 +Node: ExPseudo179178 +Node: ExCdrecord180072 +Node: ExMkisofs180387 +Node: ExGrowisofs181390 +Node: ExException182514 +Node: ExTime182968 +Node: ExIncBackup183427 +Node: ExRestore186995 +Node: ExRecovery187964 +Node: Files188530 +Node: Seealso189758 +Node: Legal190282 +Node: CommandIdx191204 +Node: ConceptIdx205576  End Tag Table diff --git a/xorriso/xorriso.texi b/xorriso/xorriso.texi index 34ed9d10..479cae1e 100644 --- a/xorriso/xorriso.texi +++ b/xorriso/xorriso.texi @@ -44,7 +44,7 @@ @c man .\" First parameter, NAME, should be all caps @c man .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection @c man .\" other parameters are allowed: see man(7), man(1) -@c man .TH XORRISO 1 "Feb 02, 2011" +@c man .TH XORRISO 1 "Feb 04, 2011" @c man .\" Please adjust this date whenever revising the manpage. @c man .\" @c man .\" Some roff macros, for reference: @@ -1326,6 +1326,19 @@ The copies may then be manipulated independendly of their originals. @* This command will refuse execution if the address iso_rr_path_copy already exists in the ISO tree. +@c man .TP +@item -cp_clone iso_rr_path_original [***] iso_rr_path_dest +@kindex -cp_clone copies ISO directory tree +@cindex Directories, copy, -cp_clone +Create copies of one or more ISO file objects as with command -clone. +Do not not overwrite existing ISO file objects. +@* +The rules for generating the copy addresses are the same as with +command -cpr (see above) resp. shell command cp -r. Other than with -cpr, +relative iso_rr_path_original will get prepended the -cd path and not +the -cdx path. Consider to -mkdir iso_rr_path_dest before -cp_clone +so the copy address does not depend on the number of iso_rr_path_original +arguments. @end table @c man .TP @c man .B Settings for file insertion: diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index c8e77d57..d9eaca56 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2011.02.02.174154" +#define Xorriso_timestamP "2011.02.04.191922"