"Fossies" - the Fresh Open Source Software Archive

Member "xorriso-1.5.4/xorriso/sort_cmp.c" (30 Jan 2021, 18396 Bytes) of package /linux/misc/xorriso-1.5.4.pl02.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sort_cmp.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.5.2_vs_1.5.4.

    1 
    2 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
    3 
    4    Copyright 2007-2016 Thomas Schmitt, <scdbackup@gmx.net>
    5 
    6    Provided under GPL version 2 or later.
    7 
    8    This file contains functions which sort and compare tree nodes.
    9 */
   10 
   11 #ifdef HAVE_CONFIG_H
   12 #include "../config.h"
   13 #endif
   14 
   15 #include <ctype.h>
   16 #include <sys/types.h>
   17 #include <unistd.h>
   18 #include <stdlib.h>
   19 #include <stdio.h>
   20 #include <string.h>
   21 #include <sys/stat.h>
   22 #include <sys/time.h>
   23 #include <time.h>
   24 #include <errno.h>
   25 
   26 
   27 #include "base_obj.h"
   28 #include "lib_mgt.h"
   29 #include "sort_cmp.h"
   30 #include "iso_tree.h"
   31 #include "iso_manip.h"
   32 
   33 
   34 int Xorriso__findi_sorted_ino_cmp(const void *p1, const void *p2)
   35 {
   36  int ret;
   37  IsoNode *n1, *n2;
   38 
   39  n1= *((IsoNode **) p1);
   40  n2= *((IsoNode **) p2);
   41 
   42  ret= Xorriso__node_lba_cmp(&n1, &n2);
   43  if(ret)
   44    return (ret > 0 ? 1 : -1);
   45  ret= iso_node_cmp_ino(n1, n2, 0);
   46  return(ret);
   47 }
   48 
   49 
   50 /* Not suitable for qsort() but for cross-array comparisons.
   51    p1 and p2 are actually IsoNode *p1, IsoNode *p2
   52 */
   53 int Xorriso__hln_cmp(const void *p1, const void *p2)
   54 {
   55  int ret;
   56 
   57  ret= Xorriso__findi_sorted_ino_cmp(&p1, &p2);
   58  if(ret)
   59    return (ret > 0 ? 1 : -1);
   60  if(p1 != p2)
   61    return(p1 < p2 ? -1 : 1);
   62  return(0);
   63 }
   64 
   65 
   66 /* 
   67    p1 and p2 are actually IsoNode **p1, IsoNode **p2
   68 */
   69 int Xorriso__findi_sorted_cmp(const void *p1, const void *p2)
   70 {
   71  int ret;
   72 
   73  ret= Xorriso__findi_sorted_ino_cmp(p1, p2);
   74  if(ret)
   75    return (ret > 0 ? 1 : -1);
   76  if(p1 != p2)
   77    return(p1 < p2 ? -1 : 1);
   78  return(0);
   79 }
   80 
   81 
   82 int Xorriso_sort_node_array(struct XorrisO *xorriso, int flag)
   83 {
   84  if(xorriso->node_counter <= 0)
   85    return(0);
   86  qsort(xorriso->node_array, xorriso->node_counter, sizeof(IsoNode *),
   87        Xorriso__findi_sorted_cmp);
   88  return(1);
   89 }
   90 
   91 
   92 int Xorriso__search_node(void *node_array[], int n,
   93                          int (*cmp)(const void *p1, const void *p2),
   94                          void *node, int *idx, int flag)
   95 {
   96  int ret, l, r, p, pos;
   97 
   98  if(n == 0)
   99    return(0);
  100  l= 0;
  101  r= n + 1;
  102  while(1) {
  103    p= (r - l) / 2;
  104    if(p == 0)
  105  break;
  106    p+= l;
  107 
  108    /* NULL elements may indicate invalid nodes.Their first valid right neighbor
  109       will serve as proxy. If none exists, then the test pushes leftwards.
  110     */
  111    for(pos= p - 1; pos < n; pos++)
  112      if(node_array[pos] != NULL)
  113    break;
  114    if(pos < n)
  115      ret= (*cmp)(&(node_array[pos]), &node);
  116    else
  117      ret= 1;
  118 
  119    if(ret < 0)
  120      l= p;
  121    else if(ret > 0)
  122      r= p;
  123    else {
  124      *idx= pos;
  125      return(1);
  126    }
  127  }
  128  return(0);
  129 }
  130 
  131 
  132 int Xorriso_search_in_hln_array(struct XorrisO *xorriso,
  133                                  void *node, int *idx, int flag)
  134 {
  135  int ret;
  136 
  137  if(xorriso->hln_array == NULL || xorriso->hln_count <= 0)
  138    return(0);
  139  ret= Xorriso__search_node(xorriso->hln_array, xorriso->hln_count, 
  140                            Xorriso__findi_sorted_ino_cmp, node, idx, 0);
  141  return ret;
  142 }
  143 
  144 
  145 int Xorriso__get_di(IsoNode *node, dev_t *dev, ino_t *ino, int flag)
  146 {
  147  int ret, i, i_end, imgid, error_code;
  148  size_t value_length= 0;
  149  char *value= NULL, *msg= NULL, severity[80];
  150  unsigned char *vpt;
  151  static char *name= "isofs.di";
  152 
  153 #ifdef NIX
  154  /* <<< */
  155  Xorriso_get_di_counteR++;
  156 #endif /* NIX */
  157 
  158  msg= TSOB_FELD(char, ISO_MSGS_MESSAGE_LEN);
  159  if(msg == NULL)
  160    {ret= -1; goto ex;}
  161  *dev= 0;
  162  *ino= 0;
  163  ret= iso_node_lookup_attr(node, name, &value_length, &value, 0);
  164  if(ret <= 0) {
  165    /* Drop any pending messages because there is no xorriso to take them */
  166    iso_obtain_msgs("NEVER", &error_code, &imgid, msg, severity);
  167    goto ex;
  168  }
  169  vpt= (unsigned char *) value;
  170  if(vpt[0] > sizeof(ino_t)) {
  171 
  172    /* >>> obviously not the same system that recorded the device number */; 
  173 
  174  }
  175  for(i= 1; i <= vpt[0] && i < (int) value_length; i++)
  176    *dev= ((*dev) << 8) | vpt[i];
  177  i_end= i + vpt[i] + 1;
  178  if(vpt[i] > sizeof(ino_t)) {
  179 
  180    /* >>> obviously not the same system that recorded the inode number */; 
  181 
  182  }
  183  for(i++; i < i_end && i < (int) value_length; i++)
  184    *ino= ((*ino) << 8) | vpt[i];
  185  free(value);
  186  ret= 1;
  187 ex:;
  188  if(msg != NULL)
  189    free(msg);
  190  return(ret);
  191 }
  192 
  193 
  194 int Xorriso__di_ino_cmp(const void *p1, const void *p2)
  195 {  
  196  int ret; 
  197  IsoNode *n1, *n2;
  198  dev_t d1, d2;
  199  ino_t i1, i2;
  200  
  201  n1= *((IsoNode **) p1);
  202  n2= *((IsoNode **) p2);
  203 
  204  ret= Xorriso__get_di(n1, &d1, &i1, 0);
  205  if(ret <= 0)
  206    {d1= 0; i1= 0;}
  207  ret= Xorriso__get_di(n2, &d2, &i2, 0);
  208  if(ret <= 0)
  209    {d2= 0; i2= 0;}
  210 
  211  if(d1 < d2)
  212    return(-1);
  213  if(d1 > d2)
  214    return(1);
  215  if(i1 < i2)
  216    return(-1);
  217  if(i1 > i2)
  218    return(1);
  219  if(d1 == 0 && i1 == 0 && n1 != n2)
  220    return(n1 < n2 ? -1 : 1);
  221  return(0);
  222 } 
  223 
  224 
  225 int Xorriso__di_cmp(const void *p1, const void *p2)
  226 {  
  227  int ret; 
  228  IsoNode *n1, *n2;
  229 
  230  ret= Xorriso__di_ino_cmp(p1, p2);
  231  if(ret)
  232    return(ret);
  233  n1= *((IsoNode **) p1);
  234  n2= *((IsoNode **) p2);
  235  if(n1 != n2)
  236    return(n1 < n2 ? -1 : 1);
  237  return(0);
  238 } 
  239 
  240 
  241 int Xorriso__sort_di(void *node_array[], int count, int flag)
  242 {
  243  if(count <= 0)
  244    return(0);
  245  qsort(node_array, count, sizeof(IsoNode *), Xorriso__di_cmp);
  246  return(1);
  247 }
  248 
  249 
  250 int Xorriso_invalidate_di_item(struct XorrisO *xorriso, IsoNode *node,
  251                                int flag)
  252 {
  253  int ret, idx;
  254 
  255  if(xorriso->di_array == NULL)
  256    return(1);
  257  ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
  258                            Xorriso__di_cmp, node, &idx, 0);
  259  if(ret <= 0)
  260    return(ret == 0);
  261  if(xorriso->di_array[idx] != NULL)
  262    iso_node_unref(xorriso->di_array[idx]);
  263  xorriso->di_array[idx]= NULL;
  264  return(1);
  265 }
  266 
  267 
  268 /* @param flag bit0= return 1 even if matching nodes were found but node is
  269                      not among them
  270                bit1= use Xorriso__di_cmp() rather than Xorriso__di_ino_cmp()
  271 */
  272 int Xorriso_search_di_range(struct XorrisO *xorriso, IsoNode *node,
  273                             int *idx, int *low, int *high, int flag)
  274 {
  275  int ret, i, found;
  276  int (*cmp)(const void *p1, const void *p2)= Xorriso__di_ino_cmp;
  277 
  278  if(flag & 2)
  279    cmp= Xorriso__di_cmp;
  280 
  281  *high= *low= *idx= -1;                            
  282  ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
  283                            cmp, node, &found, 0);
  284  if(ret <= 0)
  285    return(0);
  286  *low= *high= found;
  287  for(i= found + 1; i < xorriso->di_count; i++)
  288    if(xorriso->di_array[i] != NULL) {
  289      if((*cmp)(&node, &(xorriso->di_array[i])) != 0)
  290  break;
  291      *high= i;
  292    }
  293  for(i= found - 1; i >= 0; i--)
  294    if(xorriso->di_array[i] != NULL) {
  295      if((*cmp)(&node, &(xorriso->di_array[i])) != 0)
  296  break;
  297      *low= i;
  298    }
  299  for(i= *low; i <= *high; i++)
  300    if(xorriso->di_array[i] == node) {
  301      *idx= i;
  302  break;
  303    }
  304  return(*idx >= 0 || (flag & 1));
  305 }
  306 
  307 
  308 int Xorriso__node_lba_cmp(const void *node1, const void *node2)
  309 {
  310  int ret;
  311  int lba1= 0, lba2= 0;
  312 
  313  ret= Xorriso__file_start_lba(*((IsoNode **) node1), &lba1, 0);
  314  if(ret!=1) 
  315    lba1= 0;
  316  ret= Xorriso__file_start_lba(*((IsoNode **) node2), &lba2, 0);
  317  if(ret!=1)
  318    lba2= 0;
  319  return(lba1-lba2);  
  320 }
  321 
  322 
  323 int Xorriso__node_name_cmp(const void *node1, const void *node2)
  324 {
  325  char *name1, *name2;
  326 
  327  name1= (char *) iso_node_get_name(*((IsoNode **) node1));
  328  name2= (char *) iso_node_get_name(*((IsoNode **) node2));
  329  return(strcmp(name1,name2));
  330 }
  331 
  332 
  333 /* @param flag bit0= only accept directory nodes
  334                bit1= do not report memory usage as DEBUG
  335                bit2= do not apply search pattern but accept any node
  336 */
  337 int Xorriso_sorted_node_array(struct XorrisO *xorriso, 
  338                               IsoDir *dir_node,
  339                               int *nodec, IsoNode ***node_array,
  340                               off_t boss_mem, int flag)
  341 {
  342  int i, ret, failed_at;
  343  char *npt;
  344  IsoDirIter *iter= NULL;
  345  IsoNode *node;
  346  off_t mem;
  347 
  348  mem= ((*nodec)+1)*sizeof(IsoNode *);
  349  ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, flag&2);
  350  if(ret<=0)
  351    return(ret);
  352 
  353  *node_array= calloc(sizeof(IsoNode *), (*nodec)+1);
  354  if(*node_array==NULL) {
  355    sprintf(xorriso->info_text,
  356            "Cannot allocate memory for %d directory entries", *nodec); 
  357    Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
  358    return(-1);
  359  }
  360 
  361  ret= iso_dir_get_children(dir_node, &iter);
  362  if(ret<0) {
  363    Xorriso_cannot_create_iter(xorriso, ret, 0);
  364    return(-1);
  365  }
  366  
  367  for(i= 0; iso_dir_iter_next(iter, &node) == 1 && i<*nodec; ) {
  368    npt= (char *) iso_node_get_name(node);
  369    if(!(flag&4)) {
  370      ret= Xorriso_regexec(xorriso, npt, &failed_at, 0);
  371      if(ret)
  372  continue; /* no match */
  373    }
  374    if(flag&1)
  375      if(!LIBISO_ISDIR(node))
  376  continue;
  377    (*node_array)[i++]= node;
  378  }
  379  iso_dir_iter_free(iter);
  380  *nodec= i;
  381  if(*nodec<=0)
  382    return(1);
  383  qsort(*node_array, *nodec, sizeof(IsoNode *), Xorriso__node_name_cmp);
  384  return(1);
  385 }
  386 
  387 
  388 int Xorriso_remake_hln_array(struct XorrisO *xorriso, int flag)
  389 {  
  390  int ret, addon_nodes= 0, i, old_count, old_pt, new_pt;
  391  IsoNode **old_nodes;
  392  char **old_targets;
  393 
  394  /* Count hln_targets of which the node has been deleted meanwhile */
  395  for(i= 0; i < xorriso->hln_count; i++) {
  396    if(xorriso->hln_targets[i] == NULL)
  397  continue;
  398    if(Xorriso_node_is_valid(xorriso, xorriso->hln_array[i], 0))
  399  continue;
  400    addon_nodes++;
  401  }
  402  ret= Xorriso_all_node_array(xorriso, addon_nodes, 0);
  403  if(ret <= 0)
  404    goto ex;
  405  if(addon_nodes > 0) {
  406    /* Transfer delete nodes with hln_target to node array */
  407    for(i= 0; i < xorriso->hln_count; i++) {
  408      if(xorriso->hln_targets[i] == NULL)
  409    continue;
  410      if(Xorriso_node_is_valid(xorriso, xorriso->hln_array[i], 0))
  411    continue;
  412      if(xorriso->node_counter < xorriso->node_array_size) {
  413        xorriso->node_array[xorriso->node_counter++]= xorriso->hln_array[i];
  414        iso_node_ref(xorriso->node_array[xorriso->node_counter - 1]);
  415      }
  416    }
  417  }
  418 
  419  Xorriso_sort_node_array(xorriso, 0);
  420  old_nodes= (IsoNode **) xorriso->hln_array;
  421  old_targets= (char **) xorriso->hln_targets;
  422  old_count= xorriso->hln_count;
  423  xorriso->hln_array= 0;
  424  xorriso->hln_targets= NULL;
  425 
  426  /* Transfer node_array to di_array without unrefering nodes */
  427  xorriso->hln_count= xorriso->node_counter;
  428  xorriso->hln_array= xorriso->node_array;
  429  xorriso->node_counter= 0;
  430  xorriso->node_array_size= 0;
  431  xorriso->node_array= NULL;
  432 
  433  /* Allocate hln_targets */
  434  ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1);
  435  if(ret<=0)
  436    goto ex;
  437  xorriso->node_targets_availmem= xorriso->temp_mem_limit;
  438  if(old_targets != NULL) {
  439    /* Transfer targets from old target array */;
  440    new_pt= old_pt= 0;
  441    while(new_pt < xorriso->hln_count && old_pt < old_count) {
  442      ret= Xorriso__hln_cmp(xorriso->hln_array[new_pt], old_nodes[old_pt]);
  443      if(ret < 0) {
  444        new_pt++;
  445      } else if(ret > 0) {
  446        old_pt++;
  447      } else {
  448        xorriso->hln_targets[new_pt]= old_targets[old_pt];
  449        if(old_targets[old_pt] != NULL)
  450          xorriso->temp_mem_limit-= strlen(old_targets[old_pt]) + 1;
  451        old_targets[old_pt]= NULL;
  452        new_pt++;
  453        old_pt++;
  454      }
  455    }
  456    for(old_pt= 0; old_pt < old_count; old_pt++)
  457      if(old_targets[old_pt] != NULL) /* (should not happen) */
  458        free(old_targets[old_pt]);
  459    free((char *) old_targets);
  460  }
  461  if(old_nodes != NULL) {
  462    for(old_pt= 0; old_pt < old_count; old_pt++)
  463      if(old_nodes[old_pt] != NULL)
  464        iso_node_unref(old_nodes[old_pt]);
  465    free((char *) old_nodes);
  466  }
  467  xorriso->hln_change_pending= 0;
  468  ret= 1;
  469 ex:;
  470  return(ret);
  471 }
  472 
  473 
  474 /* @param flag bit0= overwrite existing hln_array (else return 2)
  475 */
  476 int Xorriso_make_hln_array(struct XorrisO *xorriso, int flag)
  477 {  
  478  int ret;
  479 
  480  if(xorriso->hln_array != NULL && !(flag & 1)) {
  481    /* If no fresh image manipulations occurred: keep old array */
  482    if(!xorriso->hln_change_pending)
  483      return(2);
  484    ret= Xorriso_remake_hln_array(xorriso, 0);
  485    return(ret);
  486  }
  487  Xorriso_destroy_hln_array(xorriso, 0);
  488 
  489  ret= Xorriso_all_node_array(xorriso, 0, 0);
  490  if(ret <= 0)
  491    goto ex;
  492  Xorriso_sort_node_array(xorriso, 0);
  493 
  494  /* Transfer node_array to di_array without unrefering nodes */
  495  xorriso->hln_count= xorriso->node_counter;
  496  xorriso->hln_array= xorriso->node_array;
  497  xorriso->node_counter= 0;
  498  xorriso->node_array_size= 0;
  499  xorriso->node_array= NULL;
  500 
  501  /* Allocate hln_targets */
  502  ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1);
  503  if(ret<=0) {
  504    Xorriso_destroy_hln_array(xorriso, 0);
  505    goto ex;
  506  }
  507  xorriso->node_targets_availmem= xorriso->temp_mem_limit;
  508  xorriso->hln_change_pending= 0;
  509  ret= 1;
  510 ex:;
  511  return(ret);
  512 }
  513 
  514 
  515 /* @param flag bit0= overwrite existing di_array (else return 2)
  516                bit1= make di_array despite xorriso->ino_behavior bit 3
  517 */
  518 int Xorriso_make_di_array(struct XorrisO *xorriso, int flag)
  519 {  
  520  int ret, bytes; 
  521 
  522 #ifdef NIX
  523  /* <<< */
  524  unsigned long old_gdic;
  525  old_gdic= Xorriso_get_di_counteR;
  526 #endif /* NIX */
  527 
  528  if((xorriso->ino_behavior & 8 ) && !(flag & 2))
  529    return(2);
  530  if(xorriso->di_array != NULL && !(flag & 1))
  531    return(2);
  532  Xorriso_finish_hl_update(xorriso, 0);
  533 
  534  ret= Xorriso_all_node_array(xorriso, 0, 0);
  535  if(ret <= 0)
  536    goto ex;
  537  bytes= xorriso->node_array_size / 8 + 1;
  538  xorriso->di_do_widen= calloc(bytes, 1);
  539  if(xorriso->di_do_widen == NULL) {
  540    Xorriso_no_malloc_memory(xorriso, NULL, 0);
  541    ret= -1; goto ex;
  542  }
  543 
  544  /* Transfer node_array to di_array without unrefering nodes */
  545  xorriso->di_count= xorriso->node_counter;
  546  xorriso->di_array= xorriso->node_array;
  547  xorriso->node_counter= 0;
  548  xorriso->node_array_size= 0;
  549  xorriso->node_array= NULL;
  550 
  551  Xorriso__sort_di((void *) xorriso->di_array, xorriso->di_count, 0);
  552 
  553  ret= 1;
  554 ex:;
  555 
  556 #ifdef NIX
  557 /* <<< */
  558  fprintf(stderr, "xorriso_DEBUG: sort_count= %lu\n",
  559          Xorriso_get_di_counteR - old_gdic);
  560 #endif /* NIX */
  561 
  562  return(ret);
  563 }
  564 
  565 
  566 /*
  567    @param flag  bit0= iso_rr_path is freshly added and up to date
  568                 bit1= do not mark as changed content (implied by bit0 too)
  569                 bit2= -follow: this is not a command parameter
  570    @return -1= severe error
  571             0= not applicable for hard links
  572             1= go on with processing
  573             2= iso_rr_path is fully updated
  574  */
  575 int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
  576                             char *disk_path, char *iso_rr_path, int flag)
  577 {
  578  int ret, hret, idx, low, high, i, do_overwrite= 0, did_fake_di= 0;
  579  int follow_links, old_idx= -1;
  580  IsoNode *node;
  581  struct stat stbuf;
  582  dev_t old_dev;
  583  ino_t old_ino;
  584 
  585  if(xorriso->di_array == NULL)
  586    return(1);
  587  follow_links= xorriso->do_follow_links ||
  588                (xorriso->do_follow_param && !(flag & 4));
  589  ret= Xorriso_node_from_path(xorriso, NULL, iso_rr_path, &node, 0);
  590  if(ret <= 0)
  591    return(ret);
  592  if(LIBISO_ISDIR(node))
  593    return(1);
  594 
  595  /* Handle eventual hardlink split : */
  596  /* This is achieved by setting the content change bit. Reason:
  597     The node needs to be removed from di_array because its di is
  598     not matching its array index any more. So it becomes invisible for
  599     the join check of eventual later hardlink siblings. Therefore
  600     it must be updated now, even if it has currently no siblings
  601     which it leaves or which it joins.
  602  */
  603  if(!(flag & (1 | 2)))
  604    do_overwrite= 1;
  605 
  606  Xorriso__get_di(node, &old_dev, &old_ino, 0);
  607  ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
  608                            Xorriso__di_cmp, node, &idx, 0);
  609  if(ret < 0)
  610    {ret= 0; goto ex;}
  611  if(ret > 0)
  612    old_idx= idx;
  613 
  614  /* Handle eventual hardlink joining : */
  615 
  616  if(follow_links)
  617    ret= stat(disk_path, &stbuf);
  618  else
  619    ret= lstat(disk_path, &stbuf);
  620  if(ret==-1)
  621    {ret= 0; goto ex;}
  622 
  623  /* Are there new dev-ino-siblings in the image ? */
  624  /* Fake isofs.di */
  625  if(!(flag & 1)) {
  626    ret= Xorriso_record_dev_inode(xorriso, disk_path, stbuf.st_dev,
  627                                  stbuf.st_ino, node, iso_rr_path, 1);
  628    if(ret <= 0)
  629      {ret= -1; goto ex;}
  630    did_fake_di= 1;
  631    /* temporarily remove node from di_array so it does not disturb 
  632        search by its fake di info */;
  633    if(old_idx >= 0)
  634      xorriso->di_array[old_idx]= NULL;
  635  }
  636  ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 1);
  637  if(did_fake_di) {
  638    /* Revoke fake of isofs.di */
  639    hret= Xorriso_record_dev_inode(xorriso, disk_path, old_dev, old_ino,
  640                                   node, iso_rr_path, 1);
  641    if(hret <= 0)
  642      {ret= -1; goto ex;}
  643    if(old_idx >= 0)
  644      xorriso->di_array[old_idx]= node;
  645  }
  646  if(ret == 0)
  647    {ret= 1; goto ex;}
  648  if(ret < 0)
  649    {ret= 0; goto ex;}
  650 
  651 
  652 #ifdef Xorriso_hardlink_update_debuG
  653  /* <<< */
  654  if(low < high || idx < 0) {
  655    fprintf(stderr,
  656    "xorriso_DEBUG: old_idx= %d , low= %d , high= %d , iso= '%s' , disk='%s'\n",
  657    old_idx, low, high, iso_rr_path, disk_path);
  658    fprintf(stderr,
  659          "xorriso_DEBUG: old_dev= %lu , old_ino= %.f ,  dev= %lu , ino= %.f\n",
  660          (unsigned long) old_dev, (double) old_ino,
  661          (unsigned long) stbuf.st_dev, (double) stbuf.st_ino);
  662 
  663    if(idx >= 0 && idx != old_idx)
  664      fprintf(stderr, "xorriso_DEBUG: idx= %d , old_idx = %d\n", idx, old_idx);
  665  }
  666 #endif /* Xorriso_hardlink_update_debuG */
  667 
  668  /* Overwrite all valid siblings : */
  669  for(i= low; i <= high; i++) {
  670    if(i == idx || xorriso->di_array[i] == NULL)
  671  continue;
  672 
  673 #ifdef Xorriso_hardlink_update_debuG
  674  /* <<< */
  675 {
  676  ino_t ino;
  677  dev_t dev;
  678 
  679  Xorriso__get_di(xorriso->di_array[i], &dev, &ino, 0);
  680  fprintf(stderr, "xorriso_DEBUG: iso_sibling= '%s' , dev= %lu , ino= %.f\n",
  681          node_path, (unsigned long) dev, (double) ino);
  682 }
  683 #endif /* Xorriso_hardlink_update_debuG */
  684 
  685    xorriso->di_do_widen[i / 8]|= 1 << (i % 8);
  686  }
  687 
  688  ret= 1;
  689 ex:;
  690  if(do_overwrite)
  691    *compare_result|= (1<<15);
  692  if(old_idx >= 0 && (*compare_result & (3 << 21))) {
  693    /* The old di info is obsolete */
  694    if(xorriso->di_array[old_idx] != NULL)
  695      iso_node_unref(xorriso->di_array[old_idx]);
  696    xorriso->di_array[old_idx]= NULL;
  697  }
  698  return(ret);
  699 }
  700 
  701 
  702 /* @param flag bit0= do not destroy di_array
  703 */
  704 int Xorriso_finish_hl_update(struct XorrisO *xorriso, int flag)
  705 {
  706  int ret, zero= 0;
  707  char *argv[4];
  708  struct Xorriso_lsT *disk_lst, *iso_lst;
  709 
  710  if(xorriso->di_array == NULL)
  711    {ret= 1; goto ex;}
  712  disk_lst= xorriso->di_disk_paths;
  713  iso_lst= xorriso->di_iso_paths;
  714  while(disk_lst != NULL && iso_lst != NULL) {
  715    argv[0]= Xorriso_lst_get_text(iso_lst, 0);
  716    argv[1]= "-exec";
  717    argv[2]= "widen_hardlinks";
  718    argv[3]= Xorriso_lst_get_text(disk_lst, 0);
  719    zero= 0;
  720    ret= Xorriso_option_find(xorriso, 4, argv, &zero, 0); /* -findi */
  721    if(ret < 0)
  722      goto ex;
  723    disk_lst= Xorriso_lst_get_next(disk_lst, 0);
  724    iso_lst= Xorriso_lst_get_next(iso_lst, 0);
  725  }
  726  ret= 1;
  727 ex:;
  728  if(!(flag & 1))
  729    Xorriso_destroy_di_array(xorriso, 0);
  730  return(ret);
  731 }
  732