Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
[privoxy.git] / loaders.c
similarity index 87%
rename from src/loaders.c
rename to loaders.c
index 9834e38..d679070 100644 (file)
+++ b/loaders.c
@@ -1,7 +1,7 @@
-const char loaders_rcs[] = "$Id: loaders.c,v 2.1 2002/06/04 17:22:37 jongfoster Exp $";
+const char loaders_rcs[] = "$Id: loaders.c,v 1.50.2.8 2006/01/30 15:16:25 david__schmidt Exp $";
 /*********************************************************************
  *
- * File        :  $Source: /cvsroot/ijbswa//current/src/loaders.c,v $
+ * File        :  $Source: /cvsroot/ijbswa/current/Attic/loaders.c,v $
  *
  * Purpose     :  Functions to load and unload the various
  *                configuration files.  Also contains code to manage
@@ -35,11 +35,35 @@ const char loaders_rcs[] = "$Id: loaders.c,v 2.1 2002/06/04 17:22:37 jongfoster
  *
  * Revisions   :
  *    $Log: loaders.c,v $
- *    Revision 2.1  2002/06/04 17:22:37  jongfoster
- *    Adding comments
+ *    Revision 1.50.2.8  2006/01/30 15:16:25  david__schmidt
+ *    Remove a little residual debugging info
  *
- *    Revision 2.0  2002/06/04 14:34:21  jongfoster
- *    Moving source files to src/
+ *    Revision 1.50.2.7  2006/01/29 23:10:56  david__schmidt
+ *    Multiple filter file support
+ *
+ *    Revision 1.50.2.6  2003/10/24 10:17:54  oes
+ *    Nit: Allowed tabs as separators in filter headings
+ *
+ *    Revision 1.50.2.5  2003/05/08 15:19:15  oes
+ *    sweep: Made loop structure of sweep step mirror that of mark step
+ *
+ *    Revision 1.50.2.4  2003/05/06 15:57:12  oes
+ *    Bugfix: Update last_active pointer in sweep() before
+ *    leaving an active client. Closes bugs #724395, #727882
+ *
+ *    Revision 1.50.2.3  2002/11/20 17:12:30  oes
+ *    Ooops, forgot one change.
+ *
+ *    Revision 1.50.2.2  2002/11/20 14:38:15  oes
+ *    Fixed delayed/incomplete freeing of client resources and
+ *    simplified loop structure in sweep.
+ *    Thanks to Oliver Stoeneberg for the hint.
+ *
+ *    Revision 1.50.2.1  2002/07/26 15:19:24  oes
+ *    - PCRS jobs now chained in order of appearance. Previous
+ *      reverse chaining was counter-intuitive.
+ *    - Changed loglevel of PCRS job compile errors to
+ *      LOG_LEVEL_ERROR
  *
  *    Revision 1.50  2002/04/24 02:12:16  oes
  *    Jon's multiple AF patch: Sweep now takes care of all AFs
@@ -302,37 +326,21 @@ const char loaders_rcs[] = "$Id: loaders.c,v 2.1 2002/06/04 17:22:37 jongfoster
 
 const char loaders_h_rcs[] = LOADERS_H_VERSION;
 
+/*
+ * Currently active files.
+ * These are also entered in the main linked list of files.
+ */
 
 #ifdef FEATURE_TRUST
-/**
- * Currently active trust file.
- * This is also entered in the main linked list of files.
- */
 static struct file_list *current_trustfile      = NULL;
 #endif /* def FEATURE_TRUST */
 
+static int load_one_re_filterfile(struct client_state *csp, int fileid);
 
-/**
- * Currently active re_filter file.
- * This is also entered in the main linked list of files.
- */
-static struct file_list *current_re_filterfile  = NULL;
-
-
-/**
- * Character code for CR (ASCII 13).
- * If you have a wierd compiler and this definition is
- * incorrect, you also need to fix NEWLINE() in loaders.h
- */
-#define CHAR_CR '\r' /* ASCII 13 */
-
-
-/**
- * Character code for LF (ASCII 10).
- * If you have a wierd compiler and this definition is
- * incorrect, you also need to fix NEWLINE() in loaders.h
- */
-#define CHAR_LF '\n' /* ASCII 10 */
+static struct file_list *current_re_filterfile[MAX_AF_FILES]  = {
+   NULL, NULL, NULL, NULL, NULL,
+   NULL, NULL, NULL, NULL, NULL
+};
 
 
 
@@ -363,7 +371,7 @@ static struct file_list *current_re_filterfile  = NULL;
 void sweep(void)
 {
    struct file_list *fl, *nfl;
-   struct client_state *csp, *ncsp;
+   struct client_state *csp, *last_active;
    int i;
 
    /* clear all of the file's active flags */
@@ -372,92 +380,112 @@ void sweep(void)
       fl->active = 0;
    }
 
