Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
[privoxy.git] / actions.c
similarity index 92%
rename from src/actions.c
rename to actions.c
index 977f116..dc33b9f 100644 (file)
+++ b/actions.c
@@ -1,7 +1,7 @@
-const char actions_rcs[] = "$Id: actions.c,v 2.0 2002/06/04 14:34:21 jongfoster Exp $";
+const char actions_rcs[] = "$Id: actions.c,v 1.32.2.6 2006/01/29 23:10:56 david__schmidt Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /cvsroot/ijbswa/current/src/actions.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/Attic/actions.c,v $
  *
  * Purpose     :  Declares functions to work with actions files
  *                Functions declared include: FIXME
@@ -33,10 +33,27 @@ const char actions_rcs[] = "$Id: actions.c,v 2.0 2002/06/04 14:34:21 jongfoster
  *
  * Revisions   :
  *    $Log: actions.c,v $
- *    Revision 2.0  2002/06/04 14:34:21  jongfoster
- *    Moving source files to src/
+ *    Revision 1.32.2.6  2006/01/29 23:10:56  david__schmidt
+ *    Multiple filter file support
  *
- *    Revision 1.33  2002/05/26 12:14:19  roro
+ *    Revision 1.32.2.5  2005/06/09 01:18:41  david__schmidt
+ *    Tweaks to conditionally include pthread.h if FEATURE_PTHREAD is enabled -
+ *    this becomes important when jcc.h gets included later down the line.
+ *
+ *    Revision 1.32.2.4  2003/12/03 10:33:11  oes
+ *    - Implemented Privoxy version requirement through
+ *      for-privoxy-version= statement in {{settings}}
+ *      block
+ *    - Fix for unchecked out-of-memory condition
+ *
+ *    Revision 1.32.2.3  2003/02/28 12:52:10  oes
+ *    Fixed memory leak reported by Dan Price in Bug #694713
+ *
+ *    Revision 1.32.2.2  2002/11/20 14:36:55  oes
+ *    Extended unload_current_actions_file() to multiple AFs.
+ *    Thanks to Oliver Stoeneberg for the hint.
+ *
+ *    Revision 1.32.2.1  2002/05/26 12:13:16  roro
  *    Change unsigned to unsigned long in actions_name struct.  This closes
  *    SourceForge Bug #539284.
  *
@@ -191,6 +208,10 @@ const char actions_rcs[] = "$Id: actions.c,v 2.0 2002/06/04 14:34:21 jongfoster
 #include <assert.h>
 #include <stdlib.h>
 
+#ifdef FEATURE_PTHREAD
+#include <pthread.h>
+#endif
+
 #include "project.h"
 #include "jcc.h"
 #include "list.h"
@@ -201,6 +222,7 @@ const char actions_rcs[] = "$Id: actions.c,v 2.0 2002/06/04 14:34:21 jongfoster
 #include "encode.h"
 #include "urlmatch.h"
 #include "cgi.h"
+#include "ssplit.h"
 
 const char actions_h_rcs[] = ACTIONS_H_VERSION;
 
@@ -215,26 +237,27 @@ const char actions_h_rcs[] = ACTIONS_H_VERSION;
  * an enumerated type (well, the preprocessor equivalent).  Here are
  * the values:
  */
-#define AV_NONE       0 /**< Action type: +bool-action or -bool-action */
-#define AV_ADD_STRING 1 /**< Action type: +string-action{string} */
-#define AV_REM_STRING 2 /**< Action type: -string-action */
-#define AV_ADD_MULTI  3 /**< Action type: +multi-action{string} */
-#define AV_REM_MULTI  4 /**< Action type: -multi-action{string} or -multi-action */
-
-/**
- * A structure holding information about a single built-in action string.
+#define AV_NONE       0 /* +opt -opt */
+#define AV_ADD_STRING 1 /* +stropt{string} */
+#define AV_REM_STRING 2 /* -stropt */
+#define AV_ADD_MULTI  3 /* +multiopt{string} +multiopt{string2} */
+#define AV_REM_MULTI  4 /* -multiopt{string} -multiopt          */
+
+/*
+ * We need a structure to hold the name, flag changes,
+ * type, and string index.
  */
 struct action_name
 {
-   const char * name;    /**< Action name */
-   unsigned long mask;   /**< A bit set to "0" = remove action */
-   unsigned long add;    /**< A bit set to "1" = add action */
-   int takes_value;      /**< An AV_... constant */
-   int index;            /**< Index into strings[] or multi[] */
+   const char * name;
+   unsigned long mask;   /* a bit set to "0" = remove action */
+   unsigned long add;    /* a bit set to "1" = add action */
+   int takes_value;      /* an AV_... constant */
+   int index;            /* index into strings[] or multi[] */
 };
 
-/**
- * The array of all built-in action strings.
+/*
+ * And with those building blocks in place, here's the array.
  */
 static const struct action_name action_names[] =
 {
@@ -266,15 +289,6 @@ static const struct action_name action_names[] =
 };
 
 
