diff --git a/libisoburn/trunk/xorriso/xorriso.1 b/libisoburn/trunk/xorriso/xorriso.1 index b5376051..1519dd4a 100644 --- a/libisoburn/trunk/xorriso/xorriso.1 +++ b/libisoburn/trunk/xorriso/xorriso.1 @@ -1004,8 +1004,10 @@ Like -setfacl but affecting all files below eventual directories. Read the output of -getfacl_r or shell command getfacl -R and apply it to the iso_rr_paths as given in lines beginning with "# file:". This will change ownership, group and ACL of the given files. +If disk_path is "-" then lines are read from standard input. Line "@" ends the +list, "@@@" aborts without changing the pending iso_rr_path. .br -Since -getfacl and getfacl strip leading "/" from file paths, the setting of +Since -getfacl and getfacl -R strip leading "/" from file paths, the setting of -cd does always matter. .TP \fB\-setfattr\fR [-]name value iso_rr_path [***] @@ -1017,10 +1019,34 @@ be an empty text. .br 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. .TP \fB\-setfattr_r\fR [-]name value iso_rr_path [***] Like -setfattr but affecting all files below eventual directories. .TP +\fB\-setfattr_list\fR disk_path +Read the output of -getfattr_r or shell command getfattr -Rd and apply it to +the iso_rr_paths as given in lines beginning with "# file:". All previously +existing user space xattr of the given iso_rr_paths will be deleted. +If disk_path is "-" then lines are read from standard input. +.br +Since -getfattr and getfattr -Rd strip leading "/" from file paths, the setting +of -cd does always matter. +.br +Empty input lines and lines which begin by "#" will be ignored +(except "# file:"). Line "@" ends the list, "@@@" aborts without changing the +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. +.TP \fB\-alter_date\fR type timestring iso_rr_path [***] Alter the date entries of a file in the ISO image. type is one of "a", "m", "b" for access time, modification time, diff --git a/libisoburn/trunk/xorriso/xorriso.c b/libisoburn/trunk/xorriso/xorriso.c index a152a660..895cbd6c 100644 --- a/libisoburn/trunk/xorriso/xorriso.c +++ b/libisoburn/trunk/xorriso/xorriso.c @@ -512,6 +512,7 @@ int Sfile_off_t_text(char text[80], off_t num, int flag) The scope of a backslash (0 to 3 characters) is not affected. @param eaten returns the difference in length between input and output @param flag bit0= only determine *eaten, do not convert + bit1= allow to convert \000 to binary 0 */ int Sfile_bsl_interpreter(char *text, int upto, int *eaten, int flag) { @@ -553,7 +554,7 @@ int Sfile_bsl_interpreter(char *text, int upto, int *eaten, int flag) num_text[3]= *(rpt + 2); num_text[4]= 0; sscanf(num_text, "%o", &num); - if(num > 0 && num <= 255) { + if((num > 0 || (flag & 2)) && num <= 255) { rpt+= 2; (*eaten)+= 2; *(wpt++)= num; @@ -663,9 +664,8 @@ int Sfile_bsl_encoder(char **result, char *text, size_t text_len, int flag) dq_open= !(sq_open || dq_open); if(flag & 8) { - if(!(*rpt <= 42 || *rpt == 59 || *rpt == 60 || *rpt == 62 || - *rpt == 63 || *rpt == 92 || *rpt == 94 || *rpt == 96 || - *rpt >= 123)) { + if(!(*rpt <= 42 || (*rpt >= 59 && *rpt <= 63) || + *rpt == 92 || *rpt == 94 || *rpt == 96 || *rpt >= 123)) { *(wpt++)= *rpt; continue; } @@ -10486,8 +10486,11 @@ int Xorriso_afile_fopen(struct XorrisO *xorriso, (mode[0]=='r' && mode[1]=='+') || (mode[0]=='r' && mode[1]=='b' && mode[2]=='+')) fp= stdout; - else + else { + Xorriso_msgs_submit(xorriso, 0, "Ready for data at standard input", 0, + "NOTE", 0); fp= stdin; + } } else if(strncmp(filename,"tcp:",4)==0){ Xorriso_msgs_submit(xorriso, 0, "TCP/IP service isn't implemented yet.", 0, "FAILURE", 0); @@ -11070,6 +11073,87 @@ int Xorriso_path_setfattr(struct XorrisO *xorriso, void *in_node, char *path, } +/* Warning: The text content of lst gets mangled by 0s and unescaping. +*/ +int Xorriso_perform_attr_from_list(struct XorrisO *xorriso, char *path, + struct Xorriso_lsT *lst_start, int flag) +{ + int ret, eaten; + char *valuept, *ept, *line, **names= NULL, **values= NULL; + size_t num_attr= 0, *value_lengths= NULL, v_len; + struct Xorriso_lsT *lst; + + for(lst= lst_start; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) + num_attr++; + if(num_attr == 0) { + ret= Xorriso_setfattr(xorriso, NULL, path, num_attr, NULL, NULL, NULL, 0); + goto ex; + } + + names= calloc(num_attr, sizeof(char *)); + if(names == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + value_lengths= calloc(num_attr, sizeof(size_t)); + if(value_lengths== NULL) { + free(names); + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + values= calloc(num_attr, sizeof(char *)); + if(values== NULL) { + free(names); + free(value_lengths); + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + + num_attr= 0; + for(lst= lst_start; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) { + line= Xorriso_lst_get_text(lst, 0); + ept= strchr(line, '='); + if(ept == NULL) + continue; + /* Split into name and content */; + *ept= 0; + valuept= ept + 1; + + /* Strip quotes from value */ + v_len= strlen(valuept); + if(v_len < 2 || *valuept != '"' || *(valuept + v_len - 1) != '"') + continue; + *valuept= 0; + *(valuept + v_len - 1)= 0; + valuept++; + v_len-= 2; + + /* Unescape backslashes , values eventually with 0-bytes */ + ret= Sfile_bsl_interpreter(line, strlen(line), &eaten, 0); + if(ret <= 0) + continue; + ret= Sfile_bsl_interpreter(valuept, (int) v_len, &eaten, 2); + if(ret <= 0) + continue; + + names[num_attr]= line; + values[num_attr]= valuept; + value_lengths[num_attr]= v_len - eaten; + num_attr++; + } + ret= Xorriso_setfattr(xorriso, NULL, path, num_attr, names, + value_lengths, values, 0); +ex:; + if(names != NULL) + free(names); + if(value_lengths != NULL) + free(value_lengths); + if(values != NULL) + free(values); + return(ret); +} + + /* ---------------------------- Options API ------------------------ */ @@ -13690,6 +13774,9 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " an empty text.", " -setfattr_r [-]name value iso_rr_path [***]", " Like -setfattr but affecting all files below directories.", +" -setfattr_list disk_path", +" Read output of getfattr from file disk_path. Replace the", +" xattr of the iso_rr_path given by line \"# file:\".", " -alter_date type timestring iso_rr_path [***]", " Alter the date entries of a file in the ISO image. type is", " one of \"a\", \"m\", \"b\" for:", @@ -14710,7 +14797,7 @@ int Xorriso_option_not_list(struct XorrisO *xorriso, char *adr, int flag) } ret= 1; ex:; - if(fp!=NULL) + if(fp != NULL && fp != stdin) fclose(fp); Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, 2); if(ret<=0) { @@ -14920,7 +15007,7 @@ ex:; Sfile_make_argv("", "", &argc, &argv, 2); /* release memory */ Xorriso_read_lines(xorriso, fp, &linecount, &linec, &linev, 2); Xorriso_reset_counters(xorriso,0); - if(fp!=NULL) + if(fp != NULL && fp != stdin) fclose(fp); if(ret<=0) { sprintf(xorriso->info_text, @@ -15135,7 +15222,7 @@ ex:; if(flag & 1) Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, 2); - if(fp!=NULL) + if(fp != NULL && fp != stdin) fclose(fp); Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, xorriso->pacifier_total, "", 1); @@ -15546,6 +15633,7 @@ int Xorriso_option_setfacl_listi(struct XorrisO *xorriso, char *path, int flag) if(buf == NULL) goto out_of_mem; wpt= buf; + *wpt= 0; uid[0]= gid[0]= 0; while(1) { @@ -15560,6 +15648,7 @@ int Xorriso_option_setfacl_listi(struct XorrisO *xorriso, char *path, int flag) if(ret<=0) goto ex; wpt= buf; + *wpt= 0; file_path[0]= uid[0]= gid[0]= 0; } /* Unescape line and register as file path */ @@ -15589,6 +15678,14 @@ int Xorriso_option_setfacl_listi(struct XorrisO *xorriso, char *path, int flag) continue; } else if(line[0] == '#' || line[0] == 0) { continue; + } else if(strcmp(line, "@") == 0) { + Xorriso_msgs_submit(xorriso, 0, + "-setfacl_list input ended by '@'", 0, "NOTE", 0); + break; + } else if(strcmp(line, "@@@") == 0) { + Xorriso_msgs_submit(xorriso, 0, + "-setfacl_list aborted by input line '@@@'", 0, "WARNING", 0); + ret= 0; goto ex; } /* Register ACL entry */ @@ -15627,7 +15724,7 @@ int Xorriso_option_setfacl_listi(struct XorrisO *xorriso, char *path, int flag) ex:; if(buf != NULL) free(buf); - if(fp!=NULL) + if(fp != NULL && fp != stdin) fclose(fp); if(ret <= 0) { sprintf(xorriso->info_text, "-setfacl_list "); @@ -15775,6 +15872,141 @@ ex:; } +/* Option -setfattr_list alias -setfattr_listi */ +int Xorriso_option_setfattr_listi(struct XorrisO *xorriso, char *path, + int flag) +{ + int ret, eaten; + size_t linecount= 0, mem_used= 0, num_attr= 0, v_len; + char line[SfileadrL * 4], limit_text[80], *ept, *valuept; + char file_path[SfileadrL]; + FILE *fp= NULL; + struct Xorriso_lsT *lst_curr= NULL, *lst_start= NULL; + + Xorriso_pacifier_reset(xorriso, 0); + if(path[0]==0) { + sprintf(xorriso->info_text, "Empty file name given with -setfattr_list"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 0); + if(ret <= 0) + return(0); + + while(1) { + if(Sfile_fgets_n(line, sizeof(line), fp, 0) == NULL) + break; + linecount++; + if(strncmp(line, "# file: ", 8) ==0) { + if(num_attr > 0 && file_path[0]) { + /* Commit previous list */ + ret= Xorriso_perform_attr_from_list(xorriso, file_path, lst_start, 0); + if(ret<=0) + goto ex; + num_attr= 0; + file_path[0]= 0; + Xorriso_lst_destroy_all(&lst_start, 0); + lst_curr= NULL; + } + /* Unescape line and register as file path */ + Sfile_bsl_interpreter(line + 8, strlen(line + 8), &eaten, 0); + if(strlen(line + 8) >= SfileadrL) { + sprintf(xorriso->info_text, "-setfattr_list: Oversized file path"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + strcpy(file_path, line + 8); + continue; + } else if(line[0] == '#' || line[0] == 0) { + continue; + } else if(strcmp(line, "@") == 0) { + Xorriso_msgs_submit(xorriso, 0, + "-setfattr_list input ended by '@'", 0, "NOTE", 0); + break; + } else if(strcmp(line, "@@@") == 0) { + Xorriso_msgs_submit(xorriso, 0, + "-setfattr_list aborted by input line '@@@'", 0, "WARNING", 0); + ret= 1; goto ex; + } + mem_used+= strlen(line) + 1; + if(mem_used > xorriso->temp_mem_limit) { + Sfile_scale((double) xorriso->temp_mem_limit, limit_text,5,1e4,1); + sprintf(xorriso->info_text, + "-setfattr_list: List entry for a single file exceeds -temp_mem_limit %s", + limit_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + /* Register attr pair */ + + ept= strchr(line, '='); + if(ept == NULL) { + sprintf(xorriso->info_text, "-setfattr_list: "); + Text_shellsafe(path, xorriso->info_text, 1); + sprintf(xorriso->info_text + strlen(xorriso->info_text), + " : Line %.f : No separator '=' found", + (double) linecount); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + continue; + } + valuept= ept + 1; + v_len= strlen(valuept); + for(ept= valuept + v_len - 1; ept > valuept; ept--) + if(isspace(*ept)) + *ept= 0; + else + break; + v_len= strlen(valuept); + if(v_len < 2 || *valuept != '"' || *(valuept + v_len -1) != '"') { + sprintf(xorriso->info_text, "-setfattr_list: "); + Text_shellsafe(path, xorriso->info_text, 1); + sprintf(xorriso->info_text + strlen(xorriso->info_text), + " : Line %.f : Value not enclosed in quotes", + (double) linecount); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + + continue; + } + + ret= Xorriso_lst_new(&lst_curr, line, lst_curr, 0); + if(ret <= 0) + goto out_of_mem; + if(lst_start == NULL) + lst_start= lst_curr; + num_attr++; + } + + if(file_path[0]) { + /* Commit last list */ + ret= Xorriso_perform_attr_from_list(xorriso, file_path, lst_start, 0); + if(ret<=0) + goto ex; + } else { + sprintf(xorriso->info_text, "-setfattr_list: Unexpected end of file "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + ret= 1; +ex:; + if(fp != NULL && fp != stdin) + fclose(fp); + Xorriso_lst_destroy_all(&lst_start, 0); + if(ret <= 0) { + sprintf(xorriso->info_text, "-setfattr_list "); + Text_shellsafe(path, xorriso->info_text, 1); + sprintf(xorriso->info_text + strlen(xorriso->info_text), + " aborted in line %.f\n", (double) linecount); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + return(ret); +out_of_mem:; + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; + goto ex; +} + + /* Option -speed */ int Xorriso_option_speed(struct XorrisO *xorriso, char *speed, int flag) { @@ -16311,7 +16543,8 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, "lsx","lslx","lsdx","lsdlx","map_l","mv","mvi","mkdir","mkdiri", "not_paths","rm","rmi","rm_r","rm_ri","rmdir","rmdiri","update_l", "setfacl","setfacli","setfacl_list","setfacl_listi", - "setfacl_r","setfacl_ri","setfattr","setfattri","setfattr_r","setfattr_ri", + "setfacl_r","setfacl_ri","setfattr","setfattri", + "setfattr_list","setfattr_listi","setfattr_r","setfattr_ri", "" }; @@ -16959,6 +17192,10 @@ next_command:; (*idx)+= 2; ret= Xorriso_option_setfattri(xorriso, arg1, arg2, argc, argv, idx, 0); + } else if(strcmp(cmd,"setfattr_list")==0 || strcmp(cmd,"setfattr_listi")==0) { + (*idx)+= 1; + ret= Xorriso_option_setfattr_listi(xorriso, arg1, 0); + } else if(strcmp(cmd,"setfattr_r")==0 || strcmp(cmd,"setfattr_ri")==0) { (*idx)+= 2; ret= Xorriso_option_setfattri(xorriso, arg1, arg2, argc, argv, idx, 1); diff --git a/libisoburn/trunk/xorriso/xorriso.h b/libisoburn/trunk/xorriso/xorriso.h index b6d7e305..cf5dad80 100644 --- a/libisoburn/trunk/xorriso/xorriso.h +++ b/libisoburn/trunk/xorriso/xorriso.h @@ -686,6 +686,10 @@ int Xorriso_option_setfacli(struct XorrisO *xorriso, char *acl_text, int Xorriso_option_setfattri(struct XorrisO *xorriso, char *name, char *value, int argc, char **argv, int *idx, int flag); +/* Option -setfattr_list alias -setfattr_listi */ +int Xorriso_option_setfattr_listi(struct XorrisO *xorriso, char *path, + int flag); + /* Option -speed */ int Xorriso_option_speed(struct XorrisO *xorriso, char *speed, int flag); diff --git a/libisoburn/trunk/xorriso/xorriso_eng.html b/libisoburn/trunk/xorriso/xorriso_eng.html index 30df3235..a6d35b32 100644 --- a/libisoburn/trunk/xorriso/xorriso_eng.html +++ b/libisoburn/trunk/xorriso/xorriso_eng.html @@ -50,6 +50,7 @@ and to MMC-5 for DVD or BD).