X-Git-Url: http://www.privoxy.org/gitweb/new.html?a=blobdiff_plain;f=cgiedit.c;h=e73d5ee74371ea1283cb0070f65d9964f5fed4b8;hb=7fb978c74a8a46bd105d9f0ced92a4be0c9647e6;hp=8463328a2ebfdf7d3ca1987cc58ea7b596eaa33e;hpb=4f4d26f5a63e82b6429a28db1b28698ec5f6c19c;p=privoxy.git
diff --git a/cgiedit.c b/cgiedit.c
index 8463328a..e73d5ee7 100644
--- a/cgiedit.c
+++ b/cgiedit.c
@@ -1,4 +1,3 @@
-const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.86 2014/10/18 11:29:48 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/cgiedit.c,v $
@@ -14,7 +13,7 @@ const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.86 2014/10/18 11:29:48 fabiankeil
* Stick to the short names in this file for consistency.
*
* Copyright : Written by and Copyright (C) 2001-2014 the
- * Privoxy team. http://www.privoxy.org/
+ * Privoxy team. https://www.privoxy.org/
*
* Based on the Internet Junkbuster originally written
* by and Copyright (C) 1997 Anonymous Coders and
@@ -71,8 +70,6 @@ const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.86 2014/10/18 11:29:48 fabiankeil
#endif /* def FEATURE_TOGGLE */
#include "urlmatch.h"
-const char cgiedit_h_rcs[] = CGIEDIT_H_VERSION;
-
#ifdef FEATURE_CGI_EDIT_ACTIONS
@@ -191,7 +188,7 @@ struct editable_file
* Information about the filter types.
* Used for macro replacement in cgi_edit_actions_for_url.
*/
-struct filter_type_info
+struct action_type_info
{
const int multi_action_index; /**< The multi action index as defined in project.h */
const char *macro_name; /**< Name of the macro that has to be replaced
@@ -211,7 +208,7 @@ struct filter_type_info
};
/* Accessed by index, keep the order in the way the FT_ macros are defined. */
-static const struct filter_type_info filter_type_info[] =
+static const struct action_type_info action_type_info[] =
{
{
ACTION_MULTI_FILTER,
@@ -243,6 +240,24 @@ static const struct filter_type_info filter_type_info[] =
"server-header-tagger-all", "server_header_tagger_all",
"E", "SERVER-HEADER-TAGGER"
},
+ {
+ ACTION_MULTI_SUPPRESS_TAG,
+ "suppress-tag-params", "suppress-tag",
+ "suppress-tag-all", "suppress_tag_all",
+ "U", "SUPPRESS-TAG"
+ },
+ {
+ ACTION_MULTI_CLIENT_BODY_FILTER,
+ "client-body-filter-params", "client-body-filter",
+ "client-body-filter-all", "client_body_filter_all",
+ "P", "CLIENT-BODY-FILTER"
+ },
+ {
+ ACTION_MULTI_ADD_HEADER,
+ "add-header-params", "add-header",
+ "add-header-all", "add_header_all",
+ "H", "ADD-HEADER"
+ },
#ifdef FEATURE_EXTERNAL_FILTERS
{
ACTION_MULTI_EXTERNAL_FILTER,
@@ -253,6 +268,30 @@ static const struct filter_type_info filter_type_info[] =
#endif
};
+/**
+ * Information about the string filter actions.
+ * Used for macro replacement in action_render_string_actions_template
+ */
+struct string_action_type_info
+{
+ const enum filter_type action_type; /**< Action type */
+ const char *description; /**< Action description */
+ const char *input_description; /**< Input field description */
+};
+
+/* String action types: special CGI handling */
+static const struct string_action_type_info string_action_type_info[] =
+{
+ {
+ FT_SUPPRESS_TAG,
+ "Suppress tag", "Tag to suppress"
+ },
+ {
+ FT_ADD_HEADER,
+ "Add HTTP client header", "HTTP client header to add"
+ },
+};
+
/* FIXME: Following non-static functions should be prototyped in .h or made static */
/* Functions to read and write arbitrary config files */
@@ -309,6 +348,10 @@ static jb_err actions_to_radio(struct map * exports,
const struct action_spec *action);
static jb_err actions_from_radio(const struct map * parameters,
struct action_spec *action);
+static jb_err action_render_string_actions_template(struct map * exports,
+ const struct action_spec *action,
+ const char* action_template,
+ const struct string_action_type_info *string_action_type);
static jb_err map_copy_parameter_html(struct map *out,
@@ -1103,7 +1146,7 @@ jb_err edit_parse_actions_file(struct editable_file * file)
/* alias_list contains the aliases defined in this file.
* It might be better to use the "file_line.data" fields
- * in the relavent places instead.
+ * in the relevant places instead.
*/
cur_line = file->lines;
@@ -1219,14 +1262,7 @@ jb_err edit_parse_actions_file(struct editable_file * file)
return JB_ERR_PARSE;
}
- if ((new_alias = zalloc(sizeof(*new_alias))) == NULL)
- {
- /* Out of memory */
- free(name);
- free(value);
- free_alias_list(alias_list);
- return JB_ERR_MEMORY;
- }
+ new_alias = zalloc_or_die(sizeof(*new_alias));
err = get_actions(value, alias_list, new_alias->action);
if (err)
@@ -1394,11 +1430,7 @@ jb_err edit_read_file_lines(FILE *fp, struct file_line ** pfile, int *newline)
*pfile = NULL;
- cur_line = first_line = zalloc(sizeof(struct file_line));
- if (cur_line == NULL)
- {
- return JB_ERR_MEMORY;
- }
+ cur_line = first_line = zalloc_or_die(sizeof(struct file_line));
cur_line->type = FILE_LINE_UNPROCESSED;
@@ -1414,13 +1446,7 @@ jb_err edit_read_file_lines(FILE *fp, struct file_line ** pfile, int *newline)
do
{
prev_line = cur_line;
- cur_line = prev_line->next = zalloc(sizeof(struct file_line));
- if (cur_line == NULL)
- {
- /* Out of memory */
- edit_free_file_lines(first_line);
- return JB_ERR_MEMORY;
- }
+ cur_line = prev_line->next = zalloc_or_die(sizeof(struct file_line));
cur_line->type = FILE_LINE_UNPROCESSED;
@@ -1550,12 +1576,7 @@ jb_err edit_read_file(struct client_state *csp,
return err;
}
- file = (struct editable_file *) zalloc(sizeof(*file));
- if (file == NULL)
- {
- edit_free_file_lines(lines);
- return err;
- }
+ file = zalloc_or_die(sizeof(*file));
file->lines = lines;
file->newline = newline;
@@ -1878,12 +1899,12 @@ static jb_err get_url_spec_param(struct client_state *csp,
}
err = create_pattern_spec(compiled, s);
free(s);
+ free_pattern_spec(compiled);
if (err)
{
free(param);
return (err == JB_ERR_MEMORY) ? JB_ERR_MEMORY : JB_ERR_CGI_PARAMS;
}
- free_pattern_spec(compiled);
if (param[strlen(param) - 1] == '\\')
{
@@ -1914,12 +1935,12 @@ static jb_err get_url_spec_param(struct client_state *csp,
}
err = create_pattern_spec(compiled, s);
free(s);
+ free_pattern_spec(compiled);
if (err)
{
free(param);
return (err == JB_ERR_MEMORY) ? JB_ERR_MEMORY : JB_ERR_CGI_PARAMS;
}
- free_pattern_spec(compiled);
}
*pvalue = param;
@@ -2710,6 +2731,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
const struct map *parameters)
{
struct map * exports;
+ char *filter_template;
unsigned sectionid;
struct editable_file * file;
struct file_line * cur_line;
@@ -2759,12 +2781,27 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
return JB_ERR_MEMORY;
}
+ err = template_load(csp, &filter_template, "edit-actions-for-url-string-action", 0);
+ if (err)
+ {
+ edit_free_file(file);
+ free_map(exports);
+ return cgi_error_no_template(csp, rsp, "edit-actions-for-url-string-action");
+ }
+
err = map(exports, "f", 1, stringify(file->identifier), 0);
if (!err) err = map(exports, "v", 1, file->version_str, 1);
if (!err) err = map(exports, "s", 1, url_encode(lookup(parameters, "s")), 0);
if (!err) err = actions_to_radio(exports, cur_line->data.action);
+ for (i = 0; !err && i < SZ(string_action_type_info); i++)
+ {
+ err = action_render_string_actions_template(exports, cur_line->data.action, filter_template,
+ &string_action_type_info[i]);
+ }
+ freez(filter_template);
+
/*
* XXX: Some browsers (at least IE6 and IE7) have an artificial URL
* length limitation and ignore clicks on the Submit buttons if
@@ -2775,7 +2812,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
* browsers (BR #1570678).
*
* The config option split-large-forms works around this browser
- * bug (HTTP has no URL length limitation) by deviding the action
+ * bug (HTTP has no URL length limitation) by dividing the action
* list form into multiple smaller ones. It means the URLs are shorter
* and work in broken browsers as well, but the user can no longer change
* all actions with one submit.
@@ -2807,6 +2844,9 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
#ifndef FEATURE_EXTERNAL_FILTERS
if (!err) err = map_block_killer(exports, "external-content-filters");
#endif
+#ifndef FEATURE_HTTPS_INSPECTION
+ if (!err) err = map_block_killer(exports, "https-inspection");
+#endif
if (err)
{
@@ -2824,7 +2864,6 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
/*
* List available filters and their settings.
*/
- char *filter_template;
int filter_identifier = 0;
char *prepared_templates[MAX_FILTER_TYPES];
@@ -2858,8 +2897,8 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
char number[20];
struct list_entry *filter_name;
struct map *line_exports;
- const int type = filter_group->type;
- const int multi_action_index = filter_type_info[type].multi_action_index;
+ const enum filter_type type = filter_group->type;
+ const int multi_action_index = action_type_info[type].multi_action_index;
assert(type < MAX_FILTER_TYPES);
@@ -2905,9 +2944,9 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
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);
- if (!err) err = map(line_exports, "filter-type", 1, filter_type_info[type].type, 1);
- if (!err) err = map(line_exports, "abbr-filter-type", 1, filter_type_info[type].abbr_type, 1);
- if (!err) err = map(line_exports, "anchor", 1, filter_type_info[type].anchor, 1);
+ if (!err) err = map(line_exports, "filter-type", 1, action_type_info[type].type, 1);
+ if (!err) err = map(line_exports, "abbr-action-type", 1, action_type_info[type].abbr_type, 1);
+ if (!err) err = map(line_exports, "anchor", 1, action_type_info[type].anchor, 1);
if (!err)
{
@@ -2915,7 +2954,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
if (filter_line == NULL) err = JB_ERR_MEMORY;
}
if (!err) err = template_fill(&filter_line, line_exports);
- string_join(&prepared_templates[type], filter_line);
+ if (!err) err = string_join(&prepared_templates[type], filter_line);
free_map(line_exports);
}
@@ -2928,7 +2967,7 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
for (i = 0; i < MAX_FILTER_TYPES; i++)
{
if (err) break;
- err = map(exports, filter_type_info[i].macro_name, 1, prepared_templates[i], 0);
+ err = map(exports, action_type_info[i].macro_name, 1, prepared_templates[i], 0);
}
if (err)
@@ -2944,10 +2983,10 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
/* Check or uncheck the "disable all of this type" radio buttons. */
for (i = 0; i < MAX_FILTER_TYPES; i++)
{
- const int a = filter_type_info[i].multi_action_index;
+ const int a = action_type_info[i].multi_action_index;
const int disable_all = cur_line->data.action->multi_remove_all[a];
if (err) break;
- err = map_radio(exports, filter_type_info[i].disable_all_option, "nx", (disable_all ? 'n' : 'x'));
+ err = map_radio(exports, action_type_info[i].disable_all_option, "nx", (disable_all ? 'n' : 'x'));
}
edit_free_file(file);
@@ -2962,6 +3001,215 @@ jb_err cgi_edit_actions_for_url(struct client_state *csp,
}
+/*********************************************************************
+ *
+ * Function : get_number_of_filters
+ *
+ * Description : Counts the number of filter available.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns : Number of filters available.
+ *
+ *********************************************************************/
+static int get_number_of_filters(const struct client_state *csp)
+{
+ int i;
+ struct re_filterfile_spec *b;
+ struct file_list *fl;
+ int number_of_filters = 0;
+
+ for (i = 0; i < MAX_AF_FILES; i++)
+ {
+ fl = csp->rlist[i];
+ if ((NULL == fl) || (NULL == fl->f))
+ {
+ /*
+ * Either there are no filter files left or this
+ * filter file just contains no valid filters.
+ *
+ * Continue to be sure we don't miss valid filter
+ * files that are chained after empty or invalid ones.
+ */
+ continue;
+ }
+
+ for (b = fl->f; b != NULL; b = b->next)
+ {
+ number_of_filters++;
+ }
+ }
+
+ return number_of_filters;
+
+}
+
+
+/*********************************************************************
+ *
+ * Function : cgi_edit_process_string_action
+ *
+ * Description : Helper CGI function that actually edits the Actions list for
+ * the action string parameters.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ * 2 : rsp = http_response data structure for output
+ * 3 : parameters = map of cgi parameters
+ * 4 : cur_line = current config file line
+ * 5 : action_type = string filter type to process
+ *
+ * Returns : JB_ERR_OK on success
+ * JB_ERR_MEMORY on out-of-memory
+ * JB_ERR_CGI_PARAMS if the CGI parameters are not
+ * specified or not valid.
+ *
+ *********************************************************************/
+static jb_err cgi_edit_process_string_action(struct client_state *csp,
+ struct http_response *rsp,
+ const struct map *parameters,
+ struct file_line *cur_line,
+ enum filter_type action_type)
+{
+ jb_err err = JB_ERR_OK;
+ const char *abbr_type = action_type_info[action_type].abbr_type;
+ int action_identifier = 0;
+
+ /* process existing string filter actions */
+ for (action_identifier = 0; !err; action_identifier++)
+ {
+ char key_value[30];
+ char key_name[30];
+ char old_name[30];
+ char key_type[30];
+ const char *name, *new_name;
+ char value; /*
+ * Action state. Valid states are: 'Y' (active),
+ * 'N' (inactive) and 'X' (no change).
+ * XXX: bad name.
+ */
+ char type; /*
+ * Abbreviated filter type. Valid types are: 'U' (suppress tag), 'H' (add header)
+ */
+ int multi_action_index = 0;
+
+ /* Generate the keys */
+ snprintf(key_value, sizeof(key_value), "string_action_%s_r%x", abbr_type, action_identifier);
+ snprintf(key_name, sizeof(key_name), "string_action_%s_n%x", abbr_type, action_identifier);
+ snprintf(old_name, sizeof(old_name), "string_action_%s_o%x", abbr_type, action_identifier);
+ snprintf(key_type, sizeof(key_type), "string_action_%s_t%x", abbr_type, action_identifier);
+
+ err = get_string_param(parameters, old_name, &name);
+ if (err) break;
+
+ if (name == NULL)
+ {
+ /* The action identifier isn't present: we're done! */
+ break;
+ }
+
+ err = get_string_param(parameters, key_name, &new_name);
+ if (err) break;
+ if (new_name == NULL) new_name = name;
+
+ type = get_char_param(parameters, key_type);
+ switch (type)
+ {
+ case 'U':
+ multi_action_index = ACTION_MULTI_SUPPRESS_TAG;
+ break;
+ case 'H':
+ multi_action_index = ACTION_MULTI_ADD_HEADER;
+ break;
+ default:
+ log_error(LOG_LEVEL_ERROR,
+ "Unknown action type: %c for action %s. Action ignored.", type, name);
+ continue;
+ }
+
+ value = get_char_param(parameters, key_value);
+ if (value == 'X' || value == 'Y' || value == 'N')
+ {
+ list_remove_item(cur_line->data.action->multi_add[multi_action_index], name);
+ list_remove_item(cur_line->data.action->multi_remove[multi_action_index], name);
+ }
+
+ if (value == 'Y')
+ {
+ err = enlist(cur_line->data.action->multi_add[multi_action_index], new_name);
+ }
+ else if (value == 'N')
+ {
+ err = enlist(cur_line->data.action->multi_remove[multi_action_index], new_name);
+ }
+ }
+
+ /* process new string filter actions */
+ for (action_identifier = 0; !err; action_identifier++)
+ {
+ char key_value[30];
+ char key_name[30];
+ char key_type[30];
+ const char *name;
+ char value; /*
+ * Action state. Valid states are: 'Y' (active),
+ * 'N' (inactive) and 'X' (no change).
+ * XXX: bad name.
+ */
+ char type; /*
+ * Abbreviated filter type. Valid types are: 'U' (suppress tag), 'H' (add header)
+ */
+ int multi_action_index = 0;
+
+ /* Generate the keys */
+ snprintf(key_value, sizeof(key_value), "new_string_action_%s_r%x", abbr_type, action_identifier);
+ snprintf(key_name, sizeof(key_name), "new_string_action_%s_n%x", abbr_type, action_identifier);
+ snprintf(key_type, sizeof(key_type), "new_string_action_%s_t%x", abbr_type, action_identifier);
+
+ err = get_string_param(parameters, key_name, &name);
+ if (err) break;
+
+ if (name == NULL)
+ {
+ /* The action identifier isn't present: we've done! */
+ break;
+ }
+
+ type = get_char_param(parameters, key_type);
+ switch (type)
+ {
+ case 'U':
+ multi_action_index = ACTION_MULTI_SUPPRESS_TAG;
+ break;
+ case 'H':
+ multi_action_index = ACTION_MULTI_ADD_HEADER;
+ break;
+ default:
+ log_error(LOG_LEVEL_ERROR,
+ "Unknown filter type: %c for filter %s. Filter ignored.", type, name);
+ continue;
+ }
+
+ value = get_char_param(parameters, key_value);
+ if (value == 'Y')
+ {
+ list_remove_item(cur_line->data.action->multi_add[multi_action_index], name);
+ if (!err) err = enlist(cur_line->data.action->multi_add[multi_action_index], name);
+ list_remove_item(cur_line->data.action->multi_remove[multi_action_index], name);
+ }
+ else if (value == 'N')
+ {
+ list_remove_item(cur_line->data.action->multi_add[multi_action_index], name);
+ list_remove_item(cur_line->data.action->multi_remove[multi_action_index], name);
+ if (!err) err = enlist(cur_line->data.action->multi_remove[multi_action_index], name);
+ }
+ /* nothing to do if the value is 'X' */
+ }
+ return err;
+}
+
+
/*********************************************************************
*
* Function : cgi_edit_actions_submit
@@ -3000,6 +3248,7 @@ jb_err cgi_edit_actions_submit(struct client_state *csp,
const char * action_set_name;
struct file_list * fl;
struct url_actions * b;
+ int number_of_filters;
if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
{
@@ -3073,8 +3322,8 @@ jb_err cgi_edit_actions_submit(struct client_state *csp,
/* Check the "disable all of this type" parameters. */
for (i = 0; i < MAX_FILTER_TYPES; i++)
{
- const int multi_action_index = filter_type_info[i].multi_action_index;
- const char ch = get_char_param(parameters, filter_type_info[i].disable_all_param);
+ const int multi_action_index = action_type_info[i].multi_action_index;
+ const char ch = get_char_param(parameters, action_type_info[i].disable_all_param);
if (ch == 'N')
{
@@ -3088,7 +3337,9 @@ jb_err cgi_edit_actions_submit(struct client_state *csp,
}
}
- for (filter_identifier = 0; !err; filter_identifier++)
+ number_of_filters = get_number_of_filters(csp);
+
+ for (filter_identifier = 0; filter_identifier < number_of_filters && !err; filter_identifier++)
{
char key_value[30];
char key_name[30];
@@ -3117,8 +3368,8 @@ jb_err cgi_edit_actions_submit(struct client_state *csp,
if (name == NULL)
{
- /* End of list */
- break;
+ /* The filter identifier isn't present. Try the next one. */
+ continue;
}
type = get_char_param(parameters, key_type);
@@ -3139,6 +3390,9 @@ jb_err cgi_edit_actions_submit(struct client_state *csp,
case 'E':
multi_action_index = ACTION_MULTI_SERVER_HEADER_TAGGER;
break;
+ case 'P':
+ multi_action_index = ACTION_MULTI_CLIENT_BODY_FILTER;
+ break;
default:
log_error(LOG_LEVEL_ERROR,
"Unknown filter type: %c for filter %s. Filter ignored.", type, name);
@@ -3169,6 +3423,13 @@ jb_err cgi_edit_actions_submit(struct client_state *csp,
}
}
+ /* process new string filters */
+ for (i = 0; !err && i < SZ(string_action_type_info); i++)
+ {
+ err = cgi_edit_process_string_action(csp, rsp, parameters, cur_line,
+ string_action_type_info[i].action_type);
+ }
+
if (err)
{
/* Out of memory */
@@ -3218,8 +3479,8 @@ jb_err cgi_edit_actions_submit(struct client_state *csp,
return err;
}
- snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%i#l%u",
- (long) time(NULL), file->identifier, sectionid);
+ snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u#l%u",
+ (unsigned long) time(NULL), file->identifier, sectionid);
edit_free_file(file);
@@ -3339,8 +3600,8 @@ jb_err cgi_edit_actions_url(struct client_state *csp,
return err;
}
- snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%i#l%u",
- (long) time(NULL), file->identifier, section_start_line_number);
+ snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u#l%u",
+ (unsigned long) time(NULL), file->identifier, section_start_line_number);
edit_free_file(file);
@@ -3435,13 +3696,7 @@ jb_err cgi_edit_actions_add_url(struct client_state *csp,
/* At this point, the section header is in cur_line - add after this. */
/* Allocate the new line */
- new_line = (struct file_line *)zalloc(sizeof(*new_line));
- if (new_line == NULL)
- {
- free(new_pattern);
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
+ new_line = zalloc_or_die(sizeof(*new_line));
/* Fill in the data members of the new line */
new_line->raw = NULL;
@@ -3468,8 +3723,8 @@ jb_err cgi_edit_actions_add_url(struct client_state *csp,
return err;
}
- snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%i#l%u",
- (long) time(NULL), file->identifier, sectionid);
+ snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u#l%u",
+ (unsigned long) time(NULL), file->identifier, sectionid);
edit_free_file(file);
@@ -3580,7 +3835,7 @@ jb_err cgi_edit_actions_remove_url(struct client_state *csp,
}
snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u#l%u",
- (long) time(NULL), file->identifier, section_start_line_number);
+ (unsigned long) time(NULL), file->identifier, section_start_line_number);
edit_free_file(file);
@@ -3702,7 +3957,7 @@ jb_err cgi_edit_actions_section_remove(struct client_state *csp,
}
snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u",
- (long) time(NULL), file->identifier);
+ (unsigned long) time(NULL), file->identifier);
edit_free_file(file);
@@ -3828,13 +4083,7 @@ jb_err cgi_edit_actions_section_add(struct client_state *csp,
}
/* Allocate the new line */
- new_line = (struct file_line *)zalloc(sizeof(*new_line));
- if (new_line == NULL)
- {
- free(new_text);
- edit_free_file(file);
- return JB_ERR_MEMORY;
- }
+ new_line = zalloc_or_die(sizeof(*new_line));
/* Fill in the data members of the new line */
new_line->raw = NULL;
@@ -3871,7 +4120,7 @@ jb_err cgi_edit_actions_section_add(struct client_state *csp,
}
snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u",
- (long) time(NULL), file->identifier);
+ (unsigned long) time(NULL), file->identifier);
edit_free_file(file);
@@ -4060,7 +4309,7 @@ jb_err cgi_edit_actions_section_swap(struct client_state *csp,
} /* END if (section1 != section2) */
snprintf(target, sizeof(target), CGI_PREFIX "edit-actions-list?foo=%lu&f=%u",
- (long) time(NULL), file->identifier);
+ (unsigned long) time(NULL), file->identifier);
edit_free_file(file);
@@ -4234,6 +4483,88 @@ static jb_err actions_to_radio(struct map * exports,
return JB_ERR_OK;
}
+/*********************************************************************
+ *
+ * Function : action_render_string_actions_template
+ *
+ * Description : Converts a actionsfile entry into HTML template for actions with string
+ * filters (currently SUPPRESS-TAG actions only)
+ *
+ * Parameters :
+ * 1 : exports = List of substitutions to add to.
+ * 2 : action = Action to read
+ * 3 : action_template = template to fill
+ * 4 : type = filter type info for rendered values/macro name
+ *
+ * Returns : JB_ERR_OK on success
+ * JB_ERR_MEMORY on out-of-memory
+ *
+ *********************************************************************/
+static jb_err action_render_string_actions_template(struct map * exports,
+ const struct action_spec *action,
+ const char* action_template,
+ const struct string_action_type_info *string_action_type)
+{
+ jb_err err = JB_ERR_OK;
+ int filter_identifier = 0;
+ int i;
+ char *prepared_template = strdup("");
+ const struct action_type_info *type = &action_type_info[string_action_type->action_type];
+
+ struct action_multi {
+ char radio;
+ struct list_entry *list;
+ };
+
+ struct action_multi desc[] = {
+ { 'y', action->multi_add[type->multi_action_index][0].first },
+ { 'n', action->multi_remove[type->multi_action_index][0].first }
+ };
+
+ for (i = 0; i < SZ(desc); ++i)
+ {
+ const char radio = desc[i].radio;
+ struct list_entry *entry = desc[i].list;
+ for (;(!err) && (entry != NULL); entry = entry->next)
+ {
+ char number[20];
+ struct map *line_exports;
+
+ /* Generate a unique serial number */
+ snprintf(number, sizeof(number), "%x", filter_identifier++);
+
+ line_exports = new_map();
+ if (line_exports == NULL)
+ {
+ err = JB_ERR_MEMORY;
+ }
+ else
+ {
+ char *action_line;
+ if (!err) err = map(line_exports, "index", 1, number, 1);
+ if (!err) err = map(line_exports, "name", 1, entry->str, 1);
+ if (!err) err = map_radio(line_exports, "this-filter", "ynx", radio);
+ if (!err) err = map(line_exports, "filter-type", 1, type->type, 1);
+ if (!err) err = map(line_exports, "abbr-action-type", 1, type->abbr_type, 1);
+ if (!err) err = map(line_exports, "anchor", 1, type->anchor, 1);
+ if (!err) err = map(line_exports, "desc", 1, string_action_type->description, 1);
+ if (!err) err = map(line_exports, "input_desc", 1, string_action_type->input_description, 1);
+ if (!err)
+ {
+ action_line = strdup(action_template);
+ if (action_line == NULL) err = JB_ERR_MEMORY;
+ }
+ if (!err) err = template_fill(&action_line, line_exports);
+ if (!err) err = string_join(&prepared_template, action_line);
+
+ free_map(line_exports);
+ }
+ }
+ }
+ if (!err) map(exports, type->macro_name, 1, prepared_template, 1);
+ freez(prepared_template);
+ return err;
+}
/*********************************************************************
*
@@ -4441,6 +4772,8 @@ jb_err cgi_toggle(struct client_state *csp,
global_toggle_state = !global_toggle_state;
}
+ log_error(LOG_LEVEL_INFO, "Now toggled %s.", global_toggle_state ? "ON" : "OFF");
+
if (NULL == (exports = default_exports(csp, "toggle")))
{
return JB_ERR_MEMORY;