Fix: Use ulink, not link accross documents
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index 7eb369e..62694b0 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.84 2002/03/24 13:25:43 swa Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.91 2002/04/08 20:35:58 swa Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -7,7 +7,7 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.84 2002/03/24 13:25:43 swa Exp $";
  *                the main connection-handling function.
  *
  * Copyright   :  Written by and Copyright (C) 2001 the SourceForge
- *                Privoxy team.  http://ijbswa.sourceforge.net
+ *                Privoxy team. http://www.privoxy.org/
  *
  *                Based on the Internet Junkbuster originally written
  *                by and Copyright (C) 1997 Anonymous Coders and
@@ -33,6 +33,27 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.84 2002/03/24 13:25:43 swa Exp $";
  *
  * Revisions   :
  *    $Log: jcc.c,v $
+ *    Revision 1.91  2002/04/08 20:35:58  swa
+ *    fixed JB spelling
+ *
+ *    Revision 1.90  2002/04/02 14:57:28  oes
+ *    Made sending wafers independent of FEATURE_COOKIE_JAR
+ *
+ *    Revision 1.89  2002/03/31 17:18:59  jongfoster
+ *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
+ *
+ *    Revision 1.88  2002/03/27 14:32:43  david__schmidt
+ *    More compiler warning message maintenance
+ *
+ *    Revision 1.87  2002/03/26 22:29:54  swa
+ *    we have a new homepage!
+ *
+ *    Revision 1.86  2002/03/25 17:04:55  david__schmidt
+ *    Workaround for closing the jarfile before load_config() comes around again
+ *
+ *    Revision 1.85  2002/03/24 15:23:33  jongfoster
+ *    Name changes
+ *
  *    Revision 1.84  2002/03/24 13:25:43  swa
  *    name change related issues
  *
@@ -518,6 +539,9 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.84 2002/03/24 13:25:43 swa Exp $";
 
 #ifdef _WIN32
 # ifndef FEATURE_PTHREAD
+#  ifndef STRICT
+#   define STRICT
+#  endif
 #  include <windows.h>
 #  include <process.h>
 # endif /* ndef FEATURE_PTHREAD */
@@ -765,8 +789,15 @@ static void chat(struct client_state *csp)
       len = read_socket(csp->cfd, buf, sizeof(buf));
 
       if (len <= 0) break;      /* error! */
-
-      add_to_iob(csp, buf, len);
+      
+      /*
+       * If there is no memory left for buffering the
+       * request, there is nothing we can do but hang up
+       */
+      if (add_to_iob(csp, buf, len))
+      {
+         return;
+      }
 
       req = get_header(csp);
 
@@ -949,19 +980,15 @@ static void chat(struct client_state *csp)
    enlist(csp->headers, http->cmd);
 
 
-#ifdef FEATURE_COOKIE_JAR
    /*
-    * If we're logging cookies in a cookie jar, and the user has not
-    * supplied any wafers, and the user has not told us to suppress the
-    * vanilla wafer, then send the vanilla wafer.
+    * If the user has not supplied any wafers, and the user has not
+    * told us to suppress the vanilla wafer, then send the vanilla wafer.
     */
-   if ((csp->config->jarfile != NULL)
-       && list_is_empty(csp->action->multi[ACTION_MULTI_WAFER])
+   if (list_is_empty(csp->action->multi[ACTION_MULTI_WAFER])
        && ((csp->action->flags & ACTION_VANILLA_WAFER) != 0))
    {
       enlist(csp->action->multi[ACTION_MULTI_WAFER], VANILLA_WAFER);
    }
-#endif /* def FEATURE_COOKIE_JAR */
 
 
 #ifdef FEATURE_KILL_POPUPS
@@ -985,7 +1012,15 @@ static void chat(struct client_state *csp)
             log_error(LOG_LEVEL_ERROR, "read from client failed: %E");
             return;
          }
-         add_to_iob(csp, buf, len);
+         
+         /*
+          * If there is no memory left for buffering the
+          * request, there is nothing we can do but hang up
+          */
+         if (add_to_iob(csp, buf, len))
+         {
+            return;
+         }
          continue;
       }
 
