diff options
author | Jacek Masiulaniec <jacekm@cvs.openbsd.org> | 2010-04-20 15:34:57 +0000 |
---|---|---|
committer | Jacek Masiulaniec <jacekm@cvs.openbsd.org> | 2010-04-20 15:34:57 +0000 |
commit | 318ca7cef0691f6d5daeca58557bfd79b3220e12 (patch) | |
tree | f6eae7893a3065a5685c10c071f6b64305ed5286 /usr.sbin/smtpd/mda.c | |
parent | 001b3d12570bfa08c409e5bc9e1a8a299473cb9e (diff) |
Kill *2400* lines of code by abstracting common bits of the imsg handlers.
Diffstat (limited to 'usr.sbin/smtpd/mda.c')
-rw-r--r-- | usr.sbin/smtpd/mda.c | 332 |
1 files changed, 97 insertions, 235 deletions
diff --git a/usr.sbin/smtpd/mda.c b/usr.sbin/smtpd/mda.c index 750f80b8c97..a9b52bdb8bb 100644 --- a/usr.sbin/smtpd/mda.c +++ b/usr.sbin/smtpd/mda.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mda.c,v 1.39 2010/04/19 20:10:36 jacekm Exp $ */ +/* $OpenBSD: mda.c,v 1.40 2010/04/20 15:34:56 jacekm Exp $ */ /* * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> @@ -37,11 +37,9 @@ #include "smtpd.h" +void mda_imsg(struct smtpd *, struct imsgev *, struct imsg *); __dead void mda_shutdown(void); void mda_sig_handler(int, short, void *); -void mda_dispatch_parent(int, short, void *); -void mda_dispatch_queue(int, short, void *); -void mda_dispatch_runner(int, short, void *); void mda_setup_events(struct smtpd *); void mda_disable_events(struct smtpd *); void mda_store(struct mda_session *); @@ -51,88 +49,106 @@ struct mda_session *mda_lookup(struct smtpd *, u_int32_t); int mda_id; void -mda_sig_handler(int sig, short event, void *p) +mda_imsg(struct smtpd *env, struct imsgev *iev, struct imsg *imsg) { - switch (sig) { - case SIGINT: - case SIGTERM: - mda_shutdown(); - break; - default: - fatalx("mda_sig_handler: unexpected signal"); - } -} + char output[128], *error, *parent_error; + struct deliver deliver; + struct mda_session *s; + struct path *path; + + if (iev->proc == PROC_RUNNER) { + switch (imsg->hdr.type) { + case IMSG_MDA_SESS_NEW: + /* make new session based on provided args */ + s = calloc(1, sizeof *s); + if (s == NULL) + fatal(NULL); + msgbuf_init(&s->w); + s->msg = *(struct message *)imsg->data; + s->msg.status = S_MESSAGE_TEMPFAILURE; + s->id = mda_id++; + s->datafp = fdopen(imsg->fd, "r"); + if (s->datafp == NULL) + fatalx("mda: fdopen"); + LIST_INSERT_HEAD(&env->mda_sessions, s, entry); -void -mda_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); - return; - } - } + /* request parent to fork a helper process */ + path = &s->msg.recipient; + switch (path->rule.r_action) { + case A_EXT: + deliver.mode = A_EXT; + strlcpy(deliver.user, path->pw_name, + sizeof deliver.user); + strlcpy(deliver.to, path->rule.r_value.path, + sizeof deliver.to); + break; - if (event & EV_WRITE) { - if (msgbuf_write(&ibuf->w) == -1) - fatal("msgbuf_write"); - } + case A_MBOX: + deliver.mode = A_EXT; + strlcpy(deliver.user, "root", + sizeof deliver.user); + snprintf(deliver.to, sizeof deliver.to, + "%s -f %s@%s %s", PATH_MAILLOCAL, + s->msg.sender.user, s->msg.sender.domain, + path->pw_name); + break; - for (;;) { - if ((n = imsg_get(ibuf, &imsg)) == -1) - fatal("mda_dispatch_parent: imsg_get error"); - if (n == 0) - break; + case A_MAILDIR: + deliver.mode = A_MAILDIR; + strlcpy(deliver.user, path->pw_name, + sizeof deliver.user); + strlcpy(deliver.to, path->rule.r_value.path, + sizeof deliver.to); + break; - switch (imsg.hdr.type) { - case IMSG_PARENT_FORK_MDA: { - struct mda_session *s; + case A_FILENAME: + deliver.mode = A_FILENAME; + /* XXX: unconditional SMTPD_USER is wrong. */ + strlcpy(deliver.user, SMTPD_USER, + sizeof deliver.user); + strlcpy(deliver.to, path->u.filename, + sizeof deliver.to); + break; - s = mda_lookup(env, imsg.hdr.peerid); + default: + fatalx("mda: unknown rule action"); + } - if (imsg.fd < 0) + imsg_compose_event(env->sc_ievs[PROC_PARENT], + IMSG_PARENT_FORK_MDA, s->id, 0, -1, &deliver, + sizeof deliver); + return; + } + } + + if (iev->proc == PROC_PARENT) { + switch (imsg->hdr.type) { + case IMSG_PARENT_FORK_MDA: + s = mda_lookup(env, imsg->hdr.peerid); + + if (imsg->fd < 0) fatalx("mda: fd pass fail"); - s->w.fd = imsg.fd; + s->w.fd = imsg->fd; - /* send message content to the helper process */ mda_store(s); - break; - } - - case IMSG_MDA_DONE: { - char output[128]; - struct mda_session *s; - struct path *path; - char *error, *parent_error; + return; - s = mda_lookup(env, imsg.hdr.peerid); + case IMSG_MDA_DONE: + s = mda_lookup(env, imsg->hdr.peerid); /* * Grab last line of mda stdout/stderr if available. */ output[0] = '\0'; - if (imsg.fd != -1) { + if (imsg->fd != -1) { char *ln, *buf; FILE *fp; size_t len; buf = NULL; - if (lseek(imsg.fd, 0, SEEK_SET) < 0) + if (lseek(imsg->fd, 0, SEEK_SET) < 0) fatalx("lseek"); - fp = fdopen(imsg.fd, "r"); + fp = fdopen(imsg->fd, "r"); if (fp == NULL) fatal("mda: fdopen"); while ((ln = fgetln(fp, &len))) { @@ -163,7 +179,7 @@ mda_dispatch_parent(int sig, short event, void *p) * the former. */ error = NULL; - parent_error = imsg.data; + parent_error = imsg->data; if (strcmp(parent_error, "exited okay") == 0) { if (!feof(s->datafp) || s->w.queued) error = "mda exited prematurely"; @@ -218,185 +234,30 @@ mda_dispatch_parent(int sig, short event, void *p) /* update runner's session count */ imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_MDA_SESS_NEW, 0, 0, -1, NULL, 0); - break; - } - - case IMSG_CTL_VERBOSE: { - int verbose; - - IMSG_SIZE_CHECK(&verbose); - - memcpy(&verbose, imsg.data, sizeof(verbose)); - log_verbose(verbose); - break; - } - - default: - log_warnx("mda_dispatch_parent: got imsg %d", - imsg.hdr.type); - fatalx("mda_dispatch_parent: unexpected imsg"); - } - imsg_free(&imsg); - } - imsg_event_add(iev); -} + return; -void -mda_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); + 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("mda_dispatch_queue: imsg_get error"); - if (n == 0) - break; - - switch (imsg.hdr.type) { - default: - log_warnx("mda_dispatch_queue: got imsg %d", - imsg.hdr.type); - fatalx("mda_dispatch_queue: unexpected imsg"); - } - imsg_free(&imsg); - } - imsg_event_add(iev); + fatalx("mda_imsg: unexpected imsg"); } void -mda_dispatch_runner(int sig, short event, void *p) +mda_sig_handler(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("mda_dispatch_runner: imsg_get error"); - if (n == 0) - break; - - switch (imsg.hdr.type) { - case IMSG_MDA_SESS_NEW: { - struct deliver deliver; - struct mda_session *s; - struct path *path; - - /* make new session based on provided args */ - s = calloc(1, sizeof *s); - if (s == NULL) - fatal(NULL); - msgbuf_init(&s->w); - s->msg = *(struct message *)imsg.data; - s->msg.status = S_MESSAGE_TEMPFAILURE; - s->id = mda_id++; - s->datafp = fdopen(imsg.fd, "r"); - if (s->datafp == NULL) - fatalx("mda: fdopen"); - LIST_INSERT_HEAD(&env->mda_sessions, s, entry); - - /* request parent to fork a helper process */ - path = &s->msg.recipient; - switch (path->rule.r_action) { - case A_EXT: - deliver.mode = A_EXT; - strlcpy(deliver.user, path->pw_name, - sizeof deliver.user); - strlcpy(deliver.to, path->rule.r_value.path, - sizeof deliver.to); - break; - - case A_MBOX: - deliver.mode = A_EXT; - strlcpy(deliver.user, "root", - sizeof deliver.user); - snprintf(deliver.to, sizeof deliver.to, - "%s -f %s@%s %s", PATH_MAILLOCAL, - s->msg.sender.user, s->msg.sender.domain, - path->pw_name); - break; - - case A_MAILDIR: - deliver.mode = A_MAILDIR; - strlcpy(deliver.user, path->pw_name, - sizeof deliver.user); - strlcpy(deliver.to, path->rule.r_value.path, - sizeof deliver.to); - break; - - case A_FILENAME: - deliver.mode = A_FILENAME; - /* XXX: unconditional SMTPD_USER is wrong. */ - strlcpy(deliver.user, SMTPD_USER, - sizeof deliver.user); - strlcpy(deliver.to, path->u.filename, - sizeof deliver.to); - break; - - default: - fatalx("unknown rule action"); - } - - imsg_compose_event(env->sc_ievs[PROC_PARENT], - IMSG_PARENT_FORK_MDA, s->id, 0, -1, &deliver, - sizeof deliver); - break; - } - default: - log_warnx("mda_dispatch_runner: got imsg %d", - imsg.hdr.type); - fatalx("mda_dispatch_runner: unexpected imsg"); - } - imsg_free(&imsg); + switch (sig) { + case SIGINT: + case SIGTERM: + mda_shutdown(); + break; + default: + fatalx("mda_sig_handler: unexpected signal"); } - imsg_event_add(iev); } - void mda_shutdown(void) { @@ -424,9 +285,9 @@ mda(struct smtpd *env) struct event ev_sigterm; struct peer peers[] = { - { PROC_PARENT, mda_dispatch_parent }, - { PROC_QUEUE, mda_dispatch_queue }, - { PROC_RUNNER, mda_dispatch_runner } + { PROC_PARENT, imsg_dispatch }, + { PROC_QUEUE, imsg_dispatch }, + { PROC_RUNNER, imsg_dispatch } }; switch (pid = fork()) { @@ -463,6 +324,7 @@ mda(struct smtpd *env) LIST_INIT(&env->mda_sessions); + imsg_callback = mda_imsg; event_init(); signal_set(&ev_sigint, SIGINT, mda_sig_handler, env); |