DOS->Unix line endings
[privoxy.git] / loaders.c
index b200b90..2ec1ffe 100644 (file)
--- a/loaders.c
+++ b/loaders.c
@@ -1,21 +1,21 @@
-const char loaders_rcs[] = "$Id: loaders.c,v 1.25 2001/09/13 22:44:03 jongfoster Exp $";
+const char loaders_rcs[] = "$Id: loaders.c,v 1.34 2001/12/30 14:07:32 steudten Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/loaders.c,v $
  *
  * Purpose     :  Functions to load and unload the various
  *                configuration files.  Also contains code to manage
- *                the list of active loaders, and to automatically 
+ *                the list of active loaders, and to automatically
  *                unload files that are no longer in use.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
  *                IJBSWA team.  http://ijbswa.sourceforge.net
  *
  *                Based on the Internet Junkbuster originally written
- *                by and Copyright (C) 1997 Anonymous Coders and 
+ *                by and Copyright (C) 1997 Anonymous Coders and
  *                Junkbusters Corporation.  http://www.junkbusters.com
  *
- *                This program is free software; you can redistribute it 
+ *                This program is free software; you can redistribute it
  *                and/or modify it under the terms of the GNU General
  *                Public License as published by the Free Software
  *                Foundation; either version 2 of the License, or (at
@@ -35,6 +35,47 @@ const char loaders_rcs[] = "$Id: loaders.c,v 1.25 2001/09/13 22:44:03 jongfoster
  *
  * Revisions   :
  *    $Log: loaders.c,v $
+ *    Revision 1.34  2001/12/30 14:07:32  steudten
+ *    - Add signal handling (unix)
+ *    - Add SIGHUP handler (unix)
+ *    - Add creation of pidfile (unix)
+ *    - Add action 'top' in rc file (RH)
+ *    - Add entry 'SIGNALS' to manpage
+ *    - Add exit message to logfile (unix)
+ *
+ *    Revision 1.33  2001/11/13 00:16:38  jongfoster
+ *    Replacing references to malloc.h with the standard stdlib.h
+ *    (See ANSI or K&R 2nd Ed)
+ *
+ *    Revision 1.32  2001/11/07 00:02:13  steudten
+ *    Add line number in error output for lineparsing for
+ *    actionsfile and configfile.
+ *    Special handling for CLF added.
+ *
+ *    Revision 1.31  2001/10/26 17:39:01  oes
+ *    Removed csp->referrer
+ *    Moved ijb_isspace and ijb_tolower to project.h
+ *
+ *    Revision 1.30  2001/10/25 03:40:48  david__schmidt
+ *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
+ *    threads to call select() simultaneously.  So, it's time to do a real, live,
+ *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
+ *    (native). Both versions will work, but using __OS2__ offers multi-threading.
+ *
+ *    Revision 1.29  2001/10/23 21:38:53  jongfoster
+ *    Adding error-checking to create_url_spec()
+ *
+ *    Revision 1.28  2001/10/07 15:40:39  oes
+ *    Replaced 6 boolean members of csp with one bitmap (csp->flags)
+ *
+ *    Revision 1.27  2001/09/22 16:36:59  jongfoster
+ *    Removing unused parameter fs from read_config_line()
+ *
+ *    Revision 1.26  2001/09/22 14:05:22  jongfoster
+ *    Bugfix: Multiple escaped "#" characters in a configuration
+ *    file are now permitted.
+ *    Also removing 3 unused headers.
+ *
  *    Revision 1.25  2001/09/13 22:44:03  jongfoster
  *    Adding {} to an if statement
  *
@@ -172,12 +213,12 @@ const char loaders_rcs[] = "$Id: loaders.c,v 1.25 2001/09/13 22:44:03 jongfoster
 #include <stdlib.h>
 #include <sys/types.h>
 #include <string.h>
-#include <malloc.h>
 #include <errno.h>
 #include <sys/stat.h>
 #include <ctype.h>
+#include <assert.h>
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__OS2__)
 #include <unistd.h>
 #endif
 
