2008-05-24 16:05:49 +08:00
|
|
|
/* tinyproxy - A fast light-weight HTTP proxy
|
2009-10-07 07:08:03 +08:00
|
|
|
*
|
2008-05-24 16:05:49 +08:00
|
|
|
* 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>
|
2010-01-10 20:51:33 +08:00
|
|
|
* Copyright (C) 2009-2010 Mukund Sivaraman <muks@banu.com>
|
|
|
|
* Copyright (C) 2009-2010 Michael Adam <obnox@samba.org>
|
2000-02-17 01:32:49 +08:00
|
|
|
*
|
2008-05-24 16:05:49 +08:00
|
|
|
* 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,
|
2000-02-17 01:32:49 +08:00
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2009-08-07 06:12:53 +08:00
|
|
|
#include "main.h"
|
2000-02-17 01:32:49 +08:00
|
|
|
|
2000-09-12 08:03:53 +08:00
|
|
|
#include "anonymous.h"
|
2010-01-18 21:35:31 +08:00
|
|
|
#include "authors.h"
|
2000-02-17 01:32:49 +08:00
|
|
|
#include "buffer.h"
|
2009-09-21 12:11:59 +08:00
|
|
|
#include "conf.h"
|
2002-05-24 02:27:01 +08:00
|
|
|
#include "daemon.h"
|
|
|
|
#include "heap.h"
|
2000-02-17 01:32:49 +08:00
|
|
|
#include "filter.h"
|
2002-05-27 02:52:23 +08:00
|
|
|
#include "child.h"
|
2000-09-12 08:03:53 +08:00
|
|
|
#include "log.h"
|
|
|
|
#include "reqs.h"
|
|
|
|
#include "sock.h"
|
|
|
|
#include "stats.h"
|
|
|
|
#include "utils.h"
|
2000-02-17 01:32:49 +08:00
|
|
|
|
2008-05-24 16:05:49 +08:00
|
|
|
/*
|
2000-02-17 01:32:49 +08:00
|
|
|
* Global Structures
|
|
|
|
*/
|
2000-09-12 08:03:53 +08:00
|
|
|
struct config_s config;
|
2009-12-07 08:11:17 +08:00
|
|
|
struct config_s config_defaults;
|
2008-12-08 21:39:44 +08:00
|
|
|
unsigned int received_sighup = FALSE; /* boolean */
|
2000-02-17 01:32:49 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Handle a signal
|
|
|
|
*/
|
2009-09-20 16:33:56 +08:00
|
|
|
static void
|
2009-09-15 06:23:35 +08:00
|
|
|
takesig (int sig)
|
2000-02-17 01:32:49 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
pid_t pid;
|
|
|
|
int status;
|
2002-05-24 02:27:01 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
switch (sig) {
|
|
|
|
case SIGHUP:
|
|
|
|
received_sighup = TRUE;
|
|
|
|
break;
|
2002-04-19 00:57:06 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
case SIGTERM:
|
|
|
|
config.quit = TRUE;
|
|
|
|
break;
|
2002-05-24 02:27:01 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
case SIGCHLD:
|
|
|
|
while ((pid = waitpid (-1, &status, WNOHANG)) > 0) ;
|
|
|
|
break;
|
|
|
|
}
|
2000-12-08 11:35:07 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
return;
|
2000-02-17 01:32:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-09-12 08:03:53 +08:00
|
|
|
* Display the version information for the user.
|
|
|
|
*/
|
2009-09-15 06:23:35 +08:00
|
|
|
static void
|
|
|
|
display_version (void)
|
2000-09-12 08:03:53 +08:00
|
|
|
{
|
2009-09-20 15:10:52 +08:00
|
|
|
printf ("%s %s\n", PACKAGE, VERSION);
|
2001-08-27 05:17:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Display the copyright and license for this program.
|
|
|
|
*/
|
2009-09-15 06:23:35 +08:00
|
|
|
static void
|
|
|
|
display_license (void)
|
2001-08-27 05:17:30 +08:00
|
|
|
{
|
2010-01-18 21:35:31 +08:00
|
|
|
const char * const *authors;
|
|
|
|
const char * const *documenters;
|
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
display_version ();
|
2001-08-27 05:17:30 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
printf ("\
|
2010-01-18 21:35:31 +08:00
|
|
|
\n\
|
2001-08-27 05:17:30 +08:00
|
|
|
Copyright 1998 Steven Young (sdyoung@well.com)\n\
|
2002-04-08 05:36:39 +08:00
|
|
|
Copyright 1998-2002 Robert James Kaes (rjkaes@users.sourceforge.net)\n\
|
2001-08-27 05:17:30 +08:00
|
|
|
Copyright 1999 George Talusan (gstalusan@uwaterloo.ca)\n\
|
|
|
|
Copyright 2000 Chris Lightfoot (chris@ex-parrot.com)\n\
|
2010-01-10 20:51:33 +08:00
|
|
|
Copyright 2009-2010 Mukund Sivaraman (muks@banu.com)\n\
|
|
|
|
Copyright 2009-2010 Michael Adam (obnox@samba.org)\n\
|
2001-08-27 05:17:30 +08:00
|
|
|
\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\
|
2000-09-12 08:03:53 +08:00
|
|
|
\n\
|
2001-08-27 05:17:30 +08:00
|
|
|
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\
|
2000-09-12 08:03:53 +08:00
|
|
|
\n\
|
2001-08-27 05:17:30 +08:00
|
|
|
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\
|
2010-01-18 21:35:31 +08:00
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.\n\
|
|
|
|
\n");
|
|
|
|
|
|
|
|
printf ("\nAUTHORS:\n");
|
2010-01-19 07:44:06 +08:00
|
|
|
for (authors = authors_get_authors (); *authors; authors++) {
|
2010-01-18 21:35:31 +08:00
|
|
|
printf (" %s\n", *authors);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf ("\nDOCUMENTERS:\n");
|
2010-01-19 07:44:06 +08:00
|
|
|
for (documenters = authors_get_documenters ();
|
|
|
|
*documenters; documenters++) {
|
2010-01-18 21:35:31 +08:00
|
|
|
printf (" %s\n", *documenters);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf ("\n");
|
2000-09-12 08:03:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Display usage to the user.
|
2000-02-17 01:32:49 +08:00
|
|
|
*/
|
2009-09-15 06:23:35 +08:00
|
|
|
static void
|
|
|
|
display_usage (void)
|
2000-02-17 01:32:49 +08:00
|
|
|
{
|
2009-09-26 15:00:54 +08:00
|
|
|
int features = 0;
|
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
printf ("Usage: %s [options]\n", PACKAGE);
|
2009-09-26 15:00:54 +08:00
|
|
|
printf ("\n"
|
|
|
|
"Options are:\n"
|
|
|
|
" -d Do not daemonize (run in foreground).\n"
|
|
|
|
" -c FILE Use an alternate configuration file.\n"
|
|
|
|
" -h Display this usage information.\n"
|
|
|
|
" -l Display the license.\n"
|
|
|
|
" -v Display version information.\n");
|
2000-09-12 08:03:53 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
/* Display the modes compiled into tinyproxy */
|
|
|
|
printf ("\nFeatures compiled in:\n");
|
2009-09-26 15:00:54 +08:00
|
|
|
|
2000-09-12 08:03:53 +08:00
|
|
|
#ifdef XTINYPROXY_ENABLE
|
2009-09-15 03:41:25 +08:00
|
|
|
printf (" XTinyproxy header\n");
|
2009-09-26 15:00:54 +08:00
|
|
|
features++;
|
2008-12-01 23:01:11 +08:00
|
|
|
#endif /* XTINYPROXY */
|
2009-09-26 15:00:54 +08:00
|
|
|
|
2000-02-17 01:32:49 +08:00
|
|
|
#ifdef FILTER_ENABLE
|
2009-09-15 03:41:25 +08:00
|
|
|
printf (" Filtering\n");
|
2009-09-26 15:00:54 +08:00
|
|
|
features++;
|
2008-12-01 23:01:11 +08:00
|
|
|
#endif /* FILTER_ENABLE */
|
2009-09-26 15:00:54 +08:00
|
|
|
|
2000-02-17 01:32:49 +08:00
|
|
|
#ifndef NDEBUG
|
2009-09-15 03:41:25 +08:00
|
|
|
printf (" Debugging code\n");
|
2009-09-26 15:00:54 +08:00
|
|
|
features++;
|
2008-12-01 23:01:11 +08:00
|
|
|
#endif /* NDEBUG */
|
2009-09-26 15:00:54 +08:00
|
|
|
|
2002-06-07 04:28:02 +08:00
|
|
|
#ifdef TRANSPARENT_PROXY
|
2009-09-15 03:41:25 +08:00
|
|
|
printf (" Transparent proxy support\n");
|
2009-09-26 15:00:54 +08:00
|
|
|
features++;
|
2008-12-01 23:01:11 +08:00
|
|
|
#endif /* TRANSPARENT_PROXY */
|
2009-09-26 15:00:54 +08:00
|
|
|
|
2004-01-27 03:11:52 +08:00
|
|
|
#ifdef REVERSE_SUPPORT
|
2009-09-15 03:41:25 +08:00
|
|
|
printf (" Reverse proxy support\n");
|
2009-09-26 15:00:54 +08:00
|
|
|
features++;
|
2008-12-01 23:01:11 +08:00
|
|
|
#endif /* REVERSE_SUPPORT */
|
2009-09-26 15:00:54 +08:00
|
|
|
|
2010-02-18 01:41:45 +08:00
|
|
|
#ifdef UPSTREAM_SUPPORT
|
|
|
|
printf (" Upstream proxy support\n");
|
|
|
|
features++;
|
|
|
|
#endif /* UPSTREAM_SUPPORT */
|
|
|
|
|
2009-09-26 15:00:54 +08:00
|
|
|
if (0 == features)
|
|
|
|
printf (" None\n");
|
|
|
|
|
|
|
|
printf ("\n"
|
2010-02-17 02:59:29 +08:00
|
|
|
"For support and bug reporting instructions, please visit\n"
|
2016-01-04 05:16:21 +08:00
|
|
|
"<https://tinyproxy.github.io/>.\n");
|
2000-02-17 01:32:49 +08:00
|
|
|
}
|
|
|
|
|
2009-09-15 06:23:35 +08:00
|
|
|
static int
|
|
|
|
get_id (char *str)
|
2008-07-14 20:10:20 +08:00
|
|
|
{
|
2009-09-15 03:41:25 +08:00
|
|
|
char *tstr;
|
2008-07-14 20:10:20 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (str == NULL)
|
|
|
|
return -1;
|
2008-07-14 20:10:20 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
tstr = str;
|
|
|
|
while (*tstr != 0) {
|
|
|
|
if (!isdigit (*tstr))
|
|
|
|
return -1;
|
|
|
|
tstr++;
|
|
|
|
}
|
2008-07-14 20:10:20 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
return atoi (str);
|
2008-07-14 20:10:20 +08:00
|
|
|
}
|
|
|
|
|
2009-09-15 04:04:30 +08:00
|
|
|
/**
|
|
|
|
* process_cmdline:
|
|
|
|
* @argc: argc as passed to main()
|
|
|
|
* @argv: argv as passed to main()
|
|
|
|
*
|
|
|
|
* This function parses command line arguments.
|
|
|
|
**/
|
|
|
|
static void
|
2009-11-09 06:40:13 +08:00
|
|
|
process_cmdline (int argc, char **argv, struct config_s *conf)
|
2000-02-17 01:32:49 +08:00
|
|
|
{
|
2009-09-15 04:04:30 +08:00
|
|
|
int opt;
|
2009-09-15 03:41:25 +08:00
|
|
|
|
2009-09-15 04:04:30 +08:00
|
|
|
while ((opt = getopt (argc, argv, "c:vldh")) != EOF) {
|
|
|
|
switch (opt) {
|
2009-09-15 03:41:25 +08:00
|
|
|
case 'v':
|
|
|
|
display_version ();
|
|
|
|
exit (EX_OK);
|
2009-09-15 04:04:30 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
case 'l':
|
|
|
|
display_license ();
|
|
|
|
exit (EX_OK);
|
2009-09-15 04:04:30 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
case 'd':
|
2009-11-09 06:40:13 +08:00
|
|
|
conf->godaemon = FALSE;
|
2009-09-15 03:41:25 +08:00
|
|
|
break;
|
2009-09-15 04:04:30 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
case 'c':
|
2009-12-07 07:30:41 +08:00
|
|
|
if (conf->config_file != NULL) {
|
|
|
|
safefree (conf->config_file);
|
|
|
|
}
|
2009-11-09 06:40:13 +08:00
|
|
|
conf->config_file = safestrdup (optarg);
|
|
|
|
if (!conf->config_file) {
|
2009-09-15 03:41:25 +08:00
|
|
|
fprintf (stderr,
|
|
|
|
"%s: Could not allocate memory.\n",
|
|
|
|
argv[0]);
|
|
|
|
exit (EX_SOFTWARE);
|
|
|
|
}
|
|
|
|
break;
|
2009-09-15 04:04:30 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
case 'h':
|
|
|
|
display_usage ();
|
|
|
|
exit (EX_OK);
|
2009-09-15 06:23:18 +08:00
|
|
|
|
|
|
|
default:
|
|
|
|
display_usage ();
|
|
|
|
exit (EX_USAGE);
|
2009-09-15 03:41:25 +08:00
|
|
|
}
|
|
|
|
}
|
2009-09-15 04:04:30 +08:00
|
|
|
}
|
|
|
|
|
2009-09-15 04:30:20 +08:00
|
|
|
/**
|
|
|
|
* change_user:
|
|
|
|
* @program: The name of the program. Pass argv[0] here.
|
|
|
|
*
|
|
|
|
* This function tries to change UID and GID to the ones specified in
|
|
|
|
* the config file. This function is typically called during
|
|
|
|
* initialization when the effective user is root.
|
|
|
|
**/
|
2009-09-15 04:23:07 +08:00
|
|
|
static void
|
|
|
|
change_user (const char *program)
|
|
|
|
{
|
|
|
|
if (config.group && strlen (config.group) > 0) {
|
|
|
|
int gid = get_id (config.group);
|
|
|
|
|
|
|
|
if (gid < 0) {
|
|
|
|
struct group *thisgroup = getgrnam (config.group);
|
|
|
|
|
|
|
|
if (!thisgroup) {
|
|
|
|
fprintf (stderr,
|
|
|
|
"%s: Unable to find group \"%s\".\n",
|
|
|
|
program, config.group);
|
|
|
|
exit (EX_NOUSER);
|
|
|
|
}
|
|
|
|
|
|
|
|
gid = thisgroup->gr_gid;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setgid (gid) < 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
"%s: Unable to change to group \"%s\".\n",
|
|
|
|
program, config.group);
|
2009-09-15 04:24:26 +08:00
|
|
|
exit (EX_NOPERM);
|
2009-09-15 04:23:07 +08:00
|
|
|
}
|
|
|
|
|
2013-09-09 14:33:48 +08:00
|
|
|
#ifdef HAVE_SETGROUPS
|
|
|
|
/* Drop all supplementary groups, otherwise these are inherited from the calling process */
|
|
|
|
if (setgroups (0, NULL) < 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
"%s: Unable to drop supplementary groups.\n",
|
|
|
|
program);
|
|
|
|
exit (EX_NOPERM);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2009-09-15 04:23:07 +08:00
|
|
|
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) {
|
|
|
|
struct passwd *thisuser = getpwnam (config.user);
|
|
|
|
|
|
|
|
if (!thisuser) {
|
|
|
|
fprintf (stderr,
|
|
|
|
"%s: Unable to find user \"%s\".\n",
|
|
|
|
program, config.user);
|
|
|
|
exit (EX_NOUSER);
|
|
|
|
}
|
|
|
|
|
|
|
|
uid = thisuser->pw_uid;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setuid (uid) < 0) {
|
|
|
|
fprintf (stderr,
|
|
|
|
"%s: Unable to change to user \"%s\".\n",
|
|
|
|
program, config.user);
|
2009-09-15 04:24:26 +08:00
|
|
|
exit (EX_NOPERM);
|
2009-09-15 04:23:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
log_message (LOG_INFO, "Now running as user \"%s\".",
|
|
|
|
config.user);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-09 06:39:24 +08:00
|
|
|
static void initialize_config_defaults (struct config_s *conf)
|
|
|
|
{
|
|
|
|
memset (conf, 0, sizeof(*conf));
|
|
|
|
|
2009-12-07 07:30:41 +08:00
|
|
|
conf->config_file = safestrdup (SYSCONFDIR "/tinyproxy.conf");
|
|
|
|
if (!conf->config_file) {
|
|
|
|
fprintf (stderr, PACKAGE ": Could not allocate memory.\n");
|
|
|
|
exit (EX_SOFTWARE);
|
|
|
|
}
|
2009-11-09 06:39:24 +08:00
|
|
|
conf->godaemon = TRUE;
|
|
|
|
/*
|
|
|
|
* Make sure the HTML error pages array is NULL to begin with.
|
|
|
|
* (FIXME: Should have a better API for all this)
|
|
|
|
*/
|
|
|
|
conf->errorpages = NULL;
|
2009-12-06 08:35:49 +08:00
|
|
|
conf->stathost = safestrdup (TINYPROXY_STATHOST);
|
2009-12-06 08:39:33 +08:00
|
|
|
conf->idletimeout = MAX_IDLE_TIME;
|
2010-03-03 06:11:57 +08:00
|
|
|
conf->logf_name = safestrdup (LOCALSTATEDIR "/log/tinyproxy/tinyproxy.log");
|
2017-11-05 03:26:41 +08:00
|
|
|
conf->pidpath = NULL;
|
2009-11-09 06:39:24 +08:00
|
|
|
}
|
|
|
|
|
2009-12-22 06:37:17 +08:00
|
|
|
/**
|
|
|
|
* convenience wrapper around reload_config_file
|
2009-12-23 07:18:31 +08:00
|
|
|
* that also re-initializes logging.
|
2009-12-22 06:37:17 +08:00
|
|
|
*/
|
|
|
|
int reload_config (void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2009-12-23 07:18:31 +08:00
|
|
|
shutdown_logging ();
|
|
|
|
|
2009-12-22 06:37:17 +08:00
|
|
|
ret = reload_config_file (config_defaults.config_file, &config,
|
|
|
|
&config_defaults);
|
2009-12-23 07:18:31 +08:00
|
|
|
if (ret != 0) {
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = setup_logging ();
|
2009-12-22 06:37:17 +08:00
|
|
|
|
2009-12-23 07:18:31 +08:00
|
|
|
done:
|
2009-12-22 06:37:17 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-09-15 04:04:30 +08:00
|
|
|
int
|
|
|
|
main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
/* Only allow u+rw bits. This may be required for some versions
|
|
|
|
* of glibc so that mkstemp() doesn't make us vulnerable.
|
|
|
|
*/
|
|
|
|
umask (0177);
|
|
|
|
|
2010-03-03 05:05:28 +08:00
|
|
|
log_message (LOG_INFO, "Initializing " PACKAGE " ...");
|
|
|
|
|
2010-06-02 12:41:10 +08:00
|
|
|
if (config_compile_regex()) {
|
2010-06-01 10:24:25 +08:00
|
|
|
exit (EX_SOFTWARE);
|
|
|
|
}
|
|
|
|
|
2009-12-07 08:11:17 +08:00
|
|
|
initialize_config_defaults (&config_defaults);
|
|
|
|
process_cmdline (argc, argv, &config_defaults);
|
2009-11-04 07:29:35 +08:00
|
|
|
|
2010-06-02 12:41:10 +08:00
|
|
|
if (reload_config_file (config_defaults.config_file,
|
|
|
|
&config,
|
|
|
|
&config_defaults)) {
|
2010-03-03 04:57:03 +08:00
|
|
|
exit (EX_SOFTWARE);
|
|
|
|
}
|
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
init_stats ();
|
|
|
|
|
2009-09-15 06:37:06 +08:00
|
|
|
/* If ANONYMOUS is turned on, make sure that Content-Length is
|
2009-09-15 03:41:25 +08:00
|
|
|
* in the list of allowed headers, since it is required in a
|
2009-09-15 06:37:06 +08:00
|
|
|
* HTTP/1.0 request. Also add the Content-Type header since it
|
|
|
|
* goes hand in hand with Content-Length. */
|
2009-09-15 03:41:25 +08:00
|
|
|
if (is_anonymous_enabled ()) {
|
|
|
|
anonymous_insert ("Content-Length");
|
|
|
|
anonymous_insert ("Content-Type");
|
|
|
|
}
|
|
|
|
|
2009-09-15 04:04:30 +08:00
|
|
|
if (config.godaemon == TRUE)
|
2009-09-15 03:41:25 +08:00
|
|
|
makedaemon ();
|
|
|
|
|
|
|
|
if (set_signal_handler (SIGPIPE, SIG_IGN) == SIG_ERR) {
|
|
|
|
fprintf (stderr, "%s: Could not set the \"SIGPIPE\" signal.\n",
|
|
|
|
argv[0]);
|
|
|
|
exit (EX_OSERR);
|
2008-12-08 21:39:44 +08:00
|
|
|
}
|
2009-09-15 06:37:06 +08:00
|
|
|
|
2000-09-12 08:03:53 +08:00
|
|
|
#ifdef FILTER_ENABLE
|
2009-09-15 03:41:25 +08:00
|
|
|
if (config.filter)
|
|
|
|
filter_init ();
|
2008-12-01 23:01:11 +08:00
|
|
|
#endif /* FILTER_ENABLE */
|
|
|
|
|
2009-09-15 06:37:06 +08:00
|
|
|
/* Start listening on the selected port. */
|
2013-11-07 18:00:19 +08:00
|
|
|
if (child_listening_sockets(config.listen_addrs, config.port) < 0) {
|
|
|
|
fprintf (stderr, "%s: Could not create listening sockets.\n",
|
2009-09-15 03:41:25 +08:00
|
|
|
argv[0]);
|
|
|
|
exit (EX_OSERR);
|
2008-12-08 21:39:44 +08:00
|
|
|
}
|
2009-09-15 03:41:25 +08:00
|
|
|
|
2010-04-21 22:40:56 +08:00
|
|
|
/* Switch to a different user if we're running as root */
|
|
|
|
if (geteuid () == 0)
|
|
|
|
change_user (argv[0]);
|
|
|
|
else
|
|
|
|
log_message (LOG_WARNING,
|
|
|
|
"Not running as root, so not changing UID/GID.");
|
|
|
|
|
2010-06-02 12:49:49 +08:00
|
|
|
/* Create log file after we drop privileges */
|
|
|
|
if (setup_logging ()) {
|
|
|
|
exit (EX_SOFTWARE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create pid file after we drop privileges */
|
|
|
|
if (config.pidpath) {
|
|
|
|
if (pidfile_create (config.pidpath) < 0) {
|
|
|
|
fprintf (stderr, "%s: Could not create PID file.\n",
|
|
|
|
argv[0]);
|
|
|
|
exit (EX_OSERR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (child_pool_create () < 0) {
|
2009-09-15 06:37:06 +08:00
|
|
|
fprintf (stderr,
|
|
|
|
"%s: Could not create the pool of children.\n",
|
2009-09-15 03:41:25 +08:00
|
|
|
argv[0]);
|
|
|
|
exit (EX_SOFTWARE);
|
|
|
|
}
|
|
|
|
|
2009-09-15 06:37:06 +08:00
|
|
|
/* These signals are only for the parent process. */
|
2009-09-15 03:41:25 +08:00
|
|
|
log_message (LOG_INFO, "Setting the various signals.");
|
2009-09-15 06:37:06 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (set_signal_handler (SIGCHLD, takesig) == SIG_ERR) {
|
|
|
|
fprintf (stderr, "%s: Could not set the \"SIGCHLD\" signal.\n",
|
|
|
|
argv[0]);
|
|
|
|
exit (EX_OSERR);
|
|
|
|
}
|
2009-09-15 06:37:06 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (set_signal_handler (SIGTERM, takesig) == SIG_ERR) {
|
|
|
|
fprintf (stderr, "%s: Could not set the \"SIGTERM\" signal.\n",
|
|
|
|
argv[0]);
|
|
|
|
exit (EX_OSERR);
|
|
|
|
}
|
2009-09-15 06:37:06 +08:00
|
|
|
|
2009-09-15 03:41:25 +08:00
|
|
|
if (set_signal_handler (SIGHUP, takesig) == SIG_ERR) {
|
|
|
|
fprintf (stderr, "%s: Could not set the \"SIGHUP\" signal.\n",
|
|
|
|
argv[0]);
|
|
|
|
exit (EX_OSERR);
|
|
|
|
}
|
|
|
|
|
2009-09-15 06:37:06 +08:00
|
|
|
/* Start the main loop */
|
2009-09-15 03:41:25 +08:00
|
|
|
log_message (LOG_INFO, "Starting main loop. Accepting connections.");
|
|
|
|
|
|
|
|
child_main_loop ();
|
|
|
|
|
|
|
|
log_message (LOG_INFO, "Shutting down.");
|
|
|
|
|
2009-10-26 03:25:06 +08:00
|
|
|
child_kill_children (SIGTERM);
|
2009-09-15 03:41:25 +08:00
|
|
|
child_close_sock ();
|
|
|
|
|
2009-09-15 06:37:06 +08:00
|
|
|
/* Remove the PID file */
|
2017-11-05 03:26:41 +08:00
|
|
|
if (config.pidpath != NULL && unlink (config.pidpath) < 0) {
|
2009-09-15 03:41:25 +08:00
|
|
|
log_message (LOG_WARNING,
|
|
|
|
"Could not remove PID file \"%s\": %s.",
|
|
|
|
config.pidpath, strerror (errno));
|
2008-12-08 21:39:44 +08:00
|
|
|
}
|
2009-09-15 06:37:06 +08:00
|
|
|
|
2000-02-17 01:32:49 +08:00
|
|
|
#ifdef FILTER_ENABLE
|
2009-09-15 03:41:25 +08:00
|
|
|
if (config.filter)
|
|
|
|
filter_destroy ();
|
2008-12-01 23:01:11 +08:00
|
|
|
#endif /* FILTER_ENABLE */
|
2000-02-17 01:32:49 +08:00
|
|
|
|
2009-12-23 07:30:11 +08:00
|
|
|
shutdown_logging ();
|
2000-02-17 01:32:49 +08:00
|
|
|
|
2009-09-15 06:36:26 +08:00
|
|
|
return EXIT_SUCCESS;
|
2000-02-17 01:32:49 +08:00
|
|
|
}
|