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