diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2001-11-02 13:08:32 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2001-11-02 13:08:32 +0000 |
commit | 0e68861f9fe358112677480badced4abd65337cf (patch) | |
tree | 358055b51e5b4ce45f2098754ae7cb74154b981c /comsat | |
parent | 873f12bf0c9d9533d0576d4d428f8064d98bb694 (diff) | |
download | mailutils-0e68861f9fe358112677480badced4abd65337cf.tar.gz mailutils-0e68861f9fe358112677480badced4abd65337cf.tar.bz2 |
Restart on sighup when in daemon mode.
Fight floods by increasing delays exponentially.
Fill in `hostname' on startup.
Diffstat (limited to 'comsat')
-rw-r--r-- | comsat/comsat.c | 62 |
1 files changed, 51 insertions, 11 deletions
diff --git a/comsat/comsat.c b/comsat/comsat.c index d50d811a9..753c59d69 100644 --- a/comsat/comsat.c +++ b/comsat/comsat.c @@ -76,11 +76,15 @@ static struct option long_options[] = #define NOT_HERE 1 #define PERMISSION_DENIED 2 +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 64 +#endif + int mode = MODE_INETD; int port = 512; /* Default biff port */ int timeout = 0; int maxlines = 5; -char *hostname; +char hostname[MAXHOSTNAMELEN]; static int syslog_error_printer (const char *fmt, va_list ap); static void comsat_init (void); @@ -93,6 +97,9 @@ static void help (void); char *mailbox_path (const char *user); void change_user (char *user); +static int xargc; +static char **xargv; + int main(int argc, char **argv) { @@ -140,7 +147,12 @@ main(int argc, char **argv) comsat_init (); if (mode == MODE_DAEMON) - comsat_daemon_init (); + { + /* Preserve invocation arguments */ + xargc = argc; + xargv = argv; + comsat_daemon_init (); + } /* Set up error messaging */ openlog ("gnu-comsat", LOG_PID, LOG_LOCAL1); @@ -159,18 +171,33 @@ main(int argc, char **argv) return c != 0; } +RETSIGTYPE +sig_hup (int sig) +{ + syslog (LOG_NOTICE, "restarting"); + + if (xargv[0][0] != '/') + syslog (LOG_ERR, "can't restart: not started with absolute pathname"); + else + execvp (xargv[0], xargv); + + signal (sig, sig_hup); +} + void comsat_init () { - /* Register desired formats. Maybe should be configurable */ list_t bookie; + registrar_get_list (&bookie); /* list_append (bookie, mbox_record); */ list_append (bookie, path_record); + gethostname (hostname, sizeof hostname); + /* Set signal handlers */ - signal(SIGTTOU, SIG_IGN); - signal(SIGCHLD, SIG_IGN); + signal (SIGTTOU, SIG_IGN); + signal (SIGCHLD, SIG_IGN); signal (SIGHUP, SIG_IGN); /* Ignore SIGHUP. */ } @@ -190,6 +217,8 @@ comsat_daemon_init (void) exit (EXIT_SUCCESS); /* Parent exits. */ /* Child: */ + signal (SIGHUP, sig_hup); + setsid (); /* Become session leader. */ /* The second fork is to guarantee that the daemon cannot acquire a @@ -255,6 +284,9 @@ comsat_daemon (int port) exit (1); } + syslog (LOG_NOTICE, "GNU comsat started"); + + last_request_time = last_overflow_time = time (NULL); while (1) { fd_set fdset; @@ -276,15 +308,22 @@ comsat_daemon (int port) now = time (NULL); if (reqcount > maxrequests) { + unsigned delay; + + delay = overflow_delay_time << (overflow_count + 1); syslog (LOG_NOTICE, "too many requests: pausing for %u seconds", - overflow_delay_time * (overflow_count + 1)); - sleep (overflow_delay_time * (overflow_count + 1)); + delay); + sleep (delay); reqcount = 0; if (now - last_overflow_time <= overflow_control_interval) - ++overflow_count; + { + if ((overflow_delay_time << (overflow_count + 2)) > + overflow_delay_time) + ++overflow_count; + } else overflow_count = 0; - last_overflow_time = now; + last_overflow_time = time (NULL); } if (now - last_request_time <= request_control_interval) @@ -336,7 +375,7 @@ comsat_main (int fd) /* Parse the buffer */ p = strchr (buffer, '@'); - if (!p) + if (!p && !isspace (*p)) { syslog (LOG_ERR, "malformed input: %s", buffer); return 1; @@ -631,12 +670,13 @@ help () { printf ("Usage: comsatd [OPTIONS]\n"); printf ("Options are:"); + printf (" -c, --config=PATH read configuration from the file\n"); printf (" -d, --daemon run in daemon mode\n"); printf (" -h, --help display this help and exit\n"); printf (" -i, --inetd run in inetd mode (default)\n"); printf (" -p, --port=PORT specify port to listen on, implies -d\n"); printf (" -t, --timeout=VALUE set idle timeout (implies -i)\n"); - printf (" -v, --version display version information and exit\n"); + printf (" -v, --version display version information and exit\n"); printf ("\nReport bugs to bug-mailutils@gnu.org\n"); exit (EXIT_SUCCESS); } |