@@ -1342,41 +1377,50 @@ static void chat(struct client_state *csp)
          {
             if (content_filter)
             {
-               add_to_iob(csp, buf, len);
-
                /*
-                * If the buffer limit will be reached on the next read,
-                * switch to non-filtering mode, i.e. make & write the
-                * header, flush the socket and get out of the way.
+                * If there is no memory left for buffering the content, or the buffer limit
+                * has been reached, switch to non-filtering mode, i.e. make & write the
+                * header, flush the iob and buf, and get out of the way.
                 */
-               if (((size_t)(csp->iob->eod - csp->iob->buf)) + (size_t)BUFFER_SIZE > csp->config->buffer_limit)
+               if (add_to_iob(csp, buf, len))
                {
                   size_t hdrlen;
+                  int flushed;
 
-                  log_error(LOG_LEVEL_ERROR, "Buffer size limit reached! Flushing and stepping back.");
+                  log_error(LOG_LEVEL_ERROR, "Flushing header and buffers. Stepping back from filtering.");
 
                   hdr = sed(server_patterns, add_server_headers, csp);
                   if (hdr == NULL)
                   {
-                     /* FIXME Should handle error properly */
-                     log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header");
+                     /* 
+                      * Memory is too tight to even generate the header.
+                      * Send our static "Out-of-memory" page.
+                      */
+                     log_error(LOG_LEVEL_ERROR, "Out of memory while trying to flush.");
+                     rsp = cgi_error_memory();
+
+                     if (write_socket(csp->cfd, rsp->head, rsp->head_length)
+                         || write_socket(csp->cfd, rsp->body, rsp->content_length))
+                     {
+                        log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
+                     }
+                     return;
                   }
 
                   hdrlen = strlen(hdr);
-                  byte_count += hdrlen;
 
                   if (write_socket(csp->cfd, hdr, hdrlen)
-                   || ((len = flush_socket(csp->cfd, csp)) < 0))
+                   || ((flushed = flush_socket(csp->cfd, csp)) < 0)
+                   || (write_socket(csp->cfd, buf, len)))
                   {
-                     log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E");
+                     log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E");
 
                      freez(hdr);
                      return;
                   }
 
+                  byte_count += hdrlen + flushed + len;
                   freez(hdr);
-                  byte_count += len;
-
                   content_filter = NULL;
                   server_body = 1;
 
@@ -1400,8 +1444,23 @@ static void chat(struct client_state *csp)
              * parsing an "out of body experience" ?
              */
 
-            /* buffer up the data we just read */
-            add_to_iob(csp, buf, len);
+            /* 
+             * buffer up the data we just read.  If that fails, 
+             * there's little we can do but send our static
+             * out-of-memory page.
+             */
+            if (add_to_iob(csp, buf, len))
+            {
+               log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers.");
+               rsp = cgi_error_memory();
+               
+               if (write_socket(csp->cfd, rsp->head, rsp->head_length)
+                   || write_socket(csp->cfd, rsp->body, rsp->content_length))
+               {
+                  log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
+               }
+               return;
+            }
 
             /* get header lines from the iob */
 
@@ -2019,6 +2078,23 @@ static void listen_loop(void)
       }
 #endif
 
+#ifdef __OS2__
+#ifdef FEATURE_COOKIE_JAR
+      /*
+       * Need a workaround here: we have to fclose() the jarfile, or we die because it's
+       * already open.  I think unload_configfile() is not being run, which should do
+       * this work.  Until that can get resolved, we'll use this workaround.
+       */
+       if (csp)
+         if(csp->config)
+           if (csp->config->jar)
+           {
+             fclose(csp->config->jar);
+             csp->config->jar = NULL;
+           }
+#endif /* FEATURE_COOKIE_JAR */
+#endif /* __OS2__ */
+
       if ( NULL == (csp = (struct client_state *) zalloc(sizeof(*csp))) )
       {
          log_error(LOG_LEVEL_FATAL, "malloc(%d) for csp failed: %E", sizeof(*csp));
@@ -2130,7 +2206,7 @@ static void listen_loop(void)
 #if defined(__OS2__) && !defined(SELECTED_ONE_OPTION)
 #define SELECTED_ONE_OPTION
          child_id = _beginthread(
-            serve,
+            (void(* _Optlink)(void*))serve,
             NULL,
             64 * 1024,
             csp);
@@ -2208,7 +2284,7 @@ static void listen_loop(void)
 
             log_error(LOG_LEVEL_ERROR, "can't fork: %E");
 
-            sprintf(buf , "JunkBuster: can't fork: errno = %d", errno);
+            sprintf(buf , "Privoxy: can't fork: errno = %d", errno);
 
             write_socket(csp->cfd, buf, strlen(buf));
             close_socket(csp->cfd);