diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 1519dd4a..c457758f 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -53,14 +53,14 @@ Updates ISO subtrees incrementally to match given disk subtrees. Writes result either as completely new image or as add-on session to optical media or filesystem objects. .br -Can record and restore ACL of disk files. -.br 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. +.br Can issue commands to mount older sessions on Linux or FreeBSD. .br Can check media for damages and copy readable blocks to disk. @@ -386,7 +386,8 @@ The MBR of a follow-up session can get in effect only on overwriteable media. are an advanced way of controlling access permissions to file objects. Neither ISO 9660 nor Rock Ridge specify a way to record ACLs. So libisofs has introduced a standard conformant extension named AAIP for that purpose. -It uses this extension if enabled by option -acl. +It uses this extension if enabled by option +.B -acl. .br AAIP enhanced images are supposed to be mountable normally, but one cannot expect that the mounted filesystem will show and respect the eventual ACLs. @@ -403,9 +404,10 @@ eventually removing the ACL from a file. are pairs of name and value which can be attached to file objects. AAIP is able to represent them and xorriso allows to record and restore pairs which have names out of the user namespace. I.e. those which begin with "user.", -like "user.x" or "user.whatever". Value can be any string which does -not exceed the size of 4095 characters. xattr processing happens only if -it is enabled by option -xattr. +like "user.x" or "user.whatever". Name has to be a 0 terminated string. +Value may be any array of bytes which does not exceed the size of 4095 bytes. +xattr processing happens only if it is enabled by option +.B -xattr. .br As with ACL, currently only xorriso is able to retrieve xattr from AAIP enhanced images and to restore them to xattr capable file systems. @@ -656,15 +658,14 @@ will be copied to -in_charset. Enable or disable processing of ACLs. If enabled, then xorriso will obtain ACLs from disk file objects, store ACLs in the ISO image using the libisofs specific AAIP format, -load AAIP data from ISO images, and restore ACLs to disk files when -extracting them from ISO images. See also options -getfacl, -setfacl. +load AAIP data from ISO images, test ACL during file comparison, +and restore ACLs to disk files when extracting them from ISO images. +See also options -getfacl, -setfacl. .TP \fB\-xattr\fR "on"|"off" -Enable or disable processing of XFS style Extended Attributes. These are -pairs of name and value. The names are 0-terminated strings. Values can -be arbitrary binary data. -If enabled, then xorriso will import and export xattr similar to ACL. -See also options -getfattr, -setfattr. +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\-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 @@ -1021,7 +1022,8 @@ Only names from the user namespace are allowed. I.e. a name has to begin with "user.", like "user.x" or "user.whatever". .br Values and names undergo the normal input processing of xorriso. -See also option -backslash_codes. Byte value 0 cannot be expressed. +See also option -backslash_codes. Other than with option -setfattr_list, +the byte value 0 cannot be expressed via -setfattr. .TP \fB\-setfattr_r\fR [-]name value iso_rr_path [***] Like -setfattr but affecting all files below eventual directories. @@ -1041,11 +1043,12 @@ pending iso_rr_path. Other input lines must have the form .br name="value" .br -Name should be of the form user.xyz with only printable characters in -xyz. The separator "=" is not allowed in names. Value may contain any kind -of bytes. It must be in quotes. Trailing whitespace after the end quote will -be ignored. Non-printables bytes and quotes must be represented as \\XYZ by -their octal ASCII code XYZ. Use code \\000 for 0-bytes. +Name must be from user namespace. I.e. user.xyz where xyz should consist of +printable characters only. The separator "=" is not allowed in names. +Value may contain any kind of bytes. It must be in quotes. Trailing +whitespace after the end quote will be ignored. Non-printables bytes and quotes +must be represented as \\XYZ by their octal ASCII code XYZ. +Use code \\000 for 0-bytes. .TP \fB\-alter_date\fR type timestring iso_rr_path [***] Alter the date entries of a file in the ISO image. type is @@ -2152,8 +2155,8 @@ Like -gefacl but listing recursively the whole file trees underneath eventual directories. .TP \fB\-getfattr\fR iso_rr_pattern [***] -Print the XFS style Extended Attributes of the given files in the ISO image. -If ia file has no such xattr then noting is printed for it. +Print the xattr of the given files in the ISO image. +If a file has no such xattr then noting is printed for it. .TP \fB\-getfattr_r\fR iso_rr_pattern [***] Like -gefattr but listing recursively the whole file trees underneath eventual diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index a2abfd4a..16f2dc66 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -1013,6 +1013,132 @@ int Sort_argv(int argc, char **argv, int flag) } +static int Text_to_argv(char *text, int *argc, char ***argv, int flag) +{ + char *npt, *cpt; + int pass; + + *argv= NULL; + *argc= 0; + for(pass= 0; pass < 2; pass++) { + if(pass) { + if(*argc == 0) + return(1); + (*argv)= calloc(*argc, sizeof(char *)); + if(*argv == NULL) { + *argc= 0; + return(-1); + } + *argc= 0; + } + for(npt= cpt= text; npt != NULL; cpt= npt + 1) { + npt= strchr(cpt, '\n'); + if(pass) { + if(npt != NULL) + *npt= 0; + (*argv)[*argc]= cpt; + } + (*argc)++; + } + } + return(1); +} + + +static int Count_diffs(int argc1, char **argv1, int argc2, char **argv2, + int flag) +{ + int count= 0, i1= 0, i2= 0, cmp, end_corr= 0; + + Sort_argv(argc1, argv1, 0); + Sort_argv(argc2, argv2, 0); + + while(1) { + if(i1 >= argc1) { + count+= argc2 - i2 - end_corr; + break; + } + if(i2 >= argc2) { + count+= argc1 - i1 - end_corr; + break; + } + cmp= strcmp(argv1[i1], argv2[i2]); + if(cmp == 0) { + end_corr= 0; + i1++; + i2++; + } else if(cmp > 0) { + count++; + end_corr= 1; + i2++; + if(i2 < argc2 && i1 < argc1 - 1) + if(strcmp(argv1[i1 + 1], argv2[i2]) == 0) { + i1++; + end_corr= 0; + } + } else { + count++; + end_corr= 1; + i1++; + if(i1 < argc1 && i2 < argc2 - 1) + if(strcmp(argv2[i2 + 1], argv1[i1]) == 0) { + i2++; + end_corr= 0; + } + } + } + return(count); +} + + +/* + @flag bit0= do not initialize *diff_count + @return <0 error , 0 = mismatch , 1 = match +*/ +static int Compare_text_lines(char *text1, char *text2, int *diff_count, + int flag) +{ + int ret, argc1= 0, argc2= 0; + char **argv1= NULL, **argv2= NULL, *copy1= NULL, *copy2= NULL; + + if(!(flag & 1)) + *diff_count= 0; + if(text1 == NULL && text2 == NULL) + return(1); + if(text1 != NULL) { + copy1= strdup(text1); + if(copy1 == NULL) + {ret= -1; goto ex;} + ret= Text_to_argv(copy1, &argc1, &argv1, 0); + if(ret <= 0) + {ret= -1; goto ex;} + } + if(text2 != NULL) { + copy2= strdup(text2); + if(copy2 == NULL) + {ret= -1; goto ex;} + ret= Text_to_argv(copy2, &argc2, &argv2, 0); + if(ret <= 0) + {ret= -1; goto ex;} + } + ret= Count_diffs(argc1, argv1, argc2, argv2, 1); + if(ret < 0) + goto ex; + *diff_count+= ret; + ret= (*diff_count == 0); +ex:; + if(argv1 != NULL) + free(argv1); + if(argv2 != NULL) + free(argv2); + if(copy1 != NULL) + free(copy1); + if(copy2 != NULL) + free(copy2); + return ret; +} + + /** Convert a text into a number of type double and multiply it by unit code [kmgtpe] (2^10 to 2^60) or [s] (2048). (Also accepts capital letters.) @param text Input like "42", "2k", "3.14m" or "-1g" @@ -6570,6 +6696,9 @@ cannot_address:; bit16= symbolic link on disk pointing to dir, dir in iso bit17= file chunks detected and compared bit18= incomplete chunk collection encountered + bit19= ACL differs (this condition sets also bit2) + bit20= xattr differ + >>> bit21= mismatch of recorded dev,inode @param flag bit0= compare atime bit1= compare ctime bit2= check only existence of both file objects @@ -6586,10 +6715,12 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, int *result, int flag) { struct stat s1, s2, stbuf; - int ret, missing= 0, is_split= 0, i, was_error= 0; + int ret, missing= 0, is_split= 0, i, was_error= 0, diff_count= 0; char *respt; char a[5*SfileadrL], sfe[5*SfileadrL]; char ttx1[40], ttx2[40]; + char *a1_acl= NULL, *a2_acl= NULL, *d1_acl= NULL, *d2_acl= NULL; + char *attrlist1= NULL, *attrlist2= NULL; struct SplitparT *split_parts= NULL; int split_count= 0; @@ -6677,6 +6808,7 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, Xorriso_result(xorriso,0); (*result)|= 4; } + if((s1.st_mode&S_IFMT)!=(s2.st_mode&S_IFMT)) { sprintf(respt, "%s type : %s <> %s\n", a, Ftypetxt(s1.st_mode, 0), Ftypetxt(s2.st_mode, 0)); @@ -6692,6 +6824,60 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, } } } + + /* ACL */ + if(xorriso->do_aaip & 3) { + Xorriso_local_getfacl(xorriso, disk_adr, &a1_acl, + 16 | ((flag & (1 << 28)) >> 23)); + if(S_ISDIR(s1.st_mode)) + Xorriso_local_getfacl(xorriso, disk_adr, &d1_acl, 1); + ret= Xorriso_getfacl(xorriso, NULL, iso_adr, &a2_acl, 1 | 4 | 16); + if(ret < 0) + goto ex; + if(S_ISDIR(s1.st_mode)) { + ret= Xorriso_getfacl(xorriso, NULL, iso_adr, &d2_acl, 1 | 8); + if(ret < 0) + goto ex; + } + ret= Compare_text_lines(a1_acl, a2_acl, &diff_count, 0); + if(ret < 0) + goto ex; + if(ret == 0) + (*result)|= 4 | (1 << 19); + ret= Compare_text_lines(d1_acl, d2_acl, &diff_count, 1); + if(ret < 0) + goto ex; + if(ret == 0) + (*result)|= 4 | (1 << 19); + if((*result) & (1 << 19)) { + sprintf(respt, "%s ACL : %d difference%s\n", + a, diff_count, diff_count == 1 ? "" : "s"); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + } + } + + /* xattr */ + if(xorriso->do_aaip & 12) { + ret= Xorriso_getfattr(xorriso, NULL, disk_adr, &attrlist1, + 1 | 2 | ((flag & (1 << 28)) >> 23)); + if(ret < 0) + goto ex; + ret= Xorriso_getfattr(xorriso, NULL, iso_adr, &attrlist2, 1); + if(ret < 0) + goto ex; + ret= Compare_text_lines(attrlist1, attrlist2, &diff_count, 0); + if(ret < 0) + goto ex; + if(ret == 0) { + (*result)|= (1 << 20); + sprintf(respt, "%s xattr : %d difference%s\n", + a, diff_count, diff_count == 1 ? "" : "s"); + if(!(flag&(1<<31))) + Xorriso_result(xorriso,0); + } + } + if(s1.st_uid != s2.st_uid) { sprintf(respt, "%s st_uid : %d <> %d\n", a, s1.st_uid, s2.st_uid); if(!(flag&(1<<31))) @@ -6754,6 +6940,11 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, (*result)|= 1024; } } + + + /* >>> dev,inode comparison. Eventually skip content comparison */ + + if(S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)) { /* Content */ if(is_split) { @@ -6801,6 +6992,12 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, ex:; if(split_parts!=NULL) Splitparts_destroy(&split_parts, split_count, 0); + Xorriso_local_getfacl(xorriso, disk_adr, &a1_acl, 1 << 15); + Xorriso_local_getfacl(xorriso, disk_adr, &d1_acl, 1 << 15); + if(a2_acl != NULL) + free(a2_acl); + if(d2_acl != NULL) + free(d2_acl); return(ret); } @@ -10166,8 +10363,8 @@ delete:; } sprintf(xorriso->info_text, "Added/overwrote "); - } else if(compare_result&(4|16|32|256|512|1024)) { - /* access permissions, user id, group id, mtime, atime, ctime */ + } 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 */ if(is_split) { ret= Xorriso_identify_split(xorriso, iso_rr_path, NULL, @@ -13539,7 +13736,7 @@ int Xorriso_option_getfacli(struct XorrisO *xorriso, Findjob_destroy(&job, 0); } else { if(flag & 2) - ret= Xorriso_getfattr(xorriso, NULL, optv[i], 0); + ret= Xorriso_getfattr(xorriso, NULL, optv[i], NULL, 0); else ret= Xorriso_getfacl(xorriso, NULL, optv[i], NULL, 0); } diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 27a5cb2a..a53882e6 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.02.14.133013" +#define Xorriso_timestamP "2009.02.16.082645" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index d4e0bd64..70f1ac71 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -6506,7 +6506,7 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, if(target == NULL || target[0] || text_2 == NULL || text_2[0]) ret= Xorriso_setfacl(xorriso, (void *) node, show_path, target, text_2,0); } else if(action == 26) { - ret= Xorriso_getfattr(xorriso, (void *) node, show_path, 0); + ret= Xorriso_getfattr(xorriso, (void *) node, show_path, NULL, 0); } else if(action == 27) { ret= Xorriso_path_setfattr(xorriso, (void *) node, show_path, target, strlen(text_2), text_2, 0); @@ -6581,7 +6581,7 @@ int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, } Findjob_get_xattr_filter(job, &a_filter, 0); if(a_filter) { - ret = Xorriso_getfattr(xorriso, (void *) node, "", 2); + ret = Xorriso_getfattr(xorriso, (void *) node, "", NULL, 64); if(ret < 0) { Xorriso_process_msg_queues(xorriso, 0); goto ex; @@ -8841,6 +8841,11 @@ int Xorriso_getfname(struct XorrisO *xorriso, char *path, int flag) @param flag bit0= do not report to result but only retrieve ACL text bit1= check for existence of true ACL (not fabricated), do not allocate and set acl_text but return 1 or 2 + bit2-3: what ALC to retrieve: + 0= "access" and "default", mark "default:" + 1= "access" only + 2= "default" only, do not mark "default:" + bit4= get "access" ACL only if not trivial @return 2 ok, no ACL available, eventual *acl_text will be NULL 1 ok, ACL available, eventual *acl_text stems from malloc() <=0 error @@ -8848,7 +8853,7 @@ int Xorriso_getfname(struct XorrisO *xorriso, char *path, int flag) int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path, char **acl_text, int flag) { - int ret, d_ret, result_len= 0, pass; + int ret, d_ret, result_len= 0, pass, what; IsoNode *node; char *text= NULL, *d_text= NULL, *cpt, *npt; uid_t uid; @@ -8856,6 +8861,10 @@ int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path, struct passwd *pwd; struct group *grp; + what= (flag >> 2) & 3; + if(acl_text != NULL) + *acl_text= NULL; + node= (IsoNode *) in_node; if(node == NULL) { ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); @@ -8864,7 +8873,7 @@ int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path, } #ifdef Xorriso_with_aaiP - ret= iso_node_get_acl_text(node, &text, &d_text, 0); + ret= iso_node_get_acl_text(node, &text, &d_text, flag & 16); d_ret= (d_text != NULL); #else ret= d_ret= 0; @@ -8927,33 +8936,45 @@ int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path, ret= -1; goto ex; } } - for(npt= cpt= text; npt != NULL; cpt= npt + 1) { - npt= strchr(cpt, '\n'); - if(npt != NULL) - *npt= 0; - if(*cpt == 0) { - if(d_text != NULL || pass) - continue; - } else - result_len+= strlen(cpt) + 1; - if(pass) { - sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt); - } else if(!(flag & 1)) { - Sfile_str(xorriso->result_line, cpt, 0); - strcat(xorriso->result_line, "\n"); - Xorriso_result(xorriso, 0); + if(text != NULL && what <= 1) { + for(npt= cpt= text; npt != NULL; cpt= npt + 1) { + npt= strchr(cpt, '\n'); + if(npt != NULL) + *npt= 0; + if(*cpt == 0) { + if(d_text != NULL || pass) { + if(npt != NULL) + *npt= '\n'; + continue; + } + } else + result_len+= strlen(cpt) + 1; + if(pass) { + sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt); + } else if(!(flag & 1)) { + Sfile_str(xorriso->result_line, cpt, 0); + strcat(xorriso->result_line, "\n"); + Xorriso_result(xorriso, 0); + } + if(npt != NULL) + *npt= '\n'; } } - if(d_text != NULL) { + if(d_text != NULL && (what == 0 || what == 2)) { for(npt= cpt= d_text; npt != NULL; cpt= npt + 1) { npt= strchr(cpt, '\n'); if(npt != NULL) *npt= 0; if(*cpt != 0) { if(pass) { - sprintf(*acl_text + strlen(*acl_text), "default:%s\n", cpt); + if(what == 0) + sprintf(*acl_text + strlen(*acl_text), "default:%s\n", cpt); + else + sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt); } else { - Sfile_str(xorriso->result_line, "default:", 0); + xorriso->result_line[0]= 0; + if(what == 0) + Sfile_str(xorriso->result_line, "default:", 0); Sfile_str(xorriso->result_line, cpt, 1); result_len+= strlen(cpt) + 9; } @@ -8963,6 +8984,8 @@ int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path, strcat(xorriso->result_line, "\n"); Xorriso_result(xorriso, 0); } + if(npt != NULL) + *npt= '\n'; } } } @@ -9029,78 +9052,91 @@ ex:; return(ret); } + /* - @param flag - bit1= check for existence of non-ACL xattr, + @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, return 0 or 1 */ int Xorriso_getfattr(struct XorrisO *xorriso, void *in_node, char *path, - int flag) + char **attr_text, int flag) { - int ret= 1, i, bsl_mem; + int ret= 1, i, bsl_mem, result_len= 0, pass; size_t num_attrs= 0, *value_lengths= NULL; char **names= NULL, **values= NULL, *bsl; - IsoNode *node; - node= (IsoNode *) in_node; - if(node == NULL) { - ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); - if(ret<=0) - goto ex; - } - -#ifdef Xorriso_with_aaiP - ret= iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, - &values, 0); -#else - ret= 1; -#endif - - if(ret < 0) { - strcpy(xorriso->info_text, "Error with obtaining xattr of "); - Text_shellsafe(path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - if(flag & 2) { + if(attr_text != NULL) + *attr_text= NULL; + ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, + &value_lengths, &values, flag & (2 | 32)); + if(ret <= 0) + goto ex; + if(flag & 64) { ret= (num_attrs > 0); goto ex; } if(num_attrs == 0) {ret= 2; goto ex;} - ret= Xorriso_getfname(xorriso, path, 0); - if(ret <= 0) - goto ex; - - for(i= 0; i < num_attrs; i++) { - if(strlen(names[i]) + value_lengths[i] >= SfileadrL) { - sprintf(xorriso->result_line, "# oversized: name %d , value %d bytes\n", - (int) strlen(names[i]), (int) value_lengths[i]); - } else { - ret= Sfile_bsl_encoder(&bsl, names[i], strlen(names[i]), 8); - if(ret <= 0) - {ret= -1; goto ex;} - strcpy(xorriso->result_line, bsl); - free(bsl); - ret= Sfile_bsl_encoder(&bsl, values[i], value_lengths[i], 8); - if(ret <= 0) - {ret= -1; goto ex;} - sprintf(xorriso->result_line + strlen(xorriso->result_line), - "=\"%s\"\n", bsl); - free(bsl); - } - /* temporarily disable -backslash_codes with result output */ - bsl_mem= xorriso->bsl_interpretation; - xorriso->bsl_interpretation= 0; - Xorriso_result(xorriso, 0); - xorriso->bsl_interpretation= bsl_mem; + if(!(flag & 1)) { + ret= Xorriso_getfname(xorriso, path, 0); + if(ret <= 0) + goto ex; + } + for(pass= 0; pass < 1 + (attr_text != NULL); pass++) { + if(pass) { + *attr_text= calloc(result_len + 1, 1); + if(*attr_text == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + } + for(i= 0; i < num_attrs; i++) { + if(strlen(names[i]) + value_lengths[i] >= SfileadrL) { + sprintf(xorriso->result_line, "# oversized: name %d , value %d bytes\n", + (int) strlen(names[i]), (int) value_lengths[i]); + } else { + ret= Sfile_bsl_encoder(&bsl, names[i], strlen(names[i]), 8); + if(ret <= 0) + {ret= -1; goto ex;} + strcpy(xorriso->result_line, bsl); + free(bsl); + ret= Sfile_bsl_encoder(&bsl, values[i], value_lengths[i], 8); + if(ret <= 0) + {ret= -1; goto ex;} + sprintf(xorriso->result_line + strlen(xorriso->result_line), + "=\"%s\"\n", bsl); + free(bsl); + } + /* temporarily disable -backslash_codes with result output */ + result_len+= strlen(xorriso->result_line); + if(pass) { + strcat(*attr_text, xorriso->result_line); + } else if(!(flag & 1)) { + bsl_mem= xorriso->bsl_interpretation; + xorriso->bsl_interpretation= 0; + Xorriso_result(xorriso, 0); + xorriso->bsl_interpretation= bsl_mem; + } + } + } + if(!(flag & 1)) { + strcpy(xorriso->result_line, "\n"); + Xorriso_result(xorriso, 0); } - strcpy(xorriso->result_line, "\n"); - Xorriso_result(xorriso, 0); ret= 1; ex:; + +#ifndef NIX + Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, + &value_lengths, &values, 1 << 15); +#else /* NIX */ iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values, 1 << 15); /* free memory */ +#endif /* NIX */ + return(ret); } @@ -9177,17 +9213,151 @@ ex:; int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path, char **text, int flag) { - int ret; - #ifdef Xorriso_with_aaiP - ret= iso_local_get_acl_text(disk_path, text, - flag & (1 | 16 | 32 | (1 << 15))); - Xorriso_process_msg_queues(xorriso,0); -#else - ret= 0; -#endif - return(ret); + int ret, skip= 0, colons= 0, countdown= 0; + char *acl= NULL, *cpt, *wpt; + + if(flag & (1 << 15)) { + if(*text != NULL) + free(*text); + *text= NULL; + return(1); + } + *text= NULL; + ret= iso_local_get_acl_text(disk_path, &acl, flag & (1 | 16 | 32)); + Xorriso_process_msg_queues(xorriso,0); + if(ret < 0 || ret == 2) + return(ret); + if(acl == NULL) + return(0); + *text= strdup(acl); + iso_local_get_acl_text(disk_path, &acl, 1 << 15); + if(*text == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + + /* Garbage collection about trailing remarks after 3 permission chars */ + wpt= *text; + for(cpt= *text; *cpt; cpt++) { + if(skip) { + if(*cpt == '\n') + skip= 0; + else + continue; + } + if(*cpt == ':' && !countdown) { + colons++; + if(colons == 2) { + countdown= 4; + colons= 0; + } + } + if(countdown > 0) { + countdown--; + if(countdown == 0) + skip= 1; + } + *wpt= *cpt; + wpt++; + } + *wpt= 0; + + return(1); +#else + + *text= NULL; + return(0); + +#endif /* ! Xorriso_with_aaiP */ } +/* + @param flag + bit1= path is disk_path + bit5= in case of symbolic link on disk: inquire link target + bit15= free memory +*/ +int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, + size_t *num_attrs, char ***names, + size_t **value_lengths, char ***values, int flag) +{ + int ret, i, widx; + IsoNode *node; + + if(flag & (1 << 15)) { +#ifdef Xorriso_with_aaiP + if(flag & 2) { + iso_local_get_attrs(NULL, num_attrs, names, value_lengths, values, + 1 << 15); + } else { + iso_node_get_attrs(NULL, num_attrs, names, value_lengths, values, + 1 << 15); + } +#endif /* Xorriso_with_aaiP */ + return(1); + } + + *num_attrs= 0; + if(flag & 2) { + +#ifdef Xorriso_with_aaiP + ret= iso_local_get_attrs(path, num_attrs, names, value_lengths, values, + flag & 32); + if(ret < 0) { + strcpy(xorriso->info_text, "Error with reading xattr of disk file "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + } +#endif /* Xorriso_with_aaiP */ + ; + + } else { + node= (IsoNode *) in_node; + if(node == NULL) { + ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); + if(ret<=0) + goto ex; + } +#ifdef Xorriso_with_aaiP + ret= iso_node_get_attrs(node, num_attrs, names, value_lengths, values, + 0); + if(ret < 0) { + Xorriso_report_iso_error(xorriso, "", ret, + "Error when obtaining xattr of ISO node", 0, "FAILURE", 1); + goto ex; + } +#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]; + (*names)[i]= NULL; + (*value_lengths)[i]= 0; + (*values)[i]= NULL; + } + widx++; + } + } + *num_attrs= widx; + } + ret= 1; +ex:; + Xorriso_process_msg_queues(xorriso,0); + return(ret); +} + diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 575fea36..700b0df3 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -399,7 +399,7 @@ int Xorriso_getfacl(struct XorrisO *xorriso, void *node, char *path, char **acl_text, int flag); int Xorriso_getfattr(struct XorrisO *xorriso, void *in_node, char *path, - int flag); + char **attr_text, int flag); /* Calls iso_image_set_ignore_aclea() according to xorriso->do_aaip */ int Xorriso_set_ignore_aclea(struct XorrisO *xorriso, int flag); @@ -416,10 +416,15 @@ int Xorriso_set_ignore_aclea(struct XorrisO *xorriso, int flag); int Xorriso_setfacl(struct XorrisO *xorriso, void *in_node, char *path, char *access_text, char *default_text, int flag); +int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, + size_t *num_attrs, char ***names, + size_t **value_lengths, char ***values, int flag); + 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_local_getfacl(struct XorrisO *xorriso, char *disk_path, char **text, int flag);