-   for (csp = clients; csp && (NULL != (ncsp = csp->next)) ; csp = csp->next)
+   last_active = clients;
+   csp = clients->next;
+
+   while (NULL != csp)
    {
-      if (ncsp->flags & CSP_FLAG_ACTIVE)
+      if (csp->flags & CSP_FLAG_ACTIVE)
       {
-         /* mark this client's files as active */
+         /* Mark this client's files as active */
 
          /*
           * Always have a configuration file.
           * (Also note the slightly non-standard extra
           * indirection here.)
           */
-         ncsp->config->config_file_list->active = 1;
+         csp->config->config_file_list->active = 1;
 
-         for (i = 0; i < MAX_ACTION_FILES; i++)
+         /* 
+          * Actions files
+          */
+         for (i = 0; i < MAX_AF_FILES; i++)
          {
-            if (ncsp->actions_list[i])     /* actions files */
+            if (csp->actions_list[i])     
             {
-               ncsp->actions_list[i]->active = 1;
+               csp->actions_list[i]->active = 1;
             }
          }
 
-         if (ncsp->rlist)     /* pcrsjob files */
+         /*
+          * Filter files
+          */
+         for (i = 0; i < MAX_AF_FILES; i++)
          {
-            ncsp->rlist->active = 1;
+            if (csp->rlist[i])     
+            {
+               csp->rlist[i]->active = 1;
+            }
          }
 
+         /*
+          * Trust file
+          */
 #ifdef FEATURE_TRUST
-         if (ncsp->tlist)     /* trust files */
+         if (csp->tlist)
          {
-            ncsp->tlist->active = 1;
+            csp->tlist->active = 1;
          }
 #endif /* def FEATURE_TRUST */
+         
+         last_active = csp;
+         csp = csp->next;
 
       }
-      else
+      else 
       /*
-       * this client is not active, release its resources
-       * and the ones of all inactive clients that might
-       * follow it
+       * This client is not active. Free its resources.
        */
       {
-         while (!(ncsp->flags & CSP_FLAG_ACTIVE))
-         {
-            csp->next = ncsp->next;
+         last_active->next = csp->next;
 
-            freez(ncsp->ip_addr_str);
-            freez(ncsp->my_ip_addr_str);
-            freez(ncsp->my_hostname);
-            freez(ncsp->x_forwarded);
-            freez(ncsp->iob->buf);
+         freez(csp->ip_addr_str);
+         freez(csp->my_ip_addr_str);
+         freez(csp->my_hostname);
+         freez(csp->x_forwarded);
+         freez(csp->iob->buf);
 
-            free_http_request(ncsp->http);
+         free_http_request(csp->http);
 
-            destroy_list(ncsp->headers);
-            destroy_list(ncsp->cookie_list);
+         destroy_list(csp->headers);
+         destroy_list(csp->cookie_list);
 
-            free_current_action(ncsp->action);
+         free_current_action(csp->action);
 
 #ifdef FEATURE_STATISTICS
-            urls_read++;
-            if (ncsp->flags & CSP_FLAG_REJECTED)
-            {
-               urls_rejected++;
-            }
+         urls_read++;
+         if (csp->flags & CSP_FLAG_REJECTED)
+         {
+            urls_rejected++;
+         }
 #endif /* def FEATURE_STATISTICS */
 
-            freez(ncsp);
-
-            /* are there any more in sequence after it? */
-            if( (ncsp = csp->next) == NULL)
-               break;
-         }
+         freez(csp);
+         
+         csp = last_active->next;
       }
    }
 
-   for (fl = files; fl && ((nfl = fl->next) != NULL) ; fl = fl->next)
+   nfl = files;
+   fl = files->next;
+
+   while (fl != NULL)
    {
-      if ( ( 0 == nfl->active ) && ( NULL != nfl->unloader ) )
+      if ( ( 0 == fl->active ) && ( NULL != fl->unloader ) )
       {
-         fl->next = nfl->next;
+         nfl->next = fl->next;
 
-         (nfl->unloader)(nfl->f);
+         (fl->unloader)(fl->f);
 
-         freez(nfl->filename);
+         freez(fl->filename);
+         freez(fl);
 
-         freez(nfl);
+         fl = nfl->next;
+      }
+      else
+      {
+         nfl = fl;
+         fl = fl->next;
       }
    }
 
@@ -519,6 +547,7 @@ int check_file_changed(const struct file_list * current,
       return 1;
    }
 
+
    fs->filename = strdup(filename);
    fs->lastmodified = statbuf->st_mtime;
 
