With -update_r : detecting hardlink splits and fusions on disk
This commit is contained in:
parent
b7bb047464
commit
bf702dc38e
@ -668,30 +668,37 @@ terminal where xorriso runs. Before attributing this local character set
|
||||
to the produced ISO image, check whether the terminal properly displays
|
||||
all intended filenames, especially exotic national characters.
|
||||
.TP
|
||||
\fB\-hardlinks\fR "on"|"off"
|
||||
\fB\-hardlinks\fR "on"|"off"|"without_update"|"start_update"|"end_update"
|
||||
Enable or disable loading and recording of hardlink relations.
|
||||
.br
|
||||
In default mode "off", iso_rr files lose their inode numbers at image load
|
||||
time. Each iso_rr file object which has no inode number at image generation
|
||||
time will get a new unique inode number if -compliance is set to -new_rr.
|
||||
time will get a new unique inode number if -compliance is set to new_rr.
|
||||
.br
|
||||
Mode "on" preserves eventual inode numbers from the loaded image.
|
||||
When committing a session it searches for families of iso_rr files
|
||||
which stem from the same disk file, have identical content and have
|
||||
which stem from the same disk file, have identical content filtering and have
|
||||
identical properties. The family members all get the same inode number.
|
||||
Whether these numbers are respected at mount time depends on the operating
|
||||
system.
|
||||
.br
|
||||
xorriso commands which extract files from an ISO image try to restore files
|
||||
with the same inode number as hard links. This applies only to files which
|
||||
Commands -update and -update_r detect splits and fusions of hard links in
|
||||
filesystems which have stable device and inode numbers.
|
||||
Multiple -update_r commands should be surrounded by -hardlinks "start_update"
|
||||
and -hardlinks "end_update". This avoids multiple sorting of ISO image nodes.
|
||||
"start_update" implies "on".
|
||||
Mode "without_update" avoids hardlink processing during update commands.
|
||||
.br
|
||||
xorriso commands which extract files from an ISO image try to hardlink files
|
||||
with identical inode number. This applies only to files which
|
||||
get extracted during execution of that same command. A large number of
|
||||
hardlink families may exhaust -temp_mem_limit if not -osirrox option
|
||||
"sort_lba_on" is in effect.
|
||||
.br
|
||||
Mode "on" automatically enables \fB\-compliance new_rr\fR. This may be
|
||||
overridden by a following -compliance old_rr . In this case the resulting
|
||||
image will violate the RRIP-1.10 specs for entry PX in the same way as
|
||||
mkisofs does.
|
||||
Hardlink processing automatically enables \fB\-compliance new_rr\fR.
|
||||
This may be overridden by a following -compliance old_rr . In this case
|
||||
the resulting image will violate the RRIP-1.10 specs for entry PX in
|
||||
the same way as mkisofs does.
|
||||
.TP
|
||||
\fB\-acl\fR "on"|"off"
|
||||
Enable or disable processing of ACLs.
|
||||
|
@ -5397,6 +5397,9 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
|
||||
m->node_disk_prefixes= NULL;
|
||||
m->node_img_prefixes= NULL;
|
||||
|
||||
m->di_count= 0;
|
||||
m->di_array= NULL;
|
||||
|
||||
m->perm_stack= NULL;
|
||||
|
||||
m->result_line[0]= 0;
|
||||
@ -5483,6 +5486,8 @@ int Xorriso_destroy(struct XorrisO **xorriso, int flag)
|
||||
Xorriso_lst_destroy_all(&(m->drive_greylist), 0);
|
||||
Xorriso_lst_destroy_all(&(m->drive_whitelist), 0);
|
||||
Xorriso_destroy_node_array(m, 0);
|
||||
Xorriso_destroy_di_array(m, 0);
|
||||
|
||||
Xorriso_detach_libraries(m, flag&1);
|
||||
|
||||
free((char *) m);
|
||||
@ -7593,9 +7598,10 @@ 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 & 7) == 7);
|
||||
switch (xorriso->ino_behavior & 7) {
|
||||
is_default= ((xorriso->ino_behavior & 15) == 7);
|
||||
switch (xorriso->ino_behavior & 15) {
|
||||
case 0: form= "on";
|
||||
break; case 8: form= "without_update";
|
||||
break; default: form= "off";
|
||||
}
|
||||
sprintf(line,"-hardlinks %s\n", form);
|
||||
@ -7969,6 +7975,8 @@ cannot_address:;
|
||||
bit21= mismatch of recorded dev,inode
|
||||
bit22= no recorded dev,inode found in node
|
||||
bit23= timestamps younger than xorriso->isofs_st_in
|
||||
bit24= hardlink split
|
||||
bit25= hardlink fusion
|
||||
@param flag bit0= compare atime
|
||||
bit1= compare ctime
|
||||
bit2= check only existence of both file objects
|
||||
@ -8220,15 +8228,18 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
|
||||
((flag & 2) && xorriso->isofs_st_in <= s2.st_ctime)))
|
||||
(*result)|= 1 << 23;
|
||||
|
||||
if(xorriso->do_aaip & 32) {
|
||||
/* dev,inode comparison. Eventually skip content comparison */
|
||||
if((xorriso->do_aaip & 32) || !(xorriso->ino_behavior & 2)) {
|
||||
/* dev,inode comparison.
|
||||
For skipping content comparison or for hardlink detection.
|
||||
*/
|
||||
ret= Xorriso_record_dev_inode(xorriso, "", s1.st_dev, s1.st_ino, NULL,
|
||||
iso_adr, 1 | 2 | ((flag & (1 << 28)) >> 23) | (xorriso->do_aaip & 128));
|
||||
if(ret < 0) {
|
||||
ret= -1; goto ex;
|
||||
} else if(ret == 0) { /* match */
|
||||
if((xorriso->do_aaip & 64) && S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)){
|
||||
content_shortcut= 1;
|
||||
if(xorriso->do_aaip & 32)
|
||||
content_shortcut= 1;
|
||||
if((*result) & (8 | 128 | 256 | 512 | 1024 | (1 << 23))) {
|
||||
(*result)|= (1 << 15); /* content bytes differ */
|
||||
if(((*result) & (1 << 23)) &&
|
||||
@ -8260,8 +8271,10 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
|
||||
sprintf(respt, "%s dev_ino : differing\n", a);
|
||||
if(!(flag&(1<<31)))
|
||||
Xorriso_result(xorriso,0);
|
||||
|
||||
if((xorriso->do_aaip & 64) && S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)){
|
||||
content_shortcut= 1;
|
||||
if(xorriso->do_aaip & 32)
|
||||
content_shortcut= 1;
|
||||
(*result)|= (1 << 15); /* content bytes differ */
|
||||
sprintf(respt,
|
||||
"%s content : assuming inequality after dev_ino mismatch\n", a);
|
||||
@ -8319,7 +8332,7 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
|
||||
if(was_error)
|
||||
ret= -1;
|
||||
else
|
||||
ret= (((*result)&~((1<<17)|(1<<18)))==0);
|
||||
ret= (((*result) & ~((1 << 17) | (1 << 18) | (1 << 23)))==0);
|
||||
ex:;
|
||||
if(split_parts!=NULL)
|
||||
Splitparts_destroy(&split_parts, split_count, 0);
|
||||
@ -11634,7 +11647,11 @@ int Xorriso_as_cdrskin(struct XorrisO *xorriso, int argc, char **argv,
|
||||
|
||||
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
|
||||
Set to NULL if calling this function from outside ISO world
|
||||
@param flag bit2= -follow: this is not a command parameter
|
||||
@param flag bit0= widen hardlink sibling:
|
||||
Do not call Xorriso_hardlink_update()
|
||||
Overwrite exactly if normal mode would not,
|
||||
else do nothing
|
||||
bit2= -follow: this is not a command parameter
|
||||
@return <=0 error, 1= ok , 2= iso_rr_path node object has been deleted ,
|
||||
3= no action taken
|
||||
*/
|
||||
@ -11642,7 +11659,7 @@ int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter,
|
||||
int compare_result, char *disk_path,
|
||||
char *iso_rr_path, int flag)
|
||||
{
|
||||
int ret, deleted= 0, is_split= 0, i, loop_count;
|
||||
int ret, deleted= 0, is_split= 0, i, loop_count, late_hardlink_update= 0;
|
||||
char sfe[5*SfileadrL];
|
||||
struct stat stbuf;
|
||||
struct SplitparT *split_parts= NULL;
|
||||
@ -11660,6 +11677,8 @@ int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter,
|
||||
}
|
||||
|
||||
if(compare_result&((1<<11)|(1<<13))) {
|
||||
if(flag & 1)
|
||||
{ret= 3; goto ex;}
|
||||
/* cannot open regular disk file, early eof of disk file */
|
||||
sprintf(xorriso->info_text, "Problems with reading disk file %s",
|
||||
Text_shellsafe(disk_path, sfe, 0));
|
||||
@ -11670,8 +11689,26 @@ int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter,
|
||||
xorriso->info_text[0]= 0;
|
||||
is_split= !!(compare_result & (1<<17));
|
||||
|
||||
if((!(xorriso->ino_behavior & 2)) && (compare_result & (2 | (3 << 21))) &&
|
||||
!(flag & 1)) {
|
||||
if(compare_result & 2) {
|
||||
/* File is not yet in image */
|
||||
late_hardlink_update= 1;
|
||||
} else {
|
||||
/* Hard link relation has changed resp. was not recorded. */
|
||||
ret= Xorriso_hardlink_update(xorriso, &compare_result,
|
||||
disk_path, iso_rr_path, flag & 4);
|
||||
if(ret < 0)
|
||||
goto ex;
|
||||
if(ret == 2)
|
||||
{ret= 1; goto ex;}
|
||||
}
|
||||
}
|
||||
|
||||
if(compare_result&(8|64)) {
|
||||
/* file type, minor+major with device file */
|
||||
if(flag & 1)
|
||||
{ret= 3; goto ex;}
|
||||
ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1); /* rm_r */
|
||||
if(ret>0) {
|
||||
deleted= 1;
|
||||
@ -11691,6 +11728,9 @@ delete:;
|
||||
/* iso_adr not existing, size, cannot open iso file, early eof of iso file
|
||||
content bytes differ */
|
||||
|
||||
if(flag & 1)
|
||||
{ret= 3; goto ex;}
|
||||
overwrite:;
|
||||
if(is_split) {
|
||||
ret= Xorriso_identify_split(xorriso, iso_rr_path, NULL,
|
||||
&split_parts, &split_count, &stbuf, 0);
|
||||
@ -11755,12 +11795,25 @@ delete:;
|
||||
if(ret>0 && !(compare_result&2))
|
||||
deleted= 1;
|
||||
}
|
||||
sprintf(xorriso->info_text, "Added/overwrote ");
|
||||
if(late_hardlink_update) {
|
||||
/* Handle eventual hardlink siblings of newly created file */
|
||||
ret= Xorriso_hardlink_update(xorriso, &compare_result,
|
||||
disk_path, iso_rr_path, 1 | (flag & 4));
|
||||
if(ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
if(flag & 1)
|
||||
sprintf(xorriso->info_text, "Widened hard link ");
|
||||
else
|
||||
sprintf(xorriso->info_text, "Added/overwrote ");
|
||||
|
||||
} else if(compare_result&(4|16|32|256|512|1024|(1<<19)|(1<<20)|(1<<22))) {
|
||||
/* access permissions, user id, group id, mtime, atime, ctime, ACL, xattr,
|
||||
dev_ino missing */
|
||||
|
||||
if(flag & 1)
|
||||
goto overwrite;
|
||||
|
||||
if(is_split) {
|
||||
ret= Xorriso_identify_split(xorriso, iso_rr_path, NULL,
|
||||
&split_parts, &split_count, &stbuf, 0);
|
||||
@ -11789,6 +11842,8 @@ delete:;
|
||||
ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 4);
|
||||
sprintf(xorriso->info_text, "Adjusted attributes of ");
|
||||
|
||||
} else if(flag & 1) {
|
||||
goto overwrite;
|
||||
} else
|
||||
ret= 1;
|
||||
if(ret>0 && xorriso->info_text[0]) {
|
||||
@ -13134,7 +13189,7 @@ int Xorriso_option_alter_date(struct XorrisO *xorriso,
|
||||
if(flag&1) {
|
||||
ret= Findjob_new(&job, optv[i], 0);
|
||||
if(ret<=0) {
|
||||
Xorriso_no_findjob(xorriso, "-chmod_r", 0);
|
||||
Xorriso_no_findjob(xorriso, "-alter_date", 0);
|
||||
{ret= -1; goto ex;}
|
||||
}
|
||||
Findjob_set_action_ad(job, t_type, t, 0);
|
||||
@ -15599,10 +15654,24 @@ int Xorriso_option_grow_blindly(struct XorrisO *xorriso, char *msc2, int flag)
|
||||
/* Option -hardlinks "on"|"off" */
|
||||
int Xorriso_option_hardlinks(struct XorrisO *xorriso, char *mode, int flag)
|
||||
{
|
||||
if(strcmp(mode, "off")==0) {
|
||||
int ret;
|
||||
|
||||
if(strcmp(mode, "off") == 0) {
|
||||
xorriso->ino_behavior|= 1 | 2 | 4;
|
||||
} else if(strcmp(mode, "on")==0) {
|
||||
xorriso->ino_behavior&= ~8;
|
||||
} else if(strcmp(mode, "on") == 0) {
|
||||
xorriso->ino_behavior&= ~(1 | 2 | 4 | 8);
|
||||
} else if(strcmp(mode, "without_update") == 0) {
|
||||
xorriso->ino_behavior&= ~(1 | 2 | 4);
|
||||
xorriso->ino_behavior|= 8;
|
||||
Xorriso_destroy_di_array(xorriso, 0);
|
||||
} else if(strcmp(mode, "start_update") == 0) {
|
||||
xorriso->ino_behavior&= ~(1 | 2 | 4 | 8);
|
||||
ret= Xorriso_make_di_array(xorriso, 0);
|
||||
if(ret <= 0)
|
||||
return(ret);
|
||||
} else if(strcmp(mode, "end_update") == 0) {
|
||||
Xorriso_destroy_di_array(xorriso, 0);
|
||||
} else {
|
||||
sprintf(xorriso->info_text, "-hardlinks: unknown mode '%s'", mode);
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
||||
@ -15664,8 +15733,10 @@ 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 hard links.",
|
||||
" -hardlinks \"on\"|\"off\"|\"start_update\"|\"end_update\"|\"without_update\"",
|
||||
" Enable resp. disable recording and restoring of hard links,",
|
||||
" or prepare for -update_r, or release prepared memory, or",
|
||||
" disable hardlink detection with -update_r.",
|
||||
" -acl \"on\"|\"off\"",
|
||||
" Enable resp. disable reading and writing of ACLs.",
|
||||
" -xattr \"on\"|\"off\"",
|
||||
@ -16542,7 +16613,9 @@ int Xorriso_option_map(struct XorrisO *xorriso, char *disk_path,
|
||||
|
||||
|
||||
/* Options -map_l , -compare_l , -update_l , -extract_l */
|
||||
/* @param flag bit8-11= mode 0= -map_l
|
||||
/* @param flag bit4= do not establish and dispose xorriso->di_array
|
||||
for update_l
|
||||
bit8-11= mode 0= -map_l
|
||||
1= -compare_l
|
||||
2= -update_l
|
||||
3= -extract_l
|
||||
@ -16551,7 +16624,7 @@ int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv,
|
||||
int *idx, int flag)
|
||||
{
|
||||
int ret, end_idx, optc= 0, was_failure= 1, i, fret, mode;
|
||||
int ns_flag= 2|4, nt_flag= 2, opt_args_flag= 2;
|
||||
int ns_flag= 2|4, nt_flag= 2, opt_args_flag= 2, made_di_array= 0;
|
||||
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], **eff_src_array= NULL, **eff_tgt_array= NULL;
|
||||
@ -16607,6 +16680,14 @@ int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv,
|
||||
for(i= 0; i < optc; i++)
|
||||
eff_src_array[i]= eff_tgt_array[i]= NULL;
|
||||
}
|
||||
if(mode == 2 && !((xorriso->ino_behavior & 2) || (flag & 16) ||
|
||||
xorriso->di_array != NULL)) {
|
||||
/* Create all-image node array sorted by isofs.di */
|
||||
ret= Xorriso_make_di_array(xorriso, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
made_di_array= 1;
|
||||
}
|
||||
|
||||
for(i= 0; i<optc; i++) {
|
||||
ret= Xorriso_normalize_img_path(xorriso, s_wd, optv[i],
|
||||
@ -16634,7 +16715,7 @@ int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv,
|
||||
else if(mode==1)
|
||||
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);
|
||||
ret= Xorriso_option_update(xorriso, eff_source, eff_target, 2 | 8 | 16);
|
||||
else if(mode==3) {
|
||||
if(eff_src_array != NULL) {
|
||||
eff_src_array[i]= strdup(eff_source);
|
||||
@ -16685,6 +16766,8 @@ ex:;
|
||||
i= optc;
|
||||
Sfile_destroy_argv(&i, &eff_tgt_array, 0);
|
||||
(*idx)= end_idx;
|
||||
if(made_di_array)
|
||||
Xorriso_destroy_di_array(xorriso, 0);
|
||||
Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &optc, &optv, 256);
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
@ -18425,12 +18508,13 @@ int Xorriso_option_uid(struct XorrisO *xorriso, char *uid, int flag)
|
||||
bit1= do not reset pacifier, no final pacifier message
|
||||
bit2= do not issue pacifier messages at all
|
||||
bit3= recursive: -update_r
|
||||
bit4= do not establish and dispose xorriso->di_array
|
||||
*/
|
||||
int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path,
|
||||
char *iso_path, int flag)
|
||||
{
|
||||
int ret, mem_pci, zero= 0, result, uret, follow_links;
|
||||
int not_in_iso= 0, not_on_disk= 0;
|
||||
int not_in_iso= 0, not_on_disk= 0, made_di_array= 0;
|
||||
double mem_lut= 0.0, start_time;
|
||||
char *ipth, *argv[6], sfe[5*SfileadrL];
|
||||
char eff_origin[SfileadrL], eff_dest[SfileadrL];
|
||||
@ -18475,6 +18559,16 @@ int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path,
|
||||
ret= 0;
|
||||
if(ret!=0)
|
||||
goto report_outcome;
|
||||
|
||||
if(!((xorriso->ino_behavior & 2) || (flag & 16) ||
|
||||
xorriso->di_array != NULL)) {
|
||||
/* Create all-image node array sorted by isofs.di */
|
||||
made_di_array= 1;
|
||||
ret= Xorriso_make_di_array(xorriso, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
}
|
||||
|
||||
if(flag&8) {
|
||||
xorriso->find_compare_result= 1;
|
||||
ret= Xorriso_iso_lstat(xorriso, eff_dest, &stbuf, 0);
|
||||
@ -18560,7 +18654,13 @@ report_outcome:;
|
||||
" (runtime %.1f s)\n", Sfile_microtime(0)-start_time);
|
||||
if(flag&1)
|
||||
Xorriso_info(xorriso,0);
|
||||
if(ret<0)
|
||||
|
||||
ex:;
|
||||
if(made_di_array) {
|
||||
/* Dispose all-image node array sorted by isofs.di */
|
||||
Xorriso_destroy_di_array(xorriso, 0);
|
||||
}
|
||||
if(ret < 0)
|
||||
return(ret);
|
||||
return(1);
|
||||
}
|
||||
|
@ -106,6 +106,8 @@ struct XorrisO { /* the global context of xorriso */
|
||||
Do not consolidate suitable nodes to hardlinks.
|
||||
bit2= at restore-to-disk time:
|
||||
Do not consolidate suitable nodes to hardlinks.
|
||||
bit3= with update:
|
||||
Do not try to detect hardlink splits and joinings.
|
||||
*/
|
||||
|
||||
int do_joliet;
|
||||
@ -389,6 +391,7 @@ struct XorrisO { /* the global context of xorriso */
|
||||
|
||||
int find_compare_result; /* 1=everything matches , 0=mismatch , -1=error */
|
||||
|
||||
/* LBA sorting and hardlink matching facility */
|
||||
int node_counter;
|
||||
int node_array_size;
|
||||
void **node_array;
|
||||
@ -397,6 +400,10 @@ struct XorrisO { /* the global context of xorriso */
|
||||
struct Xorriso_lsT *node_disk_prefixes;
|
||||
struct Xorriso_lsT *node_img_prefixes;
|
||||
|
||||
/* Array of all nodes in the tree, sorted by disk dev,ino */
|
||||
int di_count;
|
||||
void **di_array;
|
||||
|
||||
struct PermiteM *perm_stack; /* Temporarily altered dir access permissions */
|
||||
|
||||
/* result (stdout, R: ) */
|
||||
@ -640,6 +647,10 @@ int Xorriso_path_setfattr(struct XorrisO *xorriso, void *in_node, char *path,
|
||||
int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp,
|
||||
int flag);
|
||||
|
||||
int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
|
||||
char *iso_adr, char *adr_common_tail,
|
||||
int *result, int flag);
|
||||
|
||||
int Sfile_str(char target[SfileadrL], char *source, int flag);
|
||||
|
||||
double Sfile_microtime(int flag);
|
||||
@ -990,6 +1001,10 @@ int Findjob_test_2(struct XorrisO *xorriso, struct FindjoB *o,
|
||||
|
||||
int Findjob_set_action_found_path(struct FindjoB *o, int flag);
|
||||
|
||||
/* @param flag bit0= recursive
|
||||
*/
|
||||
int Findjob_set_action_target(struct FindjoB *o, int action, char *target,
|
||||
int flag);
|
||||
int Findjob_get_action(struct FindjoB *o, int flag);
|
||||
|
||||
int Findjob_get_action_parms(struct FindjoB *o, char **target, char **text_2,
|
||||
|
@ -1 +1 @@
|
||||
#define Xorriso_timestamP "2009.06.03.082041"
|
||||
#define Xorriso_timestamP "2009.06.15.121525"
|
||||
|
@ -124,6 +124,10 @@ int Xorriso__node_lba_cmp(const void *node1, const void *node2);
|
||||
isoburn_igopt_always_gmt | \
|
||||
isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10 )
|
||||
|
||||
#ifdef NIX
|
||||
/* <<< */
|
||||
unsigned long Xorriso_get_di_counteR= 0;
|
||||
#endif /* NIX */
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
@ -154,12 +158,39 @@ int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag)
|
||||
}
|
||||
|
||||
|
||||
int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(xorriso->di_array != NULL) {
|
||||
for(i= 0; i < xorriso->di_count; i++)
|
||||
if(xorriso->di_array[i] != NULL)
|
||||
iso_node_unref((IsoNode *) xorriso->di_array[i]);
|
||||
free(xorriso->di_array);
|
||||
xorriso->di_array= NULL;
|
||||
}
|
||||
xorriso->di_count= 0;
|
||||
|
||||
#ifdef NIX
|
||||
/* <<< */
|
||||
fprintf(stderr, "xorriso_DEBUG: get_di_count= %lu\n",
|
||||
Xorriso_get_di_counteR);
|
||||
#endif /* NIX */
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= allocate xorriso->node_targets too
|
||||
*/
|
||||
int Xorriso_new_node_array(struct XorrisO *xorriso, off_t mem_limit, int flag)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(xorriso->node_counter <= 0) {
|
||||
Xorriso_destroy_node_array(xorriso, 0);
|
||||
return(1);
|
||||
}
|
||||
xorriso->node_array= calloc(xorriso->node_counter, sizeof(IsoNode *));
|
||||
if(xorriso->node_array == NULL) {
|
||||
Xorriso_no_malloc_memory(xorriso, NULL, 0);
|
||||
@ -228,14 +259,12 @@ int Xorriso_sort_node_array(struct XorrisO *xorriso, int flag)
|
||||
}
|
||||
|
||||
|
||||
int Xorriso_search_in_node_array(struct XorrisO *xorriso,
|
||||
void *node, int *idx, int flag)
|
||||
int Xorriso__search_node(void *node_array[], int n,
|
||||
int (*cmp)(const void *p1, const void *p2),
|
||||
void *node, int *idx, int flag)
|
||||
{
|
||||
int ret, l, r, p, n;
|
||||
int ret, l, r, p, pos;
|
||||
|
||||
if(xorriso->node_array_size <= 0 || xorriso->node_array == NULL)
|
||||
return(0);
|
||||
n= xorriso->node_counter;
|
||||
if(n == 0)
|
||||
return(0);
|
||||
l= 0;
|
||||
@ -245,13 +274,24 @@ int Xorriso_search_in_node_array(struct XorrisO *xorriso,
|
||||
if(p == 0)
|
||||
break;
|
||||
p+= l;
|
||||
ret= Xorriso__findi_sorted_ino_cmp(&(xorriso->node_array[p - 1]), &node);
|
||||
|
||||
/* NULL elements may indicate invalid nodes. Their first valid right neigbor
|
||||
will serve as proxy. If none exists, then the test pushes leftwards.
|
||||
*/
|
||||
for(pos= p - 1; pos < n; pos++)
|
||||
if(node_array[pos] != NULL)
|
||||
break;
|
||||
if(pos < n)
|
||||
ret= (*cmp)(&(node_array[pos]), &node);
|
||||
else
|
||||
ret= 1;
|
||||
|
||||
if(ret < 0)
|
||||
l= p;
|
||||
else if(ret > 0)
|
||||
r= p;
|
||||
else {
|
||||
*idx= p - 1;
|
||||
*idx= pos;
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
@ -259,6 +299,139 @@ int Xorriso_search_in_node_array(struct XorrisO *xorriso,
|
||||
}
|
||||
|
||||
|
||||
int Xorriso_search_in_node_array(struct XorrisO *xorriso,
|
||||
void *node, int *idx, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(xorriso->node_array_size <= 0 || xorriso->node_array == NULL)
|
||||
return(0);
|
||||
ret= Xorriso__search_node(xorriso->node_array, xorriso->node_counter,
|
||||
Xorriso__findi_sorted_ino_cmp, node, idx, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int Xorriso__get_di(IsoNode *node, dev_t *dev, ino_t *ino, int flag)
|
||||
{
|
||||
int ret, i, i_end, imgid, error_code;
|
||||
size_t value_length= 0;
|
||||
char *value= NULL, msg[ISO_MSGS_MESSAGE_LEN], severity[80];
|
||||
unsigned char *vpt;
|
||||
static char *name= "isofs.di";
|
||||
|
||||
#ifdef NIX
|
||||
/* <<< */
|
||||
Xorriso_get_di_counteR++;
|
||||
#endif /* NIX */
|
||||
|
||||
*dev= 0;
|
||||
*ino= 0;
|
||||
ret= iso_node_lookup_attr(node, name, &value_length, &value, 0);
|
||||
if(ret <= 0) {
|
||||
/* Drop any pending messages because there is no xorriso to take them */
|
||||
iso_obtain_msgs("NEVER", &error_code, &imgid, msg, severity);
|
||||
return(ret);
|
||||
}
|
||||
vpt= (unsigned char *) value;
|
||||
for(i= 1; i <= vpt[0] && i < value_length; i++)
|
||||
*dev= ((*dev) << 8) | vpt[i];
|
||||
i_end= i + vpt[i] + 1;
|
||||
for(i++; i < i_end && i < value_length; i++)
|
||||
*ino= ((*ino) << 8) | vpt[i];
|
||||
|
||||
#ifdef NIX
|
||||
/* <<< */
|
||||
if(*ino > 10000000 || *ino < 0) {
|
||||
fprintf(stderr,
|
||||
"xorriso_DEBUG: name= '%s' , vl= %lu , i_end= %d\n",
|
||||
iso_node_get_name(node), (unsigned long) value_length, i_end);
|
||||
fprintf(stderr, " ");
|
||||
for(i= 0; i < value_length; i++)
|
||||
fprintf(stderr, " %-3.3u", (unsigned int) vpt[i]);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
free(value);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int Xorriso__di_ino_cmp(const void *p1, const void *p2)
|
||||
{
|
||||
int ret;
|
||||
IsoNode *n1, *n2;
|
||||
dev_t d1, d2;
|
||||
ino_t i1, i2;
|
||||
|
||||
n1= *((IsoNode **) p1);
|
||||
n2= *((IsoNode **) p2);
|
||||
|
||||
ret= Xorriso__get_di(n1, &d1, &i1, 0);
|
||||
if(ret <= 0)
|
||||
{d1= 0; i1= 0;}
|
||||
ret= Xorriso__get_di(n2, &d2, &i2, 0);
|
||||
if(ret <= 0)
|
||||
{d2= 0; i2= 0;}
|
||||
|
||||
if(d1 < d2)
|
||||
return(-1);
|
||||
if(d1 > d2)
|
||||
return(1);
|
||||
if(i1 < i2)
|
||||
return(-1);
|
||||
if(i1 > i2)
|
||||
return(1);
|
||||
if(d1 == 0 && i1 == 0 && n1 != n2)
|
||||
return(n1 < n2 ? -1 : 1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int Xorriso__di_cmp(const void *p1, const void *p2)
|
||||
{
|
||||
int ret;
|
||||
IsoNode *n1, *n2;
|
||||
|
||||
ret= Xorriso__di_ino_cmp(p1, p2);
|
||||
if(ret)
|
||||
return(ret);
|
||||
n1= *((IsoNode **) p1);
|
||||
n2= *((IsoNode **) p2);
|
||||
if(n1 != n2)
|
||||
return(n1 < n2 ? -1 : 1);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int Xorriso__sort_di(void *node_array[], int count, int flag)
|
||||
{
|
||||
if(count <= 0)
|
||||
return(0);
|
||||
qsort(node_array, count, sizeof(IsoNode *), Xorriso__di_cmp);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int Xorriso_invalidate_di_item(struct XorrisO *xorriso, IsoNode *node,
|
||||
int flag)
|
||||
{
|
||||
int ret, idx;
|
||||
|
||||
if(xorriso->di_array == NULL)
|
||||
return(1);
|
||||
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
|
||||
Xorriso__di_cmp, node, &idx, 0);
|
||||
if(ret <= 0)
|
||||
return(ret == 0);
|
||||
if(xorriso->di_array[idx] != NULL)
|
||||
iso_node_unref(xorriso->di_array[idx]);
|
||||
xorriso->di_array[idx]= NULL;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
@ -393,6 +566,7 @@ int Xorriso_detach_libraries(struct XorrisO *xorriso, int flag)
|
||||
iso_image_unref((IsoImage *) xorriso->in_volset_handle);
|
||||
xorriso->in_volset_handle= NULL;
|
||||
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
|
||||
Xorriso_destroy_di_array(xorriso, 0);
|
||||
}
|
||||
if(flag&1) {
|
||||
if(xorriso->libs_are_started==0)
|
||||
@ -550,6 +724,7 @@ int Xorriso_create_empty_iso(struct XorrisO *xorriso, int flag)
|
||||
iso_image_unref((IsoImage *) xorriso->in_volset_handle);
|
||||
xorriso->in_volset_handle= NULL;
|
||||
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
|
||||
Xorriso_destroy_di_array(xorriso, 0);
|
||||
xorriso->loaded_volid[0]= 0;
|
||||
xorriso->volset_change_pending= 0;
|
||||
xorriso->no_volset_present= 0;
|
||||
@ -728,7 +903,7 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag)
|
||||
aquire_flag= 1 | ((flag&(8|4))>>1) | ((xorriso->toc_emulation_flag & 3)<<3);
|
||||
if(!(xorriso->do_aaip & 1))
|
||||
aquire_flag|= 32;
|
||||
if(!(xorriso->do_aaip & 4))
|
||||
if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (4 | 32)))
|
||||
aquire_flag|= 64;
|
||||
ret= isoburn_drive_aquire(&dinfo, libburn_adr, aquire_flag);
|
||||
Xorriso_process_msg_queues(xorriso,0);
|
||||
@ -827,6 +1002,7 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag)
|
||||
iso_image_unref((IsoImage *) xorriso->in_volset_handle);
|
||||
xorriso->in_volset_handle= NULL;
|
||||
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
|
||||
Xorriso_destroy_di_array(xorriso, 0);
|
||||
|
||||
/* check for invalid state */
|
||||
if(state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE &&
|
||||
@ -842,7 +1018,7 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag)
|
||||
goto ex;
|
||||
|
||||
ext= isoburn_ropt_noiso1999;
|
||||
if(!(xorriso->do_aaip & (1 | 4 | 32)))
|
||||
if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (1 | 4 | 32)))
|
||||
ext|= isoburn_ropt_noaaip;
|
||||
if(!(xorriso->do_aaip & 1))
|
||||
ext|= isoburn_ropt_noacl;
|
||||
@ -1017,6 +1193,7 @@ int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag)
|
||||
iso_image_unref((IsoImage *) xorriso->in_volset_handle);
|
||||
xorriso->in_volset_handle= NULL;
|
||||
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
|
||||
Xorriso_destroy_di_array(xorriso, 0);
|
||||
xorriso->loaded_volid[0]= 0;
|
||||
xorriso->isofs_st_out= time(0) - 1;
|
||||
xorriso->isofs_st_in= 0;
|
||||
@ -1490,7 +1667,7 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag)
|
||||
}
|
||||
}
|
||||
|
||||
if(xorriso->do_aaip & 16) {
|
||||
if((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2)) {
|
||||
/* Overwrite isofs.st of root node by xorriso->isofs_st_out */
|
||||
char *name= "isofs.st";
|
||||
char timestamp[16], *value= timestamp;
|
||||
@ -1506,7 +1683,8 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag)
|
||||
ext= isoburn_igopt_rockridge |
|
||||
((!!xorriso->do_joliet) * isoburn_igopt_joliet) |
|
||||
(( !(xorriso->ino_behavior & 2)) * isoburn_igopt_hardlinks) |
|
||||
((!!(xorriso->do_aaip & (2 | 8 | 16 | 256))) * isoburn_igopt_aaip);
|
||||
(( (!(xorriso->ino_behavior & 2)) ||
|
||||
(xorriso->do_aaip & (2 | 8 | 16 | 256))) * isoburn_igopt_aaip);
|
||||
isoburn_igopt_set_extensions(sopts, ext);
|
||||
isoburn_igopt_set_relaxed(sopts, relax);
|
||||
isoburn_igopt_set_sort_files(sopts, 1);
|
||||
@ -1965,6 +2143,11 @@ int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume,
|
||||
path_pt= path;
|
||||
if(path[0]==0)
|
||||
path_pt= "/";
|
||||
if(volume == NULL) {
|
||||
ret= Xorriso_get_volume(xorriso, &volume, 0);
|
||||
if(ret <= 0)
|
||||
return(ret);
|
||||
}
|
||||
*node= NULL;
|
||||
ret= iso_tree_path_to_node(volume, path_pt, node);
|
||||
Xorriso_process_msg_queues(xorriso,0);
|
||||
@ -2295,7 +2478,7 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
|
||||
}
|
||||
}
|
||||
|
||||
if((flag & 4) && (xorriso->do_aaip & 16)) {
|
||||
if((flag & 4) && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) {
|
||||
ret= Xorriso_record_dev_inode(xorriso, disk_path, (dev_t) 0, (ino_t) 0,
|
||||
(void *) node, "", flag & 32);
|
||||
if(ret <= 0)
|
||||
@ -2403,7 +2586,7 @@ int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume,
|
||||
goto ex;
|
||||
}
|
||||
|
||||
if(stbuf_valid && (xorriso->do_aaip & 16)) {
|
||||
if(stbuf_valid && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) {
|
||||
ret= Xorriso_record_dev_inode(xorriso, disk_path,
|
||||
stbuf.st_dev, stbuf.st_ino, (void *) *node, "", 1);
|
||||
if(ret <= 0)
|
||||
@ -2425,6 +2608,7 @@ ex:;
|
||||
|
||||
/* @param flag bit0= recursion is active
|
||||
bit1= do not report added files
|
||||
bit6= do not delete eventually existing node from di_array
|
||||
*/
|
||||
int Xorriso_add_tree(struct XorrisO *xorriso, IsoDir *dir,
|
||||
char *img_dir_path, char *disk_dir_path,
|
||||
@ -2586,7 +2770,8 @@ cannot_lstat:;
|
||||
/* handle overwrite situation */;
|
||||
if(xorriso->do_overwrite==1 ||
|
||||
(xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) {
|
||||
ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, img_path, 1|8);
|
||||
ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, img_path,
|
||||
1 | 8 | (flag & 64));
|
||||
if(ret<=0)
|
||||
goto was_problem;
|
||||
if(ret==3) {
|
||||
@ -2659,7 +2844,8 @@ cannot_lstat:;
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
|
||||
} else {
|
||||
ret= Xorriso_add_tree(xorriso, (IsoDir *) node,
|
||||
img_path, disk_path, own_link_stack, 1|(flag&2));
|
||||
img_path, disk_path, own_link_stack,
|
||||
1 | (flag & (2 | 64)));
|
||||
}
|
||||
if(ret<=0)
|
||||
goto was_problem;
|
||||
@ -2781,6 +2967,7 @@ int Xorriso_copy_properties(struct XorrisO *xorriso,
|
||||
bit3= use offset and cut_size for cut_out_node
|
||||
bit4= return 3 on rejection by exclusion or user
|
||||
bit5= if directory then do not add sub tree
|
||||
bit6= do not delete eventually existing node from di_array
|
||||
bit7= no special handling of split file directories
|
||||
@return <=0 = error , 1 = added simple node , 2 = added directory ,
|
||||
3 = rejected
|
||||
@ -2911,7 +3098,8 @@ int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter,
|
||||
/* handle overwrite situation */;
|
||||
if(xorriso->do_overwrite==1 ||
|
||||
(xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) {
|
||||
ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, path, 1|8);
|
||||
ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, path,
|
||||
1 | 8 | (flag & 64));
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
if(ret==3) {
|
||||
@ -2968,7 +3156,7 @@ attach_source:;
|
||||
(IsoNode *) dir, 4 | 32);
|
||||
if(!(flag&32)) {
|
||||
ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL,
|
||||
flag&2);
|
||||
flag & (2 | 64));
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
}
|
||||
@ -5728,6 +5916,7 @@ cannot_iter:;
|
||||
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= do not delete eventually existing node from di_array
|
||||
@return <=0 = error
|
||||
1 = removed simple node
|
||||
2 = removed directory or tree
|
||||
@ -5828,7 +6017,8 @@ cannot_create_iter:;
|
||||
if(Xorriso_much_too_long(xorriso, pl+1+strlen(name), 0)<=0)
|
||||
{ret= 0; goto rm_r_problem_handler;}
|
||||
strcpy(sub_name, name);
|
||||
ret= Xorriso_rmi(xorriso, iter, mem, sub_path, (flag&(1|2|8|16))|4);
|
||||
ret= Xorriso_rmi(xorriso, iter, mem, sub_path,
|
||||
(flag & ( 1 | 2 | 8 | 16 | 64)) | 4);
|
||||
if(ret==3 || ret<=0 || xorriso->request_to_abort) {
|
||||
rm_r_problem_handler:;
|
||||
not_removed= 1;
|
||||
@ -5925,6 +6115,9 @@ dir_not_removed:;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(flag & 64))
|
||||
Xorriso_invalidate_di_item(xorriso, victim_node, 0);
|
||||
|
||||
#ifdef Libisofs_iso_dir_iter_sufficienT
|
||||
|
||||
if(boss_iter!=NULL) {
|
||||
@ -5950,6 +6143,7 @@ dir_not_removed:;
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
|
||||
ret= -1; goto ex;
|
||||
}
|
||||
|
||||
if(flag&16)
|
||||
xorriso->pacifier_count++;
|
||||
xorriso->volset_change_pending= 1;
|
||||
@ -10185,14 +10379,16 @@ ex:;
|
||||
|
||||
int Xorriso_set_ignore_aclea(struct XorrisO *xorriso, int flag)
|
||||
{
|
||||
int ret;
|
||||
int ret, hflag;
|
||||
IsoImage *volume;
|
||||
|
||||
ret= Xorriso_get_volume(xorriso, &volume, 1);
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
iso_image_set_ignore_aclea(volume,
|
||||
((~xorriso->do_aaip) & 1) | (((~xorriso->do_aaip) & (4 | 16)) >> 1));
|
||||
hflag= (~xorriso->do_aaip) & 1;
|
||||
if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (4 | 16)))
|
||||
hflag|= 2;
|
||||
iso_image_set_ignore_aclea(volume, hflag);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -11395,3 +11591,251 @@ int Xorriso_status_zisofs(struct XorrisO *xorriso, char *filter, FILE *fp,
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= overwrite existing di_array (else return 2)
|
||||
bit1= make di_array despite xorriso->ino_behavior bit 3
|
||||
*/
|
||||
int Xorriso_make_di_array(struct XorrisO *xorriso, int flag)
|
||||
{
|
||||
int ret;
|
||||
struct FindjoB *job= NULL;
|
||||
struct stat dir_stbuf;
|
||||
|
||||
#ifdef NIX
|
||||
/* <<< */
|
||||
unsigned long old_gdic;
|
||||
old_gdic= Xorriso_get_di_counteR;
|
||||
#endif /* NIX */
|
||||
|
||||
if((xorriso->ino_behavior & 8 ) && !(flag & 2))
|
||||
return(2);
|
||||
if(xorriso->di_array != NULL && !(flag & 1))
|
||||
return(2);
|
||||
Xorriso_destroy_di_array(xorriso, 0);
|
||||
ret= Findjob_new(&job, "/", 0);
|
||||
if(ret<=0) {
|
||||
Xorriso_no_findjob(xorriso, "xorriso", 0);
|
||||
{ret= -1; goto ex;}
|
||||
}
|
||||
Findjob_set_action_target(job, 30, NULL, 0);
|
||||
Xorriso_destroy_node_array(xorriso, 0);
|
||||
ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/",
|
||||
&dir_stbuf, 0, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
Findjob_set_action_target(job, 31, NULL, 0);
|
||||
ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/",
|
||||
&dir_stbuf, 0, 0);
|
||||
if(ret <= 0)
|
||||
goto ex;
|
||||
xorriso->di_count= xorriso->node_counter;
|
||||
xorriso->di_array= xorriso->node_array;
|
||||
xorriso->node_counter= 0;
|
||||
xorriso->node_array_size= 0;
|
||||
xorriso->node_array= 0;
|
||||
Xorriso__sort_di((void *) xorriso->di_array, xorriso->di_count, 0);
|
||||
|
||||
ret= 1;
|
||||
ex:;
|
||||
|
||||
#ifdef NIX
|
||||
/* <<< */
|
||||
fprintf(stderr, "xorriso_DEBUG: sort_count= %lu\n",
|
||||
Xorriso_get_di_counteR - old_gdic);
|
||||
#endif /* NIX */
|
||||
|
||||
Findjob_destroy(&job, 0);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= return 1 even if matching nodes were found but node is
|
||||
not among them
|
||||
*/
|
||||
int Xorriso_search_di_range(struct XorrisO *xorriso, IsoNode *node,
|
||||
int *idx, int *low, int *high, int flag)
|
||||
{
|
||||
int ret, i, found;
|
||||
|
||||
*high= *low= *idx= -1;
|
||||
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
|
||||
Xorriso__di_ino_cmp, node, &found, 0);
|
||||
if(ret <= 0)
|
||||
return(0);
|
||||
*low= *high= found;
|
||||
for(i= found + 1; i < xorriso->di_count; i++)
|
||||
if(xorriso->di_array[i] != NULL) {
|
||||
if(Xorriso__di_ino_cmp(&node, &(xorriso->di_array[i])) != 0)
|
||||
break;
|
||||
*high= i;
|
||||
}
|
||||
for(i= found - 1; i >= 0; i--)
|
||||
if(xorriso->di_array[i] != NULL) {
|
||||
if(Xorriso__di_ino_cmp(&node, &(xorriso->di_array[i])) != 0)
|
||||
break;
|
||||
*low= i;
|
||||
}
|
||||
for(i= *low; i <= *high; i++)
|
||||
if(xorriso->di_array[i] == node) {
|
||||
*idx= i;
|
||||
break;
|
||||
}
|
||||
return(*idx >= 0 || (flag & 1));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@param flag bit0= iso_rr_path is freshly added and up to date
|
||||
bit2= -follow: this is not a command parameter
|
||||
@return -1= severe error
|
||||
0= not applicable for hard links
|
||||
1= go on with processing
|
||||
2= iso_rr_path is fully updated
|
||||
*/
|
||||
int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
|
||||
char *disk_path, char *iso_rr_path, int flag)
|
||||
{
|
||||
int ret, hret, idx, low, high, i, do_overwrite= 0, did_fake_di= 0;
|
||||
int follow_links, node_result, old_idx= -1;
|
||||
char node_path[SfileadrL];
|
||||
IsoNode *node;
|
||||
struct stat stbuf;
|
||||
dev_t old_dev;
|
||||
ino_t old_ino;
|
||||
|
||||
if(xorriso->di_array == NULL)
|
||||
return(1);
|
||||
follow_links= xorriso->do_follow_links ||
|
||||
(xorriso->do_follow_param && !(flag & 4));
|
||||
ret= Xorriso_node_from_path(xorriso, NULL, iso_rr_path, &node, 0);
|
||||
if(ret <= 0)
|
||||
return(ret);
|
||||
if(LIBISO_ISDIR(node))
|
||||
return(1);
|
||||
|
||||
/* Handle eventual hardlink split : */
|
||||
/* This is achieved by setting the content change bit. Reason:
|
||||
The node needs to be removed from di_array because its di is
|
||||
not matching it array index any more. So it becomes invisible for
|
||||
the join check of eventual later hardlink siblings. Therefore
|
||||
it must be updated now, even if it has currently no siblings
|
||||
which it leaves or which it joins.
|
||||
*/
|
||||
if(!(flag & 1))
|
||||
do_overwrite= 1;
|
||||
|
||||
Xorriso__get_di(node, &old_dev, &old_ino, 0);
|
||||
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
|
||||
Xorriso__di_cmp, node, &idx, 0);
|
||||
if(ret < 0)
|
||||
{ret= 0; goto ex;}
|
||||
if(ret > 0)
|
||||
old_idx= idx;
|
||||
|
||||
/* Handle eventual hardlink joining : */
|
||||
|
||||
if(follow_links)
|
||||
ret= stat(disk_path, &stbuf);
|
||||
else
|
||||
ret= lstat(disk_path, &stbuf);
|
||||
if(ret==-1)
|
||||
{ret= 0; goto ex;}
|
||||
|
||||
/* Are there new dev-ino-siblings in the image ? */
|
||||
/* Fake isofs.di */
|
||||
if(!(flag & 1)) {
|
||||
ret= Xorriso_record_dev_inode(xorriso, disk_path, stbuf.st_dev,
|
||||
stbuf.st_ino, node, iso_rr_path, 1);
|
||||
if(ret <= 0)
|
||||
{ret= -1; goto ex;}
|
||||
did_fake_di= 1;
|
||||
/* temporarily remove node from di_array so it does not disturb
|
||||
search by its fake di info */;
|
||||
if(old_idx >= 0)
|
||||
xorriso->di_array[old_idx]= NULL;
|
||||
}
|
||||
ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 1);
|
||||
if(did_fake_di) {
|
||||
/* Revoke fake of isofs.di */
|
||||
hret= Xorriso_record_dev_inode(xorriso, disk_path, old_dev, old_ino,
|
||||
node, iso_rr_path, 1);
|
||||
if(hret <= 0)
|
||||
{ret= -1; goto ex;}
|
||||
if(old_idx >= 0)
|
||||
xorriso->di_array[old_idx]= node;
|
||||
}
|
||||
if(ret == 0)
|
||||
{ret= 1; goto ex;}
|
||||
if(ret < 0)
|
||||
{ret= 0; goto ex;}
|
||||
|
||||
|
||||
#ifdef NIX
|
||||
/* <<< */
|
||||
if(low < high || idx < 0) {
|
||||
fprintf(stderr,
|
||||
"xorriso_DEBUG: old_idx= %d , low= %d , high= %d , iso= '%s' , disk='%s'\n",
|
||||
old_idx, low, high, iso_rr_path, disk_path);
|
||||
fprintf(stderr,
|
||||
"xorriso_DEBUG: old_dev= %lu , old_ino= %lu , dev= %lu , ino= %lu\n",
|
||||
(unsigned long) old_dev, (unsigned long) old_ino,
|
||||
(unsigned long) stbuf.st_dev, (unsigned long) stbuf.st_ino);
|
||||
|
||||
if(idx >= 0 && idx != old_idx)
|
||||
fprintf(stderr, "xorriso_DEBUG: idx= %d , old_idx = %d\n", idx, old_idx);
|
||||
}
|
||||
#endif /* NIX */
|
||||
|
||||
/* Overwrite all valid siblings : */
|
||||
for(i= low; i <= high; i++) {
|
||||
if(i == idx || xorriso->di_array[i] == NULL)
|
||||
continue;
|
||||
/* Is the alleged sibling still a valid mirror of disk_path ? */
|
||||
ret= Xorriso_path_from_node(xorriso, xorriso->di_array[i], node_path, 0);
|
||||
if(ret < 0)
|
||||
goto ex;
|
||||
if(ret == 0)
|
||||
continue; /* Node is deleted from tree */
|
||||
|
||||
#ifdef NIX
|
||||
/* <<< */
|
||||
{
|
||||
ino_t ino;
|
||||
dev_t dev;
|
||||
|
||||
Xorriso__get_di(xorriso->di_array[i], &dev, &ino, 0);
|
||||
fprintf(stderr, "xorriso_DEBUG: iso_sibling= '%s' , dev= %lu , ino= %lu\n",
|
||||
node_path, (unsigned long) dev, (unsigned long) ino);
|
||||
}
|
||||
#endif /* NIX */
|
||||
|
||||
node_result= 0;
|
||||
ret= Xorriso_compare_2_files(xorriso, disk_path, node_path, "",
|
||||
&node_result, 2 | follow_links | (7 << 29));
|
||||
if(ret >= 0) {
|
||||
/* Overwrite sibling if it would *not* be overwritten by itself.
|
||||
(If it would be overwritten then it might be not a valid hardlink
|
||||
sibling.) */
|
||||
ret= Xorriso_update_interpreter(xorriso, NULL, node_result, disk_path,
|
||||
node_path, 1 | 4);
|
||||
if(ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
ret= 1;
|
||||
ex:;
|
||||
if(do_overwrite)
|
||||
*compare_result|= (1<<15);
|
||||
if(old_idx >= 0 && (*compare_result & (3 << 21))) {
|
||||
/* The old di info is obsolete */
|
||||
if(xorriso->di_array[old_idx] != NULL)
|
||||
iso_node_unref(xorriso->di_array[old_idx]);
|
||||
xorriso->di_array[old_idx]= NULL;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
@ -306,6 +306,8 @@ int Xorriso_set_local_charset(struct XorrisO *xorriso, char *name, int flag);
|
||||
|
||||
int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag);
|
||||
|
||||
int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag);
|
||||
|
||||
int Xorriso_new_node_array(struct XorrisO *xorriso, off_t mem_limit, int flag);
|
||||
|
||||
int Xorriso_sort_node_array(struct XorrisO *xorriso, int flag);
|
||||
@ -458,6 +460,20 @@ int Xorriso_set_zisofs_params(struct XorrisO *xorriso, int flag);
|
||||
int Xorriso_status_zisofs(struct XorrisO *xorriso, char *filter, FILE *fp,
|
||||
int flag);
|
||||
|
||||
/* @param flag bit0= overwrite existing di_array (else return 2)
|
||||
*/
|
||||
int Xorriso_make_di_array(struct XorrisO *xorriso, int flag);
|
||||
|
||||
/*
|
||||
@param flag bit2= -follow: this is not a command parameter
|
||||
@return -1= severe error
|
||||
0= not applicable for hard links
|
||||
1= go on with processing
|
||||
2= iso_rr_path is fully updated
|
||||
*/
|
||||
int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
|
||||
char *disk_path, char *iso_rr_path, int flag);
|
||||
|
||||
|
||||
/* A pseudo file type for El-Torito bootsectors as in man 2 stat :
|
||||
For now take the highest possible value.
|
||||
|
Loading…
Reference in New Issue
Block a user