-const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.38 2002/05/03 23:00:38 jongfoster Exp $";
+const char cgiedit_rcs[] = "$Id: cgiedit.c,v 1.41.2.12 2006/01/30 15:16:25 david__schmidt Exp $";
/*********************************************************************
*
- * File : $Source: /cvsroot/ijbswa/current/cgiedit.c,v $
+ * File : $Source: /cvsroot/ijbswa/current/Attic/cgiedit.c,v $
*
* Purpose : CGI-based actionsfile editor.
*
*
* Revisions :
* $Log: cgiedit.c,v $
+ * Revision 1.41.2.12 2006/01/30 15:16:25 david__schmidt
+ * Remove a little residual debugging info
+ *
+ * Revision 1.41.2.11 2006/01/29 23:10:56 david__schmidt
+ * Multiple filter file support
+ *
+ * Revision 1.41.2.10 2005/07/04 03:13:43 david__schmidt
+ * Undo some damaging memory leak patches
+ *
+ * Revision 1.41.2.9 2005/07/04 00:31:04 david__schmidt
+ * Removing a double free
+ *
+ * Revision 1.41.2.8 2005/05/07 21:50:54 david__schmidt
+ * A few memory leaks plugged (mostly on error paths)
+ *
+ * Revision 1.41.2.7 2004/02/17 13:30:23 oes
+ * Moved cgi_error_disabled() from cgiedit.c to
+ * cgi.c to re-enable build with --disable-editor.
+ * Fixes Bug #892744. Thanks to Matthew Fischer
+ * for spotting.
+ *
+ * Revision 1.41.2.6 2003/12/18 08:13:48 oes
+ * One line lost in last commit
+ *
+ * Revision 1.41.2.5 2003/12/17 16:33:47 oes
+ * - All edit functions that redirect back to the list page
+ * now use cgi_redirect
+ * - All redirects now contain useless parameter "foo", whose
+ * value are raw seconds since epoch, in order to force
+ * Opera and Konqueror to properly reload the list. Closes
+ * bug #859993
+ *
+ * Revision 1.41.2.4 2003/03/11 11:53:59 oes
+ * Cosmetic: Renamed cryptic variable
+ *
+ * Revision 1.41.2.3 2002/11/12 15:01:41 oes
+ * Fix: Don't free uninitialized struct editable_file
+ *
+ * Revision 1.41.2.2 2002/08/05 20:02:59 oes
+ * Bugfix: "Insert new section at top" did not work properly if first non-comment line in file was of type FILE_LINE_ACTION
+ *
+ * Revision 1.41.2.1 2002/08/02 12:43:14 oes
+ * Fixed bug #588514: first_time now set on a per-string basis in actions_from_radio; javascriptify now called on copies
+ *
+ * Revision 1.41 2002/05/21 19:09:45 oes
+ * - Made Add/Edit/Remove URL Submit and Cancel
+ * buttons jump back to relevant section in eal
+ * - Bugfix: remove-url-form needs p export
+ *
+ * Revision 1.40 2002/05/19 11:34:35 jongfoster
+ * Handling read-only actions files better - report the actual
+ * error, not "Out of memory"!
+ *
+ * Bug report:
+ * http://sourceforge.net/tracker/index.php?func=detail
+ * &aid=557905&group_id=11118&atid=111118
+ *
+ * Revision 1.39 2002/05/12 21:39:15 jongfoster
+ * - Adding Doxygen-style comments to structures and #defines.
+ * - Correcting function comments
+ *
* Revision 1.38 2002/05/03 23:00:38 jongfoster
* Support for templates for "standard actions" buttons.
* See bug #549871
#include "errlog.h"
#include "loaders.h"
#include "loadcfg.h"
-/* loadcfg.h is for g_bToggleIJB only */
+/* loadcfg.h is for global_toggle_state only */
#include "urlmatch.h"
const char cgiedit_h_rcs[] = CGIEDIT_H_VERSION;
jb_err cgi_error_file(struct client_state *csp,
struct http_response *rsp,
const char *filename);
-jb_err cgi_error_disabled(struct client_state *csp,
- struct http_response *rsp);
+jb_err cgi_error_file_read_only(struct client_state *csp,
+ struct http_response *rsp,
+ const char *filename);
/* Internal arbitrary config file support functions */
static jb_err edit_read_file_lines(FILE *fp, struct file_line ** pfile, int *newline);
const char *name);
#endif /* unused function */
+/* Internal convenience functions */
+static char *section_target(const unsigned sectionid);
+
+/*********************************************************************
+ *
+ * Function : section_target
+ *
+ * Description : Given an unsigned (section id) n, produce a dynamically
+ * allocated string of the form #l<n>, for use in link
+ * targets.
+ *
+ * Parameters :
+ * 1 : sectionid = start line number of section
+ *
+ * Returns : String with link target, or NULL if out of
+ * memory
+ *
+ *********************************************************************/
+static char *section_target(const unsigned sectionid)
+{
+ char buf[30];
+
+ snprintf(buf, 30, "#l%d", sectionid);
+ return(strdup(buf));
+
+}
+
+
/*********************************************************************
*
* Function : map_copy_parameter_html
struct editable_file * file;
struct file_line * cur_line;
unsigned line_number;
+ unsigned section_start_line_number = 0;
jb_err err;
assert(csp);
for (line_number = 1; (cur_line != NULL) && (line_number < patternid); line_number++)
{
+ if (cur_line->type == FILE_LINE_ACTION)
+ {
+ section_start_line_number = line_number;
+ }
cur_line = cur_line->next;
}
if (!err) err = map(exports, "v", 1, file->version_str, 1);
if (!err) err = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0);
if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0);
+ if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0);
edit_free_file(file);
struct editable_file * file;
struct file_line * cur_line;
unsigned line_number;
+ unsigned section_start_line_number = 0;
jb_err err;
assert(csp);
for (line_number = 1; (cur_line != NULL) && (line_number < patternid); line_number++)
{
+ if (cur_line->type == FILE_LINE_ACTION)
+ {
+ section_start_line_number = line_number;
+ }
cur_line = cur_line->next;
}
err = map(exports, "f", 1, file->identifier, 1);
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 = map(exports, "p", 1, url_encode(lookup(parameters, "p")), 0);
if (!err) err = map(exports, "u", 1, html_encode(cur_line->unprocessed), 0);
+ if (!err) err = map(exports, "jumptarget", 1, section_target(section_start_line_number), 0);
edit_free_file(file);
/*********************************************************************
*
- * Function : cgi_error_disabled
+ * Function : cgi_error_file
*
- * Description : CGI function that is called if the actions editor
- * is called although it's disabled in config
+ * Description : CGI function that is called when a file cannot be
+ * opened for writing 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 we can't write to
*
* CGI Parameters : none
*
* JB_ERR_MEMORY on out-of-memory error.
*
*********************************************************************/
-jb_err cgi_error_disabled(struct client_state *csp,
- struct http_response *rsp)
+jb_err cgi_error_file_read_only(struct client_state *csp,
+ struct http_response *rsp,
+ const char *filename)
{
struct map *exports;
+ jb_err err;
assert(csp);
assert(rsp);
+ assert(filename);
if (NULL == (exports = default_exports(csp, NULL)))
{
return JB_ERR_MEMORY;
}
- return template_fill_for_cgi(csp, "cgi-error-disabled", exports, rsp);
+ err = map(exports, "f", 1, html_encode(filename), 0);
+ if (err)
+ {
+ free_map(exports);
+ return err;
+ }
+
+ return template_fill_for_cgi(csp, "cgi-error-file-read-only", exports, rsp);
}
}
/* FIXME: Incomplete */
- 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=default"))
- {
- free(rsp->status);
- rsp->status = NULL;
- return JB_ERR_MEMORY;
- }
- return JB_ERR_OK;
+ return cgi_redirect(rsp, CGI_PREFIX "edit-actions-list?f=default");
+
}
if (NULL == (exports = default_exports(csp, NULL)))
{
- edit_free_file(file);
return JB_ERR_MEMORY;
}
}
buttons = strdup("");
- for (i = 0; i < MAX_ACTION_FILES; i++)
+ for (i = 0; i < MAX_AF_FILES; i++)
{
if (((fl = csp->actions_list[i]) != NULL) && ((b = fl->f) != NULL))
{
/* Could also do section-specific exports here, but it wouldn't be as fast */
+ snprintf(buf, 150, "%d", line_number);
+ if (!err) err = map(section_exports, "s-next", 1, buf, 1);
+
if ( (cur_line != NULL)
&& (cur_line->type == FILE_LINE_ACTION))
{
/* Not last section */
- snprintf(buf, 150, "%d", line_number);
- if (!err) err = map(section_exports, "s-next", 1, buf, 1);
if (!err) err = map_block_keep(section_exports, "s-next-exists");
}
else
struct file_line * cur_line;
unsigned line_number;
jb_err err;
- struct file_list *filter_file;
struct re_filterfile_spec *filter_group;
+ int i, have_filters = 0;
if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
{
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));
+ for (i = 0; i < MAX_AF_FILES; i++)
+ {
+ if ((csp->rlist[i] != NULL) && (csp->rlist[i]->f != NULL))
+ {
+ if (!err) err = map_conditional(exports, "any-filters-defined", 1);
+ have_filters = 1;
+ break;
+ }
+ }
if (err)
{
return err;
}
- if (filter_group == NULL)
- {
+ if (0 == have_filters)
err = map(exports, "filter-params", 1, "", 1);
- }
else
{
/* We have some entries in the filter list */
result = strdup("");
- for (;(!err) && (filter_group != NULL); filter_group = filter_group->next)
+ for (i = 0; i < MAX_AF_FILES; i++)
{
- 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)))
+ if ((csp->rlist[i] != NULL) && (csp->rlist[i]->f != NULL))
{
- 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)
+ filter_group = csp->rlist[i]->f;
+ for (;(!err) && (filter_group != NULL); filter_group = filter_group->next)
{
- current_mode = 'n';
- }
- }
+ 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;
+ }
- /* Generate a unique serial number */
- snprintf(number, sizeof(number), "%x", index++);
- number[sizeof(number) - 1] = '\0';
+ 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';
+ }
+ }
- 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);
+ /* Generate a unique serial number */
+ snprintf(number, sizeof(number), "%x", index++);
+ number[sizeof(number) - 1] = '\0';
- 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);
+ 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);
+ free_map(line_exports);
+ }
+ }
}
}
-
freez(filter_template);
if (!err)
struct editable_file * file;
struct file_line * cur_line;
unsigned line_number;
- char * target;
+ char target[1024];
jb_err err;
int index;
const char * action_set_name;
get_string_param(parameters, "p", &action_set_name);
if (action_set_name != NULL)
{
- for (index = 0; index < MAX_ACTION_FILES; index++)
+ for (index = 0; index < MAX_AF_FILES; index++)
{
if (((fl = csp->actions_list[index]) != NULL) && ((b = fl->f) != NULL))
{
if (err)
{
/* Error writing file */
+ if (err == JB_ERR_FILE)
+ {
+ /* Read-only file. */
+ err = cgi_error_file_read_only(csp, rsp, file->identifier);
+ }
edit_free_file(file);
return err;
}
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
+ snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s#l%d",
+ (long) time(NULL), file->identifier, sectionid);
edit_free_file(file);
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
+ return cgi_redirect(rsp, target);
}
struct editable_file * file;
struct file_line * cur_line;
unsigned line_number;
- char * target;
+ unsigned section_start_line_number = 0;
+ char target[1024];
jb_err err;
+ assert(csp);
+ assert(rsp);
+ assert(parameters);
+
if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
{
return cgi_error_disabled(csp, rsp);
while ((cur_line != NULL) && (line_number < patternid))
{
+ if (cur_line->type == FILE_LINE_ACTION)
+ {
+ section_start_line_number = line_number;
+ }
cur_line = cur_line->next;
line_number++;
}
if (err)
{
/* Error writing file */
+ if (err == JB_ERR_FILE)
+ {
+ /* Read-only file. */
+ err = cgi_error_file_read_only(csp, rsp, file->identifier);
+ }
edit_free_file(file);
return err;
}
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
+ snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s#l%d",
+ (long) time(NULL), file->identifier, section_start_line_number);
edit_free_file(file);
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
+ return cgi_redirect(rsp, target);
}
struct editable_file * file;
struct file_line * cur_line;
unsigned line_number;
- char * target;
+ char target[1024];
jb_err err;
if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
if (err)
{
/* Error writing file */
+ if (err == JB_ERR_FILE)
+ {
+ /* Read-only file. */
+ err = cgi_error_file_read_only(csp, rsp, file->identifier);
+ }
edit_free_file(file);
return err;
}
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
+ snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s#l%d",
+ (long) time(NULL), file->identifier, sectionid);
edit_free_file(file);
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
+ return cgi_redirect(rsp, target);
}
struct file_line * cur_line;
struct file_line * prev_line;
unsigned line_number;
- char * target;
+ unsigned section_start_line_number = 0;
+ char target[1024];
jb_err err;
if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
while ((cur_line != NULL) && (line_number < patternid))
{
+ if (cur_line->type == FILE_LINE_ACTION)
+ {
+ section_start_line_number = line_number;
+ }
prev_line = cur_line;
cur_line = cur_line->next;
line_number++;
if (err)
{
/* Error writing file */
+ if (err == JB_ERR_FILE)
+ {
+ /* Read-only file. */
+ err = cgi_error_file_read_only(csp, rsp, file->identifier);
+ }
edit_free_file(file);
return err;
}
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
+ snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s#l%d",
+ (long) time(NULL), file->identifier, section_start_line_number);
edit_free_file(file);
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
+ return cgi_redirect(rsp, target);
}
struct file_line * cur_line;
struct file_line * prev_line;
unsigned line_number;
- char * target;
+ char target[1024];
jb_err err;
if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
if (err)
{
/* Error writing file */
+ if (err == JB_ERR_FILE)
+ {
+ /* Read-only file. */
+ err = cgi_error_file_read_only(csp, rsp, file->identifier);
+ }
edit_free_file(file);
return err;
}
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
+ snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s",
+ (long) time(NULL), file->identifier);
edit_free_file(file);
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
+ return cgi_redirect(rsp, target);
}
struct editable_file * file;
struct file_line * cur_line;
unsigned line_number;
- char * target;
+ char target[1024];
jb_err err;
if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
line_number = 1;
cur_line = file->lines;
- if (sectionid < 1U)
+ if (sectionid <= 1U)
{
/* Add to start of file */
- if (cur_line != NULL)
+ if (cur_line != NULL && cur_line->type != FILE_LINE_ACTION)
{
/* There's something in the file, find the line before the first
* action.
line_number++;
}
}
+ else
+ {
+ /* File starts with action line, so insert at top */
+ cur_line = NULL;
+ }
}
else
{
if (err)
{
/* Error writing file */
+ if (err == JB_ERR_FILE)
+ {
+ /* Read-only file. */
+ err = cgi_error_file_read_only(csp, rsp, file->identifier);
+ }
edit_free_file(file);
return err;
}
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
+ snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s",
+ (long) time(NULL), file->identifier);
edit_free_file(file);
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
+ return cgi_redirect(rsp, target);
}
struct file_line * line_end_section2;
struct file_line * line_after_section2;
unsigned line_number;
- char * target;
+ char target[1024];
jb_err err;
if (0 == (csp->config->feature_flags & RUNTIME_FEATURE_CGI_EDIT_ACTIONS))
if (err)
{
/* Error writing file */
+ if (err == JB_ERR_FILE)
+ {
+ /* Read-only file. */
+ err = cgi_error_file_read_only(csp, rsp, file->identifier);
+ }
edit_free_file(file);
return err;
}
} /* END if (section1 != section2) */
- target = strdup(CGI_PREFIX "edit-actions-list?f=");
- string_append(&target, file->identifier);
+ snprintf(target, 1024, CGI_PREFIX "edit-actions-list?foo=%lu&f=%s",
+ (long) time(NULL), file->identifier);
edit_free_file(file);
- if (target == NULL)
- {
- /* Out of memory */
- return JB_ERR_MEMORY;
- }
-
- rsp->status = strdup("302 Local Redirect from Privoxy");
- if (rsp->status == NULL)
- {
- free(target);
- return JB_ERR_MEMORY;
- }
- err = enlist_unique_header(rsp->headers, "Location", target);
- free(target);
-
- return err;
+ return cgi_redirect(rsp, target);
}
if (mode == 'E')
{
/* Enable */
- g_bToggleIJB = 1;
+ global_toggle_state = 1;
}
else if (mode == 'D')
{
/* Disable */
- g_bToggleIJB = 0;
+ global_toggle_state = 0;
}
else if (mode == 'T')
{
/* Toggle */
- g_bToggleIJB = !g_bToggleIJB;
+ global_toggle_state = !global_toggle_state;
}
if (NULL == (exports = default_exports(csp, "toggle")))
static jb_err actions_from_radio(const struct map * parameters,
struct action_spec *action)
{
- static int first_time = 1;
const char * param;
char * param_dup;
char ch;
* but in this case we're safe and don't need semaphores.
* Be careful if you modify this function.
* - Jon
+ * The js_name_arr's are never free()d, but this is no
+ * problem, since they will only be created once and
+ * used by all threads thereafter. -oes
*/
#define JAVASCRIPTIFY(dest_var, string) \
{ \
- static char js_name_arr[] = string; \
+ static int first_time = 1; \
+ static char *js_name_arr; \
if (first_time) \
{ \
+ js_name_arr = strdup(string); \
javascriptify(js_name_arr); \
} \
dest_var = js_name_arr; \
+ first_time = 0; \
} \
#define DEFINE_ACTION_BOOL(name, bit) \
#undef DEFINE_ACTION_ALIAS
#undef JAVASCRIPTIFY
- first_time = 0;
-
return err;
}