diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 2c8d8fec..efc74b4a 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 "Mar 21, 2009" +.TH XORRISO 1 "Apr 02, 2009" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -1082,6 +1082,74 @@ 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\-external_filter\fR name option[:option] program_path [arguments] -- +Register a content filter by associating a name with a program path, +program arguments, and some behavioral options. Once registered it can be +applied to multiple data files in the ISO image, regardless whether their +content resides in the loaded ISO image or in the local filesystem. +External filter processes may produce synthetic file content by reading the +original content from stdin and writing to stdout whatever they want. +They must deliver the same output on the same input in repeated runs. +.br +Options are: +.br + "suffix=..." sets a file name suffix. If it is not empty then it will be +appended to the file name or removed from it. +.br + "remove_suffix" will remove an eventual file name suffix +rather than appending it. +.br + "if_nonempty" will leave 0-sized files unfiltered. +.br + "if_reduction" will try filtering and revoke it if the content size does not +shrink. +.br + "if_block_reduction" will revoke if the number of 2 kB blocks does not shrink. +.br + "used=..." is ignored. Command -status shows it with the number of +files which currently have the filter applied. +.br +Examples: +.br + -external_filter gzip suffix=.gz:if_block_reduction \\ +.br + /usr/bin/gzip -- +.br + -external_filter gunzip suffix=.gz:remove_suffix:if_nonempty \\ +.br + /usr/bin/gunzip -- +.TP +\fB\-unregister_filter\fR name +Remove an -external_filter registration. This is only possible if the filter +is not applied to any file in the ISO image. +.TP +\fB\-set_filter\fR name iso_rr_path [***] +Apply an -external_filter to the given data files in the ISO image. +If the filter suffix is not empty , then it will be appended to the file name. +Renaming only happens if the filter really gets attached and is not revoked by +its options. Files which already bear the suffix will not get filtered. +If the filter has option "remove_suffix", then the filter will only be +applied if the suffix is present and can be removed. +Name collisons caused by suffix change will prevent filtering. +.br +This command will immediately run the filter once for each file +in order to determine the output size. +Content reading operations like -extract , -compare and image generation will +perform further filter runs and deliver filtered content. +.br +At image generation time the filter output must still be the same as the +output from the first run. Filtering for image generation does not happen +with files from the loaded ISO image if the write method of growing is in +effect (i.e -indev and -outdev are identical). +.br +The reserved filter name "--remove-all-filters" revokes filtering. A suffix +may be appended after a "+" or "-". "-" will restrict the filter removal +to files with that suffix and remove it from the file name. "+" will only +process files without that suffix and add it to the name. +.TP +\fB\-set_filter_r\fR name isuffix iso_rr_path [***] +Like -set_filter but affecting all data files below eventual directories. +.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, @@ -1233,7 +1301,7 @@ path of the file. .br E.g.: .br - -find / -damaged -exec report_damage + -find / -damaged -exec report_damage -- .br "report_lba" prints files which are associated to image data blocks. It tells the logical block address, the block number, the byte size, @@ -1243,7 +1311,7 @@ different extent number in column "xt". .br E.g.: .br - -find / -lba_range 302000 50000 -exec report_lba + -find / -lba_range 302000 50000 -exec report_lba -- .br "getfacl" prints access permissions in ACL text form to the result channel. .br @@ -1256,22 +1324,29 @@ ACL is given in text form as defined with option -setfacl. .br E.g.: .br - -find /workgroup -exec setfacl u:lisa:rw,u::rw,g::r,o::-,m::rw + -find /work -exec setfacl u:lisa:rw,u::rw,g::r,o::-,m::rw -- .br "getfattr" prints eventual xattr name-value pairs to the result channel. .br E.g.: .br - -find / -has_xattr -exec getfattr + -find / -has_xattr -exec getfattr -- .br "setfattr" sets or deletes xattr name value pairs. .br E.g.: .br - -find / -has_xattr -exec setfattr --remove-all '' + -find / -has_xattr -exec setfattr --remove-all '' -- +.br +"set_filter" applies or removes filters (see -external_filter). +.br +E.g.: +.br + -find / -type f -exec set_filter gzip -- .br "find" performs another run of -find on the matching file address. It accepts the same params as -find, except iso_rr_path. +.br E.g.: .br -find / -name '???' -type d -exec find -name '[abc]*' -exec chmod a-w,a+r -- diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 132a6639..156da39b 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -2202,6 +2202,7 @@ return: @param flag Bitfield for control purposes bit0= insert before link rather than after it bit1= do not copy data (e.g. because *data is invalid) + bit2= attach data directly by pointer rather than by copying */ int Xorriso_lst_new_binary(struct Xorriso_lsT **lstring, char *data, int data_len, struct Xorriso_lsT *link, int flag) @@ -2215,13 +2216,17 @@ int Xorriso_lst_new_binary(struct Xorriso_lsT **lstring, char *data, s->text= NULL; s->next= s->prev= NULL; - if(data_len<=0) - {ret= -1; goto failed;} - s->text= Smem_malloC(data_len); - if(s->text==NULL) - {ret= -1; goto failed;} - if(!(flag&2)) - memcpy(s->text,data,data_len); + if(flag & 4) { + s->text= data; + } else { + if(data_len<=0) + {ret= -1; goto failed;} + s->text= Smem_malloC(data_len); + if(s->text==NULL) + {ret= -1; goto failed;} + if(!(flag&2)) + memcpy(s->text,data,data_len); + } if(link==NULL) { ; @@ -2249,14 +2254,14 @@ failed:; /* @param flag Bitfield for control purposes - bit0= insert before link rather than after it + see */ int Xorriso_lst_new(struct Xorriso_lsT **lstring, char *text, struct Xorriso_lsT *link, int flag) { int ret; - ret= Xorriso_lst_new_binary(lstring,text,strlen(text)+1,link,flag&1); + ret= Xorriso_lst_new_binary(lstring,text,strlen(text)+1,link,flag); return(ret); } @@ -2310,9 +2315,9 @@ int Xorriso_lst_append_binary(struct Xorriso_lsT **entry, if(*entry!=NULL) for(target= *entry; target->next!=NULL; target= target->next); - if(Xorriso_lst_new_binary(&newby, data, data_len, target, 0)<=0) + if(Xorriso_lst_new_binary(&newby, data, data_len, target, flag & ~1)<=0) return(-1); - if(*entry==NULL) + if(*entry==NULL || (flag & 1)) *entry= newby; return(1); } @@ -2336,6 +2341,13 @@ char *Xorriso_lst_get_text(struct Xorriso_lsT *entry, int flag) } +int Xorriso_lst_detach_text(struct Xorriso_lsT *entry, int flag) +{ + entry->text= NULL; + return(1); +} + + /* ------------------------------ LinkiteM -------------------------------- */ struct LinkiteM { @@ -2481,7 +2493,7 @@ struct FindjoB { 25= setfacl access_acl default_acl 26= getfattr 27= setfattr - 28= set_filter name suffix + 28= set_filter name */ int action; @@ -4078,6 +4090,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->do_global_mode= 0; m->global_dir_mode= 0555; m->global_file_mode= 0444; + m->filters= NULL; m->do_overwrite= 2; m->do_reassure= 0; m->drive_blacklist= NULL; @@ -4271,6 +4284,7 @@ int Xorriso_destroy(struct XorrisO **xorriso, int flag) free(m->out_charset); Xorriso_destroy_re(m,0); Exclusions_destroy(&(m->disk_exclusions), 0); + Xorriso_destroy_all_extf(m, 0); Xorriso_lst_destroy_all(&(m->drive_blacklist), 0); Xorriso_lst_destroy_all(&(m->drive_greylist), 0); Xorriso_lst_destroy_all(&(m->drive_whitelist), 0); @@ -6190,6 +6204,8 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) Xorriso_status_result(xorriso,filter,fp,flag&2); } + Xorriso_status_extf(xorriso, filter, fp, flag & 2); + is_default= !xorriso->allow_graft_points; sprintf(line,"-pathspecs %s\n", xorriso->allow_graft_points ? "on" : "off"); if(!(is_default && no_defaults)) @@ -12757,6 +12773,14 @@ report_outcome:; } +/* Option -compliance */ +int Xorriso_option_compliance(struct XorrisO *xorriso, char *mode, + int flag) +{ + return(Xorriso_relax_compliance(xorriso, mode, 0)); +} + + /* Option -cpr alias -cpri */ int Xorriso_option_cpri(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) @@ -13327,6 +13351,29 @@ unknown_behavior:; } +/* Option -external_filter */ +int Xorriso_option_external_filter(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag) +{ + int ret, start_idx, end_idx; + + start_idx= *idx; + end_idx= Xorriso_end_idx(xorriso, argc, argv, start_idx, 1); + (*idx)= end_idx; + if(end_idx - start_idx < 3) { + sprintf(xorriso->info_text, + "-external_filter : Not enough arguments given. Needed: name options path %s", + xorriso->list_delimiter); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_external_filter(xorriso, argv[start_idx], + argv[start_idx + 1], argv[start_idx + 2], + end_idx - start_idx - 3, argv + start_idx + 3, 0); + return(ret); +} + + /* Options -extract , -extract_single */ /* @param flag bit0=do not report the restored item bit1=do not reset pacifier, no final pacifier message @@ -13703,10 +13750,10 @@ not_enough_arguments:; goto ex; Findjob_set_action_text_2(job, 27, argv[i - 1], argv[i], 0); } else if(strcmp(cpt, "set_filter")==0) { - if(i+2>=end_idx) + if(i + 1 >= end_idx) goto not_enough_arguments; - i+= 2; - Findjob_set_action_text_2(job, 28, argv[i - 1], argv[i], 0); + i+= 1; + Findjob_set_action_target(job, 28, argv[i], 0); if(!(flag&2)) { Xorriso_pacifier_reset(xorriso, 0); mem_lut= xorriso->last_update_time; @@ -14144,7 +14191,7 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " Action may be one of: echo, chown, chown_r, chgrp, chgrp_r", " chmod, chmod_r, alter_date, alter_date_r, lsdl, compare,", " rm, rm_r, compare, update, report_damage, report_lba,", -" getfacl, setfacl, getfattr, setfattr, find.", +" getfacl, setfacl, getfattr, setfattr, set_filter, find.", " params are their arguments except iso_rr_path.", " echo, lsdl, rm, rm_r, report_damage have no params at all.", " -mkdir iso_rr_path [...]", @@ -14175,8 +14222,21 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " If \"on\" then ask the user for \"y\" or \"n\" with any", " file before deleting or overwriting it in the ISO image.", "", -"Write-to-media options:", +"Filter options:", +"External filter processes may produce synthetic file content by reading the", +"original content from stdin and writing to stdout whatever they want.", +" -external_filter name option[:option] program_path [arguments] --", +" Define an external filter. Options are: suffix=...: ", +" remove_suffix:if_nonempty:if_reduction:if_block_reduction.", +" -unregister_filter name", +" Undefine an external filter.", +" -set_filter name iso_rr_path [***]", +" Apply a defined filter to the given data files.", +" Special name \"--remove-all-filters\" revokes filtering.", +" -set_filter_r name iso_rr_path [***]", +" Like -set_filter but affecting all files below directories.", "", +"Write-to-media options:", " -rollback Discard the manipulated ISO image and reload it.", "", " -commit Perform the write operation and then perform -dev outdrive.", @@ -15763,11 +15823,14 @@ int Xorriso_option_reassure(struct XorrisO *xorriso, char *mode, int flag) } -/* Option -compliance */ -int Xorriso_option_compliance(struct XorrisO *xorriso, char *mode, - int flag) +/* Option -unregister_filter */ +int Xorriso_option_unregister_filter(struct XorrisO *xorriso, char *name, + int flag) { - return(Xorriso_relax_compliance(xorriso, mode, 0)); + int ret; + + ret= Xorriso_external_filter(xorriso, name, "", "", 0, NULL, 1); + return(ret); } @@ -16356,6 +16419,59 @@ out_of_mem:; } +/* Options -set_filter , -set_filter_r */ +/* @param flag bit0=recursive -set_filter_r +*/ +int Xorriso_option_set_filter(struct XorrisO *xorriso, char *name, + int argc, char **argv, int *idx, int flag) +{ + int i, ret, was_failure= 0, end_idx, fret; + int optc= 0; + char **optv= NULL; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + + ret= Xorriso_opt_args(xorriso, "-set_filter", + argc, argv, *idx, &end_idx, &optc, &optv, 0); + if(ret <= 0) + goto ex; + + for(i= 0; i0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + ret= 0; goto ex; + } + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-set_filter", argc, argv, *idx, &end_idx, + &optc, &optv, 256); + Findjob_destroy(&job, 0); + if(ret<=0) + return(ret); + return(!was_failure); +} + + /* Option -speed */ int Xorriso_option_speed(struct XorrisO *xorriso, char *speed, int flag) { @@ -16878,7 +16994,8 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, "prog","prog_help","publisher","quoted_not_list","quoted_path_list", "reassure","report_about","rom_toc_scan", "session_log","speed","split_size","status","status_history_max", - "stream_recording","temp_mem_limit","uid","use_readline","volid","xattr", + "stream_recording","temp_mem_limit", + "uid","unregister_filter","use_readline","volid","xattr", "" }; static char arg2_commands[][40]= { @@ -16898,7 +17015,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, "chgrp","chgrpi","chgrp_r","chgrp_ri","chmod","chmodi", "chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri", "compare_l","cpr","cpri","cp_rax","cp_rx","cpax","cpx", - "du","dui","dus","dusi","dux","dusx","extract_l", + "du","dui","dus","dusi","dux","dusx","external_filter","extract_l", "file_size_limit","find","findi","findx", "getfacl","getfacli","getfacl_r","getfacl_ri", "getfattr","getfattri","getfattr_r","getfattr_ri", @@ -16908,6 +17025,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, "setfacl","setfacli","setfacl_list","setfacl_listi", "setfacl_r","setfacl_ri","setfattr","setfattri", "setfattr_list","setfattr_listi","setfattr_r","setfattr_ri", + "set_filter","set_filter_r", "" }; @@ -17142,6 +17260,10 @@ next_command:; (*idx)+= 2; ret= Xorriso_option_compare(xorriso, arg1, arg2, 1|8); + } else if(strcmp(cmd,"compliance")==0) { + (*idx)++; + Xorriso_option_compliance(xorriso, arg1, 0); + } else if(strcmp(cmd,"cpr")==0 || strcmp(cmd,"cpri")==0) { ret= Xorriso_option_cpri(xorriso, argc, argv, idx, 0); @@ -17218,6 +17340,9 @@ next_command:; (*idx)+= 2; ret= Xorriso_option_error_behavior(xorriso, arg1, arg2, 0); + } else if(strcmp(cmd,"external_filter")==0) { + ret= Xorriso_option_external_filter(xorriso, argc, argv, idx, 0); + } else if(strcmp(cmd,"extract")==0) { (*idx)+= 2; ret= Xorriso_option_extract(xorriso, arg1, arg2, 0); @@ -17493,10 +17618,6 @@ next_command:; (*idx)++; ret= Xorriso_option_reassure(xorriso, arg1, 0); - } else if(strcmp(cmd,"compliance")==0) { - (*idx)++; - Xorriso_option_compliance(xorriso, arg1, 0); - } else if(strcmp(cmd,"report_about")==0) { (*idx)++; ret= Xorriso_option_report_about(xorriso, arg1, 0); @@ -17571,6 +17692,11 @@ next_command:; (*idx)+= 2; ret= Xorriso_option_setfattri(xorriso, arg1, arg2, argc, argv, idx, 1); + } else if(strcmp(cmd,"set_filter")==0 || strcmp(cmd,"set_filter_r")==0) { + (*idx)+= 1; + ret= Xorriso_option_set_filter(xorriso, arg1, argc, argv, idx, + strcmp(cmd,"set_filter_r")==0); + } else if(strcmp(cmd,"speed")==0) { (*idx)++; ret= Xorriso_option_speed(xorriso, arg1, 0); @@ -17610,6 +17736,10 @@ next_command:; (*idx)++; ret= Xorriso_option_uid(xorriso,arg1,0); + } else if(strcmp(cmd,"unregister_filter")==0) { + (*idx)++; + ret= Xorriso_option_unregister_filter(xorriso, arg1, 0); + } else if(strcmp(cmd,"update")==0) { (*idx)+= 2; ret= Xorriso_option_update(xorriso, arg1, arg2, 1); diff --git a/xorriso/xorriso.h b/xorriso/xorriso.h index ec5fc799..953299df 100644 --- a/xorriso/xorriso.h +++ b/xorriso/xorriso.h @@ -446,6 +446,10 @@ int Xorriso_option_errfile_log(struct XorrisO *xorriso, int Xorriso_option_error_behavior(struct XorrisO *xorriso, char *occasion, char *behavior, int flag); +/* Option -external_filter */ +int Xorriso_option_external_filter(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag); + /* Options -extract , -extract_single */ /* @param flag bit0=do not report the restored item bit1=do not reset pacifier, no final pacifier message @@ -696,6 +700,12 @@ int Xorriso_option_setfattri(struct XorrisO *xorriso, char *name, char *value, int Xorriso_option_setfattr_listi(struct XorrisO *xorriso, char *path, int flag); +/* Options -set_filter , -set_filter_r */ +/* @param flag bit0=recursive -set_filter_r +*/ +int Xorriso_option_set_filter(struct XorrisO *xorriso, char *name, + int argc, char **argv, int *idx, int flag); + /* Option -speed */ int Xorriso_option_speed(struct XorrisO *xorriso, char *speed, int flag); @@ -726,6 +736,10 @@ int Xorriso_option_toc(struct XorrisO *xorriso, int flag); /* Option -uid */ int Xorriso_option_uid(struct XorrisO *xorriso, char *uid, int flag); +/* Option -unregister_filter */ +int Xorriso_option_unregister_filter(struct XorrisO *xorriso, char *name, + int flag); + /* Options -update and -update_r @param flag bit0= issue summary message bit1= do not reset pacifier, no final pacifier message diff --git a/xorriso/xorriso_eng.html b/xorriso/xorriso_eng.html index e0f5e215..2b4597e1 100644 --- a/xorriso/xorriso_eng.html +++ b/xorriso/xorriso_eng.html @@ -490,7 +490,12 @@ New -stream_recording modes with start address or "data". "on" is now 32s.
Enhancements towards stable version 0.3.6.pl00: