From: jongfoster Date: Sun, 14 Oct 2001 21:58:22 +0000 (+0000) Subject: Adding support for the CGI-based editor: X-Git-Tag: v_2_9_10~133 X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=commitdiff_plain;h=b8a25c6ddb98b93e2fea939522025674bf573ab7;hp=bcc571c691fcc50777f5106d99234b06cb3ff350 Adding support for the CGI-based editor: - Exported get_actions() - Added new function free_alias_list() - Added support for {{settings}} and {{description}} blocks in the actions file. They are currently ignored. - Added restriction to only one {{alias}} block which must appear first in the file, to simplify the editor's rewriting rules. - Note that load_actions_file() is no longer used by the CGI-based editor, but some of the other routines in this file are. --- diff --git a/actions.c b/actions.c index f08104bc..e86d613d 100644 --- a/actions.c +++ b/actions.c @@ -1,4 +1,4 @@ -const char actions_rcs[] = "$Id: actions.c,v 1.13 2001/09/16 15:47:37 jongfoster Exp $"; +const char actions_rcs[] = "$Id: actions.c,v 1.14 2001/09/22 16:36:59 jongfoster Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/actions.c,v $ @@ -33,6 +33,9 @@ const char actions_rcs[] = "$Id: actions.c,v 1.13 2001/09/16 15:47:37 jongfoster * * Revisions : * $Log: actions.c,v $ + * Revision 1.14 2001/09/22 16:36:59 jongfoster + * Removing unused parameter fs from read_config_line() + * * Revision 1.13 2001/09/16 15:47:37 jongfoster * First version of CGI-based edit interface. This is very much a * work-in-progress, and you can't actually use it to edit anything @@ -103,23 +106,6 @@ const char actions_rcs[] = "$Id: actions.c,v 1.13 2001/09/16 15:47:37 jongfoster const char actions_h_rcs[] = ACTIONS_H_VERSION; -/* Turn off everything except forwarding */ -/* This structure is used to hold user-defined aliases */ -struct action_alias -{ - const char * name; - struct action_spec action[1]; - struct action_alias * next; -}; - - -/* - * Must declare this in this file for the above structure. - */ -static int get_actions (char *line, - struct action_alias * alias_list, - struct action_spec *cur_action); - /* * We need the main list of options. * @@ -442,9 +428,9 @@ int get_action_token(char **line, char **name, char **value) * nonzero => Error (line was trashed anyway) * *********************************************************************/ -static int get_actions(char *line, - struct action_alias * alias_list, - struct action_spec *cur_action) +int get_actions(char *line, + struct action_alias * alias_list, + struct action_spec *cur_action) { init_action(cur_action); cur_action->mask = ACTION_MASK_ALL; @@ -990,6 +976,32 @@ void unload_actions_file(void *file_data) } +/********************************************************************* + * + * Function : free_alias_list + * + * Description : Free memory used by a list of aliases. + * + * Parameters : + * 1 : alias_list = Linked list to free. + * + * Returns : N/A + * + *********************************************************************/ +void free_alias_list(struct action_alias *alias_list) +{ + while (alias_list != NULL) + { + struct action_alias * next = alias_list->next; + alias_list->next = NULL; + freez((char *)alias_list->name); + free_action(alias_list->action); + free(alias_list); + alias_list = next; + } +} + + /********************************************************************* * * Function : load_actions_file @@ -1007,21 +1019,28 @@ int load_actions_file(struct client_state *csp) { static struct file_list *current_actions_file = NULL; - FILE *fp; + /* + * Parser mode. + * Note: Keep these in the order they occur in the file, they are + * sometimes tested with <= + */ +#define MODE_START_OF_FILE 1 +#define MODE_SETTINGS 2 +#define MODE_DESCRIPTION 3 +#define MODE_ALIAS 4 +#define MODE_ACTIONS 5 + + int mode = MODE_START_OF_FILE; + FILE *fp; struct url_actions *last_perm; struct url_actions *perm; char buf[BUFFER_SIZE]; struct file_list *fs; -#define MODE_START_OF_FILE 1 -#define MODE_ACTIONS 2 -#define MODE_ALIAS 3 - int mode = MODE_START_OF_FILE; - struct action_spec cur_action[1]; + struct action_spec * cur_action = NULL; + int cur_action_used = 0; struct action_alias * alias_list = NULL; - init_action(cur_action); - if (!check_file_changed(current_actions_file, csp->config->actions_file, &fs)) { /* No need to load */ @@ -1088,10 +1107,72 @@ int load_actions_file(struct client_state *csp) return 1; /* never get here */ } - if (0 == strcmpic(start, "alias")) + /* + * An actionsfile can optionally contain the following blocks. + * They *MUST* be in this order, to simplify processing: + * + * {{settings}} + * name=value... + * + * {{description}} + * ...free text, format TBD, but no line may start with a '{'... + * + * {{alias}} + * name=actions... + * + * The actual actions must be *after* these special blocks. + * None of these special blocks may be repeated. + * + */ + if (0 == strcmpic(start, "settings")) + { + /* it's a {{settings}} block */ + if (mode >= MODE_SETTINGS) + { + /* {{settings}} must be first thing in file and must only + * appear once. + */ + fclose(fp); + log_error(LOG_LEVEL_FATAL, + "can't load actions file '%s': {{settings}} must only appear once, and it must be before anything else.", + csp->config->actions_file); + } + mode = MODE_SETTINGS; + } + else if (0 == strcmpic(start, "description")) + { + /* it's a {{description}} block */ + if (mode >= MODE_DESCRIPTION) + { + /* {{description}} is a singleton and only {{settings}} may proceed it + */ + fclose(fp); + log_error(LOG_LEVEL_FATAL, + "can't load actions file '%s': {{description}} must only appear once, and only a {{settings}} block may be above it.", + csp->config->actions_file); + } + mode = MODE_DESCRIPTION; + } + else if (0 == strcmpic(start, "alias")) { /* it's an {{alias}} block */ - + if (mode >= MODE_ALIAS) + { + /* {{alias}} must be first thing in file, possibly after + * {{settings}} and {{description}} + * + * {{alias}} must only appear once. + * + * Note that these are new restrictions introduced in + * v2.9.10 in order to make actionsfile editing simpler. + * (Otherwise, reordering actionsfile entries without + * completely rewriting the file becomes non-trivial) + */ + fclose(fp); + log_error(LOG_LEVEL_FATAL, + "can't load actions file '%s': {{alias}} must only appear once, and it must be before all actions.", + csp->config->actions_file, start); + } mode = MODE_ALIAS; } else @@ -1115,7 +1196,26 @@ int load_actions_file(struct client_state *csp) mode = MODE_ACTIONS; /* free old action */ - free_action(cur_action); + if (cur_action) + { + if (!cur_action_used) + { + free_action(cur_action); + free(cur_action); + } + cur_action = NULL; + } + cur_action_used = 0; + cur_action = (struct action_spec *)zalloc(sizeof(*cur_action)); + if (cur_action == NULL) + { + fclose(fp); + log_error(LOG_LEVEL_FATAL, + "can't load actions file '%s': out of memory", + csp->config->actions_file); + return 1; /* never get here */ + } + init_action(cur_action); /* trim { */ strcpy(actions_buf, buf + 1); @@ -1157,9 +1257,26 @@ int load_actions_file(struct client_state *csp) } } } + else if (mode == MODE_SETTINGS) + { + /* + * Part of the {{settings}} block. + * Ignore for now, but we may want to read & check permissions + * when we go multi-user. + */ + } + else if (mode == MODE_DESCRIPTION) + { + /* + * Part of the {{description}} block. + * Ignore for now. + */ + } else if (mode == MODE_ALIAS) { - /* define an alias */ + /* + * define an alias + */ char actions_buf[BUFFER_SIZE]; struct action_alias * new_alias; @@ -1282,14 +1399,7 @@ int load_actions_file(struct client_state *csp) free_action(cur_action); - while (alias_list != NULL) - { - struct action_alias * next = alias_list->next; - freez((char *)alias_list->name); - free_action(alias_list->action); - free(alias_list); - alias_list = next; - } + free_alias_list(alias_list); /* the old one is now obsolete */ if (current_actions_file) diff --git a/actions.h b/actions.h index c823a656..366c6d71 100644 --- a/actions.h +++ b/actions.h @@ -1,6 +1,6 @@ #ifndef ACTIONS_H_INCLUDED #define ACTIONS_H_INCLUDED -#define ACTIONS_H_VERSION "$Id: actions.h,v 1.3 2001/09/14 00:17:32 jongfoster Exp $" +#define ACTIONS_H_VERSION "$Id: actions.h,v 1.4 2001/09/16 15:47:37 jongfoster Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/actions.h,v $ @@ -35,6 +35,12 @@ * * Revisions : * $Log: actions.h,v $ + * Revision 1.4 2001/09/16 15:47:37 jongfoster + * First version of CGI-based edit interface. This is very much a + * work-in-progress, and you can't actually use it to edit anything + * yet. You must #define FEATURE_CGI_EDIT_ACTIONS for these changes + * to have any effect. + * * Revision 1.3 2001/09/14 00:17:32 jongfoster * Tidying up memory allocation. New function init_action(). * @@ -58,6 +64,22 @@ struct action_spec; struct current_action_spec; struct client_state; + + +/* This structure is used to hold user-defined aliases */ +struct action_alias +{ + const char * name; + struct action_spec action[1]; + struct action_alias * next; +}; + + +extern int get_actions (char *line, + struct action_alias * alias_list, + struct action_spec *cur_action); +extern void free_alias_list(struct action_alias *alias_list); + extern void init_action(struct action_spec *dest); extern void free_action(struct action_spec *src); extern void merge_actions (struct action_spec *dest, @@ -80,6 +102,7 @@ extern void unload_actions_file(void *file_data); extern int load_actions_file(struct client_state *csp); + /* Revision control strings from this header and associated .c file */ extern const char actions_rcs[]; extern const char actions_h_rcs[];