@@ -577,6 +606,13 @@ jb_err simple_read_line(FILE *fp, char **dest, int *newline)
 
    p = buf;
 
+/*
+ * Character codes.  If you have a wierd compiler and the following are
+ * incorrect, you also need to fix NEWLINE() in loaders.h
+ */
+#define CHAR_CR '\r' /* ASCII 13 */
+#define CHAR_LF '\n' /* ASCII 10 */
+
    for (;;)
    {
       ch = getc(fp);
@@ -1225,10 +1261,15 @@ static void unload_re_filterfile(void *f)
  *********************************************************************/
 void unload_current_re_filterfile(void)
 {
-   if (current_re_filterfile)
+   int i;
+
+   for (i = 0; i < MAX_AF_FILES; i++)
    {
-      current_re_filterfile->unloader = unload_re_filterfile;
-      current_re_filterfile = NULL;
+      if (current_re_filterfile[i])
+      {
+         current_re_filterfile[i]->unloader = unload_re_filterfile;
+         current_re_filterfile[i] = NULL;
+      }
    }
 }
 #endif
@@ -1250,6 +1291,46 @@ void unload_current_re_filterfile(void)
  *
  *********************************************************************/
 int load_re_filterfile(struct client_state *csp)
+{
+   int i;
+   int result;
+
+   for (i = 0; i < MAX_AF_FILES; i++)
+   {
+      if (csp->config->re_filterfile[i])
+      {
+         result = load_one_re_filterfile(csp, i);
+         if (result)
+         {
+            return result;
+         }
+      }
+      else if (current_re_filterfile[i])
+      {
+         current_re_filterfile[i]->unloader = unload_re_filterfile;
+         current_re_filterfile[i] = NULL;
+      }
+   }
+
+   return 0;
+}
+
+/*********************************************************************
+ *
+ * Function    :  load_one_re_filterfile
+ *
+ * Description :  Load a re_filterfile. 
+ *                Generate a chained list of re_filterfile_spec's from
+ *                the "FILTER: " blocks, compiling all their substitutions
+ *                into chained lists of pcrs_job structs.
+ *
+ * Parameters  :
+ *          1  :  csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns     :  0 => Ok, everything else is an error.
+ *
+ *********************************************************************/
+int load_one_re_filterfile(struct client_state *csp, int fileid)
 {
    FILE *fp;
 
@@ -1264,11 +1345,11 @@ int load_re_filterfile(struct client_state *csp)
    /*
     * No need to reload if unchanged
     */
-   if (!check_file_changed(current_re_filterfile, csp->config->re_filterfile, &fs))
+   if (!check_file_changed(current_re_filterfile[fileid], csp->config->re_filterfile[fileid], &fs))
    {
       if (csp)
       {
-         csp->rlist = current_re_filterfile;
+         csp->rlist[fileid] = current_re_filterfile[fileid];
       }
       return(0);
    }
@@ -1280,7 +1361,7 @@ int load_re_filterfile(struct client_state *csp)
    /* 
     * Open the file or fail
     */
-   if ((fp = fopen(csp->config->re_filterfile, "r")) == NULL)
+   if ((fp = fopen(csp->config->re_filterfile[fileid], "r")) == NULL)
    {
       goto load_re_filterfile_error;
    }
@@ -1304,7 +1385,7 @@ int load_re_filterfile(struct client_state *csp)
 
          new_bl->name = chomp(buf + 7);
 
-         if (NULL != (new_bl->description = strchr(new_bl->name, ' ')))
+         if (NULL != (new_bl->description = strpbrk(new_bl->name, " \t")))
          {
             *new_bl->description++ = '\0';
             new_bl->description = strdup(chomp(new_bl->description));
@@ -1375,9 +1456,9 @@ int load_re_filterfile(struct client_state *csp)
    /* 
     * Schedule the now-obsolete old data for unloading
     */
-   if ( NULL != current_re_filterfile )
+   if ( NULL != current_re_filterfile[fileid] )
    {
-      current_re_filterfile->unloader = unload_re_filterfile;
+      current_re_filterfile[fileid]->unloader = unload_re_filterfile;
    }
 
    /*
@@ -1385,18 +1466,18 @@ int load_re_filterfile(struct client_state *csp)
     */
    fs->next    = files->next;
    files->next = fs;
-   current_re_filterfile = fs;
+   current_re_filterfile[fileid] = fs;
 
    if (csp)
    {
-      csp->rlist = fs;
+      csp->rlist[fileid] = fs;
    }
 
    return( 0 );
 
 load_re_filterfile_error:
    log_error(LOG_LEVEL_FATAL, "can't load re_filterfile '%s': %E",
-             csp->config->re_filterfile);
+             csp->config->re_filterfile[fileid]);
    return(-1);
 
 }