With -update_r : detecting hardlink splits and fusions on disk
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user