-/**
- * The currently loaded actions files.
- */
-static struct file_list *current_actions_file[MAX_ACTION_FILES]  = {
-   NULL, NULL, NULL, NULL, NULL,
-   NULL, NULL, NULL, NULL, NULL
-};
-
-
 static int load_one_actions_file(struct client_state *csp, int fileid);
 
 
@@ -868,6 +882,12 @@ void free_current_action (struct current_action_spec *src)
 }
 
 
+static struct file_list *current_actions_file[MAX_AF_FILES]  = {
+   NULL, NULL, NULL, NULL, NULL,
+   NULL, NULL, NULL, NULL, NULL
+};
+
+
 #ifdef FEATURE_GRACEFUL_TERMINATION
 /*********************************************************************
  *
@@ -883,10 +903,15 @@ void free_current_action (struct current_action_spec *src)
  *********************************************************************/
 void unload_current_actions_file(void)
 {
-   if (current_actions_file)
+   int i;
+
+   for (i = 0; i < MAX_AF_FILES; i++)
    {
-      current_actions_file->unloader = unload_actions_file;
-      current_actions_file = NULL;
+      if (current_actions_file[i])
+      {
+         current_actions_file[i]->unloader = unload_actions_file;
+         current_actions_file[i] = NULL;
+      }
    }
 }
 #endif /* FEATURE_GRACEFUL_TERMINATION */
@@ -965,7 +990,7 @@ int load_actions_file(struct client_state *csp)
    int i;
    int result;
 
-   for (i = 0; i < MAX_ACTION_FILES; i++)
+   for (i = 0; i < MAX_AF_FILES; i++)
    {
       if (csp->config->actions_file[i])
       {
@@ -985,23 +1010,6 @@ int load_actions_file(struct client_state *csp)
    return 0;
 }
 
-
-/** load_one_actions_file() parser status: At start of file. */
-#define MODE_START_OF_FILE 1
-
-/** load_one_actions_file() parser status: In "{{settings}}" block. */
-#define MODE_SETTINGS      2
-
-/** load_one_actions_file() parser status: In "{{description}}" block. */
-#define MODE_DESCRIPTION   3
-
-/** load_one_actions_file() parser status: In "{{alias}}" block. */
-#define MODE_ALIAS         4
-
-/** load_one_actions_file() parser status: In "{+some-actions}" block. */
-#define MODE_ACTIONS       5
-
-
 /*********************************************************************
  *
  * Function    :  load_one_actions_file
@@ -1024,6 +1032,11 @@ static int load_one_actions_file(struct client_state *csp, int fileid)
     * 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;
 
@@ -1244,9 +1257,44 @@ static int load_one_actions_file(struct client_state *csp, int fileid)
       {
          /*
           * Part of the {{settings}} block.
-          * Ignore for now, but we may want to read & check permissions
-          * when we go multi-user.
+          * For now only serves to check if the file's minimum Privoxy
+          * version requirement is met, but we may want to read & check
+          * permissions when we go multi-user.
           */
+         if (!strncmp(buf, "for-privoxy-version=", 20))
+         {
+            char *version_string, *fields[3];
+            int num_fields;
+
+            if ((version_string = strdup(buf + 20)) == NULL)
+            {
+               fclose(fp);
+               log_error(LOG_LEVEL_FATAL,
+                         "can't load actions file '%s': out of memory!",
+                         csp->config->actions_file[fileid]);
+               return 1; /* never get here */
+            }
+            
+            num_fields = ssplit(version_string, ".", fields, 3, TRUE, FALSE);
+
+            if (num_fields < 1 || atoi(fields[0]) == 0)
+            {
+               log_error(LOG_LEVEL_ERROR,
+                 "While loading actions file '%s': invalid line (%lu): %s",
+                  csp->config->actions_file[fileid], linenum, buf);
+            }
+            else if (                      atoi(fields[0]) > VERSION_MAJOR
+                     || (num_fields > 1 && atoi(fields[1]) > VERSION_MINOR)
+                     || (num_fields > 2 && atoi(fields[2]) > VERSION_POINT))
+            {
+               fclose(fp);
+               log_error(LOG_LEVEL_FATAL,
+                         "Actions file '%s', line %lu requires newer Privoxy version: %s",
+                         csp->config->actions_file[fileid], linenum, buf );
+               return 1; /* never get here */
+            }
+            free(version_string);
+         }
       }
       else if (mode == MODE_DESCRIPTION)
       {
@@ -1309,7 +1357,14 @@ static int load_one_actions_file(struct client_state *csp, int fileid)
             return 1; /* never get here */
          }
 
-         new_alias->name = strdup(buf);
+         if ((new_alias->name = strdup(buf)) == NULL)
+         {
+            fclose(fp);
+            log_error(LOG_LEVEL_FATAL,
+               "can't load actions file '%s': out of memory!",
+               csp->config->actions_file[fileid]);
+            return 1; /* never get here */
+         }
 
          strcpy(actions_buf, start);
 
@@ -1381,6 +1436,7 @@ static int load_one_actions_file(struct client_state *csp, int fileid)
    fclose(fp);
 
    free_action(cur_action);
+   freez(cur_action);
 
    free_alias_list(alias_list);