From 30437b7361c5763309639b1bf0aa015e2ad057ed Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Wed, 16 Jun 2021 07:17:29 +0300 Subject: Implement timeouts for inetd mode as well. --- mockmta.c | 111 ++++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 64 insertions(+), 47 deletions(-) diff --git a/mockmta.c b/mockmta.c index 17ec344..d2737fd 100644 --- a/mockmta.c +++ b/mockmta.c @@ -45,7 +45,8 @@ EXIT CODES 0 Success. 1 Failure (see stderr for details). - 2 Command line usage error. + 2 Timed out waiting for I/O. + 3 Command line usage error. BUGS At most 32 RCPT commands are allowed. @@ -115,6 +116,7 @@ enum { EX_OK, EX_FAILURE, + EX_TEMPFAIL, EX_USAGE }; @@ -1671,6 +1673,22 @@ thr_smtp (void *ptr) return NULL; } +static void +smtp_tempfail (void *ptr) +{ + exit (EX_TEMPFAIL); +} + +void * +thr_smtp_stdio (void *ptr) +{ + pthread_cleanup_push (smtp_tempfail, ptr); + thr_smtp (ptr); + pthread_cleanup_pop (0); + exit (EX_OK); + return NULL; +} + void * thr_mta_listener (void *ptr) { @@ -1719,6 +1737,10 @@ main (int argc, char **argv) int c; int fd; int foreground = 0; + struct sigaction act; + sigset_t sigs; + int i; + pthread_t tid; progname = argv[0]; @@ -1770,18 +1792,32 @@ main (int argc, char **argv) disable_starttls (); } + /* Set up signal handling */ + sigemptyset (&sigs); + + act.sa_flags = 0; + sigemptyset (&act.sa_mask); + act.sa_handler = signull; + + for (i = 0; fatal_signals[i]; i++) + { + sigaddset (&sigs, fatal_signals[i]); + sigaction (fatal_signals[i], &act, NULL); + } + sigaddset (&sigs, SIGPIPE); + sigaddset (&sigs, SIGALRM); + sigaddset (&sigs, SIGCHLD); + pthread_sigmask (SIG_BLOCK, &sigs, NULL); + + pthread_create (&tid, NULL, thr_watcher, NULL); + if (daemon_opt) { - struct sigaction act; - sigset_t sigs; - int i; - pthread_t tid; - fd = mta_open (port); if (!foreground) { - switch (fork()) + switch (fork ()) { case -1: terror ("daemon: %m"); @@ -1794,62 +1830,43 @@ main (int argc, char **argv) _exit (0); } - if (setsid() == -1) + if (setsid () == -1) { terror ("setsid: %m"); exit (EX_FAILURE); } - chdir("/"); + chdir ("/"); - close(0); - close(1); - close(2); - open(_PATH_DEVNULL, O_RDONLY); - open(_PATH_DEVNULL, O_WRONLY); - dup(1); + close (0); + close (1); + close (2); + open (_PATH_DEVNULL, O_RDONLY); + open (_PATH_DEVNULL, O_WRONLY); + dup (1); /* Set up logging */ openlog (progname, LOG_PID, LOG_MAIL); terror = terror_syslog; } - /* Set up signal handling */ - sigemptyset (&sigs); - - act.sa_flags = 0; - sigemptyset (&act.sa_mask); - act.sa_handler = signull; - - for (i = 0; fatal_signals[i]; i++) - { - sigaddset (&sigs, fatal_signals[i]); - sigaction (fatal_signals[i], &act, NULL); - } - sigaddset (&sigs, SIGPIPE); - sigaddset (&sigs, SIGALRM); - sigaddset (&sigs, SIGCHLD); - pthread_sigmask (SIG_BLOCK, &sigs, NULL); - - pthread_create (&tid, NULL, thr_mta_listener, &fd); - pthread_create (&tid, NULL, thr_watcher, NULL); - - /* Unblock only the fatal signals */ - sigemptyset (&sigs); - for (i = 0; fatal_signals[i]; i++) - sigaddset (&sigs, fatal_signals[i]); - - pthread_sigmask (SIG_UNBLOCK, &sigs, NULL); - - /* Wait for signal to arrive */ - sigwait (&sigs, &i); + pthread_create (&tid, NULL, thr_mta_listener, &fd); } else { - struct smtp *smtp = smtp_create (0, 1); - do_smtp (smtp); - smtp_free (smtp); + pthread_create (&tid, NULL, thr_smtp_stdio, smtp_create (0, 1)); + pthread_detach (tid); } + + /* Unblock only the fatal signals */ + sigemptyset (&sigs); + for (i = 0; fatal_signals[i]; i++) + sigaddset (&sigs, fatal_signals[i]); + + pthread_sigmask (SIG_UNBLOCK, &sigs, NULL); + + /* Wait for signal to arrive */ + sigwait (&sigs, &i); exit (EX_OK); } -- cgit v1.2.1