summaryrefslogtreecommitdiff
path: root/src/tinyproxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tinyproxy.c')
-rw-r--r--src/tinyproxy.c476
1 files changed, 0 insertions, 476 deletions
diff --git a/src/tinyproxy.c b/src/tinyproxy.c
deleted file mode 100644
index b5a214d..0000000
--- a/src/tinyproxy.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/* tinyproxy - A fast light-weight HTTP proxy
- * Copyright (C) 1998 Steven Young <sdyoung@miranda.org>
- * Copyright (C) 1998-2002 Robert James Kaes <rjkaes@users.sourceforge.net>
- * Copyright (C) 2000 Chris Lightfoot <chris@ex-parrot.com>
- *
- * 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 your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/* The initialize routine. Basically sets up all the initial stuff (logfile,
- * listening socket, config options, etc.) and then sits there and loops
- * over the new connections until the daemon is closed. Also has additional
- * functions to handle the "user friendly" aspects of a program (usage,
- * stats, etc.) Like any good program, most of the work is actually done
- * elsewhere.
- */
-
-#include "tinyproxy.h"
-
-#include "anonymous.h"
-#include "buffer.h"
-#include "conffile.h"
-#include "daemon.h"
-#include "heap.h"
-#include "filter.h"
-#include "child.h"
-#include "log.h"
-#include "reqs.h"
-#include "sock.h"
-#include "stats.h"
-#include "utils.h"
-
-RETSIGTYPE takesig (int sig);
-
-/*
- * Global Structures
- */
-struct config_s config;
-float load = 0.00;
-unsigned int received_sighup = FALSE; /* boolean */
-unsigned int processed_config_file = FALSE; /* boolean */
-
-/*
- * Handle a signal
- */
-RETSIGTYPE
-takesig (int sig)
-{
- pid_t pid;
- int status;
-
- switch (sig)
- {
- case SIGHUP:
- received_sighup = TRUE;
- break;
-
- case SIGTERM:
- config.quit = TRUE;
- break;
-
- case SIGCHLD:
- while ((pid = waitpid (-1, &status, WNOHANG)) > 0);
- break;
- }
-
- return;
-}
-
-/*
- * Display the version information for the user.
- */
-static void
-display_version (void)
-{
- printf ("%s %s (%s)\n", PACKAGE, VERSION, TARGET_SYSTEM);
-}
-
-/*
- * Display the copyright and license for this program.
- */
-static void
-display_license (void)
-{
- display_version ();
-
- printf ("\
- Copyright 1998 Steven Young (sdyoung@well.com)\n\
- Copyright 1998-2002 Robert James Kaes (rjkaes@users.sourceforge.net)\n\
- Copyright 1999 George Talusan (gstalusan@uwaterloo.ca)\n\
- Copyright 2000 Chris Lightfoot (chris@ex-parrot.com)\n\
-\n\
- This program is free software; you can redistribute it and/or modify\n\
- it under the terms of the GNU General Public License as published by\n\
- the Free Software Foundation; either version 2, or (at your option)\n\
- any later version.\n\
-\n\
- This program is distributed in the hope that it will be useful,\n\
- but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
- GNU General Public License for more details.\n\
-\n\
- You should have received a copy of the GNU General Public License\n\
- along with this program; if not, write to the Free Software\n\
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.\n");
-}
-
-/*
- * Display usage to the user.
- */
-static void
-display_usage (void)
-{
- printf ("Usage: %s [options]\n", PACKAGE);
- printf ("\
-Options:\n\
- -d Operate in DEBUG mode.\n\
- -c FILE Use an alternate configuration file.\n\
- -h Display this usage information.\n\
- -l Display the license.\n\
- -v Display the version number.\n");
-
- /* Display the modes compiled into tinyproxy */
- printf ("\nFeatures compiled in:\n");
-#ifdef XTINYPROXY_ENABLE
- printf (" XTinyproxy header\n");
-#endif /* XTINYPROXY */
-#ifdef FILTER_ENABLE
- printf (" Filtering\n");
-#endif /* FILTER_ENABLE */
-#ifndef NDEBUG
- printf (" Debugging code\n");
-#endif /* NDEBUG */
-#ifdef TRANSPARENT_PROXY
- printf (" Transparent proxy support\n");
-#endif /* TRANSPARENT_PROXY */
-#ifdef REVERSE_SUPPORT
- printf (" Reverse proxy support\n");
-#endif /* REVERSE_SUPPORT */
-}
-
-static int
-get_id (char *str)
-{
- char *tstr;
-
- if (str == NULL)
- return -1;
-
- tstr = str;
- while (*tstr != 0)
- {
- if (!isdigit (*tstr))
- return -1;
- tstr++;
- }
-
- return atoi (str);
-}
-
-int
-main (int argc, char **argv)
-{
- int optch;
- unsigned int godaemon = TRUE; /* boolean */
- struct passwd *thisuser = NULL;
- struct group *thisgroup = NULL;
- FILE *config_file;
-
- /* Only allow u+rw bits. This may be required for some versions
- * of glibc so that mkstemp() doesn't make us vulnerable.
- */
- umask (0177);
-
- /* Default configuration file location */
- config.config_file = DEFAULT_CONF_FILE;
-
- /*
- * Process the various options
- */
- while ((optch = getopt (argc, argv, "c:vldh")) != EOF)
- {
- switch (optch)
- {
- case 'v':
- display_version ();
- exit (EX_OK);
- case 'l':
- display_license ();
- exit (EX_OK);
- case 'd':
- godaemon = FALSE;
- break;
- case 'c':
- config.config_file = safestrdup (optarg);
- if (!config.config_file)
- {
- fprintf (stderr, "%s: Could not allocate memory.\n", argv[0]);
- exit (EX_SOFTWARE);
- }
- break;
- case 'h':
- default:
- display_usage ();
- exit (EX_OK);
- }
- }
-
- log_message (LOG_INFO, "Initializing " PACKAGE " ...");
-
- /*
- * Make sure the HTML error pages array is NULL to begin with.
- * (FIXME: Should have a better API for all this)
- */
- config.errorpages = NULL;
-
- /*
- * Read in the settings from the config file.
- */
- config_file = fopen (config.config_file, "r");
- if (!config_file)
- {
- fprintf (stderr,
- "%s: Could not open configuration file \"%s\".\n",
- argv[0], config.config_file);
- exit (EX_SOFTWARE);
- }
- if (config_compile () || config_parse (&config, config_file))
- {
- fprintf (stderr,
- "Unable to parse configuration file. Not starting.\n");
- exit (EX_SOFTWARE);
- }
- fclose (config_file);
-
- /*
- * Write to a user supplied log file if it's defined. This
- * will override using the syslog even if syslog is defined.
- */
- if (config.logf_name)
- {
- if (open_log_file (config.logf_name) < 0)
- {
- fprintf (stderr, "%s: Could not create log file.\n", argv[0]);
- exit (EX_SOFTWARE);
- }
- config.syslog = FALSE; /* disable syslog */
- }
- else if (config.syslog)
- {
- if (godaemon == TRUE)
- openlog ("tinyproxy", LOG_PID, LOG_DAEMON);
- else
- openlog ("tinyproxy", LOG_PID, LOG_USER);
- }
- else
- {
- fprintf (stderr,
- "%s: Either define a logfile or enable syslog logging.\n",
- argv[0]);
- exit (EX_SOFTWARE);
- }
-
- processed_config_file = TRUE;
- send_stored_logs ();
-
- /*
- * Set the default values if they were not set in the config file.
- */
- if (config.port == 0)
- {
- fprintf (stderr,
- "%s: You MUST set a Port in the configuration file.\n",
- argv[0]);
- exit (EX_SOFTWARE);
- }
- if (!config.stathost)
- {
- log_message (LOG_INFO, "Setting stathost to \"%s\".", DEFAULT_STATHOST);
- config.stathost = DEFAULT_STATHOST;
- }
- if (!config.user)
- {
- log_message (LOG_WARNING,
- "You SHOULD set a UserName in the configuration file. "
- "Using current user instead.");
- }
- if (config.idletimeout == 0)
- {
- log_message (LOG_WARNING,
- "Invalid idle time setting. Only values greater than zero "
- "allowed; therefore setting idle timeout to %u seconds.",
- MAX_IDLE_TIME);
- config.idletimeout = MAX_IDLE_TIME;
- }
-
- init_stats ();
-
- /*
- * If ANONYMOUS is turned on, make sure that Content-Length is
- * in the list of allowed headers, since it is required in a
- * HTTP/1.0 request. Also add the Content-Type header since it goes
- * hand in hand with Content-Length.
- * - rjkaes
- */
- if (is_anonymous_enabled ())
- {
- anonymous_insert ("Content-Length");
- anonymous_insert ("Content-Type");
- }
-
- if (godaemon == TRUE)
- makedaemon ();
-
- if (config.pidpath)
- {
- if (pidfile_create (config.pidpath) < 0)
- {
- fprintf (stderr, "%s: Could not create PID file.\n", argv[0]);
- exit (EX_OSERR);
- }
- }
-
- if (set_signal_handler (SIGPIPE, SIG_IGN) == SIG_ERR)
- {
- fprintf (stderr, "%s: Could not set the \"SIGPIPE\" signal.\n",
- argv[0]);
- exit (EX_OSERR);
- }
-#ifdef FILTER_ENABLE
- if (config.filter)
- filter_init ();
-#endif /* FILTER_ENABLE */
-
- /*
- * Start listening on the selected port.
- */
- if (child_listening_sock (config.port) < 0)
- {
- fprintf (stderr, "%s: Could not create listening socket.\n", argv[0]);
- exit (EX_OSERR);
- }
-
- /*
- * Switch to a different user.
- */
- if (geteuid () == 0)
- {
- if (config.group && strlen (config.group) > 0)
- {
- int gid = get_id (config.group);
- if (gid < 0)
- {
- thisgroup = getgrnam (config.group);
- if (!thisgroup)
- {
- fprintf (stderr,
- "%s: Unable to find "
- "group \"%s\".\n", argv[0], config.group);
- exit (EX_NOUSER);
- }
- gid = thisgroup->gr_gid;
- }
- if (setgid (gid) < 0)
- {
- fprintf (stderr,
- "%s: Unable to change to "
- "group \"%s\".\n", argv[0], config.group);
- exit (EX_CANTCREAT);
- }
- log_message (LOG_INFO, "Now running as group \"%s\".",
- config.group);
- }
- if (config.user && strlen (config.user) > 0)
- {
- int uid = get_id (config.user);
- if (uid < 0)
- {
- thisuser = getpwnam (config.user);
- if (!thisuser)
- {
- fprintf (stderr,
- "%s: Unable to find "
- "user \"%s\".\n", argv[0], config.user);
- exit (EX_NOUSER);
- }
- uid = thisuser->pw_uid;
- }
- if (setuid (uid) < 0)
- {
- fprintf (stderr,
- "%s: Unable to change to user \"%s\".\n",
- argv[0], config.user);
- exit (EX_CANTCREAT);
- }
- log_message (LOG_INFO, "Now running as user \"%s\".", config.user);
- }
- }
- else
- {
- log_message (LOG_WARNING,
- "Not running as root, so not changing UID/GID.");
- }
-
- if (child_pool_create () < 0)
- {
- fprintf (stderr, "%s: Could not create the pool of children.\n", argv[0]);
- exit (EX_SOFTWARE);
- }
-
- /*
- * These signals are only for the parent process.
- */
- log_message (LOG_INFO, "Setting the various signals.");
- if (set_signal_handler (SIGCHLD, takesig) == SIG_ERR)
- {
- fprintf (stderr, "%s: Could not set the \"SIGCHLD\" signal.\n",
- argv[0]);
- exit (EX_OSERR);
- }
- if (set_signal_handler (SIGTERM, takesig) == SIG_ERR)
- {
- fprintf (stderr, "%s: Could not set the \"SIGTERM\" signal.\n",
- argv[0]);
- exit (EX_OSERR);
- }
- if (set_signal_handler (SIGHUP, takesig) == SIG_ERR)
- {
- fprintf (stderr, "%s: Could not set the \"SIGHUP\" signal.\n", argv[0]);
- exit (EX_OSERR);
- }
-
- /*
- * Start the main loop.
- */
- log_message (LOG_INFO, "Starting main loop. Accepting connections.");
-
- child_main_loop ();
-
- log_message (LOG_INFO, "Shutting down.");
-
- child_kill_children ();
- child_close_sock ();
-
- /*
- * Remove the PID file.
- */
- if (unlink (config.pidpath) < 0)
- {
- log_message (LOG_WARNING,
- "Could not remove PID file \"%s\": %s.",
- config.pidpath, strerror (errno));
- }
-#ifdef FILTER_ENABLE
- if (config.filter)
- filter_destroy ();
-#endif /* FILTER_ENABLE */
-
- if (config.syslog)
- closelog ();
- else
- close_log_file ();
-
- exit (EX_OK);
-}