Enabled -hardlinks for options -extract, -extract_l and -cp*x

This commit is contained in:
2009-05-26 14:00:54 +00:00
parent 24d7ff9cf9
commit 340f89591f
6 changed files with 1052 additions and 147 deletions

View File

@ -10,7 +10,7 @@ or
-Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
-o xorriso/xorriso \
xorriso/xorriso.c xorriso/xorrisoburn.c \
-lpthread -lreadline -lburn -lisofs -lisoburn
-lz -lacl -lpthread -lreadline -lburn -lisofs -lisoburn
or
@ -2260,7 +2260,7 @@ failed:;
/*
@param flag Bitfield for control purposes
see
see Xorriso_lst_new_binary()
*/
int Xorriso_lst_new(struct Xorriso_lsT **lstring, char *text,
struct Xorriso_lsT *link, int flag)
@ -5240,7 +5240,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->add_plainly= 0;
m->split_size= 0;
strcpy(m->list_delimiter, "--");
m->ino_behavior= 3;
m->ino_behavior= 7;
m->do_joliet= 0;
m->do_aaip= 0;
m->relax_compliance= 0;
@ -5315,6 +5315,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->allow_restore= 0;
m->do_concat_split= 1;
m->do_auto_chmod= 0;
m->do_restore_sort_lba= 0;
m->dialog= 0;
m->bsl_interpretation= 0;
m->search_mode= 0;
@ -5391,12 +5392,18 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->node_counter= 0;
m->node_array_size= 0;
m->node_array= NULL;
m->node_targets= NULL;
m->node_targets_availmem= 0;
m->node_disk_prefixes= NULL;
m->node_img_prefixes= NULL;
m->perm_stack= NULL;
m->result_line[0]= 0;
m->result_line_counter= 0;
m->result_page_counter= 0;
m->result_open_line_len= 0;
m->info_text[0]= 0;
ret= Sfile_leafname(progname, leafname, 0);
@ -5457,16 +5464,6 @@ int Xorriso_destroy_re(struct XorrisO *m, int flag)
}
int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag)
{
if(xorriso->node_array != NULL)
free(xorriso->node_array);
xorriso->node_array= NULL;
xorriso->node_counter= xorriso->node_array_size= 0;
return(1);
}
/* @param flag bit0= global shutdown of libraries */
int Xorriso_destroy(struct XorrisO **xorriso, int flag)
{
@ -5485,8 +5482,7 @@ int Xorriso_destroy(struct XorrisO **xorriso, int flag)
Xorriso_lst_destroy_all(&(m->drive_blacklist), 0);
Xorriso_lst_destroy_all(&(m->drive_greylist), 0);
Xorriso_lst_destroy_all(&(m->drive_whitelist), 0);
if(m->node_array != NULL)
free(m->node_array);
Xorriso_destroy_node_array(m, 0);
Xorriso_detach_libraries(m, flag&1);
free((char *) m);
@ -7216,9 +7212,10 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
if(xorriso->allow_restore == -1)
sprintf(line,"-osirrox %s\n", mode_pt);
else
sprintf(line,"-osirrox %s:%s:%s\n", mode_pt,
sprintf(line,"-osirrox %s:%s:%s:%s\n", mode_pt,
xorriso->do_concat_split ? "concat_split_on" : "concat_split_off",
xorriso->do_auto_chmod ? "auto_chmod_on" : "auto_chmod_off"
xorriso->do_auto_chmod ? "auto_chmod_on" : "auto_chmod_off",
xorriso->do_restore_sort_lba ? "sort_lba_on" : "sort_lba_off"
);
if(!(is_default && no_defaults))
@ -7596,11 +7593,9 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default= ((xorriso->ino_behavior & (1 | 2)) == 3);
switch (xorriso->ino_behavior & 3) {
is_default= ((xorriso->ino_behavior & (1 | 2)) == 7);
switch (xorriso->ino_behavior & 7) {
case 0: form= "on";
break; case 1: form= "new_ino";
break; case 2: form= "no_hardlinks";
break; default: form= "off";
}
sprintf(line,"-hardlinks %s\n", form);
@ -8354,7 +8349,7 @@ int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter,
if(strncmp(iso_path, iso_prefix, strlen(iso_prefix))!=0)
return(-1);
if(strlen(disk_prefix)+strlen(iso_path)-strlen(iso_prefix)>=SfileadrL)
if(strlen(disk_prefix)+strlen(iso_path)-strlen(iso_prefix)+1>=SfileadrL)
return(-1);
if(iso_path[strlen(iso_prefix)]=='/')
strcpy(adrc, iso_path+strlen(iso_prefix)+1);
@ -10057,6 +10052,7 @@ ex:
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
bit6= permission to call Xorriso_make_accessible()
@return <=0 = error
1 = removed leaf file object
2 = removed directory or tree
@ -10064,10 +10060,13 @@ ex:
*/
int Xorriso_rmx(struct XorrisO *xorriso, off_t boss_mem, char *path, int flag)
{
int ret, is_dir= 0;
int ret, is_dir= 0, made_accessible= 0;
struct stat victim_stbuf, *victim_node= NULL;
struct DirseQ *dirseq= NULL;
char *sfe= NULL, *sub_path= NULL;
struct PermiteM *perm_stack_mem;
perm_stack_mem= xorriso->perm_stack;
/* Avoiding large local memory objects in order to save stack space */
sfe= malloc(5*SfileadrL);
@ -10082,10 +10081,19 @@ int Xorriso_rmx(struct XorrisO *xorriso, off_t boss_mem, char *path, int flag)
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((flag & 64) && errno == EACCES) {
ret= Xorriso_make_accessible(xorriso, path, 0);
if(ret < 0)
goto ex;
made_accessible= 1;
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");
@ -10199,16 +10207,30 @@ dir_not_removed:;
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(ret == -1) {
if((flag & 64) && errno == EACCES && !made_accessible) {
ret= Xorriso_make_accessible(xorriso, path, 0);
if(ret < 0)
goto ex;
made_accessible= 1;
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(made_accessible)
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
if(sfe!=NULL)
free(sfe);
if(sub_path!=NULL)
@ -11838,6 +11860,11 @@ int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag)
}
/* @param flag bit7= return 4 if restore fails from denied permission
do not issue error message
@return <=0 failure , 1 success ,
4 with bit7: permission to create file was denied
*/
int Xorriso_make_tmp_path(struct XorrisO *xorriso, char *orig_path,
char *tmp_path, int *fd, int flag)
{
@ -11853,6 +11880,8 @@ int Xorriso_make_tmp_path(struct XorrisO *xorriso, char *orig_path,
strcat(tmp_path, "_tmp_xorriso_restore_XXXXXX");
*fd= mkstemp(tmp_path);
if(*fd==-1) {
if(errno == EACCES && (flag & 128))
return(4);
strcpy(xorriso->info_text, "Cannot create temporary file : ");
Text_shellsafe(tmp_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
@ -11863,6 +11892,10 @@ int Xorriso_make_tmp_path(struct XorrisO *xorriso, char *orig_path,
}
/* @param flag bit0= change regardless of xorriso->do_auto_chmod
bit1= desired is only rx
@return -1=severe error , -2= cannot chmod, 0= nothing to do, 1 = chmoded
*/
int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag)
{
int ret, is_link= 0;
@ -11870,9 +11903,11 @@ int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag)
mode_t mode, desired= S_IRUSR | S_IWUSR | S_IXUSR;
struct stat stbuf;
if(!xorriso->do_auto_chmod)
if(!(xorriso->do_auto_chmod || (flag & 1)))
return(0);
if(flag & 2)
desired &= ~S_IWUSR;
path_pt= disk_path;
ret= lstat(path_pt, &stbuf);
if(ret==-1)
@ -11891,10 +11926,10 @@ int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag)
return(ret);
path_pt= link_target;
}
if(stbuf.st_uid!=geteuid())
return(0);
if((stbuf.st_mode & desired) == desired)
return(0);
if(stbuf.st_uid!=geteuid())
return(-2);
mode= (stbuf.st_mode | desired) & 07777;
ret= chmod(path_pt, mode);
@ -11903,6 +11938,7 @@ int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag)
"Cannot change access permissions of disk directory: chmod %o %s",
(unsigned int) (mode & 07777), Text_shellsafe(path_pt, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0);
return(-2);
}
ret= Permstack_push(&(xorriso->perm_stack), path_pt, &stbuf, 0);
if(ret<=0)
@ -11911,6 +11947,106 @@ int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag)
}
int Xorriso_make_accessible(struct XorrisO *xorriso, char *disk_path, int flag)
{
int done= 0, ret, just_rx= 2;
char *npt, *apt, path[SfileadrL], *wpt;
apt= disk_path;
wpt= path;
for(npt= apt; !done; apt= npt + 1) {
npt= strchr(apt, '/');
if(npt == NULL)
break;
if(strchr(npt + 1, '/') == NULL)
just_rx= 0;
strncpy(wpt, apt, npt + 1 - apt);
wpt+= npt + 1 - apt;
*wpt= 0;
ret= Xorriso_auto_chmod(xorriso, path, just_rx);
if(ret == -1)
return(-1);
if(ret == -2)
return(0);
}
return(1);
}
/* @param flag bit0= prefer to find a match after *img_prefixes
(but deliver img_prefixes if no other can be found)
*/
int Xorriso_make_restore_path(struct XorrisO *xorriso,
struct Xorriso_lsT **img_prefixes, struct Xorriso_lsT **disk_prefixes,
char img_path[SfileadrL], char disk_path[SfileadrL], int flag)
{
int li;
struct Xorriso_lsT *s, *d, *found_s= NULL, *found_d= NULL;
char *ipfx, *dpfx;
/* Obtain disk_path by replacing start piece of img_path */
d= *disk_prefixes;
for(s= *img_prefixes; s != NULL;
s= Xorriso_lst_get_next(s, 0), d= Xorriso_lst_get_next(d, 0)) {
ipfx= Xorriso_lst_get_text(s, 0);
li= strlen(ipfx);
dpfx= Xorriso_lst_get_text(d, 0);
if(strncmp(img_path, ipfx, li) != 0)
continue;
if(img_path[li] != 0 && img_path[li] != '/')
continue;
if(strlen(dpfx) + strlen(img_path) - li + 1 >= SfileadrL)
return(-1);
if(img_path[li]=='/')
sprintf(disk_path, "%s/%s", dpfx, img_path + strlen(ipfx) + 1);
else
strcpy(disk_path, dpfx);
found_s= s;
found_d= d;
if(s != *img_prefixes || !(flag & 1))
break;
}
*img_prefixes= found_s;
*disk_prefixes= found_d;
return(found_s != NULL);
}
/* @param flag bit0=permission to run Xorriso_make_accessible
*/
int Xorriso_restore_make_hl(struct XorrisO *xorriso,
char *old_path, char *new_path, int flag)
{
int ret;
struct PermiteM *perm_stack_mem;
ret= link(old_path, new_path);
if(ret == 0)
return(1);
if(errno == EACCES && (flag & 1)) {
perm_stack_mem= xorriso->perm_stack;
ret= Xorriso_make_accessible(xorriso, new_path, 0);
if(ret > 0) {
ret= link(old_path, new_path);
if(ret == 0) {
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
return(1);
}
}
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
}
sprintf(xorriso->info_text, "Hardlinking failed: ");
Text_shellsafe(new_path, xorriso->info_text, 1);
strcat(xorriso->info_text, " -> ");
Text_shellsafe(old_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
return(0);
}
/* @param flag bit0= mark untested areas as valid
*/
int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
@ -12725,6 +12861,92 @@ ex:;
}
/* @param flag bit0= no hardlink reconstruction
bit1= do not set xorriso->node_*_prefixes
bit5= -extract_single: eventually do not insert directory tree
*/
int Xorriso_restore_sorted(struct XorrisO *xorriso, int count,
char **src_array, char **tgt_array, int flag)
{
int i, ret, with_node_array= 0, hflag= 0, hret;
if(xorriso->do_restore_sort_lba ||
!((xorriso->ino_behavior & 4) || (flag & 1))) {
/* Count affected nodes */
Xorriso_destroy_node_array(xorriso, 0);
for(i= 0; i < count; i++) {
if(src_array[i] == NULL || tgt_array[i] == NULL)
continue;
if(xorriso->do_restore_sort_lba) {
/* sort_lba : Make directories plus node_array and then
run array extractor (with eventual hardlink detection)
*/
hflag= (1 << 7) | ((!!(flag & 2)) << 9);
} else {
/* Hardlink detection: Have a sorted node_array with list of pathnames
for binary lookup in Xorriso_restore()
*/
hflag= 3 << 7;
}
ret= Xorriso_restore(xorriso, src_array[i], tgt_array[i],
(off_t) 0, (off_t) 0, hflag);
if(ret <= 0) {
hret= Xorriso_eval_problem_status(xorriso, ret, 0);
if(ret < 0)
goto ex;
}
with_node_array= 1;
}
}
if(with_node_array) {
/* Allocate and fill node array */
if(xorriso->node_counter <= 0)
{ret= 2; goto ex;}
ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit,
!xorriso->do_restore_sort_lba);
if(ret<=0)
goto ex;
for(i= 0; i < count; i++) {
if(src_array[i] == NULL || tgt_array[i] == NULL)
continue;
ret= Xorriso_restore(xorriso, src_array[i], tgt_array[i],
(off_t) 0, (off_t) 0, 2 << 7);
if(ret <= 0) {
hret= Xorriso_eval_problem_status(xorriso, ret, 0);
if(ret < 0)
goto ex;
}
}
}
/* Perform restore operations */
if(xorriso->do_restore_sort_lba) {
ret= Xorriso_restore_node_array(xorriso, 0);
if(ret <= 0)
goto ex;
} else {
if(with_node_array)
Xorriso_sort_node_array(xorriso, 0);
for(i= 0; i < count; i++) {
if(src_array[i] == NULL || tgt_array[i] == NULL)
continue;
ret= Xorriso_restore(xorriso, src_array[i], tgt_array[i],
(off_t) 0, (off_t) 0, 0);
if(ret <= 0) {
hret= Xorriso_eval_problem_status(xorriso, ret, flag & 32);
if(ret < 0)
goto ex;
}
}
}
ret= 1;
ex:;
return(ret);
}
/* ---------------------------- Options API ------------------------ */
@ -14123,6 +14345,8 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
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];
char **eff_src_array= NULL, **eff_tgt_array= NULL;
int optc= 0;
char **optv= NULL;
struct stat stbuf;
@ -14142,6 +14366,17 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
ret= 0; goto ex;
}
if(xorriso->do_restore_sort_lba || !(xorriso->ino_behavior & 4)) {
eff_src_array= calloc(optc, sizeof(char *));
eff_tgt_array= calloc(optc, sizeof(char *));
if(eff_src_array == NULL || eff_tgt_array == NULL) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
for(i= 0; i < optc; i++)
eff_src_array[i]= eff_tgt_array[i]= NULL;
}
/* Perform copying */
Xorriso_pacifier_reset(xorriso, 0);
for(i= 0; i<optc && !xorriso->request_to_abort; i++) {
@ -14181,16 +14416,25 @@ int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv,
goto problem_handler;
}
}
ret= Xorriso_restore(xorriso, eff_origin, eff_dest, (off_t) 0, (off_t) 0,
16 | ((!(flag&2))<<6));
if(ret<=0 || xorriso->request_to_abort)
goto problem_handler;
if(ret==3 || (flag&1))
if(eff_src_array != NULL) {
eff_src_array[i]= strdup(eff_origin);
eff_tgt_array[i]= strdup(eff_dest);
if(eff_src_array[i] == NULL || eff_tgt_array[i] == NULL) {
Xorriso_no_malloc_memory(xorriso, &(eff_src_array[i]), 0);
ret= -1; goto ex;
}
} else {
ret= Xorriso_restore(xorriso, eff_origin, eff_dest, (off_t) 0, (off_t) 0,
16 | ((!(flag&2))<<6));
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);
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;
@ -14199,11 +14443,21 @@ problem_handler:;
continue;
goto ex;
}
if(eff_src_array != NULL) {
ret= Xorriso_restore_sorted(xorriso, optc, eff_src_array, eff_tgt_array, 0);
if(ret <= 0)
was_failure= 1;
}
if(xorriso->pacifier_count>0)
Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count,
xorriso->pacifier_total, "", 1|4);
ret= !was_failure;
ex:;
i= optc;
Sfile_destroy_argv(&i, &eff_src_array, 0);
i= optc;
Sfile_destroy_argv(&i, &eff_tgt_array, 0);
Xorriso_opt_args(xorriso, "-cp*x",
argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256);
return(ret);
@ -14643,19 +14897,20 @@ int Xorriso_option_external_filter(struct XorrisO *xorriso,
/* Options -extract , -extract_single */
/* @param flag bit0=do not report the restored item
bit1=do not reset pacifier, no final pacifier message
bit2= do not make lba-sorted node array for hardlink detection
bit5= -extract_single: eventually do not insert directory tree
*/
int Xorriso_option_extract(struct XorrisO *xorriso, char *iso_path,
char *disk_path, int flag)
{
int ret;
char eff_origin[SfileadrL], eff_dest[SfileadrL], *ipth;
char eff_origin[SfileadrL], eff_dest[SfileadrL], *ipth, *eopt[1], *edpt[1];
if(xorriso->allow_restore <= 0) {
sprintf(xorriso->info_text,
"-extract: image-to-disk copies are not enabled by option -osirrox");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
ret= 0; goto ex;
}
if(!(flag&2))
Xorriso_pacifier_reset(xorriso, 0);
@ -14666,29 +14921,36 @@ int Xorriso_option_extract(struct XorrisO *xorriso, char *iso_path,
if(disk_path[0]==0) {
sprintf(xorriso->info_text, "-extract: Empty disk_path given");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1);
return(0);
ret= 0; goto ex;
}
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_dest,
2|4);
if(ret<=0)
return(ret);
goto ex;
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_origin, 2|8);
if(ret<=0)
return(ret);
ret= Xorriso_restore(xorriso, eff_origin, eff_dest,
(off_t) 0, (off_t) 0, (flag&32));
goto ex;
eopt[0]= eff_origin;
edpt[0]= eff_dest;
ret= Xorriso_restore_sorted(xorriso, 1, eopt, edpt, (flag & 32 ? 33 : 0));
if(!(flag&2))
Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count,
xorriso->pacifier_total, "", 1|4);
if(ret<=0)
return(ret);
goto ex;
if(!(flag&1)) {
sprintf(xorriso->info_text, "Extracted from ISO image: %s '%s'='%s'\n",
(ret>1 ? "directory" : "file"), eff_origin, eff_dest);
Xorriso_info(xorriso,0);
}
return(1);
ret= 1;
ex:;
if(!(flag & (4 | 32)))
Xorriso_destroy_node_array(xorriso, 0);
return(ret);
}
@ -15334,9 +15596,9 @@ int Xorriso_option_grow_blindly(struct XorrisO *xorriso, char *msc2, int flag)
int Xorriso_option_hardlinks(struct XorrisO *xorriso, char *mode, int flag)
{
if(strcmp(mode, "off")==0) {
xorriso->ino_behavior|= 1 | 2;
xorriso->ino_behavior|= 1 | 2 | 4;
} else if(strcmp(mode, "on")==0) {
xorriso->ino_behavior&= ~(1 | 2);
xorriso->ino_behavior&= ~(1 | 2 | 4);
} else {
sprintf(xorriso->info_text, "-hardlinks: unknown mode '%s'", mode);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
@ -15398,6 +15660,8 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" Like -charset but only for conversion to media.",
" -local_charset name",
" Override system assumption of the local character set name.",
" -hardlinks \"on\"|\"off\"",
" Enable resp. disable recording and restoring of hardlinks.",
" -acl \"on\"|\"off\"",
" Enable resp. disable reading and writing of ACLs.",
" -xattr \"on\"|\"off\"",
@ -15719,7 +15983,8 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
"Restore options which copy file objects from ISO image to disk filesystem:",
" -osirrox \"on\"|\"device_files\"|\"off\"|\"banned\"",
" [:\"concat_split_on\"|\"concat_split_off\"]",
" [:\"auto_chmod__on\"|\"auto_chmod__off\"]",
" [:\"auto_chmod_on\"|\"auto_chmod_off\"]",
" [:\"sort_lba_on\"|\"sort_lba_off\"]",
" By default \"off\" the inverse operation of xorriso from ISO",
" image to disk filesystem is disabled. \"on\" allows xorriso",
" to create, overwrite, delete files in the disk filesystem.",
@ -15728,7 +15993,7 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" Copy tree under iso_rr_path onto disk address disk_path.",
" This avoids the pitfalls of cp -r addressing rules.",
" -extract_l iso_rr_prefix disk_prefix iso_rr_path [***]",
" Perform -extract_r with each iso_rr_path.",
" Perform -extract with each iso_rr_path.",
" -extract_single iso_rr_path disk_path",
" Like -extract but with directory do not restore sub tree.",
" -extract_cut iso_rr_path byte_offset byte_count disk_path",
@ -16283,7 +16548,7 @@ int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv,
int ns_flag= 2|4, nt_flag= 2, opt_args_flag= 2;
char source_prefix[SfileadrL], target_prefix[SfileadrL], *cmd, **optv= NULL;
char eff_source[SfileadrL], eff_target[SfileadrL], *source_pt, *s_wd, *t_wd;
char sfe[5*SfileadrL];
char sfe[5*SfileadrL], **eff_src_array= NULL, **eff_tgt_array= NULL;
cmd= "-map_l";
s_wd= xorriso->wdx;
@ -16324,6 +16589,19 @@ int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv,
if(ret<=0)
goto ex;
if(mode == 3 &&
(xorriso->do_restore_sort_lba || !(xorriso->ino_behavior & 4))) {
eff_src_array= calloc(optc, sizeof(char *));
eff_tgt_array= calloc(optc, sizeof(char *));
if(eff_src_array == NULL || eff_tgt_array == NULL) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
for(i= 0; i < optc; i++)
eff_src_array[i]= eff_tgt_array[i]= NULL;
}
for(i= 0; i<optc; i++) {
ret= Xorriso_normalize_img_path(xorriso, s_wd, optv[i],
eff_source, ns_flag);
@ -16351,8 +16629,18 @@ int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv,
ret= Xorriso_option_compare(xorriso, eff_source, eff_target, 2|8);
else if(mode==2)
ret= Xorriso_option_update(xorriso, eff_source, eff_target, 2|8);
else if(mode==3)
ret= Xorriso_option_extract(xorriso, eff_source, eff_target, 2);
else if(mode==3) {
if(eff_src_array != NULL) {
eff_src_array[i]= strdup(eff_source);
eff_tgt_array[i]= strdup(eff_target);
if(eff_src_array[i] == NULL || eff_tgt_array[i] == NULL) {
Xorriso_no_malloc_memory(xorriso, &(eff_src_array[i]), 0);
ret= -1; goto ex;
}
} else {
ret= Xorriso_option_extract(xorriso, eff_source, eff_target, 2 | 4);
}
}
if(ret>0 && !xorriso->request_to_abort)
continue; /* regular bottom of loop */
@ -16362,6 +16650,19 @@ int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv,
continue;
goto ex;
}
ret= 1;
if(mode == 3 && eff_src_array != NULL) {
ret= Xorriso_lst_append_binary(&(xorriso->node_disk_prefixes),
target_prefix, strlen(target_prefix) + 1, 0);
if(ret <= 0)
goto ex;
ret= Xorriso_lst_append_binary(&(xorriso->node_img_prefixes),
source_prefix, strlen(source_prefix) + 1, 0);
if(ret <= 0)
goto ex;
ret= Xorriso_restore_sorted(xorriso, optc, eff_src_array, eff_tgt_array, 0);
}
if(mode==0)
Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count,
xorriso->pacifier_total, "", 1);
@ -16371,11 +16672,14 @@ int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv,
else if(mode==3)
Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count,
xorriso->pacifier_total, "", 1|4);
ret= 1;
ex:;
Xorriso_destroy_node_array(xorriso, 0);
i= optc;
Sfile_destroy_argv(&i, &eff_src_array, 0);
i= optc;
Sfile_destroy_argv(&i, &eff_tgt_array, 0);
(*idx)= end_idx;
Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &optc, &optv,
256);
Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &optc, &optv, 256);
if(ret<=0)
return(ret);
return(!was_failure);
@ -16853,6 +17157,10 @@ int Xorriso_option_osirrox(struct XorrisO *xorriso, char *mode, int flag)
xorriso->do_auto_chmod= 1;
else if(strncmp(cpt, "auto_chmod_off", l)==0)
xorriso->do_auto_chmod= 0;
else if(strncmp(cpt, "sort_lba_on", l)==0)
xorriso->do_restore_sort_lba= 1;
else if(strncmp(cpt, "sort_lba_off", l)==0)
xorriso->do_restore_sort_lba= 0;
else {
unknown_mode:;
sprintf(xorriso->info_text, "-osirrox: unknown mode '%s'", cpt);