@@ -190,19 +231,10 @@ const char loaders_rcs[] = "$Id: loaders.c,v 1.25 2001/09/13 22:44:03 jongfoster
 #include "miscutil.h"
 #include "errlog.h"
 #include "actions.h"
+#include "urlmatch.h"
 
 const char loaders_h_rcs[] = LOADERS_H_VERSION;
 
-/* Fix a problem with Solaris.  There should be no effect on other
- * platforms.
- * Solaris's isspace() is a macro which uses it's argument directly
- * as an array index.  Therefore we need to make sure that high-bit
- * characters generate +ve values, and ideally we also want to make
- * the argument match the declared parameter type of "int".
- */
-#define ijb_isspace(__X) isspace((int)(unsigned char)(__X))
-
-
 /*
  * Currently active files.
  * These are also entered in the main linked list of files.
@@ -253,7 +285,7 @@ void sweep(void)
 
    for (csp = clients; csp && (ncsp = csp->next) ; csp = csp->next)
    {
-      if (ncsp->active)
+      if (ncsp->flags & CSP_FLAG_ACTIVE)
       {
          /* mark this client's files as active */
 
@@ -283,43 +315,39 @@ void sweep(void)
 
       }
       else
-      /* 
-       * this client is not active, release its resources 
+      /*
+       * this client is not active, release its resources
        * and the ones of all inactive clients that might
        * follow it
        */
       {
-         while( !ncsp->active )
+         while (!(ncsp->flags & CSP_FLAG_ACTIVE))
          {
             csp->next = ncsp->next;
-   
+
             freez(ncsp->ip_addr_str);
             freez(ncsp->my_ip_addr_str);
             freez(ncsp->my_hostname);
-   
-#ifdef FEATURE_TRUST
-            freez(ncsp->referrer);
-#endif /* def FEATURE_TRUST */
             freez(ncsp->x_forwarded);
             freez(ncsp->iob->buf);
-   
+
             free_http_request(ncsp->http);
-   
+
             destroy_list(ncsp->headers);
             destroy_list(ncsp->cookie_list);
-   
+
             free_current_action(ncsp->action);
-   
+
 #ifdef FEATURE_STATISTICS
             urls_read++;
-            if (ncsp->rejected)
+            if (ncsp->flags & CSP_FLAG_REJECTED)
             {
                urls_rejected++;
             }
 #endif /* def FEATURE_STATISTICS */
-   
+
             freez(ncsp);
-            
+
             /* are there any more in sequence after it? */
             if( !(ncsp = csp->next) )
                break;
@@ -344,171 +372,18 @@ void sweep(void)
 }
 
 
-/*********************************************************************
- *
- * Function    :  create_url_spec
- *
- * Description :  Creates a "url_spec" structure from a string.
- *                When finished, free with unload_url().
- *
- * Parameters  :
- *          1  :  url = Target url_spec to be filled in.  Must be
- *                      zeroed out before the call (e.g. using zalloc).
- *          2  :  buf = Source pattern, null terminated.  NOTE: The
- *                      contents of this buffer are destroyed by this
- *                      function.  If this function succeeds, the
- *                      buffer is copied to url->spec.  If this
- *                      function fails, the contents of the buffer
- *                      are lost forever.
- *
- * Returns     :  0 => Ok, everything else is an error.
- *
- *********************************************************************/
-int create_url_spec(struct url_spec * url, char * buf)
-{
-   char *p;
-   struct url_spec tmp_url[1];
-
-   /* paranoia - should never happen. */
-   if ((url == NULL) || (buf == NULL))
-   {
-      return 1;
-   }
-
-   /* save a copy of the orignal specification */
-   if ((url->spec = strdup(buf)) == NULL)
-   {
-      return 1;
-   }
-
-   if ((p = strchr(buf, '/')))
-   {
-      if (NULL == (url->path = strdup(p)))
-      {
-         freez(url->spec);
-         return 1;
-      }
-      url->pathlen = strlen(url->path);
-      *p = '\0';
-   }
-   else
-   {
-      url->path    = NULL;
-      url->pathlen = 0;
-   }
-#ifdef REGEX
-   if (url->path)
-   {
-      int errcode;
-      char rebuf[BUFFER_SIZE];
-
-      if (NULL == (url->preg = zalloc(sizeof(*url->preg))))
-      {
-         freez(url->spec);
-         freez(url->path);
-         return 1;
-      }
-
-      sprintf(rebuf, "^(%s)", url->path);
-
-      errcode = regcomp(url->preg, rebuf,
-            (REG_EXTENDED|REG_NOSUB|REG_ICASE));
-      if (errcode)
-      {
-         size_t errlen = regerror(errcode,
-            url->preg, buf, sizeof(buf));
-
-         buf[errlen] = '\0';
-
-         log_error(LOG_LEVEL_ERROR, "error compiling %s: %s",
-            url->spec, buf);
-
-         freez(url->spec);
-         freez(url->path);
-         freez(url->preg);
-
-         return 1;
-      }
-   }
-#endif
-   if ((p = strchr(buf, ':')) == NULL)
-   {
-      url->port = 0;
-   }
-   else
-   {
-      *p++ = '\0';
-      url->port = atoi(p);
-   }
-
-   if ((url->domain = strdup(buf)) == NULL)
-   {
-      freez(url->spec);
-      freez(url->path);
-#ifdef REGEX
-      freez(url->preg);
-#endif /* def REGEX */
-      return 1;
-   }
-
-   /* split domain into components */
-
-   *tmp_url = dsplit(url->domain);
-   url->dbuf = tmp_url->dbuf;
-   url->dcnt = tmp_url->dcnt;
-   url->dvec = tmp_url->dvec;
-   url->unanchored = tmp_url->unanchored;
-
-   return 0; /* OK */
-
-}
-
-
-/*********************************************************************
- *
- * Function    :  free_url
- *
- * Description :  Called from the "unloaders".  Freez the url
- *                structure elements.
- *
- * Parameters  :
- *          1  :  url = pointer to a url_spec structure.
- *
- * Returns     :  N/A
- *
- *********************************************************************/
-void free_url(struct url_spec *url)
-{
-   if (url == NULL) return;
-
-   freez(url->spec);
-   freez(url->domain);
-   freez(url->dbuf);
-   freez(url->dvec);
-   freez(url->path);
-#ifdef REGEX
-   if (url->preg)
-   {
-      regfree(url->preg);
-      freez(url->preg);
-   }
-#endif
-
-}
-
-
 /*********************************************************************
  *
  * Function    :  check_file_changed
  *
  * Description :  Helper function to check if a file needs reloading.
  *                If "current" is still current, return it.  Otherwise
- *                allocates a new (zeroed) "struct file_list", fills 
+ *                allocates a new (zeroed) "struct file_list", fills
  *                in the disk file name and timestamp, and returns it.
  *
  * Parameters  :
  *          1  :  current = The file_list currently being used - will
- *                          be checked to see if it is out of date. 
+ *                          be checked to see if it is out of date.
  *                          May be NULL (which is treated as out of
  *                          date).
  *          2  :  filename = Name of file to check.
@@ -542,11 +417,11 @@ int check_file_changed(const struct file_list * current,
        && (current->lastmodified == statbuf->st_mtime)
        && (0 == strcmp(current->filename, filename)))
    {
-      return 0;
+       /* force reload of configfile and all the logs */
+       if ( !MustReload ) return 0;
    }
 
    fs = (struct file_list *)zalloc(sizeof(struct file_list));
