From e69f4e1234e8945a4394a42e094ed43eb3f190c0 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Tue, 17 Feb 2009 18:42:41 +0000 Subject: [PATCH] New option -disk_dev_ino --- xorriso/xorriso.1 | 17 ++- xorriso/xorriso.c | 117 ++++++++++++++----- xorriso/xorriso.h | 3 + xorriso/xorriso_eng.html | 9 ++ xorriso/xorriso_timestamp.h | 2 +- xorriso/xorrisoburn.c | 221 ++++++++++++++++++++++++++++-------- xorriso/xorrisoburn.h | 3 + 7 files changed, 298 insertions(+), 74 deletions(-) diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index c457758f..c652fd76 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -667,6 +667,20 @@ Enable or disable processing of xattr attributes in user namespace. If enabled, then xorriso will handle xattr similar to ACL. See also options -getfattr, -setfattr and above paragraph about xattr. .TP +\fB\-disk_dev_ino\fR "on"|"off" +Enable or disable processing of recorded file identification numbers +(dev_t and ino_t). They are eventually stored as xattr "isofs.di" and allow +to substantially accelerate file comparison: +.br +If device numbers and inode numbers of the disk filesystems are persistent +and if no irregular alterations of timestamps or system clock happen, +then potential content changes can be detected without reading that content. +File content change is assumed if any of mtime, ctime, device number or inode +number have changed. +.br +The speed advantage appears only if the loaded session was produced with +-disk_dev_ino "on" too. +.TP \fB\-rom_toc_scan\fR "on"|"off"[:"emul_on"|"emul_off"] Read-only drives do not tell the actual media type but show any media as ROM (e.g. as DVD-ROM). The session history of MMC multi-session media might @@ -3115,7 +3129,8 @@ the old one. .br This makes sense if the full backup leaves substantial remaining capacity on media and if the expected changes are much smaller than the full backup. -An update run will probably save no time but last longer than a full backup. +An update run will probably save no time but last longer than a full backup, +unless option -disk_dev_ino "on" is used. .br With \fBmount\fR option \fB-o "sbsector="\fR on Linux resp. \fB-s\fR on FreeBSD it is possible to access the session trees which represent the older backup diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 16f2dc66..af463e63 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -6347,11 +6347,16 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) Xorriso_status_result(xorriso, filter, fp, flag & 2); } - is_default= (xorriso->do_aaip==0); + is_default= ((xorriso->do_aaip & (1 | 4)) == 0); sprintf(line,"-acl %s\n", (xorriso->do_aaip & 1 ? "on" : "off")); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); + is_default= ((xorriso->do_aaip & (2 | 8)) == 0); sprintf(line,"-xattr %s\n", (xorriso->do_aaip & 4 ? "on" : "off")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + is_default= ((xorriso->do_aaip & (16 | 32 | 64)) == 0); + sprintf(line,"-disk_dev_ino %s\n", (xorriso->do_aaip & 16 ? "on" : "off")); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); @@ -6698,7 +6703,8 @@ cannot_address:; bit18= incomplete chunk collection encountered bit19= ACL differs (this condition sets also bit2) bit20= xattr differ - >>> bit21= mismatch of recorded dev,inode + bit21= mismatch of recorded dev,inode + bit22= no recorded dev,inode found in node @param flag bit0= compare atime bit1= compare ctime bit2= check only existence of both file objects @@ -6716,6 +6722,7 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, { struct stat s1, s2, stbuf; int ret, missing= 0, is_split= 0, i, was_error= 0, diff_count= 0; + int content_shortcut= 0; char *respt; char a[5*SfileadrL], sfe[5*SfileadrL]; char ttx1[40], ttx2[40]; @@ -6941,11 +6948,45 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, } } + if(xorriso->do_aaip & 32) { + /* dev,inode comparison. Eventually skip content comparison */ + ret= Xorriso_record_dev_inode(xorriso, "", s1.st_dev, s1.st_ino, NULL, + iso_adr, 1 | 2 | ((flag & (1 << 28)) >> 23)); + 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((*result) & (8 | 128 | 256 | 512 | 1024)) { + (*result)|= (1 << 15); /* content bytes differ */ + sprintf(respt, + "%s content : assuming inequality due to size or timestamps\n", a); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + } + } + } else if(ret == 1) { /* mismatch */ + (*result)|= (1 << 21); + 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; + (*result)|= (1 << 15); /* content bytes differ */ + sprintf(respt, + "%s content : assuming inequality after dev_ino mismatch\n", a); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + } + } else { + sprintf(respt, "%s dev_ino : no dev_ino stored with image node\n", a); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + (*result)|= (1 << 22); + } + } - /* >>> dev,inode comparison. Eventually skip content comparison */ - - - if(S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)) { + if(S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode) && !content_shortcut) { /* Content */ if(is_split) { for(i= 0; iinfo_text, "Added/overwrote "); - } else if(compare_result&(4|16|32|256|512|1024|(1<<19)|(1<<20))) { - /* access permissions, user id, group id, mtime, atime, ctime, ACL, xattr */ + } 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(is_split) { ret= Xorriso_identify_split(xorriso, iso_rr_path, NULL, @@ -10380,16 +10422,18 @@ delete:; strlen(iso_rr_path)+strlen(part_path)+1, 2); {ret= -1; goto ex;} } - ret= Xorriso_copy_properties(xorriso, disk_path, part_path, 0); + ret= Xorriso_copy_properties(xorriso, disk_path, part_path, + 4 * !(compare_result & (1<<21))); + /* do not update eventually mismatching dev_ino */ if(ret<=0) goto ex; } /* Copy file attributes to iso_rr_path, augment r-perms by x-perms */ - ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 2); + ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 2 | 4); if(ret<=0) goto ex; } else - ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 0); + ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 4); sprintf(xorriso->info_text, "Adjusted attributes of "); } else @@ -12974,6 +13018,22 @@ int Xorriso_option_dialog(struct XorrisO *xorriso, char *mode, int flag) } +/* Option -disk_dev_ino "on"|"off" */ +int Xorriso_option_disk_dev_ino(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "on") == 0) + xorriso->do_aaip|= 16 | 32 | 64; + else if(strcmp(mode, "off") == 0) + xorriso->do_aaip &= ~(16 | 32 | 64); + else { + sprintf(xorriso->info_text, "-disk_dev_ino: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1); +} + + /* Option -disk_pattern "on"|"ls"|"off" */ int Xorriso_option_disk_pattern(struct XorrisO *xorriso, char *mode, int flag) { @@ -13845,6 +13905,9 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " Enable resp. disable reading and writing of ACLs.", " -xattr \"on\"|\"off\"", " Enable resp. disable reading and writing of xattr.", +" -disk_dev_ino \"on\"|\"off\"", +" Enable resp. disable recording of disk file dev_t and ino_t", +" and their use in file comparison.", " -ban_stdio_write", " Allow for writing only the usage of optical drives.", " -blank \"fast\"|\"all\"|\"deformat\"|\"deformat_quickest\"", @@ -16707,8 +16770,8 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, static char arg1_commands[][40]= { "abort_on","acl","add_plainly","application_id","backslash_codes","blank", "cd","cdi","cdx","charset","close","commit_eject","compliance", - "dev", "dummy","dialog","disk_pattern","eject","iso_rr_pattern","follow", - "format","fs","gid","grow_blindly", + "dev","dialog","disk_dev_ino","disk_pattern","dummy","eject", + "iso_rr_pattern","follow","format","fs","gid","grow_blindly", "history","indev","in_charset","joliet","list_delimiter","local_charset", "mark","not_leaf","not_list","not_mgt", "options_from_file","osirrox","outdev","out_charset","overwrite", @@ -17005,26 +17068,30 @@ next_command:; } else if(strcmp(cmd,"devices")==0) { ret= Xorriso_option_devices(xorriso, 0); - } else if(strcmp(cmd,"drive_class")==0) { - (*idx)+= 2; - ret= Xorriso_option_drive_class(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"dummy")==0) { - (*idx)++; - ret= Xorriso_option_dummy(xorriso, arg1, 0); - } else if(strcmp(cmd,"dialog")==0) { (*idx)++; ret= Xorriso_option_dialog(xorriso, arg1, 0); + } else if(strcmp(cmd,"disk_dev_ino")==0) { + (*idx)++; + ret= Xorriso_option_disk_dev_ino(xorriso, arg1, 0); + } else if(strcmp(cmd,"disk_pattern")==0) { (*idx)++; ret= Xorriso_option_disk_pattern(xorriso, arg1, 0); + } else if(strcmp(cmd,"drive_class")==0) { + (*idx)+= 2; + ret= Xorriso_option_drive_class(xorriso, arg1, arg2, 0); + } else if(strcmp(cmd,"du")==0 || strcmp(cmd,"dui")==0 || strcmp(cmd,"dus")==0 || strcmp(cmd,"dusi")==0) { ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[2]!='s')|4); + } else if(strcmp(cmd,"dummy")==0) { + (*idx)++; + ret= Xorriso_option_dummy(xorriso, arg1, 0); + } else if(strcmp(cmd,"dux")==0 || strcmp(cmd,"dusx")==0) { ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[2]!='s')|4); @@ -17430,12 +17497,8 @@ next_command:; ret= Xorriso_option_temp_mem_limit(xorriso, arg1, 0); } else if(strcmp(cmd,"test")==0) { /* This option does not exist. */ - time_t t; - (*idx)++; - Decode_timestring(arg1, &t, 0); - sprintf(xorriso->result_line, "%.f\n", (double) t); - Xorriso_result(xorriso, 0); + /* install temporary test code here */; } else if(strcmp(cmd,"toc")==0) { Xorriso_option_toc(xorriso, 0); diff --git a/xorriso/xorriso.h b/xorriso/xorriso.h index cf5dad80..a6aa583c 100644 --- a/xorriso/xorriso.h +++ b/xorriso/xorriso.h @@ -411,6 +411,9 @@ int Xorriso_option_devices(struct XorrisO *xorriso, int flag); /* Option -dialog "on"|"off" */ int Xorriso_option_dialog(struct XorrisO *xorriso, char *mode, int flag); +/* Option -disk_dev_ino "on"|"off" */ +int Xorriso_option_disk_dev_ino(struct XorrisO *xorriso, char *mode, int flag); + /* Option -disk_pattern "on"|"ls"|"off" */ int Xorriso_option_disk_pattern(struct XorrisO *xorriso, char *mode, int flag); diff --git a/xorriso/xorriso_eng.html b/xorriso/xorriso_eng.html index a6d35b32..10d3a61e 100644 --- a/xorriso/xorriso_eng.html +++ b/xorriso/xorriso_eng.html @@ -120,6 +120,13 @@ Can perform multi-session tasks as emulation of mkisofs and cdrecord.
  • Can restore single files and whole trees from ISO image to disk filesystem.
  • + + +
  • Can issue commands to mount older sessions on Linux or FreeBSD.
  • @@ -488,6 +495,8 @@ Enhancements towards previous stable version xorriso-0.3.0.pl00:
  • New -find tests -has_xattr, -has_aaip, new -find actions getfattr, setfattr
  • +
  • New option -disk_dev_ino can substantially accelerate incremental backups +
  • diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index a53882e6..55433e84 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.02.16.082645" +#define Xorriso_timestamP "2009.02.17.184231" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 70f1ac71..054f24e7 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -666,7 +666,7 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) ext= isoburn_ropt_noiso1999; #ifdef isoburn_ropt_noaaip - if(!(xorriso->do_aaip & (1 | 4))) + if(!(xorriso->do_aaip & (1 | 4 | 16))) ext|= isoburn_ropt_noaaip; #endif #ifdef isoburn_ropt_noacl @@ -1283,7 +1283,7 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag) } isoburn_igopt_set_level(sopts, 3); isoburn_igopt_set_extensions(sopts, 1 | ((!!xorriso->do_joliet)<<1) | - ((!!(xorriso->do_aaip & (2 | 8))) << 5)); + ((!!(xorriso->do_aaip & (2 | 8 | 16))) << 5)); isoburn_igopt_set_relaxed(sopts, relax); isoburn_igopt_set_sort_files(sopts, 1); isoburn_igopt_set_over_mode(sopts, 0, 0, (mode_t) 0, (mode_t) 0); @@ -1603,12 +1603,12 @@ int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive, } else { if(progress.sector<=progress.sectors) { if(progress.sectors <= 0) - strcpy(mem_text, "99.9"); + strcpy(mem_text, " 99.9"); else - sprintf(mem_text, "%4.1f", + sprintf(mem_text, "%5.1f", 100.0 * ((double) progress.sector) / ((double) progress.sectors)); - mem_text[4]= 0; - sprintf(xorriso->info_text, "Writing: %10ds %s%% ", + mem_text[5]= 0; + sprintf(xorriso->info_text, "Writing: %10ds %s%% ", progress.sector, mem_text); } else { Sfile_scale(2048.0 * (double) progress.sector, mem_text, 5, 1e4, 1); @@ -1982,6 +1982,7 @@ int Xorriso_iso_lstat(struct XorrisO *xorriso, char *path, struct stat *stbuf, /* @param flag bit0= give directory x-permission where is r-permission bit1= do not transfer ACL or xattr + bit2= record dev,inode (only if enabled by xorriso) bit5= transfer ACL or xattr from eventual link target */ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf, @@ -2015,12 +2016,9 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf, iso_node_set_mtime(node, stbuf->st_mtime); iso_node_set_ctime(node, stbuf->st_ctime); - if(flag & 2) - {ret= 1; goto ex;} - #ifdef Xorriso_with_aaiP - if(xorriso->do_aaip & 5) { + if((xorriso->do_aaip & 5) && !(flag & 2)) { ret= iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths, &values, ((xorriso->do_aaip & 1) && !(flag & 2)) | ((!(xorriso->do_aaip & 4)) << 2) @@ -2041,15 +2039,26 @@ int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf, 0, "FAILURE", 1); ret= 0; goto ex; } - ret= 1; + } + + if((flag & 4) && (xorriso->do_aaip & 16)) { + ret= Xorriso_record_dev_inode(xorriso, disk_path, (dev_t) 0, (ino_t) 0, + (void *) node, "", flag & 32); + if(ret <= 0) + goto ex; } #endif /* Xorriso_with_aaiP */ + ret= 1; ex:; Xorriso_process_msg_queues(xorriso,0); + +#ifdef Xorriso_with_aaiP iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths, &values, 1 << 15); /* free memory */ +#endif /* Xorriso_with_aaiP */ + return(ret); } @@ -2102,11 +2111,16 @@ int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume, off_t offset, off_t cut_size, IsoNode **node, int flag) { - int ret; + int ret, stbuf_valid= 0; struct stat stbuf; char sfe[5*SfileadrL]; off_t size= 0; + if(lstat(disk_path, &stbuf) != -1) { + stbuf_valid= 1; + if(S_ISREG(stbuf.st_mode)) + size= stbuf.st_size; + } if(flag&8) { if(cut_size > xorriso->file_size_limit && xorriso->file_size_limit > 0) { sprintf(xorriso->info_text, @@ -2121,10 +2135,6 @@ int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume, if(ret<0) goto ex; } else { - - if(stat(disk_path, &stbuf)!=-1) - if(S_ISREG(stbuf.st_mode)) - size= stbuf.st_size; if(xorriso->split_size > 0 && size > xorriso->split_size) { ret= Xorriso_graft_split(xorriso, volume, dir, disk_path, img_name, nominal_source, nominal_target, size, @@ -2144,6 +2154,14 @@ int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume, if(ret<0) goto ex; } + + if(stbuf_valid && (xorriso->do_aaip & 16)) { + ret= Xorriso_record_dev_inode(xorriso, disk_path, + stbuf.st_dev, stbuf.st_ino, (void *) *node, "", 1); + if(ret <= 0) + goto ex; + } + ex:; if(ret<0) { Xorriso_process_msg_queues(xorriso,0); @@ -2351,7 +2369,7 @@ cannot_lstat:; ret= iso_tree_add_new_symlink(dir, img_name, link_target, &iso_symlink); node= (IsoNode *) iso_symlink; if(ret>0) { - ret= Xorriso_transfer_properties(xorriso, &stbuf, srcpt, node, 2); + ret= Xorriso_transfer_properties(xorriso, &stbuf, srcpt, node, 2 | 4); if(ret<=0) goto was_problem; } else { @@ -2462,7 +2480,7 @@ int Xorriso_copy_implicit_properties(struct XorrisO *xorriso, IsoDir *dir, if(stat(nfd, &stbuf)==-1) return(0); Xorriso_transfer_properties(xorriso, &stbuf, nfd, (IsoNode *) dir, - ((flag&1) && d==0) | 32); + ((flag&1) && d==0) | 4 | 32); sprintf(xorriso->info_text, "Copied properties for %s", Text_shellsafe(ni, sfe, 0)); sprintf(xorriso->info_text+strlen(xorriso->info_text), @@ -2475,6 +2493,7 @@ int Xorriso_copy_implicit_properties(struct XorrisO *xorriso, IsoDir *dir, /* @param bit0= copy link target properties rather than link properties bit1= give directory x-permission where is r-permission + bit2= record dev,inode (only if enabled by xorriso) */ int Xorriso_copy_properties(struct XorrisO *xorriso, char *disk_path, char *img_path, int flag) @@ -2494,7 +2513,7 @@ int Xorriso_copy_properties(struct XorrisO *xorriso, return(0); } Xorriso_transfer_properties(xorriso, &stbuf, disk_path, node, - ((flag & 2) >> 1) | ((flag & 1) << 5)); + ((flag & 2) >> 1) | ((flag & 1) << 5) | (flag & 4)); xorriso->volset_change_pending= 1; return(1); } @@ -2692,7 +2711,7 @@ attach_source:; } else if(is_dir) { Xorriso_transfer_properties(xorriso, &stbuf, disk_path, - (IsoNode *) dir, 32); + (IsoNode *) dir, 4 | 32); if(!(flag&32)) { ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL, flag&2); @@ -2903,9 +2922,9 @@ int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, #ifdef Xorriso_with_aaiP - if(xorriso->do_aaip & 10) { + if(xorriso->do_aaip & (2 | 8 | 16)) { ret= iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values, - (!!(xorriso->do_aaip & 2)) | (!(xorriso->do_aaip & 8)) << 2); + (!!(xorriso->do_aaip & 2)) | (!(xorriso->do_aaip & (8 | 16))) << 2); if (ret < 0) { strcpy(xorriso->info_text, "Error with obtaining ACL and xattr for "); Text_shellsafe(disk_path, xorriso->info_text, 1); @@ -9005,7 +9024,7 @@ int Xorriso_set_ignore_aclea(struct XorrisO *xorriso, int flag) if(ret<=0) return(ret); iso_image_set_ignore_aclea(volume, - ((~xorriso->do_aaip) & 1) | (((~xorriso->do_aaip) & 4) >> 1)); + ((~xorriso->do_aaip) & 1) | (((~xorriso->do_aaip) & (4 | 16)) >> 1)); return(1); } @@ -9057,7 +9076,7 @@ ex:; @param flag bit0= do not report to result but only retrieve attr text bit1= path is disk_path bit5= in case of symbolic link on disk: inquire link target - bit6= check for existence of non-ACL xattr, + bit6= check for existence of user namespaceL xattr, return 0 or 1 */ int Xorriso_getfattr(struct XorrisO *xorriso, void *in_node, char *path, @@ -9151,6 +9170,7 @@ ex:; @param flag bit0= Do not maintain eventual existing ACL of the node bit1= Do not clear the existing attribute list bit2= Delete the attributes with the given names + bit3= Allow non-user attributes. @return >0 success , <=0 failure */ int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path, @@ -9169,7 +9189,7 @@ int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path, #ifdef Xorriso_with_aaiP ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values, - flag & (1 | 2 | 4)); + flag & (1 | 2 | 4 | 8)); #else ret= 0; #endif @@ -9277,6 +9297,7 @@ int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path, /* @param flag bit1= path is disk_path + bit3= do not ignore eventual non-user attributes. bit5= in case of symbolic link on disk: inquire link target bit15= free memory */ @@ -9305,7 +9326,7 @@ int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, #ifdef Xorriso_with_aaiP ret= iso_local_get_attrs(path, num_attrs, names, value_lengths, values, - flag & 32); + flag & (8 | 32)); if(ret < 0) { strcpy(xorriso->info_text, "Error with reading xattr of disk file "); Text_shellsafe(path, xorriso->info_text, 1); @@ -9331,29 +9352,31 @@ int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, } #endif /* Xorriso_with_aaiP */ - /* Filter away any non-userspace xattr */; - widx= 0; - for(i= 0; i < *num_attrs; i++) { - if(strncmp((*names)[i], "user.", 5) != 0) { - free((*names)[i]); - (*names)[i]= NULL; - if((*values)[i] != NULL) { - free((*values)[i]); - (*values)[i]= NULL; - } - } else { - if(widx != i) { - (*names)[widx]= (*names)[i]; - (*value_lengths)[widx]= (*value_lengths)[i]; - (*values)[widx]= (*values)[i]; + if(!(flag & 8)) { + /* Filter away any non-userspace xattr */; + widx= 0; + for(i= 0; i < *num_attrs; i++) { + if(strncmp((*names)[i], "user.", 5) != 0) { + free((*names)[i]); (*names)[i]= NULL; - (*value_lengths)[i]= 0; - (*values)[i]= NULL; + if((*values)[i] != NULL) { + free((*values)[i]); + (*values)[i]= NULL; + } + } else { + if(widx != i) { + (*names)[widx]= (*names)[i]; + (*value_lengths)[widx]= (*value_lengths)[i]; + (*values)[widx]= (*values)[i]; + (*names)[i]= NULL; + (*value_lengths)[i]= 0; + (*values)[i]= NULL; + } + widx++; } - widx++; } + *num_attrs= widx; } - *num_attrs= widx; } ret= 1; ex:; @@ -9361,3 +9384,111 @@ ex:; return(ret); } + +int Xorriso_get_attr_value(struct XorrisO *xorriso, void *in_node, char *path, + char *name, size_t *value_length, char **value, int flag) +{ + int ret; + size_t num_attrs= 0, *value_lengths= NULL, i; + char **names = NULL, **values= NULL; + + *value= NULL; + *value_length= 0; + ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, + &value_lengths, &values, 8); + if(ret <= 0) + goto ex; + + for(i= 0; i < num_attrs; i++) { + if(strcmp(name, names[i]) != 0) + continue; + *value= calloc(value_lengths[i] + 1, 1); + if(*value == NULL) + {ret= -1; goto ex;} + memcpy(*value, values[i], value_lengths[i]); + (*value)[value_lengths[i]]= 0; + *value_length= value_lengths[i]; + ret= 1; goto ex; + } + ret= 0; +ex: + Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, + &value_lengths, &values, 1 << 15); + return(ret); +} + + +/* + @param flag bit0= use parameters dev,ino rather than disk_path + bit1= compare attribute rather than setting it + return: 0=dev,ino match, 1=mismatch, 2=no node attribute + -1=error + bit5= if not bit0: + transfer dev,inode from eventual link target +*/ +int Xorriso_record_dev_inode(struct XorrisO *xorriso, char *disk_path, + dev_t dev, ino_t ino, + void *in_node, char *iso_path, int flag) +{ + size_t l, di_l= 0; + int i, ret; + dev_t hdev; + ino_t hino; + char buf[66], *bufpt, *wpt, *di= NULL; + static char *name= "isofs.di"; + struct stat stbuf; + + if(!(flag & 1)) { + if(flag & 32) { + if(stat(disk_path, &stbuf) == -1) + return(-1); + } else { + if(lstat(disk_path, &stbuf) == -1) + return(-1); + } + dev= stbuf.st_dev; + ino= stbuf.st_ino; + } + + wpt= buf; + hdev= dev; + for(i= 0; hdev != 0; i++) + hdev= hdev >> 8; + l= i; + *(wpt++)= l; + for(i= 0; i < l; i++) + *(wpt++)= dev >> (8 * (l - i - 1)); + hino= ino; + for(i= 0; hino != 0; i++) + hino= hino >> 8; + l= i; + *(wpt++)= l; + for(i= 0; i < l; i++) + *(wpt++)= ino >> (8 * (l - i - 1)); + l= wpt - buf; + bufpt= buf; + + if(flag & 2) { + /* Compare node attribute with bufpt,l */ + ret= Xorriso_get_attr_value(xorriso, in_node, iso_path, + "isofs.di", &di_l, &di, 0); + if(ret < 0) + goto ex; + if(ret == 0) + {ret= 2; goto ex;} + if(l != di_l) + {ret= 1; goto ex;} + for(i= 0; i < l; i++) + if(di[i] != buf[i]) + {ret= 1; goto ex;} + ret= 0; + } else { + ret= Xorriso_setfattr(xorriso, in_node, iso_path, + (size_t) 1, &name, &l, &bufpt, 2 | 8); + } +ex:; + if(di != NULL) + free(di); + return(ret); +} + diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 700b0df3..4fb2bec1 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -424,6 +424,9 @@ int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path, size_t num_attrs, char **names, size_t *value_lengths, char **values, int flag); +int Xorriso_record_dev_inode(struct XorrisO *xorriso, char *disk_path, + dev_t dev, ino_t ino, + void *in_node, char *iso_path, int flag); int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path, char **text, int flag);