summaryrefslogtreecommitdiff
path: root/usr.sbin/smtpd/smtp.c
diff options
context:
space:
mode:
authorJacek Masiulaniec <jacekm@cvs.openbsd.org>2010-04-20 15:34:57 +0000
committerJacek Masiulaniec <jacekm@cvs.openbsd.org>2010-04-20 15:34:57 +0000
commit318ca7cef0691f6d5daeca58557bfd79b3220e12 (patch)
treef6eae7893a3065a5685c10c071f6b64305ed5286 /usr.sbin/smtpd/smtp.c
parent001b3d12570bfa08c409e5bc9e1a8a299473cb9e (diff)
Kill *2400* lines of code by abstracting common bits of the imsg handlers.
Diffstat (limited to 'usr.sbin/smtpd/smtp.c')
-rw-r--r--usr.sbin/smtpd/smtp.c660
1 files changed, 184 insertions, 476 deletions
diff --git a/usr.sbin/smtpd/smtp.c b/usr.sbin/smtpd/smtp.c
index 9d779887f53..cd137f710a0 100644
--- a/usr.sbin/smtpd/smtp.c
+++ b/usr.sbin/smtpd/smtp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: smtp.c,v 1.67 2010/01/03 14:37:37 chl Exp $ */
+/* $OpenBSD: smtp.c,v 1.68 2010/04/20 15:34:56 jacekm Exp $ */
/*
* Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
@@ -38,14 +38,9 @@
#include "smtpd.h"
+void smtp_imsg(struct smtpd *, struct imsgev *, struct imsg *);
__dead void smtp_shutdown(void);
void smtp_sig_handler(int, short, void *);
-void smtp_dispatch_parent(int, short, void *);
-void smtp_dispatch_mfa(int, short, void *);
-void smtp_dispatch_lka(int, short, void *);
-void smtp_dispatch_queue(int, short, void *);
-void smtp_dispatch_control(int, short, void *);
-void smtp_dispatch_runner(int, short, void *);
void smtp_setup_events(struct smtpd *);
void smtp_disable_events(struct smtpd *);
void smtp_pause(struct smtpd *);
@@ -55,58 +50,114 @@ struct session *smtp_new(struct listener *);
struct session *session_lookup(struct smtpd *, u_int64_t);
void
-smtp_sig_handler(int sig, short event, void *p)
+smtp_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg)
{
- switch (sig) {
- case SIGINT:
- case SIGTERM:
- smtp_shutdown();
- break;
- default:
- fatalx("smtp_sig_handler: unexpected signal");
+ struct session skey;
+ struct submit_status *ss;
+ struct listener *l;
+ struct session *s;
+ struct auth *auth;
+ struct ssl *ssl;
+ struct dns *dns;
+
+ if (iev->proc == PROC_LKA) {
+ switch (imsg->hdr.type) {
+ case IMSG_DNS_PTR:
+ dns = imsg->data;
+ s = session_lookup(env, dns->id);
+ if (s == NULL)
+ fatalx("smtp: impossible quit");
+ strlcpy(s->s_hostname,
+ dns->error ? "<unknown>" : dns->host,
+ sizeof s->s_hostname);
+ strlcpy(s->s_msg.session_hostname, s->s_hostname,
+ sizeof s->s_msg.session_hostname);
+ session_init(s->s_l, s);
+ return;
+ }
}
-}
-void
-smtp_dispatch_parent(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_PARENT];
- ibuf = &iev->ibuf;
-
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ if (iev->proc == PROC_MFA) {
+ switch (imsg->hdr.type) {
+ case IMSG_MFA_RCPT:
+ case IMSG_MFA_MAIL:
+ log_debug("smtp: got imsg_mfa_mail/rcpt");
+ ss = imsg->data;
+ s = session_lookup(env, ss->id);
+ if (s == NULL)
+ return;
+ session_pickup(s, ss);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
+ if (iev->proc == PROC_QUEUE) {
+ ss = imsg->data;
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_parent: imsg_get error");
- if (n == 0)
- break;
+ switch (imsg->hdr.type) {
+ case IMSG_QUEUE_CREATE_MESSAGE:
+ log_debug("smtp: imsg_queue_create_message returned");
+ s = session_lookup(env, ss->id);
+ if (s == NULL)
+ return;
+ strlcpy(s->s_msg.message_id, ss->u.msgid,
+ sizeof s->s_msg.message_id);
+ session_pickup(s, ss);
+ return;
- switch (imsg.hdr.type) {
- case IMSG_CONF_RELOAD: {
- struct session *s;
+ case IMSG_QUEUE_MESSAGE_FILE:
+ log_debug("smtp: imsg_queue_message_file returned");
+ s = session_lookup(env, ss->id);
+ if (s == NULL) {
+ close(imsg->fd);
+ return;
+ }
+ s->datafp = fdopen(imsg->fd, "w");
+ if (s->datafp == NULL) {
+ /* queue may have experienced tempfail. */
+ if (ss->code != 421)
+ fatalx("smtp: fdopen");
+ close(imsg->fd);
+ }
+ session_pickup(s, ss);
+ return;
- /* reloading may invalidate various pointers our
+ case IMSG_QUEUE_TEMPFAIL:
+ log_debug("smtp: got imsg_queue_tempfail");
+ skey.s_id = ss->id;
+ s = SPLAY_FIND(sessiontree, &env->sc_sessions, &skey);
+ if (s == NULL)
+ fatalx("smtp: session is gone");
+ if (s->s_flags & F_WRITEONLY)
+ /* session is write-only, must not destroy it. */
+ s->s_msg.status |= S_MESSAGE_TEMPFAILURE;
+ else
+ fatalx("smtp: corrupt session");
+ return;
+
+ case IMSG_QUEUE_COMMIT_ENVELOPES:
+ log_debug("smtp: got imsg_queue_commit_envelopes");
+ s = session_lookup(env, ss->id);
+ if (s == NULL)
+ return;
+ session_pickup(s, ss);
+ return;
+
+ case IMSG_QUEUE_COMMIT_MESSAGE:
+ log_debug("smtp: got imsg_queue_commit_message");
+ s = session_lookup(env, ss->id);
+ if (s == NULL)
+ return;
+ session_pickup(s, ss);
+ return;
+ }
+ }
+
+ if (iev->proc == PROC_PARENT) {
+ switch (imsg->hdr.type) {
+ case IMSG_CONF_RELOAD:
+ /*
+ * Reloading may invalidate various pointers our
* sessions rely upon, we better tell clients we
* want them to retry.
*/
@@ -118,474 +169,129 @@ smtp_dispatch_parent(int sig, short event, void *p)
smtp_disable_events(env);
imsg_compose_event(iev, IMSG_PARENT_SEND_CONFIG, 0, 0, -1,
NULL, 0);
- break;
- }
+ return;
+
case IMSG_CONF_START:
if (env->sc_flags & SMTPD_CONFIGURING)
- break;
+ return;
env->sc_flags |= SMTPD_CONFIGURING;
-
- if ((env->sc_listeners = calloc(1, sizeof(*env->sc_listeners))) == NULL)
- fatal("smtp_dispatch_parent: calloc");
- if ((env->sc_ssl = calloc(1, sizeof(*env->sc_ssl))) == NULL)
- fatal("smtp_dispatch_parent: calloc");
+ env->sc_listeners = calloc(1, sizeof *env->sc_listeners);
+ env->sc_ssl = calloc(1, sizeof *env->sc_ssl);
+ if (env->sc_listeners == NULL || env->sc_ssl == NULL)
+ fatal(NULL);
TAILQ_INIT(env->sc_listeners);
- break;
- case IMSG_CONF_SSL: {
- struct ssl *s;
- struct ssl *x_ssl;
+ return;
+ case IMSG_CONF_SSL:
if (!(env->sc_flags & SMTPD_CONFIGURING))
- break;
-
- if ((s = calloc(1, sizeof(*s))) == NULL)
+ return;
+ ssl = calloc(1, sizeof *ssl);
+ if (ssl == NULL)
fatal(NULL);
- x_ssl = imsg.data;
- (void)strlcpy(s->ssl_name, x_ssl->ssl_name,
- sizeof(s->ssl_name));
- s->ssl_cert_len = x_ssl->ssl_cert_len;
- if ((s->ssl_cert =
- strdup((char *)imsg.data + sizeof(*s))) == NULL)
+ *ssl = *(struct ssl *)imsg->data;
+ ssl->ssl_cert = strdup((char *)imsg->data +
+ sizeof *ssl);
+ if (ssl->ssl_cert == NULL)
fatal(NULL);
- s->ssl_key_len = x_ssl->ssl_key_len;
- if ((s->ssl_key = strdup((char *)imsg.data +
- (sizeof(*s) + s->ssl_cert_len))) == NULL)
+ ssl->ssl_key = strdup((char *)imsg->data + sizeof *ssl +
+ ssl->ssl_cert_len);
+ if (ssl->ssl_key == NULL)
fatal(NULL);
+ SPLAY_INSERT(ssltree, env->sc_ssl, ssl);
+ return;
- SPLAY_INSERT(ssltree, env->sc_ssl, s);
- break;
- }
- case IMSG_CONF_LISTENER: {
- struct listener *l;
- struct ssl key;
-
+ case IMSG_CONF_LISTENER:
if (!(env->sc_flags & SMTPD_CONFIGURING))
- break;
-
- if ((l = calloc(1, sizeof(*l))) == NULL)
+ return;
+ l = calloc(1, sizeof *l);
+ if (l == NULL)
fatal(NULL);
- memcpy(l, imsg.data, sizeof(*l));
-
- if ((l->fd = imsg.fd) == -1)
- fatal("cannot get fd");
-
- (void)strlcpy(key.ssl_name, l->ssl_cert_name,
- sizeof(key.ssl_name));
-
- if (l->flags & F_SSL)
- if ((l->ssl = SPLAY_FIND(ssltree,
- env->sc_ssl, &key)) == NULL)
- fatal("parent and smtp desynchronized");
-
+ *l = *(struct listener *)imsg->data;
+ l->fd = imsg->fd;
+ if (l->fd < 0)
+ fatalx("smtp: listener pass failed");
+ if (l->flags & F_SSL) {
+ struct ssl key;
+
+ strlcpy(key.ssl_name, l->ssl_cert_name,
+ sizeof key.ssl_name);
+ l->ssl = SPLAY_FIND(ssltree, env->sc_ssl, &key);
+ if (l->ssl == NULL)
+ fatalx("smtp: ssltree out of sync");
+ }
TAILQ_INSERT_TAIL(env->sc_listeners, l, entry);
- break;
- }
+ return;
+
case IMSG_CONF_END:
if (!(env->sc_flags & SMTPD_CONFIGURING))
- break;
+ return;
smtp_setup_events(env);
env->sc_flags &= ~SMTPD_CONFIGURING;
- break;
- case IMSG_PARENT_AUTHENTICATE: {
- struct auth *reply = imsg.data;
- struct session *s;
-
- log_debug("smtp_dispatch_parent: got auth reply");
-
- IMSG_SIZE_CHECK(reply);
-
- if ((s = session_lookup(env, reply->id)) == NULL)
- break;
+ return;
- if (reply->success) {
+ case IMSG_PARENT_AUTHENTICATE:
+ auth = imsg->data;
+ s = session_lookup(env, auth->id);
+ if (s == NULL)
+ return;
+ if (auth->success) {
s->s_flags |= F_AUTHENTICATED;
s->s_msg.flags |= F_MESSAGE_AUTHENTICATED;
} else {
s->s_flags &= ~F_AUTHENTICATED;
s->s_msg.flags &= ~F_MESSAGE_AUTHENTICATED;
}
-
session_pickup(s, NULL);
- break;
- }
- case IMSG_CTL_VERBOSE: {
- int verbose;
-
- IMSG_SIZE_CHECK(&verbose);
-
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
- break;
- }
- default:
- log_warnx("smtp_dispatch_parent: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_parent: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-smtp_dispatch_mfa(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_MFA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_mfa: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_MFA_MAIL:
- case IMSG_MFA_RCPT: {
- struct submit_status *ss = imsg.data;
- struct session *s;
-
- log_debug("smtp_dispatch_mfa: mfa handled return path");
- IMSG_SIZE_CHECK(ss);
-
- if ((s = session_lookup(env, ss->id)) == NULL)
- break;
-
- session_pickup(s, ss);
- break;
- }
- default:
- log_warnx("smtp_dispatch_mfa: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_mfa: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-smtp_dispatch_lka(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_LKA];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
+ case IMSG_CTL_VERBOSE:
+ log_verbose(*(int *)imsg->data);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_lka: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_DNS_PTR: {
- struct dns *reply = imsg.data;
- struct session *s;
- struct session key;
-
- IMSG_SIZE_CHECK(reply);
-
- key.s_id = reply->id;
-
- s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key);
- if (s == NULL)
- fatal("smtp_dispatch_lka: session is gone");
-
- strlcpy(s->s_hostname,
- reply->error ? "<unknown>" : reply->host,
- sizeof(s->s_hostname));
-
- strlcpy(s->s_msg.session_hostname, s->s_hostname,
- sizeof(s->s_msg.session_hostname));
-
- session_init(s->s_l, s);
-
- break;
- }
- default:
- log_warnx("smtp_dispatch_lka: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_lka: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-smtp_dispatch_queue(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_QUEUE];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_queue: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
- case IMSG_QUEUE_CREATE_MESSAGE: {
- struct submit_status *ss = imsg.data;
- struct session *s;
-
- log_debug("smtp_dispatch_queue: queue handled message creation");
-
- IMSG_SIZE_CHECK(ss);
-
- if ((s = session_lookup(env, ss->id)) == NULL)
- break;
-
- (void)strlcpy(s->s_msg.message_id, ss->u.msgid,
- sizeof(s->s_msg.message_id));
- session_pickup(s, ss);
- break;
- }
- case IMSG_QUEUE_MESSAGE_FILE: {
- struct submit_status *ss = imsg.data;
- struct session *s;
- int fd;
-
- log_debug("smtp_dispatch_queue: queue handled message creation");
-
- IMSG_SIZE_CHECK(ss);
-
- fd = imsg.fd;
-
- if ((s = session_lookup(env, ss->id)) == NULL) {
- close(fd);
- break;
- }
-
- if ((s->datafp = fdopen(fd, "w")) == NULL) {
- /* queue may have experienced tempfail. */
- if (ss->code != 421)
- fatal("smtp_dispatch_queue: fdopen");
- close(fd);
- }
-
- session_pickup(s, ss);
- break;
- }
- case IMSG_QUEUE_TEMPFAIL: {
- struct submit_status *ss = imsg.data;
- struct session *s;
- struct session key;
-
- log_debug("smtp_dispatch_queue: tempfail in queue");
-
- IMSG_SIZE_CHECK(ss);
-
- key.s_id = ss->id;
- s = SPLAY_FIND(sessiontree, &env->sc_sessions, &key);
- if (s == NULL)
- fatalx("smtp_dispatch_queue: session is gone");
-
- if (s->s_flags & F_WRITEONLY) {
- /*
- * Session is write-only, can't destroy it.
- */
- s->s_msg.status |= S_MESSAGE_TEMPFAILURE;
- } else
- fatalx("smtp_dispatch_queue: corrupt session");
- break;
- }
-
- case IMSG_QUEUE_COMMIT_ENVELOPES:
- case IMSG_QUEUE_COMMIT_MESSAGE: {
- struct submit_status *ss = imsg.data;
- struct session *s;
-
- log_debug("smtp_dispatch_queue: queue acknowledged message submission");
-
- IMSG_SIZE_CHECK(ss);
-
- if ((s = session_lookup(env, ss->id)) == NULL)
- break;
-
- session_pickup(s, ss);
- break;
- }
- default:
- log_warnx("smtp_dispatch_queue: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_queue: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-smtp_dispatch_control(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_CONTROL];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
- return;
- }
- }
-
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_control: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
+ if (iev->proc == PROC_CONTROL) {
+ switch (imsg->hdr.type) {
case IMSG_SMTP_ENQUEUE:
imsg_compose_event(iev, IMSG_SMTP_ENQUEUE,
- imsg.hdr.peerid, 0, smtp_enqueue(env, imsg.data),
+ imsg->hdr.peerid, 0, smtp_enqueue(env, imsg->data),
NULL, 0);
- break;
+ return;
+
case IMSG_SMTP_PAUSE:
smtp_pause(env);
- break;
+ return;
+
case IMSG_SMTP_RESUME:
smtp_resume(env);
- break;
- default:
- log_warnx("smtp_dispatch_control: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_control: unexpected imsg");
- }
- imsg_free(&imsg);
- }
- imsg_event_add(iev);
-}
-
-void
-smtp_dispatch_runner(int sig, short event, void *p)
-{
- struct smtpd *env = p;
- struct imsgev *iev;
- struct imsgbuf *ibuf;
- struct imsg imsg;
- ssize_t n;
-
- iev = env->sc_ievs[PROC_RUNNER];
- ibuf = &iev->ibuf;
-
- if (event & EV_READ) {
- if ((n = imsg_read(ibuf)) == -1)
- fatal("imsg_read_error");
- if (n == 0) {
- /* this pipe is dead, so remove the event handler */
- event_del(&iev->ev);
- event_loopexit(NULL);
return;
}
}
- if (event & EV_WRITE) {
- if (msgbuf_write(&ibuf->w) == -1)
- fatal("msgbuf_write");
- }
-
- for (;;) {
- if ((n = imsg_get(ibuf, &imsg)) == -1)
- fatal("smtp_dispatch_runner: imsg_get error");
- if (n == 0)
- break;
-
- switch (imsg.hdr.type) {
+ if (iev->proc == PROC_RUNNER) {
+ switch (imsg->hdr.type) {
case IMSG_SMTP_ENQUEUE:
imsg_compose_event(iev, IMSG_SMTP_ENQUEUE, 0, 0,
- smtp_enqueue(env, NULL), imsg.data,
+ smtp_enqueue(env, NULL), imsg->data,
sizeof(struct message));
- break;
- default:
- log_warnx("smtp_dispatch_runner: got imsg %d",
- imsg.hdr.type);
- fatalx("smtp_dispatch_runner: unexpected imsg");
+ return;
}
- imsg_free(&imsg);
}
- imsg_event_add(iev);
+
+ fatalx("smtp_imsg: unexpected imsg");
+}
+
+void
+smtp_sig_handler(int sig, short event, void *p)
+{
+ switch (sig) {
+ case SIGINT:
+ case SIGTERM:
+ smtp_shutdown();
+ break;
+ default:
+ fatalx("smtp_sig_handler: unexpected signal");
+ }
}
void
@@ -605,12 +311,12 @@ smtp(struct smtpd *env)
struct event ev_sigterm;
struct peer peers[] = {
- { PROC_PARENT, smtp_dispatch_parent },
- { PROC_MFA, smtp_dispatch_mfa },
- { PROC_QUEUE, smtp_dispatch_queue },
- { PROC_LKA, smtp_dispatch_lka },
- { PROC_CONTROL, smtp_dispatch_control },
- { PROC_RUNNER, smtp_dispatch_runner }
+ { PROC_PARENT, imsg_dispatch },
+ { PROC_MFA, imsg_dispatch },
+ { PROC_QUEUE, imsg_dispatch },
+ { PROC_LKA, imsg_dispatch },
+ { PROC_CONTROL, imsg_dispatch },
+ { PROC_RUNNER, imsg_dispatch }
};
switch (pid = fork()) {
@@ -646,6 +352,7 @@ smtp(struct smtpd *env)
fatal("smtp: cannot drop privileges");
#endif
+ imsg_callback = smtp_imsg;
event_init();
signal_set(&ev_sigint, SIGINT, smtp_sig_handler, env);
@@ -813,6 +520,7 @@ smtp_accept(int fd, short event, void *p)
fatal("smtp_accept");
}
+ s->s_flags |= F_WRITEONLY;
dns_query_ptr(l->env, &s->s_ss, s->s_id);
}