-
    if (fs == NULL)
    {
       /* Out of memory error */
@@ -562,11 +437,8 @@ int check_file_changed(const struct file_list * current,
       freez (fs);
       return 1;
    }
-
-
    *newfl = fs;
    return 1;
-
 }
 
 
@@ -577,20 +449,18 @@ int check_file_changed(const struct file_list * current,
  * Description :  Read a single non-empty line from a file and return
  *                it.  Trims comments, leading and trailing whitespace
  *                and respects escaping of newline and comment char.
- *                Also writes the file to fs->proxy_args.
  *
  * Parameters  :
  *          1  :  buf = Buffer to use.
  *          2  :  buflen = Size of buffer in bytes.
  *          3  :  fp = File to read from
- *          4  :  fs = File will be written to fs->proxy_args.  May
- *                be NULL to disable this feature.
+ *         4  :  linenum = linenumber in file
  *
  * Returns     :  NULL on EOF or error
  *                Otherwise, returns buf.
  *
  *********************************************************************/
-char *read_config_line(char *buf, int buflen, FILE *fp, struct file_list *fs)
+char *read_config_line(char *buf, int buflen, FILE *fp, unsigned long *linenum)
 {
    char *p;
    char *src;
@@ -602,6 +472,7 @@ char *read_config_line(char *buf, int buflen, FILE *fp, struct file_list *fs)
 
    while (fgets(linebuf, sizeof(linebuf), fp))
    {
+       (*linenum)++;
       /* Trim off newline */
       if ((p = strpbrk(linebuf, "\r\n")) != NULL)
       {
@@ -654,7 +525,7 @@ char *read_config_line(char *buf, int buflen, FILE *fp, struct file_list *fs)
          continue;
       }
 
-      /* Remove leading and trailing whitespace */         
+      /* Remove leading and trailing whitespace */
       chomp(buf);
 
       if (*buf)
@@ -689,7 +560,7 @@ static void unload_trustfile(void *f)
 
    unload_trustfile(b->next); /* Stack is cheap, isn't it? */
 
-   free_url(b->url);
+   free_url_spec(b->url);
 
    freez(b);
 
@@ -718,6 +589,7 @@ int load_trustfile(struct client_state *csp)
    char  buf[BUFFER_SIZE], *p, *q;
    int reject, trusted;
    struct file_list *fs;
+   unsigned long linenum = 0;
 
    if (!check_file_changed(current_trustfile, csp->config->trustfile, &fs))
    {
@@ -746,7 +618,7 @@ int load_trustfile(struct client_state *csp)
 
    tl = csp->config->trust_list;
 
-   while (read_config_line(buf, sizeof(buf), fp, fs) != NULL)
+   while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL)
    {
       trusted = 0;
       reject  = 1;
@@ -800,6 +672,7 @@ int load_trustfile(struct client_state *csp)
       if (trusted)
       {
          *tl++ = b->url;
+         /* FIXME BUFFER OVERFLOW if >=64 entries */
       }
    }
 
@@ -884,6 +757,7 @@ int load_re_filterfile(struct client_state *csp)
 
    char  buf[BUFFER_SIZE];
    int error;
+   unsigned long linenum = 0;
    pcrs_job *dummy;
 
    if (!check_file_changed(current_re_filterfile, csp->config->re_filterfile, &fs))
@@ -913,14 +787,14 @@ int load_re_filterfile(struct client_state *csp)
    }
 
    /* Read line by line */
-   while (read_config_line(buf, sizeof(buf), fp, fs) != NULL)
+   while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL)
    {
       enlist( bl->patterns, buf );
 
       /* We have a meaningful line -> make it a job */
       if ((dummy = pcrs_compile_command(buf, &error)) == NULL)
       {
-         log_error(LOG_LEVEL_RE_FILTER, 
+         log_error(LOG_LEVEL_RE_FILTER,
                "Adding re_filter job %s failed with error %d.", buf, error);
          continue;
       }
@@ -952,7 +826,7 @@ int load_re_filterfile(struct client_state *csp)
    return( 0 );
 
 load_re_filterfile_error:
-   log_error(LOG_LEVEL_FATAL, "can't load re_filterfile '%s': %E", 
+   log_error(LOG_LEVEL_FATAL, "can't load re_filterfile '%s': %E",
              csp->config->re_filterfile);
    return(-1);
 
@@ -974,7 +848,7 @@ load_re_filterfile_error:
  * Returns     :  N/A
  *
  *********************************************************************/
-void add_loader(int (*loader)(struct client_state *), 
+void add_loader(int (*loader)(struct client_state *),
                 struct configuration_spec * config)
 {
    int i;