diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index c8aa35b7..0d6dcea2 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "May 29, 2009" +.TH XORRISO 1 "Jun 22, 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -42,7 +42,9 @@ incorporates the libraries of libburnia-project.org . .br Operates on an existing ISO image or creates a new one. .br -Copies files from filesystem into the ISO image. +Copies files from disk filesystem into the ISO image. +.br +Copies files from ISO image to disk filesystem (see osirrox). .br Renames or deletes file objects in the ISO image. .br @@ -57,9 +59,7 @@ Can activate ISOLINUX boot images via El Torito. .br Can perform multi-session tasks as emulation of mkisofs and cdrecord. .br -Can restore files from ISO image to disk filesystem (see osirrox). -.br -Can record and restore ACL of disk files. +Can record and restore hard links and ACL. .br Content may get zisofs compressed or filtered by external processes. .br @@ -668,7 +668,7 @@ 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"|"without_update"|"start_update"|"end_update" +\fB\-hardlinks\fR "on"|"off"|"without_update"|"start_update"|"end_update" |"start_extract"|"end_extract" Enable or disable loading and recording of hardlink relations. .br In default mode "off", iso_rr files lose their inode numbers at image load @@ -690,10 +690,15 @@ and -hardlinks "end_update". This avoids multiple sorting of ISO image nodes. 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. +with identical inode number. Normally this applies only to files which +get extracted during execution of that same command. One may surround a group +of extraction commands by -hardlinks "start_extract" and +-hardlinks "end_extract" to allow hard linking among their extracted files. +-osirrox "sort_lba_on" and -hardlinks "start_extract" mutually disable +each other. +.br +A large number of hardlink families may exhaust -temp_mem_limit +if not -osirrox option "sort_lba_on" is in effect. .br Hardlink processing automatically enables \fB\-compliance new_rr\fR. This may be overridden by a following -compliance old_rr . In this case diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 154aa4d4..32420444 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -5398,6 +5398,9 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->hln_count= 0; m->hln_array= NULL; m->hln_targets= NULL; + m->di_do_widen= NULL; + m->di_disk_paths= NULL; + m->di_iso_paths= NULL; m->node_targets_availmem= 0; @@ -8351,6 +8354,28 @@ ex:; } +int Xorriso_pfx_disk_path(struct XorrisO *xorriso, char *iso_path, + char *iso_prefix, char *disk_prefix, + char disk_path[SfileadrL], int flag) +{ + int ret; + char adrc[SfileadrL]; + + if(strncmp(iso_path, iso_prefix, strlen(iso_prefix))!=0) + return(-1); + if(strlen(disk_prefix) + strlen(iso_path) - strlen(iso_prefix)+1 >= SfileadrL) + return(-1); + if(iso_path[strlen(iso_prefix)] == '/') + strcpy(adrc, iso_path + strlen(iso_prefix) + 1); + else + strcpy(adrc, iso_path + strlen(iso_prefix)); + ret= Xorriso_make_abs_adr(xorriso, disk_prefix, adrc, disk_path, 4 | 8); + if(ret <= 0) + return(ret); + return(1); +} + + /* @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 bit0= update rather than compare @@ -8363,19 +8388,11 @@ int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter, int flag) { int ret, result, uret, follow_links, deleted= 0; - char disk_path[SfileadrL], adrc[SfileadrL]; + char disk_path[SfileadrL]; - if(strncmp(iso_path, iso_prefix, strlen(iso_prefix))!=0) - return(-1); - if(strlen(disk_prefix)+strlen(iso_path)-strlen(iso_prefix)+1>=SfileadrL) - return(-1); - if(iso_path[strlen(iso_prefix)]=='/') - strcpy(adrc, iso_path+strlen(iso_prefix)+1); - else - strcpy(adrc, iso_path+strlen(iso_prefix)); - - ret= Xorriso_make_abs_adr(xorriso, disk_prefix, adrc, disk_path, 4|8); - if(ret<=0) + ret= Xorriso_pfx_disk_path(xorriso, iso_path, iso_prefix, disk_prefix, + disk_path, 0); + if(ret <= 0) return(ret); /* compare exclusions against disk_path resp. leaf name */ @@ -8390,7 +8407,7 @@ int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter, follow_links= (xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&2))) <<28; - ret= Xorriso_compare_2_files(xorriso, disk_path, iso_path, adrc, &result, + ret= Xorriso_compare_2_files(xorriso, disk_path, iso_path, "", &result, 2 | follow_links | ((!(flag&2))<<27) | ((flag&1)<<31)); /* was once: | ((!(flag&1))<<29) */ if(retfind_compare_result) @@ -15359,13 +15376,16 @@ not_enough_exec_arguments:; Findjob_set_action_subjob(job, 13, new_job, 0); job= new_job; - } else if(strcmp(cpt, "compare")==0 || strcmp(cpt, "update")==0) { + } else if(strcmp(cpt, "compare")==0 || strcmp(cpt, "update")==0 || + strcmp(cpt, "widen_hardlinks")==0) { if(i+1>=end_idx) goto not_enough_exec_arguments; i++; action= 14; if(strcmp(cpt, "update")==0) action= 17; + if(strcmp(cpt, "widen_hardlinks")==0) + action= 32; ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, argv[i], other_path_start, 1|2|4|8); if(ret<=0) @@ -15689,14 +15709,14 @@ int Xorriso_option_hardlinks(struct XorrisO *xorriso, char *mode, int flag) } else if(strcmp(mode, "without_update") == 0) { xorriso->ino_behavior&= ~(1 | 2 | 4); xorriso->ino_behavior|= 8; - Xorriso_destroy_di_array(xorriso, 0); + Xorriso_finish_hl_update(xorriso, 0); } else if(strcmp(mode, "start_update") == 0) { xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); ret= Xorriso_make_di_array(xorriso, 1); if(ret <= 0) return(ret); } else if(strcmp(mode, "end_update") == 0) { - Xorriso_destroy_di_array(xorriso, 0); + Xorriso_finish_hl_update(xorriso, 0); } else if(strcmp(mode, "start_extract") == 0) { xorriso->do_restore_sort_lba= 0; xorriso->ino_behavior&= ~(1 | 2 | 4); @@ -16810,7 +16830,7 @@ ex:; Sfile_destroy_argv(&i, &eff_tgt_array, 0); (*idx)= end_idx; if(made_di_array) - Xorriso_destroy_di_array(xorriso, 0); + Xorriso_finish_hl_update(xorriso, 0); if(made_hln_array) Xorriso_destroy_hln_array(xorriso, 0); Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &optc, &optv, 256); @@ -18558,7 +18578,7 @@ int Xorriso_option_uid(struct XorrisO *xorriso, char *uid, int flag) 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 ret, mem_pci, zero= 0, result, uret, follow_links, do_register= 1; 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]; @@ -18605,13 +18625,33 @@ int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path, 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(!(xorriso->ino_behavior & 2)) { + if(!(xorriso->di_array != NULL || (flag & 16))) { + /* 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(xorriso->di_array != NULL) { + if(!(flag & 8)) { + /* If directory with -update : do not register di_*_paths */ + ret= lstat(eff_origin, &stbuf); + if(ret != -1) + if(S_ISDIR(stbuf.st_mode)) + do_register= 0; + } + if(do_register) { + ret= Xorriso_lst_append_binary(&(xorriso->di_disk_paths), eff_origin, + strlen(eff_origin) + 1, 0); + if(ret <= 0) + goto ex; + ret= Xorriso_lst_append_binary(&(xorriso->di_iso_paths), eff_dest, + strlen(eff_dest) + 1, 0); + if(ret <= 0) + goto ex; + } + } } if(flag&8) { @@ -18703,7 +18743,7 @@ report_outcome:; ex:; if(made_di_array) { /* Dispose all-image node array sorted by isofs.di */ - Xorriso_destroy_di_array(xorriso, 0); + Xorriso_finish_hl_update(xorriso, 0); } if(ret < 0) return(ret); diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index e6ddc8fd..e548b30c 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -391,18 +391,31 @@ struct XorrisO { /* the global context of xorriso */ int find_compare_result; /* 1=everything matches , 0=mismatch , -1=error */ - /* LBA sorting and hardlink matching facility */ + /* Tree node collection and LBA sorting facility */ int node_counter; int node_array_size; void **node_array; - char **node_targets; /* Memorizes eventual hardlink target paths */ - off_t node_targets_availmem; struct Xorriso_lsT *node_disk_prefixes; struct Xorriso_lsT *node_img_prefixes; - /* Array of all nodes in the tree, sorted by disk dev,ino */ + /* Hardlink matching at restore time memorizes hardlink target paths. + Array of nodes sorted by LBA. */ + int hln_count; + void **hln_array; + void **hln_targets; + + /* >>> this should count all temp_mem and thus change its name */ + off_t node_targets_availmem; + + /* Hardlink matching at update time: + Array of all nodes in the tree, sorted by disk dev,ino. + Bitmap of nodes which possibly got new hardlink siblings. + List of involved disk-iso path pairs. */ int di_count; void **di_array; + char *di_do_widen; + struct Xorriso_lsT *di_disk_paths; + struct Xorriso_lsT *di_iso_paths; struct PermiteM *perm_stack; /* Temporarily altered dir access permissions */ @@ -518,6 +531,10 @@ int Xorriso_pacifier_callback(struct XorrisO *xorriso, char *what_done, off_t count, off_t todo, char *current_object, int flag); +int Xorriso_pfx_disk_path(struct XorrisO *xorriso, char *iso_path, + char *iso_prefix, char *disk_prefix, + char disk_path[SfileadrL], int flag); + /* @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 bit0= update rather than compare @@ -918,6 +935,7 @@ struct FindjoB { 29= show_stream 30= internal: count by xorriso->node_counter 31= internal: register in xorriso->node_array + 32= internal: widen_hardlinks disk_equiv: update nodes marked in di_do_widen */ int action; int prune; diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 5fe09c2e..bd11b0a1 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.06.20.063853" +#define Xorriso_timestamP "2009.06.22.112850" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index fd67ff58..f2acca5b 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -187,6 +187,12 @@ int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag) free(xorriso->di_array); xorriso->di_array= NULL; } + if(xorriso->di_do_widen != NULL) { + free(xorriso->di_do_widen); + xorriso->di_do_widen= NULL; + } + Xorriso_lst_destroy_all(&(xorriso->di_disk_paths), 0); + Xorriso_lst_destroy_all(&(xorriso->di_iso_paths), 0); xorriso->di_count= 0; #ifdef NIX @@ -253,8 +259,8 @@ int Xorriso_new_hln_array(struct XorrisO *xorriso, off_t mem_limit, int flag) xorriso->node_targets_availmem= mem_limit - xorriso->hln_count * sizeof(void *) - xorriso->hln_count * sizeof(char *); - if(xorriso->node_targets_availmem < 0) - xorriso->node_targets_availmem= 0; + if(xorriso->node_targets_availmem < 0) + xorriso->node_targets_availmem= 0; return(1); } @@ -471,6 +477,46 @@ int Xorriso_invalidate_di_item(struct XorrisO *xorriso, IsoNode *node, } +/* @param flag bit0= return 1 even if matching nodes were found but node is + not among them + bit1= use Xorriso__di_cmp() rather than Xorriso__di_ino_cmp() +*/ +int Xorriso_search_di_range(struct XorrisO *xorriso, IsoNode *node, + int *idx, int *low, int *high, int flag) +{ + int ret, i, found; + int (*cmp)(const void *p1, const void *p2)= Xorriso__di_ino_cmp; + + if(flag & 2) + cmp= Xorriso__di_cmp; + + *high= *low= *idx= -1; + ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count, + 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((*cmp)(&node, &(xorriso->di_array[i])) != 0) + break; + *high= i; + } + for(i= found - 1; i >= 0; i--) + if(xorriso->di_array[i] != NULL) { + if((*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)); +} + + /* ------------------------------------------------------------------------ */ @@ -606,6 +652,7 @@ int Xorriso_detach_libraries(struct XorrisO *xorriso, int flag) xorriso->in_volset_handle= NULL; Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); Xorriso_destroy_di_array(xorriso, 0); + Xorriso_destroy_hln_array(xorriso, 0); } if(flag&1) { if(xorriso->libs_are_started==0) @@ -764,6 +811,7 @@ int Xorriso_create_empty_iso(struct XorrisO *xorriso, int flag) xorriso->in_volset_handle= NULL; Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); Xorriso_destroy_di_array(xorriso, 0); + Xorriso_destroy_hln_array(xorriso, 0); xorriso->loaded_volid[0]= 0; xorriso->volset_change_pending= 0; xorriso->no_volset_present= 0; @@ -1041,6 +1089,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_hln_array(xorriso, 0); Xorriso_destroy_di_array(xorriso, 0); /* check for invalid state */ @@ -1233,6 +1282,7 @@ int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag) xorriso->in_volset_handle= NULL; Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); Xorriso_destroy_di_array(xorriso, 0); + Xorriso_destroy_hln_array(xorriso, 0); xorriso->loaded_volid[0]= 0; xorriso->isofs_st_out= time(0) - 1; xorriso->isofs_st_in= 0; @@ -1505,6 +1555,10 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag) int profile_number; char profile_name[80]; + ret= Xorriso_finish_hl_update(xorriso, 0); + if(ret <= 0) + return(ret); + out_cs= xorriso->out_charset; if(out_cs == NULL) Xorriso_get_local_charset(xorriso, &out_cs, 0); @@ -7373,6 +7427,46 @@ int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path, } +int Xorriso_widen_hardlink(struct XorrisO *xorriso, void * boss_iter, + IsoNode *node, + char *abs_path, char *iso_prefix, char *disk_prefix, + int flag) +{ + int ret= 0, idx, low, high, i, do_widen= 0, compare_result= 0; + char disk_path[SfileadrL]; + + /* Lookup all di_array instances of node */ + if(LIBISO_ISDIR(node)) + return(1); + ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 2); + if(ret <= 0) + return(1); + /* Check and reset di_do_widen bits */ + for(i= low; i <= high; i++) { + if(node != xorriso->di_array[i]) /* might be NULL */ + continue; + if(xorriso->di_do_widen[i / 8] & (1 << (i % 8))) + do_widen= 1; + xorriso->di_do_widen[i / 8]&= ~(1 << (i % 8)); + } + if(idx < 0 || !do_widen) + return(1); + + ret= Xorriso_pfx_disk_path(xorriso, abs_path, iso_prefix, disk_prefix, + disk_path, 0); + if(ret <= 0) + return(ret); + + /* >>> compare_result bit17 = is_split */; + + ret= Xorriso_update_interpreter(xorriso, boss_iter, compare_result, disk_path, + abs_path, 1); + if(ret <= 0) + return(ret); + return 1; +} + + /* @param flag bit0= not a command parameter (directory iteration or recursion) bit1= do not count deleted files with rm and rm_r @return <=0 error, @@ -7470,6 +7564,11 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, iso_node_ref(node); /* In case node gets deleted from tree during the lifetime of xorriso->node_array */ } + } else if(action == 32) { /* internal: widen_hardlinks disk_equiv */ + Findjob_get_start_path(job, &iso_prefix, 0); + ret= Xorriso_widen_hardlink(xorriso, (void *) boss_iter, node, abs_path, + iso_prefix, target, 0); + } else { /* includes : 15 in_iso */ sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); Xorriso_result(xorriso, 0); @@ -7926,7 +8025,8 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, mem= boss_mem; hflag= 1; - if(action==1 || action==2 || action==3 || action==17 || action == 28) + if(action==1 || action==2 || action==3 || action==17 || action == 28 || + action == 32) hflag|= 2; /* need freedom to manipulate image */ if(action==14 || action==17 || action == 28) hflag|= 4; /* need LBA sorted iteration for good data reading performance */ @@ -11689,6 +11789,7 @@ int Xorriso_make_hln_array(struct XorrisO *xorriso, int flag) ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1); if(ret<=0) goto ex; + xorriso->node_targets_availmem= xorriso->temp_mem_limit; ret= 1; ex:; @@ -11701,7 +11802,7 @@ ex:; */ int Xorriso_make_di_array(struct XorrisO *xorriso, int flag) { - int ret; + int ret, bytes; #ifdef NIX /* <<< */ @@ -11713,11 +11814,17 @@ int Xorriso_make_di_array(struct XorrisO *xorriso, int flag) return(2); if(xorriso->di_array != NULL && !(flag & 1)) return(2); - Xorriso_destroy_di_array(xorriso, 0); + Xorriso_finish_hl_update(xorriso, 0); ret= Xorriso_all_node_array(xorriso, 0); if(ret <= 0) goto ex; + bytes= xorriso->node_array_size / 8 + 1; + xorriso->di_do_widen= calloc(bytes, 1); + if(xorriso->di_do_widen == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } /* Transfer node_array to di_array without unrefering nodes */ xorriso->di_count= xorriso->node_counter; @@ -11741,41 +11848,6 @@ ex:; } -/* @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 @@ -11788,13 +11860,18 @@ 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]; + int follow_links, old_idx= -1; IsoNode *node; struct stat stbuf; dev_t old_dev; ino_t old_ino; +#ifdef Xorriso_hardlink_update_direcT + /* <<< */ + int node_result; + char node_path[SfileadrL]; +#endif + if(xorriso->di_array == NULL) return(1); follow_links= xorriso->do_follow_links || @@ -11862,7 +11939,7 @@ int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result, {ret= 0; goto ex;} -#ifdef NIX +#ifdef Xorriso_hardlink_update_debuG /* <<< */ if(low < high || idx < 0) { fprintf(stderr, @@ -11876,20 +11953,14 @@ int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result, if(idx >= 0 && idx != old_idx) fprintf(stderr, "xorriso_DEBUG: idx= %d , old_idx = %d\n", idx, old_idx); } -#endif /* NIX */ +#endif /* Xorriso_hardlink_update_debuG */ /* 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 +#ifdef Xorriso_hardlink_update_debuG /* <<< */ { ino_t ino; @@ -11899,7 +11970,17 @@ int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result, fprintf(stderr, "xorriso_DEBUG: iso_sibling= '%s' , dev= %lu , ino= %lu\n", node_path, (unsigned long) dev, (unsigned long) ino); } -#endif /* NIX */ +#endif /* Xorriso_hardlink_update_debuG */ + +#ifdef Xorriso_hardlink_update_direcT + /* <<< */ + + /* 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 */ node_result= 0; ret= Xorriso_compare_2_files(xorriso, disk_path, node_path, "", @@ -11913,6 +11994,13 @@ int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result, if(ret < 0) goto ex; } + +#else /* Xorriso_hardlink_update_direcT */ + + xorriso->di_do_widen[i / 8]|= 1 << (i % 8); + +#endif /* ! Xorriso_hardlink_update_direcT */ + } ret= 1; @@ -11928,3 +12016,33 @@ ex:; return(ret); } + +int Xorriso_finish_hl_update(struct XorrisO *xorriso, int flag) +{ + int ret, zero= 0; + char *argv[4]; + struct Xorriso_lsT *disk_lst, *iso_lst; + + if(xorriso->di_array == NULL) + {ret= 1; goto ex;} + disk_lst= xorriso->di_disk_paths; + iso_lst= xorriso->di_iso_paths; + while(disk_lst != 0 && iso_lst != NULL) { + argv[0]= Xorriso_lst_get_text(iso_lst, 0); + argv[1]= "-exec"; + argv[2]= "widen_hardlinks"; + argv[3]= Xorriso_lst_get_text(disk_lst, 0); + zero= 0; + ret= Xorriso_option_find(xorriso, 4, argv, &zero, 0); /* -findi */ + if(ret < 0) + goto ex; + disk_lst= Xorriso_lst_get_next(disk_lst, 0); + iso_lst= Xorriso_lst_get_next(iso_lst, 0); + } + ret= 1; +ex:; + Xorriso_destroy_di_array(xorriso, 0); + return(ret); +} + + diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 4df32ee1..74c16fc4 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -482,6 +482,8 @@ int Xorriso_make_hln_array(struct XorrisO *xorriso, int flag); int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result, char *disk_path, char *iso_rr_path, int flag); +int Xorriso_finish_hl_update(struct XorrisO *xorriso, int flag); + /* A pseudo file type for El-Torito bootsectors as in man 2 stat : For now take the highest possible value.