|
|
|
@ -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= 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);
|
|
|
|
|
ret= Xorriso_restore(xorriso, eff_source, eff_dest, startbyte, bytecount,
|
|
|
|
|
8 | no_props);
|
|
|
|
|
ex:;
|
|
|
|
|
Xorriso_free_meM(eff_source);
|
|
|
|
|
Xorriso_free_meM(eff_dest);
|
|
|
|
|