Allowed lseekable device files with -paste_in

This commit is contained in:
2022-05-30 18:48:05 +02:00
parent 0c0d542591
commit 865115f779
5 changed files with 123 additions and 74 deletions

View File

@ -2,7 +2,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2021 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2022 Thomas Schmitt, <scdbackup@gmx.net>
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);