New option -disk_dev_ino

This commit is contained in:
Thomas Schmitt 2009-02-17 18:42:41 +00:00
parent 1251c6e135
commit e69f4e1234
7 changed files with 298 additions and 74 deletions

View File

@ -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

View File

@ -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; i<split_count; i++) {
@ -10352,7 +10393,7 @@ delete:;
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 {
@ -10363,8 +10404,9 @@ delete:;
}
sprintf(xorriso->info_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);

View File

@ -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);

View File

@ -120,6 +120,13 @@ Can perform multi-session tasks as emulation of mkisofs and cdrecord.
<LI>
Can restore single files and whole trees from ISO image to disk filesystem.
</LI>
<!--
<LI>
Can record and restore ACL of disk files.
</LI>
-->
<LI>
Can issue commands to mount older sessions on Linux or FreeBSD.
</LI>
@ -488,6 +495,8 @@ Enhancements towards previous stable version xorriso-0.3.0.pl00:
</LI>
<LI>New -find tests -has_xattr, -has_aaip, new -find actions getfattr, setfattr
</LI>
<LI>New option -disk_dev_ino can substantially accelerate incremental backups
</LI>
<!--
<LI>- none yet -</LI>
-->

View File

@ -1 +1 @@
#define Xorriso_timestamP "2009.02.16.082645"
#define Xorriso_timestamP "2009.02.17.184231"

View File

@ -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);
}

View File

@ -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);