summaryrefslogtreecommitdiff
path: root/comsat/comsat.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2001-11-02 13:08:32 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2001-11-02 13:08:32 +0000
commit0e68861f9fe358112677480badced4abd65337cf (patch)
tree358055b51e5b4ce45f2098754ae7cb74154b981c /comsat/comsat.c
parent873f12bf0c9d9533d0576d4d428f8064d98bb694 (diff)
downloadmailutils-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/comsat.c')
-rw-r--r--comsat/comsat.c62
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);
}

Return to:

Send suggestions and report system problems to the System administrator.