From e3eaea1a4e61070f5fd75f166e97f90d86963f9d Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Thu, 2 Apr 2009 16:25:33 +0000 Subject: [PATCH] New options -external_filter , -unregister_filter, -set_filter , -set_filter_r --- xorriso/xorriso.1 | 87 ++++++++- xorriso/xorriso.c | 184 +++++++++++++++--- xorriso/xorriso.h | 14 ++ xorriso/xorriso_eng.html | 13 +- xorriso/xorriso_private.h | 30 ++- xorriso/xorriso_timestamp.h | 2 +- xorriso/xorrisoburn.c | 368 ++++++++++++++++++++++++++++++------ xorriso/xorrisoburn.h | 13 +- 8 files changed, 609 insertions(+), 102 deletions(-) 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:
    -
  • - none yet -
  • +
  • +New option -auto_charset based on xattr "isofs.cs" +
  • +
  • +New options -external_filter , -unregister_filter, -set_filter , -set_filter_r +
  • @@ -551,7 +556,6 @@ Very special thanks to Andy Polyakov whose provide the libburnia project with invaluable examples on how to deal with DVD media and how to emulate multi-session on overwriteable media.

    -
    @@ -567,6 +571,11 @@ and by sourceforge.net
    SourceForge Logo +

    +Enjoying a FreeBSD shell account with the opportunity to +build, install and test xorriso at
    +free-shells.com.ar +


    diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index b84de33d..ad0502c7 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -123,6 +123,8 @@ struct XorrisO { /* the global context of xorriso */ mode_t global_dir_mode; mode_t global_file_mode; + struct Xorriso_lsT *filters; + int do_overwrite; /* 0=off, 1=on, 2=nondir */ int do_reassure; /* 0=off, 1=on, 2=tree */ @@ -576,6 +578,9 @@ int Xorriso_normalize_acl_text(struct XorrisO *xorriso, char *in_text, int Xorriso_path_setfattr(struct XorrisO *xorriso, void *in_node, char *path, char *name, size_t value_length, char *value, int flag); +int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp, + int flag); + int Sfile_str(char target[SfileadrL], char *source, int flag); @@ -634,6 +639,7 @@ struct Xorriso_lsT { @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 @return <=0 error, 1 ok */ int Xorriso_lst_new_binary(struct Xorriso_lsT **lstring, char *data, @@ -644,8 +650,7 @@ int Xorriso_lst_new_binary(struct Xorriso_lsT **lstring, char *data, @param lstring The newly created object or NULL on failure @param text A 0-terminated array of bytes @param link Xorriso_lsT object to which the new object shall be linked - @param flag Bitfield for control purposes - bit0= insert before link rather than after it + @param flag see Xorriso_lst_new_binary @return <=0 error, 1 ok */ int Xorriso_lst_new(struct Xorriso_lsT **lstring, char *text, @@ -653,12 +658,16 @@ int Xorriso_lst_new(struct Xorriso_lsT **lstring, char *text, /** Create a new list item at the end of a given list. - @param lstring Contains as input a pointer to a pointer to any existing - list item. As output this list item pointer will be - changed to the address of the new list item. + @param entry Contains as input a pointer to a pointer to any existing + list item. As output this list item pointer may be + changed to the address of the new list item: + if ((*entry == 0) || (flag & 1)) @param data An array of bytes to be copied into the new object @param data_len Number of bytes to be copied - @param flag unused yet, submit 0 + @param flag Bitfield for control purposes + bit0= Return new object address in *entry + bit1= do not copy data (e.g. because *data is invalid) + bit2= attach data directly by pointer rather than by copying @return <=0 error, 1 ok */ int Xorriso_lst_append_binary(struct Xorriso_lsT **entry, @@ -673,6 +682,15 @@ int Xorriso_lst_append_binary(struct Xorriso_lsT **entry, int Xorriso_lst_destroy(struct Xorriso_lsT **lstring, int flag); +struct Xorriso_lsT *Xorriso_lst_get_next(struct Xorriso_lsT *entry, int flag); + +struct Xorriso_lsT *Xorriso_lst_get_prev(struct Xorriso_lsT *entry, int flag); + +char *Xorriso_lst_get_text(struct Xorriso_lsT *entry, int flag); + +int Xorriso_lst_detach_text(struct Xorriso_lsT *entry, int flag); + + char *Text_shellsafe(char *in_text, char *out_text, int flag); int Sort_argv(int argc, char **argv, int flag); diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 73950364..c1a57d0c 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.03.29.164931" +#define Xorriso_timestamP "2009.04.02.162530" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 97b839d5..4c784fd0 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -490,6 +490,7 @@ int Xorriso_assert_volid(struct XorrisO *xorriso, int msc1, int flag) "-assert_volid: Cannot determine Volume Id at LBA %d.", msc1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, xorriso->assert_volid_sev, 0); + return(0); } ret= Sregex_match(xorriso->assert_volid, volid, 0); if(ret < 0) @@ -6127,6 +6128,8 @@ ex:; free(adr); if(flag&2) (*dive_count)--; + if(iter != NULL) + iso_dir_iter_free(iter); return(ret); } @@ -6600,8 +6603,7 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, ret= Xorriso_path_setfattr(xorriso, (void *) node, show_path, target, strlen(text_2), text_2, 0); } else if(action == 28) { - ret= Xorriso_set_filter(xorriso, (void *) node, show_path, - target, text_2, 1 | 2); + ret= Xorriso_set_filter(xorriso, (void *) node, show_path, target, 1 | 2); } else { /* includes : 15 in_iso */ sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); Xorriso_result(xorriso, 0); @@ -9612,48 +9614,150 @@ ex:; } +struct Xorriso_extF { + + int flag; /* unused yet */ + + IsoExternalFilterCommand *cmd; + +}; + +int Xorriso_extf_destroy(struct XorrisO *xorriso, struct Xorriso_extF **filter, + int flag); + + +/* @param flag see struct Xorriso_extF.flag */ +int Xorriso_extf_new(struct XorrisO *xorriso, struct Xorriso_extF **filter, + char *path, int argc, char **argv, int behavior, + char *suffix, char *name, int flag) +{ + int i; + struct Xorriso_extF *o= NULL; + IsoExternalFilterCommand *cmd; + + *filter= o= calloc(sizeof(struct Xorriso_extF), 1); + if(o == NULL) + goto failure; + o->flag= flag; + o->cmd= NULL; + o->cmd= cmd= calloc(sizeof(IsoExternalFilterCommand), 1); + if(cmd == NULL) + goto failure; + cmd->version= 0; + cmd->refcount= 0; + cmd->name= NULL; + cmd->path= NULL; + cmd->argv= NULL; + cmd->argc= argc + 1; + cmd->behavior= behavior; + cmd->suffix= NULL; + cmd->suffix= strdup(suffix); + if(cmd->suffix == NULL) + goto failure; + + cmd->path= strdup(path); + if(cmd->path == NULL) + goto failure; + cmd->argv= calloc(sizeof(char *), argc + 2); + if(cmd->argv == NULL) + goto failure; + for(i= 0; i < argc + 2; i++) + cmd->argv[i]= NULL; + cmd->argv[0]= strdup(path); + if(cmd->argv[0] == NULL) + goto failure; + for(i= 0; i < argc; i++) { + cmd->argv[i + 1]= strdup(argv[i]); + if(cmd->argv[i] == NULL) + goto failure; + } + cmd->name= strdup(name); + if(cmd->name == NULL) + goto failure; + return(1); +failure:; + Xorriso_extf_destroy(xorriso, filter, 0); + return(-1); +} + + +int Xorriso_extf_destroy(struct XorrisO *xorriso, struct Xorriso_extF **filter, + int flag) +{ + int i; + IsoExternalFilterCommand *cmd; + + if(*filter == NULL) + return(0); + cmd= (*filter)->cmd; + if(cmd != NULL) { + if(cmd->refcount > 0) + return(0); + if(cmd->suffix != NULL) + free(cmd->suffix); + if(cmd->argv != NULL) { + for(i= 0; i < cmd->argc; i++) + if(cmd->argv[i] != NULL) + free(cmd->argv[i]); + free((char *) cmd->argv); + } + if(cmd->name != NULL) + free(cmd->name); + } + free((char *) *filter); + *filter= NULL; + return(1); +} + + +int Xorriso_lookup_extf(struct XorrisO *xorriso, char *name, + struct Xorriso_lsT **found_lst, int flag) +{ + struct Xorriso_extF *filter; + struct Xorriso_lsT *lst; + + for(lst= xorriso->filters; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) { + filter= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0); + if(strcmp(filter->cmd->name, name) == 0) { + *found_lst= lst; + return(1); + } + } + return(0); +} + + +int Xorriso_destroy_all_extf(struct XorrisO *xorriso, int flag) +{ + struct Xorriso_extF *filter; + struct Xorriso_lsT *lst, *next_lst; + + for(lst= xorriso->filters; lst != NULL; lst= next_lst) { + filter= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0); + Xorriso_lst_detach_text(lst, 0); + next_lst= Xorriso_lst_get_next(lst, 0); + Xorriso_lst_destroy(&lst, 0); + Xorriso_extf_destroy(xorriso, &filter, 0); + } + xorriso->filters= NULL; + return(1); +} + + /* - @pram suffix to be added or stripped if not empty or "-no-suffix-" @param flag bit0= return 2 if renaming is not possible bit1= print pacifier messages */ int Xorriso_set_filter(struct XorrisO *xorriso, void *in_node, - char *path, char *filter_name, char *suffix, int flag) + char *path, char *filter_name, int flag) { int ret, lo= 0, ls= 0, strip_suffix= 0, strip_filter= 0; IsoNode *node; IsoFile *file; + struct Xorriso_lsT *found_lst; + struct Xorriso_extF *found_filter; IsoExternalFilterCommand *cmd = NULL; - char *old_name= NULL, new_name[SfileadrL]; - - static char *argv_cat[2] = {"cat", NULL}; - static IsoExternalFilterCommand cmd_cat = - {0, 0, "/bin/cat", 1, argv_cat, 1}; - - static char *argv_gzip[2] = {"gzip", NULL}; - static IsoExternalFilterCommand cmd_gzip = - {0, 0, "/usr/bin/gzip", 1, argv_gzip, 4}; - static char *argv_gunzip[2] = {"gunzip", NULL}; - static IsoExternalFilterCommand cmd_gunzip = - {0, 0, "/usr/bin/gunzip", 1, argv_gunzip, 1}; - - static char *argv_sencrypt[6] = - {"sencrypt", "-e", "-g", "-k", "1QwErTy7", NULL}; - static IsoExternalFilterCommand cmd_sencrypt = - {0, 0, "/usr/bin/sencrypt", 5, argv_sencrypt, 1}; - static char *argv_sencrypt_d[6] = - {"sencrypt", "-d", "-g", "-k", "1QwErTy7", NULL}; - static IsoExternalFilterCommand cmd_sencrypt_d = - {0, 0, "/usr/bin/sencrypt", 5, argv_sencrypt_d, 1}; - - static char *argv_sencrypt_f[6] = - {"sencrypt", "-e", "-g", "-f", "/var/opt/xorriso/keys/testkey", NULL}; - static IsoExternalFilterCommand cmd_sencrypt_f = - {0, 0, "/usr/bin/sencrypt", 5, argv_sencrypt_f, 1}; - static char *argv_sencrypt_f_d[6] = - {"sencrypt", "-d", "-g", "-f", "/var/opt/xorriso/keys/testkey", NULL}; - static IsoExternalFilterCommand cmd_sencrypt_f_d = - {0, 0, "/usr/bin/sencrypt", 5, argv_sencrypt_f_d, 1}; + char *old_name= NULL, new_name[SfileadrL], *suffix= ""; new_name[0]= 0; @@ -9678,36 +9782,30 @@ int Xorriso_set_filter(struct XorrisO *xorriso, void *in_node, } file= (IsoFile *) node; - /* >>> lookup cmd by filter_name */ - /* <<< this is a dummy for testing */ - if(strcmp(filter_name, "-cat") == 0) { - cmd= &cmd_cat; - } else if(strcmp(filter_name, "-gzip") == 0) { - cmd= &cmd_gzip; - } else if(strcmp(filter_name, "-gunzip") == 0) { - cmd= &cmd_gunzip; - strip_suffix= 1; - } else if(strcmp(filter_name, "-sencrypt") == 0) { - cmd= &cmd_sencrypt; - } else if(strcmp(filter_name, "-sencrypt_d") == 0) { - cmd= &cmd_sencrypt_d; - strip_suffix= 1; - } else if(strcmp(filter_name, "-sencrypt_f") == 0) { - cmd= &cmd_sencrypt_f; - } else if(strcmp(filter_name, "-sencrypt_f_d") == 0) { - cmd= &cmd_sencrypt_f_d; - strip_suffix= 1; - } else if(strcmp(filter_name, "--remove-all-filters") == 0) { + if(strncmp(filter_name, "--remove-all-filters", 20) == 0) { strip_filter= 1; strip_suffix= 1; + if(strlen(filter_name) > 21) { + strip_suffix= (filter_name[20] != '+'); + suffix= filter_name + 21; + } } else { - strcpy(xorriso->info_text, "-set_filter: Not a registered filter name "); - Text_shellsafe(filter_name, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; + ret= Xorriso_lookup_extf(xorriso, filter_name, &found_lst, 0); + if(ret < 0) + goto ex; + if(ret == 0) { + strcpy(xorriso->info_text, "-set_filter: Not a registered filter name "); + Text_shellsafe(filter_name, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + found_filter= (struct Xorriso_extF *) Xorriso_lst_get_text(found_lst, 0); + cmd= found_filter->cmd; + suffix= cmd->suffix; + strip_suffix= cmd->behavior & 8; } - if(suffix[0] && strcmp(suffix, "--no-suffix") != 0) { + if(suffix[0]) { old_name= strdup((char *) iso_node_get_name(node)); lo= strlen(old_name); ls= strlen(suffix); @@ -9753,6 +9851,7 @@ cannot_append_suffix:; strcpy(xorriso->info_text, "-set_filter: Cannot append suffix to "); Text_shellsafe(old_name, xorriso->info_text, 1); + strcat(xorriso->info_text, ". Left unfiltered."); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, (flag & 1) ? "WARNING" : "FAILURE", 0); ret= 2 * (flag & 1); goto ex; @@ -9775,6 +9874,7 @@ cannot_append_suffix:; if(ret != 1) break; } + ret= 1; } else { ret = iso_file_add_external_filter(file, cmd, 0); } @@ -9812,3 +9912,153 @@ ex:; } +/* @param flag bit0= delete filter with the given name +*/ +int Xorriso_external_filter(struct XorrisO *xorriso, + char *name, char *options, char *path, + int argc, char **argv, int flag) +{ + int ret, delete= 0, behavior= 0, extf_flag= 0; + char *what, *what_next, *suffix= ""; + struct Xorriso_lsT *lst; + struct Xorriso_extF *found_filter, *new_filter= NULL; + + delete= flag & 1; + ret= Xorriso_lookup_extf(xorriso, name, &lst, 0); + if(ret < 0) + return(ret); + if(ret > 0) { + if(delete) { + found_filter= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0); + if(found_filter->cmd->refcount > 0) { + sprintf(xorriso->info_text, + "-external_filter: Cannot remove filter because it is in use by %.f nodes : ", + (double) found_filter->cmd->refcount); + Text_shellsafe(name, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + Xorriso_lst_detach_text(lst, 0); + if(xorriso->filters == lst) + xorriso->filters= Xorriso_lst_get_next(lst, 0); + Xorriso_lst_destroy(&lst, 0); + Xorriso_extf_destroy(xorriso, &found_filter, 0); + ret= 1; goto ex; + } + strcpy(xorriso->info_text, + "-external_filter: filter with given name already existing: "); + Text_shellsafe(name, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(delete) { + strcpy(xorriso->info_text, + "-external_filter: filter with given name does not exist: "); + Text_shellsafe(name, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + for(what= options; what!=NULL; what= what_next) { + what_next= strchr(what, ':'); + if(what_next!=NULL) { + *what_next= 0; + what_next++; + } + if(strncmp(what, "suffix=", 7) == 0) { + suffix= what + 7; + } else if(strcmp(what, "remove_suffix") == 0) { + behavior|= 8; + } else if(strcmp(what, "if_nonempty") == 0) { + behavior|= 1; + } else if(strcmp(what, "if_reduction") == 0) { + behavior|= 2; + } else if(strcmp(what, "if_block_reduction") == 0) { + behavior|= 4; + } else if(strncmp(what, "used=", 5) == 0) { + ; /* this is informational output from -status */ + } else if(what[0]) { + strcpy(xorriso->info_text, + "-external_filter: unknown option "); + Text_shellsafe(what, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } + + ret= Xorriso_extf_new(xorriso, &new_filter, path, argc, argv, behavior, + suffix, name, extf_flag); + if(ret <= 0) { +could_not_create:; + strcpy(xorriso->info_text, + "-external_filter: Could not create filter object"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto ex; + } + ret= Xorriso_lst_append_binary(&(xorriso->filters), (char *) new_filter,0, 4); + if(ret <= 0) + goto could_not_create; + ret= 1; +ex:; + if(ret <= 0) { + if(new_filter != NULL) + Xorriso_extf_destroy(xorriso, &new_filter, 0); + } + return(ret); +} + + +int Xorriso_status_extf(struct XorrisO *xorriso, char *filter, FILE *fp, + int flag) +/* + bit1= do only report to fp +*/ +{ + int i, maxl= 4 * SfileadrL; + struct Xorriso_extF *extf; + struct Xorriso_lsT *lst; + char *line; + + line= xorriso->result_line; + for(lst= xorriso->filters; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) { + extf= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0); + + strcpy(xorriso->result_line, "-external_filter "); + Text_shellsafe(extf->cmd->name, line, 1); + if(strlen(line) > maxl) + continue; + strcat(line, " "); + if(extf->cmd->suffix[0]) { + strcat(line, "suffix="); + Text_shellsafe(extf->cmd->suffix, line, 1); + if(strlen(line) > maxl) + continue; + strcat(line, ":"); + } + if(extf->cmd->behavior & 8) + strcat(line, "remove_suffix:"); + if(extf->cmd->behavior & 1) + strcat(line, "if_nonempty:"); + if(extf->cmd->behavior & 2) + strcat(line, "if_reduction:"); + if(extf->cmd->behavior & 4) + strcat(line, "if_block_reduction:"); + sprintf(line + strlen(line), "used=%.f ", (double) extf->cmd->refcount); + if(strlen(line) > maxl) + continue; + Text_shellsafe(extf->cmd->path, line, 1); + if(strlen(line) > maxl) + continue; + for(i= 1; i < extf->cmd->argc; i++) { + strcat(line, " "); + Text_shellsafe(extf->cmd->argv[i], line, 1); + if(strlen(line) > maxl) + break; + } + if(i < extf->cmd->argc) + continue; + strcat(line, " --\n"); + Xorriso_status_result(xorriso, filter, fp, flag&2); + } + return(1); +} diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 6aaeda2f..871f026d 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -432,7 +432,18 @@ int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path, char **text, int flag); int Xorriso_set_filter(struct XorrisO *xorriso, void *in_node, - char *path, char *filter_name, char *suffix, int flag); + char *path, char *filter_name, int flag); + +/* @param flag bit0= delete filter with the given name +*/ +int Xorriso_external_filter(struct XorrisO *xorriso, + char *name, char *options, char *path, + int argc, char **argv, int flag); + +int Xorriso_status_extf(struct XorrisO *xorriso, char *filter, FILE *fp, + int flag); + +int Xorriso_destroy_all_extf(struct XorrisO *xorriso, int flag); /* A pseudo file type for El-Torito bootsectors as in man 2 stat :