aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mockmta.c111
1 files 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);
}

Return to:

Send suggestions and report system problems to the System administrator.