Renaming Makefile.in to GNUmakefile.in so that non-GNU versions of
[privoxy.git] / jcc.c
diff --git a/jcc.c b/jcc.c
index 157381d..0d52ac6 100644 (file)
--- a/jcc.c
+++ b/jcc.c
@@ -1,4 +1,4 @@
-const char jcc_rcs[] = "$Id: jcc.c,v 1.51 2001/10/26 17:38:28 oes Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.57 2001/11/16 00:47:43 jongfoster Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jcc.c,v $
@@ -33,6 +33,31 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.51 2001/10/26 17:38:28 oes Exp $";
  *
  * Revisions   :
  *    $Log: jcc.c,v $
+ *    Revision 1.57  2001/11/16 00:47:43  jongfoster
+ *    Changing the tty-disconnection code to use setsid().
+ *
+ *    Revision 1.56  2001/11/13 20:20:54  jongfoster
+ *    Tabs->spaces, fixing a bug with missing {} around an if()
+ *
+ *    Revision 1.55  2001/11/13 20:14:53  jongfoster
+ *    Patch for FreeBSD setpgrp() as suggested by Alexander Lazic
+ *
+ *    Revision 1.54  2001/11/07 00:03:14  steudten
+ *    Give reliable return value if an error
+ *    occurs not just 0 with new daemon mode.
+ *
+ *    Revision 1.53  2001/11/05 21:41:43  steudten
+ *    Add changes to be a real daemon just for unix os.
+ *    (change cwd to /, detach from controlling tty, set
+ *    process group and session leader to the own process.
+ *    Add DBG() Macro.
+ *    Add some fatal-error log message for failed malloc().
+ *    Add '-d' if compiled with 'configure --with-debug' to
+ *    enable debug output.
+ *
+ *    Revision 1.52  2001/10/26 20:11:20  jongfoster
+ *    Fixing type mismatch
+ *
  *    Revision 1.51  2001/10/26 17:38:28  oes
  *    Cosmetics
  *
@@ -379,6 +404,12 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.51 2001/10/26 17:38:28 oes Exp $";
 # endif /* ndef __OS2__ */
 # include <sys/time.h>
 # include <sys/stat.h>
+# include <sys/ioctl.h>
+
+#ifdef sun
+#include <sys/termios.h>
+#endif /* sun */
+
 # include <signal.h>
 
 # ifdef __BEOS__
@@ -401,6 +432,10 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.51 2001/10/26 17:38:28 oes Exp $";
 
 #endif
 
+#ifdef _DEBUG
+int ldebug = 0;
+#endif
+
 #include "project.h"
 #include "list.h"
 #include "jcc.h"
@@ -448,6 +483,9 @@ static int32 server_thread(void *data);
 #define sleep(N)  DosSleep(((N) * 100))
 #endif
 
+#if defined(unix)
+const char *basedir;
+#endif /* defined unix */
 
 /* The vanilla wafer. */
 static const char VANILLA_WAFER[] =
@@ -751,13 +789,13 @@ static void chat(struct client_state *csp)
 
    if (
        /* a CGI call was detected and answered */
-        (NULL != (rsp = dispatch_cgi(csp)))
+       (NULL != (rsp = dispatch_cgi(csp)))
 
        /* or we are enabled and... */
        || (IS_ENABLED_AND (
 
             /* ..the request was blocked */
-           ( NULL != (rsp = block_url(csp)))
+          ( NULL != (rsp = block_url(csp)))
 
           /* ..or untrusted */
 #ifdef FEATURE_TRUST
@@ -767,14 +805,14 @@ static void chat(struct client_state *csp)
           /* ..or a fast redirect kicked in */
 #ifdef FEATURE_FAST_REDIRECTS
           || (((csp->action->flags & ACTION_FAST_REDIRECTS) != 0) &&
-                    (NULL != (rsp = redirect_url(csp))))
+                (NULL != (rsp = redirect_url(csp))))
 #endif /* def FEATURE_FAST_REDIRECTS */
-                ))
-       )
+          ))
+      )
    {
       /* Write the answer to the client */
       if ((write_socket(csp->cfd, rsp->head, rsp->head_length) != rsp->head_length)
-            || (write_socket(csp->cfd, rsp->body, rsp->content_length) != rsp->content_length))
+           || (write_socket(csp->cfd, rsp->body, rsp->content_length) != rsp->content_length))
       {
          log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
       }
@@ -816,14 +854,14 @@ static void chat(struct client_state *csp)
 
       if (errno == EINVAL)
       {
-          rsp = error_response(csp, "no-such-domain", errno);
+         rsp = error_response(csp, "no-such-domain", errno);
 
          log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 404 0",
                    csp->ip_addr_str, http->cmd);
       }
       else
       {
-          rsp = error_response(csp, "connect-failed", errno);
+         rsp = error_response(csp, "connect-failed", errno);
 
          log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 503 0",
                    csp->ip_addr_str, http->cmd);
@@ -831,9 +869,9 @@ static void chat(struct client_state *csp)
 
       /* Write the answer to the client */
       if(rsp)
