From 865115f779eff78e82c17cb38b747aaad68de393 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Mon, 30 May 2022 18:48:05 +0200 Subject: [PATCH] Allowed lseekable device files with -paste_in --- xorriso/read_run.c | 107 +++++++++++++++++++++++++----------- xorriso/xorriso.1 | 8 ++- xorriso/xorriso.info | 72 ++++++++++++------------ xorriso/xorriso.texi | 8 ++- xorriso/xorriso_timestamp.h | 2 +- 5 files changed, 123 insertions(+), 74 deletions(-) diff --git a/xorriso/read_run.c b/xorriso/read_run.c index da3f9341..045af7ab 100644 --- a/xorriso/read_run.c +++ b/xorriso/read_run.c @@ -2,7 +2,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2021 Thomas Schmitt, + Copyright 2007-2022 Thomas Schmitt, Provided under GPL version 2 or later. @@ -41,6 +41,7 @@ #include "iso_manip.h" #include "read_run.h" #include "sort_cmp.h" +#include "disk_ops.h" int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource) @@ -824,7 +825,7 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node, int ret= 0, write_fd= -1, wanted, wret, open_flags, l_errno= 0; int target_deleted= 0, buf_size= 32 * 1024; char *what= "[unknown filetype]"; - char *buf= NULL, type_text[5], *temp_path= NULL, *buf_pt; + char *buf= NULL, type_text[5], *temp_path= NULL, *buf_pt, *reason; char *link_target, *open_path_pt= NULL; off_t todo= 0, size, seek_ret, last_p_count= 0, already_done, read_count= 0; void *data_stream= NULL; @@ -836,7 +837,7 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node, IsoBoot *bootcat; uint32_t lba; char *catcontent = NULL; - off_t catsize; + off_t catsize, iso_node_size, wanted_size, cap; char disk_md5[16], iso_md5[16]; void *ctx= NULL; int use_md5= 0, i, sparse_ret= 3; @@ -886,13 +887,30 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node, if(ret == -1 && errno == EACCES && (flag & 128)) {ret= 4; goto ex;} if(flag&2) { - if(ret!=-1 && !S_ISREG(stbuf.st_mode)) { - sprintf(xorriso->info_text, - "Restore offset demanded. But filesystem path leads to non-data file "); - Text_shellsafe(disk_path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - l_errno= 0; - goto cannot_restore; + if(ret != -1) { + wanted_size= disk_offset + bytes; + iso_node_size= iso_file_get_size((IsoFile *) node); + if(wanted_size > disk_offset + iso_node_size) + wanted_size= disk_offset + iso_node_size; + cap= wanted_size; + ret= Xorriso_determine_capacity(xorriso, open_path_pt, &cap, &reason, + 3); + if(ret <= 0 || (cap <= 0 && !S_ISREG(stbuf.st_mode))) { + if(ret > 0) + reason= "has addressable range 0"; + sprintf(xorriso->info_text, + "Restore offset demanded. But target file (%s) ", + Ftypetxt(stbuf.st_mode, 0)); + Text_shellsafe(disk_path, xorriso->info_text, 1); + strcat(xorriso->info_text, reason); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE",0); l_errno= 0; + goto cannot_restore; + } + if(cap < wanted_size && !S_ISREG(stbuf.st_mode)) { + + /* >>> non-regular file might be too small to take the interval */; + + } } } else { /* If source and target are the same disk file then do not copy content */ @@ -1378,6 +1396,7 @@ int Xorriso_register_node_target(struct XorrisO *xorriso, int node_idx, bit6= this is a copy action: do not fake times and ownership bit7= return 4 if restore fails from denied permission do not issue error message + bit10= do not restore properties @return <=0 = error , 1 = added leaf file object , 2 = added directory , 3= regularly not installed (disallowed device, UNIX domain socket) 4 = with bit7: permission to restore was denied @@ -1388,7 +1407,7 @@ int Xorriso_restore_disk_object(struct XorrisO *xorriso, off_t offset, off_t bytes, int flag) { int ret, i, split_count= 0, partno, total_parts, leaf_is_split= 0; - int record_hl_path= 0, node_idx, cannot_register= 0; + int record_hl_path= 0, node_idx, cannot_register= 0, no_props; off_t total_bytes; char *part_name, *part_path= NULL, *img_path_pt= NULL; IsoImage *volume; @@ -1398,6 +1417,8 @@ int Xorriso_restore_disk_object(struct XorrisO *xorriso, Xorriso_alloc_meM(part_path, char, SfileadrL); + no_props= !!(flag & 1024); + ret= Xorriso_get_volume(xorriso, &volume, 0); if(ret<=0) goto ex; @@ -1432,7 +1453,7 @@ int Xorriso_restore_disk_object(struct XorrisO *xorriso, if(ret == 4) goto ex; } - if(first_part_node!=NULL) + if(first_part_node != NULL && !no_props) Xorriso_restore_properties(xorriso, disk_path, first_part_node, !!(flag&64)); goto went_well; @@ -1474,10 +1495,11 @@ int Xorriso_restore_disk_object(struct XorrisO *xorriso, ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, (off_t) 0, disk_path, offset, bytes, - (flag&(4 | 8 | 128)) | (!!(flag&64)) | ((flag&1)<<1) | ( 16 * !(flag&2))); + (flag&(4 | 8 | 128)) | (!!(flag&64)) | ((flag&1)<<1) | ( 16 * !(flag&2)) + | (no_props << 3)); if(ret == 4) goto ex; - if(ret>0 && (flag&8)) + if(ret > 0 && (flag & 8) && !no_props) ret= Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64)); if(ret<=0) { restoring_failed:; @@ -1891,6 +1913,7 @@ ex: 3= count nodes in xorriso->node_counter, create no directory bit9= with operation mode 1 do net register prefixes + bit10= with bit3: do not restore properties to leaf file @return <=0 = error , 1 = added leaf file object , 2 = added directory , 3 = rejected */ @@ -1903,7 +1926,7 @@ int Xorriso_restore(struct XorrisO *xorriso, IsoNode *node= NULL; int done= 0, is_dir= 0, ret, source_is_dir, stbuf_ret, hret; int dir_create= 0, node_count= 0, node_register= 0, path_size; - 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, no_props; struct stat stbuf; struct PermiteM *perm_stack_mem; @@ -1917,6 +1940,7 @@ int Xorriso_restore(struct XorrisO *xorriso, break; case 2: node_register= 1; break; case 3: node_count= 1; } + no_props= (!!(flag & 8)) * (flag & 1024); if(dir_create && !(flag & (1 << 9))) { ret= Xorriso_lst_append_binary(&(xorriso->node_disk_prefixes), @@ -2005,7 +2029,7 @@ int Xorriso_restore(struct XorrisO *xorriso, if((flag&8) && done) { /* ??? move down from Xorriso_paste_in() : - check whether target does not exist or both are regular */; + check whether target does not exist or both are suitable */; } else if(source_is_dir || !(dir_create || node_count || node_register)) { ret= Xorriso_handle_collision(xorriso, node, img_path, path, disk_path, @@ -2078,7 +2102,7 @@ attach_source:; } } else { ret= Xorriso_restore_disk_object(xorriso, img_path, node, path, - offset, bytes, (flag & (2|4|64)) | !!(flag&8)); + offset, bytes, (flag & (2|4|64)) | no_props | !!(flag&8)); if(ret <= 0) { hret= Xorriso_eval_problem_status(xorriso, ret, 1 | 2); if(hret < 0) @@ -2218,9 +2242,10 @@ ex:; int Xorriso_paste_in(struct XorrisO *xorriso, char *disk_path, off_t startbyte, off_t bytecount, char *iso_rr_path, int flag) { - int ret; - char *eff_source= NULL, *eff_dest= NULL; - struct stat stbuf; + int ret, no_props= 0; + off_t wanted_size, cap; + char *eff_source= NULL, *eff_dest= NULL, *reason; + struct stat stbuf, disk_stbuf; IsoNode *node; Xorriso_alloc_meM(eff_source, char, SfileadrL); @@ -2240,16 +2265,6 @@ int Xorriso_paste_in(struct XorrisO *xorriso, char *disk_path, if(ret!=0) {ret= 0; goto ex;} - ret= stat(eff_dest, &stbuf); - if(ret!=-1 && !S_ISREG(stbuf.st_mode)) { - Xorriso_msgs_submit(xorriso, 0, eff_dest, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, "-paste_in: DISK file "); - Text_shellsafe(eff_source, xorriso->info_text, 1); - strcat(xorriso->info_text, " exists and is not a data file"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - {ret= 0; goto ex;} - } - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path, eff_source, 2); if(ret<=0) @@ -2266,9 +2281,37 @@ int Xorriso_paste_in(struct XorrisO *xorriso, char *disk_path, {ret= 0; goto ex;} } - /* >>> eventually obtain parameters from file name */; + /* >>> ??? flag bit to obtain startbyte and bytecount from file name */; - ret= Xorriso_restore(xorriso, eff_source, eff_dest, startbyte, bytecount, 8); + ret= lstat(eff_dest, &disk_stbuf); + if(ret != -1) { + no_props= 1 << 10; + wanted_size= startbyte + bytecount; + if(wanted_size > stbuf.st_size) + wanted_size= stbuf.st_size; + cap= wanted_size; + ret= Xorriso_determine_capacity(xorriso, eff_dest, &cap, &reason, 3); + if(ret <= 0 || (cap <= 0 && !S_ISREG(disk_stbuf.st_mode))) { + Xorriso_msgs_submit(xorriso, 0, eff_dest, 0, "ERRFILE", 0); + if(ret > 0) + reason= "has addressable range 0"; + sprintf(xorriso->info_text, "-paste_in: DISK file (%s) ", + Ftypetxt(disk_stbuf.st_mode, 0)); + Text_shellsafe(eff_dest, xorriso->info_text, 1); + sprintf(xorriso->info_text + strlen(xorriso->info_text), + " exists but %s", reason); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + if(cap < wanted_size && !S_ISREG(disk_stbuf.st_mode)) { + + /* >>> non-regular file might be too small to take the interval */; + + } + } + + ret= Xorriso_restore(xorriso, eff_source, eff_dest, startbyte, bytecount, + 8 | no_props); ex:; Xorriso_free_meM(eff_source); Xorriso_free_meM(eff_dest); diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 05bbd48b..0a1c3a05 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 "Version 1.5.5, Apr 26, 2022" +.TH XORRISO 1 "Version 1.5.5, May 30, 2022" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -5164,8 +5164,10 @@ Like \-cp_rx but restoring mtime, atime as in ISO image and trying to set ownership and group as in ISO image. .TP \fB\-paste_in\fR iso_rr_path disk_path byte_offset byte_count -Read the content of a ISO data file and write it into a data file on disk -beginning at the byte_offset. Write at most byte_count bytes. +Read the content of a ISO data file and write it into a data file or device +file on disk beginning at the byte_offset. Write at most byte_count bytes. +The file depicted by disk_path has to support random write access. +.br This is the inverse of command \-cut_out. .TP \fB\-concat\fR mode [target | lim prog [args [...]] lim] iso_rr_path [***] diff --git a/xorriso/xorriso.info b/xorriso/xorriso.info index 7b99ec73..54e072a1 100644 --- a/xorriso/xorriso.info +++ b/xorriso/xorriso.info @@ -4354,8 +4354,10 @@ The directory permissions on disk have to allow rwx. to set ownership and group as in ISO image. -paste_in iso_rr_path disk_path byte_offset byte_count Read the content of a ISO data file and write it into a data file - on disk beginning at the byte_offset. Write at most byte_count - bytes. This is the inverse of command -cut_out. + or device file on disk beginning at the byte_offset. Write at most + byte_count bytes. The file depicted by disk_path has to support + random write access. + This is the inverse of command -cut_out. -concat mode [target | lim prog [args [...]] lim] iso_rr_path [***] Copy the data content of one or more data files of the ISO image into a disk file object, into a file descriptor, or start a program @@ -5626,7 +5628,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top * -compare_l reports ISO/disk differences: Navigate. (line 147) * -compare_r reports ISO/disk differences: Navigate. (line 143) * -compliance controls standard compliance: SetWrite. (line 62) -* -concat copies ISO file content: Restore. (line 146) +* -concat copies ISO file content: Restore. (line 148) * -copyright_file sets copyright file name: SetWrite. (line 245) * -cpax copies files to disk: Restore. (line 128) * -cpr inserts like with cp -r: Insert. (line 171) @@ -5662,7 +5664,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top * -external_filter unregisters data filter: Filter. (line 47) * -extract copies file tree to disk: Restore. (line 90) * -extract_boot_images copies boot equipment to disk: Restore. - (line 174) + (line 176) * -extract_cut copies file piece to disk: Restore. (line 108) * -extract_l copies files to disk: Restore. (line 104) * -extract_single copies file to disk: Restore. (line 101) @@ -5720,7 +5722,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top * -md5 controls handling of MD5 sums: Loading. (line 184) * -mkdir creates ISO directory: Insert. (line 184) * -modesty_on_drive keep drive buffer hungry: SetWrite. (line 419) -* -mount issues mount command for ISO session: Restore. (line 202) +* -mount issues mount command for ISO session: Restore. (line 204) * -mount_cmd composes mount command line: Inquiry. (line 49) * -mount_cmd controls mount command: Inquiry. (line 65) * -msg_op perform operations on program messages: Frontend. (line 27) @@ -5913,7 +5915,7 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top * Emulation, pacifier form, -pacifier: Emulation. (line 166) * Examples: Examples. (line 6) * extattr, _definition: Extras. (line 66) -* File content, copy, -concat: Restore. (line 146) +* File content, copy, -concat: Restore. (line 148) * File names, curb length, -file_name_limit: Loading. (line 276) * File names, if Joliet is loaded: Loading. (line 242) * File names, if neither Rock Ridge nor Joliet: Loading. (line 229) @@ -6080,7 +6082,7 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top * Rename, in ISO image, -move: Manip. (line 31) * Rename, in ISO image, -mv: Manip. (line 37) * Restore, copy boot equipment to disk, -extract_boot_images: Restore. - (line 174) + (line 176) * Restore, copy file into disk file, -paste_in: Restore. (line 142) * Restore, copy file piece to disk, -extract_cut: Restore. (line 108) * Restore, copy file to disk, -extract_single: Restore. (line 101) @@ -6096,7 +6098,7 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top * Rock Ridge, _definition: Extras. (line 6) * Session, altered start address, -displacement: Loading. (line 78) * Session, info string, -session_string: Inquiry. (line 74) -* Session, issue mount command, -mount: Restore. (line 202) +* Session, issue mount command, -mount: Restore. (line 204) * Session, log when written, -session_log: Scripting. (line 134) * Session, mount command line, -mount_cmd: Inquiry. (line 49) * Session, mount parameters, -mount_opts: Inquiry. (line 65) @@ -6182,32 +6184,32 @@ Node: Inquiry200783 Node: Navigate209665 Node: Verify218372 Node: Restore229521 -Node: Emulation241637 -Node: Scripting252093 -Node: Frontend259876 -Node: Examples269502 -Node: ExDevices270680 -Node: ExCreate271341 -Node: ExDialog272641 -Node: ExGrowing273912 -Node: ExModifying274721 -Node: ExBootable275231 -Node: ExCharset275786 -Node: ExPseudo276682 -Node: ExCdrecord277609 -Node: ExMkisofs277929 -Node: ExGrowisofs279826 -Node: ExException280979 -Node: ExTime281437 -Node: ExIncBackup281895 -Node: ExRestore285921 -Node: ExRecovery286867 -Node: Files287439 -Node: Environ288773 -Node: Seealso289521 -Node: Bugreport290238 -Node: Legal290829 -Node: CommandIdx291841 -Node: ConceptIdx309666 +Node: Emulation241729 +Node: Scripting252185 +Node: Frontend259968 +Node: Examples269594 +Node: ExDevices270772 +Node: ExCreate271433 +Node: ExDialog272733 +Node: ExGrowing274004 +Node: ExModifying274813 +Node: ExBootable275323 +Node: ExCharset275878 +Node: ExPseudo276774 +Node: ExCdrecord277701 +Node: ExMkisofs278021 +Node: ExGrowisofs279918 +Node: ExException281071 +Node: ExTime281529 +Node: ExIncBackup281987 +Node: ExRestore286013 +Node: ExRecovery286959 +Node: Files287531 +Node: Environ288865 +Node: Seealso289613 +Node: Bugreport290330 +Node: Legal290921 +Node: CommandIdx291933 +Node: ConceptIdx309758  End Tag Table diff --git a/xorriso/xorriso.texi b/xorriso/xorriso.texi index cab38c61..f503fb2c 100644 --- a/xorriso/xorriso.texi +++ b/xorriso/xorriso.texi @@ -50,7 +50,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 "Version 1.5.5, Apr 26, 2022" +@c man .TH XORRISO 1 "Version 1.5.5, May 30, 2022" @c man .\" Please adjust this date whenever revising the manpage. @c man .\" @c man .\" Some roff macros, for reference: @@ -5923,8 +5923,10 @@ ownership and group as in ISO image. @item -paste_in iso_rr_path disk_path byte_offset byte_count @kindex -paste_in copies file into disk file @cindex Restore, copy file into disk file, -paste_in -Read the content of a ISO data file and write it into a data file on disk -beginning at the byte_offset. Write at most byte_count bytes. +Read the content of a ISO data file and write it into a data file or device +file on disk beginning at the byte_offset. Write at most byte_count bytes. +The file depicted by disk_path has to support random write access. +@* This is the inverse of command -cut_out. @c man .TP @item -concat mode [target | lim prog [args [...]] lim] iso_rr_path [***] diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 2c808517..c9a5a47a 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2022.05.30.164422" +#define Xorriso_timestamP "2022.05.30.164747"