X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=cgiedit.c;h=9619c1dc4c7d2e8aac71ddb7f75aacc1a9096ea6;hp=0e230eeb0673f47f4e233f2bd4d423bed0942da4;hb=3c6406b7e0431bfac8206b6558d29d28051458e8;hpb=ccedf2853b21370ecb456bda0551e7dbfa76aee9 diff --git a/cgiedit.c b/cgiedit.c index 0e230eeb..9619c1dc 100644 --- a/cgiedit.c +++ b/cgiedit.c @@ -1,4 +1,4 @@ -const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.9 2002/01/17 20:56:22 jongfoster Exp $"; +const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.28 2002/03/27 12:30:29 oes Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/cgiedit.c,v $ @@ -16,7 +16,7 @@ const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.9 2002/01/17 20:56:22 jongfoster * Stick to the short names in this file for consistency. * * Copyright : Written by and Copyright (C) 2001 the SourceForge - * IJBSWA team. http://ijbswa.sourceforge.net + * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written * by and Copyright (C) 1997 Anonymous Coders and @@ -42,6 +42,94 @@ const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.9 2002/01/17 20:56:22 jongfoster * * Revisions : * $Log: cgiedit.c,v $ + * Revision 1.28 2002/03/27 12:30:29 oes + * Deleted unsused variable + * + * Revision 1.27 2002/03/26 23:06:04 jongfoster + * Removing duplicate @ifs on the toggle page + * + * Revision 1.26 2002/03/26 22:59:17 jongfoster + * Fixing /toggle to display status consistently. + * + * Revision 1.25 2002/03/26 22:29:54 swa + * we have a new homepage! + * + * Revision 1.24 2002/03/24 15:23:33 jongfoster + * Name changes + * + * Revision 1.23 2002/03/24 13:32:41 swa + * name change related issues + * + * Revision 1.22 2002/03/24 13:25:43 swa + * name change related issues + * + * Revision 1.21 2002/03/22 18:02:48 jongfoster + * Fixing remote toggle + * + * Revision 1.20 2002/03/16 20:28:34 oes + * Added descriptions to the filters so users will know what they select in the cgi editor + * + * Revision 1.19 2002/03/16 18:38:14 jongfoster + * Stopping stupid or malicious users from breaking the actions + * file using the web-based editor. + * + * Revision 1.18 2002/03/16 14:57:44 jongfoster + * Full support for enabling/disabling modular filters. + * + * Revision 1.17 2002/03/16 14:26:42 jongfoster + * First version of modular filters support - READ ONLY! + * Fixing a double-free bug in the out-of-memory handling in map_radio(). + * + * Revision 1.16 2002/03/07 03:46:17 oes + * Fixed compiler warnings + * + * Revision 1.15 2002/03/06 22:54:35 jongfoster + * Automated function-comment nitpicking. + * + * Revision 1.14 2002/03/05 00:24:51 jongfoster + * Patch to always edit the current actions file. + * + * Revision 1.13 2002/03/04 02:07:59 david__schmidt + * Enable web editing of actions file on OS/2 (it had been broken all this time!) + * + * Revision 1.12 2002/03/03 09:18:03 joergs + * Made jumbjuster work on AmigaOS again. + * + * Revision 1.11 2002/01/23 01:03:31 jongfoster + * Fixing gcc [CygWin] compiler warnings + * + * Revision 1.10 2002/01/23 00:22:59 jongfoster + * Adding new function cgi_edit_actions_section_swap(), to reorder + * the actions file. + * + * Adding get_url_spec_param() to get a validated URL pattern. + * + * Moving edit_read_line() out of this file and into loaders.c. + * + * Adding missing html_encode() to many CGI functions. + * + * Moving the functions that #include actionlist.h to the end of the file, + * because the Visual C++ 97 debugger gets extremely confused if you try + * to debug any code that comes after them in the file. + * + * Major optimizations in cgi_edit_actions_list() to reduce the size of + * the generated HTML (down 40% from 550k to 304k), with major side-effects + * throughout the editor and templates. In particular, the length of the + * URLs throughout the editor has been drastically reduced, by cutting + * paramater names down to 1 character and CGI names down to 3-4 + * characters, by removing all non-essential CGI paramaters even at the + * expense of having to re-read the actions file for the most trivial + * page, and by using relative rather than absolute URLs. This means + * that this (typical example): + * + * + * + * is now this: + * + * + * * Revision 1.9 2002/01/17 20:56:22 jongfoster * Replacing hard references to the URL of the config interface * with #defines from project.h @@ -196,7 +284,7 @@ struct file_line struct editable_file { struct file_line * lines; - const char * filename; /* Full pathname - e.g. "/etc/junkbuster/wibble.action" */ + const char * filename; /* Full pathname - e.g. "/etc/privoxy/wibble.action" */ const char * identifier; /* Filename stub - e.g. "wibble". Use for CGI param. */ /* Pre-encoded with url_encode() for ease of use. */ const char * version_str; /* Last modification time, as a string. For CGI param */ @@ -217,6 +305,8 @@ struct editable_file * (Statically allocated) */ }; +#define CGI_ACTION_PARAM_LEN_MAX 500 + /* FIXME: Following non-static functions should be prototyped in .h or made static */ /* Functions to read and write arbitrary config files */ @@ -272,12 +362,15 @@ static jb_err get_url_spec_param(struct client_state *csp, const struct map *parameters, const char *name, char **pvalue); +static jb_err get_string_param(const struct map *parameters, + const char *param_name, + const char **pparam); /* Internal actionsfile <==> HTML conversion functions */ static jb_err map_radio(struct map * exports, const char * optionname, const char * values, - char value); + int value); static jb_err actions_to_radio(struct map * exports, const struct action_spec *action); static jb_err actions_from_radio(const struct map * parameters, @@ -287,10 +380,11 @@ static jb_err actions_from_radio(const struct map * parameters, static jb_err map_copy_parameter_html(struct map *out, const struct map *in, const char *name); +#if 0 /* unused function */ static jb_err map_copy_parameter_url(struct map *out, const struct map *in, const char *name); - +#endif /* unused function */ /********************************************************************* * @@ -300,9 +394,9 @@ static jb_err map_copy_parameter_url(struct map *out, * encoding it. * * Parameters : - * 1 : out = target map - * 2 : in = source map - * 3 : name = name of cgi parameter to copy + * 1 : out = target map + * 2 : in = source map + * 3 : name = name of cgi parameter to copy * * Returns : JB_ERR_OK on success * JB_ERR_MEMORY on out-of-memory @@ -340,6 +434,7 @@ static jb_err map_copy_parameter_html(struct map *out, } +#if 0 /* unused function */ /********************************************************************* * * Function : map_copy_parameter_html @@ -348,9 +443,9 @@ static jb_err map_copy_parameter_html(struct map *out, * encoding it. * * Parameters : - * 1 : out = target map - * 2 : in = source map - * 3 : name = name of cgi parameter to copy + * 1 : out = target map + * 2 : in = source map + * 3 : name = name of cgi parameter to copy * * Returns : JB_ERR_OK on success * JB_ERR_MEMORY on out-of-memory @@ -386,7 +481,7 @@ static jb_err map_copy_parameter_url(struct map *out, return JB_ERR_OK; } } - +#endif /* 0 - unused function */ /********************************************************************* * @@ -396,9 +491,9 @@ static jb_err map_copy_parameter_url(struct map *out, * edit-actions-url * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters * f : (filename) Identifies the file to edit @@ -492,9 +587,9 @@ jb_err cgi_edit_actions_url_form(struct client_state *csp, * edit-actions-url * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : * f : (filename) Identifies the file to edit @@ -550,9 +645,9 @@ jb_err cgi_edit_actions_add_url_form(struct client_state *csp, * edit-actions-url * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : * f : (filename) Identifies the file to edit @@ -666,7 +761,11 @@ jb_err edit_write_file(struct editable_file * file) assert(file); assert(file->filename); +#if defined(AMIGA) || defined(__OS2__) + if (NULL == (fp = fopen(file->filename, "w"))) +#else if (NULL == (fp = fopen(file->filename, "wt"))) +#endif /* def AMIGA */ { return JB_ERR_FILE; } @@ -718,7 +817,7 @@ jb_err edit_write_file(struct editable_file * file) /* Allocate new memory for string */ len = strlen(cur_line->unprocessed); - if (NULL == (str = malloc(len + 1 + numhash))) + if (NULL == (str = malloc((size_t) len + 1 + numhash))) { /* Uh oh, just trashed file! */ fclose(fp); @@ -897,15 +996,15 @@ static void edit_free_file_lines(struct file_line * first_line) * Description : Match an actions file {{header}} line * * Parameters : - * 1 : line - String from file - * 2 : name - Header to match against + * 1 : line = String from file + * 2 : name = Header to match against * * Returns : 0 iff they match. * *********************************************************************/ static int match_actions_file_header_line(const char * line, const char * name) { - int len; + size_t len; assert(line); assert(name); @@ -955,10 +1054,10 @@ static int match_actions_file_header_line(const char * line, const char * name) * Description : Match an actions file {{header}} line * * Parameters : - * 1 : line - String from file. Must not start with + * 1 : line = String from file. Must not start with * whitespace (else infinite loop!) - * 2 : name - Destination for name - * 2 : name - Destination for value + * 2 : name = Destination for name + * 2 : name = Destination for value * * Returns : JB_ERR_OK on success * JB_ERR_MEMORY on out-of-memory @@ -971,7 +1070,7 @@ static jb_err split_line_on_equals(const char * line, char ** pname, char ** pva { const char * name_end; const char * value_start; - int name_len; + size_t name_len; assert(line); assert(pname); @@ -1051,7 +1150,7 @@ static jb_err split_line_on_equals(const char * line, char ** pname, char ** pva jb_err edit_parse_actions_file(struct editable_file * file) { struct file_line * cur_line; - int len; + size_t len; const char * text; /* Text from a line */ char * name; /* For lines of the form name=value */ char * value; /* For lines of the form name=value */ @@ -1493,7 +1592,11 @@ jb_err edit_read_file(struct client_state *csp, } } +#if defined(AMIGA) || defined(__OS2__) + if (NULL == (fp = fopen(filename,"r"))) +#else if (NULL == (fp = fopen(filename,"rt"))) +#endif /* def AMIGA */ { free(filename); return JB_ERR_FILE; @@ -1666,13 +1769,13 @@ jb_err edit_read_actions_file(struct client_state *csp, * secure. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : parameters = map of cgi parameters - * 3 : param_name = The name of the parameter to read - * 4 : suffix = File extension, e.g. ".actions" - * 5 : pfilename = destination for full filename. Caller + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : parameters = map of cgi parameters + * 3 : param_name = The name of the parameter to read + * 4 : suffix = File extension, e.g. ".actions" + * 5 : pfilename = destination for full filename. Caller * free()s. Set to NULL on error. - * 6 : pparam = destination for partial filename, + * 6 : pparam = destination for partial filename, * suitable for use in another URL. Allocated as part * of the map "parameters", so don't free it. * Set to NULL if not specified. @@ -1692,7 +1795,9 @@ static jb_err get_file_name_param(struct client_state *csp, { const char *param; const char *s; +#if 0 /* Patch to make 3.0.0 work properly. */ char *name; +#endif /* 0 - Patch to make 3.0.0 work properly. */ char *fullpath; char ch; int len; @@ -1736,6 +1841,13 @@ static jb_err get_file_name_param(struct client_state *csp, } } + /* + * FIXME Following is a hack to make 3.0.0 work properly. + * Change "#if 0" --> "#if 1" below when we have modular action + * files. + * -- Jon + */ +#if 0 /* Patch to make 3.0.0 work properly. */ /* Append extension */ name = malloc(len + strlen(suffix) + 1); if (name == NULL) @@ -1748,6 +1860,16 @@ static jb_err get_file_name_param(struct client_state *csp, /* Prepend path */ fullpath = make_path(csp->config->confdir, name); free(name); +#else /* 1 - Patch to make 3.0.0 work properly. */ + if ((csp->actions_list == NULL) + || (csp->actions_list->filename == NULL)) + { + return JB_ERR_CGI_PARAMS; + } + + fullpath = ( (csp->actions_list && csp->actions_list->filename) + ? strdup(csp->actions_list->filename) : NULL); +#endif /* 1 - Patch to make 3.0.0 work properly. */ if (fullpath == NULL) { return JB_ERR_MEMORY; @@ -1760,6 +1882,111 @@ static jb_err get_file_name_param(struct client_state *csp, } +/********************************************************************* + * + * Function : get_char_param + * + * Description : Get a single-character parameter passed to a CGI + * function. + * + * Parameters : + * 1 : parameters = map of cgi parameters + * 2 : param_name = The name of the parameter to read + * + * Returns : Uppercase character on success, '\0' on error. + * + *********************************************************************/ +static char get_char_param(const struct map *parameters, + const char *param_name) +{ + char ch; + + assert(parameters); + assert(param_name); + + ch = *(lookup(parameters, param_name)); + if ((ch >= 'a') && (ch <= 'z')) + { + ch = ch - 'a' + 'A'; + } + + return ch; +} + + +/********************************************************************* + * + * Function : get_string_param + * + * Description : Get a string paramater, to be used as an + * ACTION_STRING or ACTION_MULTI paramater. + * Validates the input to prevent stupid/malicious + * users from corrupting their action file. + * + * Parameters : + * 1 : parameters = map of cgi parameters + * 2 : param_name = The name of the parameter to read + * 3 : pparam = destination for paramater. Allocated as + * part of the map "parameters", so don't free it. + * Set to NULL if not specified. + * + * Returns : JB_ERR_OK on success, or if the paramater + * was not specified. + * JB_ERR_MEMORY on out-of-memory. + * JB_ERR_CGI_PARAMS if the paramater is not valid. + * + *********************************************************************/ +static jb_err get_string_param(const struct map *parameters, + const char *param_name, + const char **pparam) +{ + const char *param; + const char *s; + char ch; + + assert(parameters); + assert(param_name); + assert(pparam); + + *pparam = NULL; + + param = lookup(parameters, param_name); + if (!*param) + { + return JB_ERR_OK; + } + + if (strlen(param) >= CGI_ACTION_PARAM_LEN_MAX) + { + /* + * Too long. + * + * Note that the length limit is arbitrary, it just seems + * sensible to limit it to *something*. There's no + * technical reason for any limit at all. + */ + return JB_ERR_CGI_PARAMS; + } + + /* Check every character to see if it's legal */ + s = param; + while ((ch = *s++) != '\0') + { + if ( ((unsigned char)ch < (unsigned char)' ') + || (ch == '}') ) + { + /* Probable hack attempt, or user accidentally used '}'. */ + return JB_ERR_CGI_PARAMS; + } + } + + /* Success */ + *pparam = param; + + return JB_ERR_OK; +} + + /********************************************************************* * * Function : get_number_param @@ -1768,10 +1995,10 @@ static jb_err get_file_name_param(struct client_state *csp, * passed to a CGI function. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : parameters = map of cgi parameters - * 3 : name = Name of CGI parameter to read - * 4 : pvalue = destination for value. + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : parameters = map of cgi parameters + * 3 : name = Name of CGI parameter to read + * 4 : pvalue = destination for value. * Set to -1 on error. * * Returns : JB_ERR_OK on success @@ -1794,7 +2021,7 @@ static jb_err get_number_param(struct client_state *csp, assert(name); assert(pvalue); - *pvalue = -1; + *pvalue = 0; param = lookup(parameters, name); if (!*param) @@ -1833,6 +2060,7 @@ static jb_err get_number_param(struct client_state *csp, *pvalue = value; return JB_ERR_OK; + } @@ -1845,10 +2073,10 @@ static jb_err get_number_param(struct client_state *csp, * spaces and validates it. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : parameters = map of cgi parameters - * 3 : name = Name of CGI parameter to read - * 4 : pvalue = destination for value. Will be malloc()'d. + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : parameters = map of cgi parameters + * 3 : name = Name of CGI parameter to read + * 4 : pvalue = destination for value. Will be malloc()'d. * Set to NULL on error. * * Returns : JB_ERR_OK on success @@ -1978,10 +2206,10 @@ static jb_err get_url_spec_param(struct client_state *csp, * Where 'sel' is 'a', 'b', or 'c'. * * Parameters : - * 1 : exports = Exports map to modify. - * 2 : optionname = name for map - * 3 : values = null-terminated list of values; - * 4 : value = Selected value. + * 1 : exports = Exports map to modify. + * 2 : optionname = name for map + * 3 : values = null-terminated list of values; + * 4 : value = Selected value. * * CGI Parameters : None * @@ -1992,9 +2220,9 @@ static jb_err get_url_spec_param(struct client_state *csp, static jb_err map_radio(struct map * exports, const char * optionname, const char * values, - char value) + int value) { - int len; + size_t len; char * buf; char * p; char c; @@ -2022,20 +2250,13 @@ static jb_err map_radio(struct map * exports, *p = c; if (map(exports, buf, 1, "", 1)) { - free(buf); return JB_ERR_MEMORY; } } } *p = value; - if (map(exports, buf, 0, "checked", 1)) - { - free(buf); - return JB_ERR_MEMORY; - } - - return JB_ERR_OK; + return map(exports, buf, 0, "checked", 1); } @@ -2047,9 +2268,9 @@ static jb_err map_radio(struct map * exports, * outside the CGI editor. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : filename = The file that was modified. + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : filename = The file that was modified. * * CGI Parameters : none * @@ -2092,9 +2313,9 @@ jb_err cgi_error_modified(struct client_state *csp, * be parsed by the CGI editor. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : file = The file that was modified. + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : file = The file that was modified. * * CGI Parameters : none * @@ -2146,9 +2367,9 @@ jb_err cgi_error_parse(struct client_state *csp, * opened by the CGI editor. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : filename = The file that was modified. + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : filename = The file that was modified. * * CGI Parameters : none * @@ -2185,14 +2406,14 @@ jb_err cgi_error_file(struct client_state *csp, /********************************************************************* * - * Function : cgi_error_bad_param + * Function : cgi_error_disabled * - * Description : CGI function that is called if the parameters - * (query string) for a CGI were wrong. + * Description : CGI function that is called if the actions editor + * is called although it's disabled in config * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output * * CGI Parameters : none * @@ -2225,9 +2446,9 @@ jb_err cgi_error_disabled(struct client_state *csp, * actions file to edit. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : None * @@ -2246,13 +2467,13 @@ jb_err cgi_edit_actions(struct client_state *csp, } /* FIXME: Incomplete */ - rsp->status = strdup("302 Local Redirect from Junkbuster"); + rsp->status = strdup("302 Local Redirect from Privoxy"); if (rsp->status == NULL) { return JB_ERR_MEMORY; } if (enlist_unique_header(rsp->headers, "Location", - CGI_PREFIX "edit-actions-list?f=ijb")) + CGI_PREFIX "edit-actions-list?f=default")) { free(rsp->status); rsp->status = NULL; @@ -2271,9 +2492,9 @@ jb_err cgi_edit_actions(struct client_state *csp, * FIXME: This function shouldn't FATAL ever. * FIXME: This function doesn't check the retval of map() * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : filename * @@ -2626,9 +2847,9 @@ jb_err cgi_edit_actions_list(struct client_state *csp, * Description : CGI function that edits the Actions list. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : None * @@ -2648,6 +2869,8 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, struct file_line * cur_line; unsigned line_number; jb_err err; + struct file_list *filter_file; + struct re_filterfile_spec *filter_group; if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) { @@ -2696,6 +2919,118 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, if (!err) err = actions_to_radio(exports, cur_line->data.action); + filter_file = csp->rlist; + filter_group = ((filter_file != NULL) ? filter_file->f : NULL); + + if (!err) err = map_conditional(exports, "any-filters-defined", (filter_group != NULL)); + + if (err) + { + edit_free_file(file); + free_map(exports); + return err; + } + + if (filter_group == NULL) + { + err = map(exports, "filter-params", 1, "", 1); + } + else + { + /* We have some entries in the filter list */ + char * result; + int index = 0; + char * filter_template; + + err = template_load(csp, &filter_template, "edit-actions-for-url-filter"); + if (err) + { + edit_free_file(file); + free_map(exports); + if (err == JB_ERR_FILE) + { + return cgi_error_no_template(csp, rsp, "edit-actions-for-url-filter"); + } + return err; + } + + result = strdup(""); + + for (;(!err) && (filter_group != NULL); filter_group = filter_group->next) + { + char current_mode = 'x'; + struct list_entry *filter_name; + char * this_line; + struct map *line_exports; + char number[20]; + + filter_name = cur_line->data.action->multi_add[ACTION_MULTI_FILTER]->first; + while ((filter_name != NULL) + && (0 != strcmp(filter_group->name, filter_name->str))) + { + filter_name = filter_name->next; + } + + if (filter_name != NULL) + { + current_mode = 'y'; + } + else + { + filter_name = cur_line->data.action->multi_remove[ACTION_MULTI_FILTER]->first; + while ((filter_name != NULL) + && (0 != strcmp(filter_group->name, filter_name->str))) + { + filter_name = filter_name->next; + } + if (filter_name != NULL) + { + current_mode = 'n'; + } + } + + /* Generate a unique serial number */ + snprintf(number, sizeof(number), "%x", index++); + number[sizeof(number) - 1] = '\0'; + + line_exports = new_map(); + if (line_exports == NULL) + { + err = JB_ERR_MEMORY; + freez(result); + } + else + { + if (!err) err = map(line_exports, "index", 1, number, 1); + if (!err) err = map(line_exports, "name", 1, filter_group->name, 1); + if (!err) err = map(line_exports, "description", 1, filter_group->description, 1); + if (!err) err = map_radio(line_exports, "this-filter", "ynx", current_mode); + + this_line = NULL; + if (!err) + { + this_line = strdup(filter_template); + if (this_line == NULL) err = JB_ERR_MEMORY; + } + if (!err) err = template_fill(&this_line, line_exports); + string_join(&result, this_line); + + free_map(line_exports); + } + } + if (!err) + { + err = map(exports, "filter-params", 1, result, 0); + } + else + { + freez(result); + } + } + + if (!err) err = map_radio(exports, "filter-all", "nx", + (cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER] ? 'n' : 'x')); + edit_free_file(file); if (err) @@ -2715,9 +3050,9 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp, * Description : CGI function that actually edits the Actions list. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : None * @@ -2734,12 +3069,14 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, unsigned sectionid; char * actiontext; char * newtext; - int len; + size_t len; struct editable_file * file; struct file_line * cur_line; unsigned line_number; char * target; jb_err err; + int index; + char ch; if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS)) { @@ -2784,6 +3121,71 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, return err; } + ch = get_char_param(parameters, "filter_all"); + if (ch == 'N') + { + list_remove_all(cur_line->data.action->multi_add[ACTION_MULTI_FILTER]); + list_remove_all(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER]); + cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER] = 1; + } + else if (ch == 'X') + { + cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER] = 0; + } + + for (index = 0; !err; index++) + { + char key_value[30]; + char key_name[30]; + const char *name; + char value; + + /* Generate the keys */ + snprintf(key_value, sizeof(key_value), "filter_r%x", index); + key_value[sizeof(key_value) - 1] = '\0'; + snprintf(key_name, sizeof(key_name), "filter_n%x", index); + key_name[sizeof(key_name) - 1] = '\0'; + + err = get_string_param(parameters, key_name, &name); + if (err) break; + + if (name == NULL) + { + /* End of list */ + break; + } + + + value = get_char_param(parameters, key_value); + if (value == 'Y') + { + list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); + if (!err) err = enlist(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); + list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); + } + else if (value == 'N') + { + list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); + if (!cur_line->data.action->multi_remove_all[ACTION_MULTI_FILTER]) + { + list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); + if (!err) err = enlist(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); + } + } + else if (value == 'X') + { + list_remove_item(cur_line->data.action->multi_add[ACTION_MULTI_FILTER], name); + list_remove_item(cur_line->data.action->multi_remove[ACTION_MULTI_FILTER], name); + } + } + + if(err) + { + /* Out of memory */ + edit_free_file(file); + return err; + } + if (NULL == (actiontext = actions_to_text(cur_line->data.action))) { /* Out of memory */ @@ -2837,7 +3239,7 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, return JB_ERR_MEMORY; } - rsp->status = strdup("302 Local Redirect from Junkbuster"); + rsp->status = strdup("302 Local Redirect from Privoxy"); if (rsp->status == NULL) { free(target); @@ -2858,9 +3260,9 @@ jb_err cgi_edit_actions_submit(struct client_state *csp, * an actions file. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : * filename : Identifies the file to edit @@ -2959,7 +3361,7 @@ jb_err cgi_edit_actions_url(struct client_state *csp, return JB_ERR_MEMORY; } - rsp->status = strdup("302 Local Redirect from Junkbuster"); + rsp->status = strdup("302 Local Redirect from Privoxy"); if (rsp->status == NULL) { free(target); @@ -2980,9 +3382,9 @@ jb_err cgi_edit_actions_url(struct client_state *csp, * an actions file. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : * filename : Identifies the file to edit @@ -3098,7 +3500,7 @@ jb_err cgi_edit_actions_add_url(struct client_state *csp, return JB_ERR_MEMORY; } - rsp->status = strdup("302 Local Redirect from Junkbuster"); + rsp->status = strdup("302 Local Redirect from Privoxy"); if (rsp->status == NULL) { free(target); @@ -3119,9 +3521,9 @@ jb_err cgi_edit_actions_add_url(struct client_state *csp, * the actions file. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : * f : (filename) Identifies the file to edit @@ -3214,7 +3616,7 @@ jb_err cgi_edit_actions_remove_url(struct client_state *csp, return JB_ERR_MEMORY; } - rsp->status = strdup("302 Local Redirect from Junkbuster"); + rsp->status = strdup("302 Local Redirect from Privoxy"); if (rsp->status == NULL) { free(target); @@ -3236,9 +3638,9 @@ jb_err cgi_edit_actions_remove_url(struct client_state *csp, * (else JB_ERR_CGI_PARAMS). * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : * f : (filename) Identifies the file to edit @@ -3346,7 +3748,7 @@ jb_err cgi_edit_actions_section_remove(struct client_state *csp, return JB_ERR_MEMORY; } - rsp->status = strdup("302 Local Redirect from Junkbuster"); + rsp->status = strdup("302 Local Redirect from Privoxy"); if (rsp->status == NULL) { free(target); @@ -3367,9 +3769,9 @@ jb_err cgi_edit_actions_section_remove(struct client_state *csp, * an actions file. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : * f : (filename) Identifies the file to edit @@ -3520,7 +3922,7 @@ jb_err cgi_edit_actions_section_add(struct client_state *csp, return JB_ERR_MEMORY; } - rsp->status = strdup("302 Local Redirect from Junkbuster"); + rsp->status = strdup("302 Local Redirect from Privoxy"); if (rsp->status == NULL) { free(target); @@ -3544,9 +3946,9 @@ jb_err cgi_edit_actions_section_add(struct client_state *csp, * specified. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : * f : (filename) Identifies the file to edit @@ -3719,7 +4121,7 @@ jb_err cgi_edit_actions_section_swap(struct client_state *csp, return JB_ERR_MEMORY; } - rsp->status = strdup("302 Local Redirect from Junkbuster"); + rsp->status = strdup("302 Local Redirect from Privoxy"); if (rsp->status == NULL) { free(target); @@ -3740,9 +4142,9 @@ jb_err cgi_edit_actions_section_swap(struct client_state *csp, * an actions file. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : rsp = http_response data structure for output - * 3 : parameters = map of cgi parameters + * 1 : csp = Current client state (buffers, headers, etc...) + * 2 : rsp = http_response data structure for output + * 3 : parameters = map of cgi parameters * * CGI Parameters : * set : If present, how to change toggle setting: @@ -3760,7 +4162,6 @@ jb_err cgi_toggle(struct client_state *csp, struct map *exports; char mode; const char *template_name; - jb_err err; assert(csp); assert(rsp); @@ -3771,37 +4172,30 @@ jb_err cgi_toggle(struct client_state *csp, return cgi_error_disabled(csp, rsp); } - if (NULL == (exports = default_exports(csp, "toggle"))) - { - return JB_ERR_MEMORY; - } - - mode = *(lookup(parameters, "set")); + mode = get_char_param(parameters, "set"); - if (mode == 'e') + if (mode == 'E') { /* Enable */ g_bToggleIJB = 1; } - else if (mode == 'd') + else if (mode == 'D') { /* Disable */ g_bToggleIJB = 0; } - else if (mode == 't') + else if (mode == 'T') { /* Toggle */ g_bToggleIJB = !g_bToggleIJB; } - err = map_conditional(exports, "enabled", g_bToggleIJB); - if (err) + if (NULL == (exports = default_exports(csp, "toggle"))) { - free_map(exports); - return err; + return JB_ERR_MEMORY; } - template_name = (*(lookup(parameters, "mini")) + template_name = (get_char_param(parameters, "mini") ? "toggle-mini" : "toggle"); @@ -3809,6 +4203,44 @@ jb_err cgi_toggle(struct client_state *csp, } +/********************************************************************* + * + * Function : javascriptify + * + * Description : Converts a string into a form JavaScript will like. + * + * Netscape 4's JavaScript sucks - it doesn't use + * "id" parameters, so you have to set the "name" + * used to submit a form element to something JavaScript + * will like. (Or access the elements by index in an + * array. That array contains >60 elements and will + * be changed whenever we add a new action to the + * editor, so I'm NOT going to use indexes that have + * to be figured out by hand.) + * + * Currently the only thing we have to worry about + * is "-" ==> "_" conversion. + * + * This is a length-preserving operation so it is + * carried out in-place, no memory is allocated + * or freed. + * + * Parameters : + * 1 : identifier = String to make JavaScript-friendly. + * + * Returns : N/A + * + *********************************************************************/ +static void javascriptify(char * identifier) +{ + char * p = identifier; + while (NULL != (p = strchr(p, '-'))) + { + *p++ = '_'; + } +} + + /********************************************************************* * * Function : actions_to_radio @@ -3938,44 +4370,6 @@ static jb_err actions_to_radio(struct map * exports, } -/********************************************************************* - * - * Function : javascriptify - * - * Description : Converts a string into a form JavaScript will like. - * - * Netscape 4's JavaScript sucks - it doesn't use - * "id" parameters, so you have to set the "name" - * used to submit a form element to something JavaScript - * will like. (Or access the elements by index in an - * array. That array contains >60 elements and will - * be changed whenever we add a new action to the - * editor, so I'm NOT going to use indexes that have - * to be figured out by hand.) - * - * Currently the only thing we have to worry about - * is "-" ==> "_" conversion. - * - * This is a length-preserving operation so it is - * carried out in-place, no memory is allocated - * or freed. - * - * Parameters : - * 1 : identifier = String to make JavaScript-friendly. - * - * Returns : N/A - * - *********************************************************************/ -static void javascriptify(char * identifier) -{ - char * p = identifier; - while (NULL != (p = strchr(p, '-'))) - { - *p++ = '_'; - } -} - - /********************************************************************* * * Function : actions_from_radio @@ -3994,13 +4388,14 @@ static void javascriptify(char * identifier) * *********************************************************************/ static jb_err actions_from_radio(const struct map * parameters, - struct action_spec *action) + struct action_spec *action) { static int first_time = 1; const char * param; char * param_dup; char ch; const char * js_name; + jb_err err = JB_ERR_OK; assert(parameters); assert(action); @@ -4023,8 +4418,7 @@ static jb_err actions_from_radio(const struct map * parameters, #define DEFINE_ACTION_BOOL(name, bit) \ JAVASCRIPTIFY(js_name, name); \ - param = lookup(parameters, js_name); \ - ch = ijb_toupper(param[0]); \ + ch = get_char_param(parameters, js_name); \ if (ch == 'Y') \ { \ action->add |= bit; \ @@ -4043,18 +4437,18 @@ static jb_err actions_from_radio(const struct map * parameters, #define DEFINE_ACTION_STRING(name, bit, index) \ JAVASCRIPTIFY(js_name, name); \ - param = lookup(parameters, js_name); \ - ch = ijb_toupper(param[0]); \ + ch = get_char_param(parameters, js_name); \ if (ch == 'Y') \ { \ + param = NULL; \ JAVASCRIPTIFY(js_name, name "-mode"); \ - param = lookup(parameters, js_name); \ - if ((*param == '\0') || (0 == strcmp(param, "CUSTOM"))) \ - { \ - JAVASCRIPTIFY(js_name, name "-param"); \ - param = lookup(parameters, js_name); \ + if (!err) err = get_string_param(parameters, js_name, ¶m); \ + if ((param == NULL) || (0 == strcmp(param, "CUSTOM"))) \ + { \ + JAVASCRIPTIFY(js_name, name "-param"); \ + if (!err) err = get_string_param(parameters, js_name, ¶m); \ } \ - if (*param != '\0') \ + if (param != NULL) \ { \ if (NULL == (param_dup = strdup(param))) \ { \ @@ -4087,8 +4481,7 @@ static jb_err actions_from_radio(const struct map * parameters, #define DEFINE_ACTION_MULTI(name, index) \ JAVASCRIPTIFY(js_name, name); \ - param = lookup(parameters, js_name); \ - ch = ijb_toupper((int)param[0]); \ + ch = get_char_param(parameters, js_name); \ if (ch == 'Y') \ { \ /* FIXME */ \ @@ -4118,7 +4511,7 @@ static jb_err actions_from_radio(const struct map * parameters, first_time = 0; - return JB_ERR_OK; + return err; }