-       {
+      {
          if ((write_socket(csp->cfd, rsp->head, rsp->head_length) != rsp->head_length)
-               || (write_socket(csp->cfd, rsp->body, rsp->content_length) != rsp->content_length))
+          || (write_socket(csp->cfd, rsp->body, rsp->content_length) != rsp->content_length))
          {
             log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
          }
@@ -870,7 +908,7 @@ static void chat(struct client_state *csp)
          if(rsp)
          {
             if ((write_socket(csp->cfd, rsp->head, n) != n)
-               || (write_socket(csp->cfd, rsp->body, rsp->content_length) != rsp->content_length))
+             || (write_socket(csp->cfd, rsp->body, rsp->content_length) != rsp->content_length))
             {
                log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
             }
@@ -970,11 +1008,11 @@ static void chat(struct client_state *csp)
             if(rsp)
             {
                if ((write_socket(csp->cfd, rsp->head, rsp->head_length) != rsp->head_length)
-                   || (write_socket(csp->cfd, rsp->body, rsp->content_length) != rsp->content_length))
+                || (write_socket(csp->cfd, rsp->body, rsp->content_length) != rsp->content_length))
                {
                   log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host);
-                          }
-                       }
+               }
+            }
 
             free_http_response(rsp);
             return;
@@ -1346,13 +1384,15 @@ int real_main(int argc, const char *argv[])
 int main(int argc, const char *argv[])
 #endif
 {
+   int argc_pos = 1;
+
    configfile =
 #ifdef AMIGA
    "AmiTCP:db/junkbuster/config"
 #elif !defined(_WIN32)
    "config"
 #else
-   "junkbstr.txt"
+   "config.txt"
 #endif
       ;
 
@@ -1371,15 +1411,51 @@ int main(int argc, const char *argv[])
       printf(VERSION "\n");
       exit(2);
    }
+#ifdef _DEBUG
+   if ((argc >= 2) && (strcmp(argv[1], "-d")==0))
+   {
+      ldebug++;
+      argc_pos++;
+      fprintf(stderr,"debugging enabled..\n");
+   }
+#endif /* _DEBUG */
 #endif /* !defined(_WIN32) || defined(_WIN_CONSOLE) */
 
    Argc = argc;
    Argv = argv;
 
-   if (argc > 1)
+   if (argc > argc_pos )
+   {
+      configfile = argv[argc_pos];
+   }
+
+#if defined(unix)
+   if ( *configfile != '/' )
    {
-      configfile = argv[1];
+      char *abs_file;
+
+      DBG(1, ("configfile before '%s'\n",configfile) );
+
+      /* make config-filename absolute here */
+      if ( !(basedir = getcwd( NULL, 1024 )))
+      {
+         perror("get working dir failed");
+         exit( 1 );
+      }
+      DBG(1, ("working dir '%s'\n",basedir) );
+      if ( !(abs_file = malloc( strlen( basedir ) + strlen( configfile ) + 5 )))
+      {
+         perror("malloc failed");
+         exit( 1 );
+      }
+      strcpy( abs_file, basedir );
+      strcat( abs_file, "/" );
+      strcat( abs_file, configfile );
+      configfile = abs_file;
+      DBG(1, ("configfile after '%s'\n",configfile) );
    }
+#endif /* defined unix */
+
 
    files->next = NULL;
 
@@ -1408,6 +1484,79 @@ int main(int argc, const char *argv[])
    /* Initialize the CGI subsystem */
    cgi_init_error_messages();
 
+#if defined(unix)
+{
+   pid_t pid = 0;
+#if 0
+   int   fd;
+#endif
+
+   /*
+    * we make us a real daemon
+    */
+#ifdef _DEBUG
+   if ( !ldebug)
+#endif
+   pid  = fork();
+   if ( pid < 0 ) /* error */
+   {
+      perror("fork");
+      exit( 3 );
+   }
+   else if ( pid != 0 ) /* parent */
+   {
+      int status;
+      pid_t wpid;
+      /*
+       * must check for errors
+       * child died due to missing files aso
+       */
+      sleep( 1 );
+      wpid = waitpid( pid, &status, WNOHANG );
+      if ( wpid != 0 )
+      {
+         exit( 1 );
+      }
+      exit( 0 );
+   }
+   /* child */
+#if 1
+   /* Should be more portable, but not as well tested */
+   setsid();
+#else /* !1 */
+#ifdef __FreeBSD__
+   setpgrp(0,0);
+#else /* ndef __FreeBSD__ */
+   setpgrp();
+#endif /* ndef __FreeBSD__ */
+   fd = open("/dev/tty", O_RDONLY);
+   if ( fd )
+   {
+      /* no error check here */
+      ioctl( fd, TIOCNOTTY,0 );
+      close ( fd );
+   }
+#endif /* !1 */
+   /* should close stderr (fd 2) here too, but the test for existence
+   ** and load config file is done in listen_loop() and puts
+   ** some messages on stderr there.
+   */
+#ifdef _DEBUG
+   if ( !ldebug )
+   {
+      close( 0 );
+      close( 1 );
+   }
+#else
+   close( 0 );
+   close( 1 );
+#endif /* _DEBUG */
+   chdir("/");
+
+}
+#endif /* defined unix */
+
+   DBG(1, ("call listen_loop() \n") );
    listen_loop();
 
    /* NOTREACHED */
@@ -1454,7 +1603,6 @@ static void listen_loop(void)
 
    config->need_bind = 0;
 
-
    while (FOREVER)
    {
 #if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)