Download raw body.
smtpd: create startup.c
Hello tech@,
Here's a followup to the shuffling of the deckchairs diff. This diff is
basically more of the same, but creates a new startup.c for functions
and variables that would cause issues for smtpctl when added to util.c.
I realize that startup.c isn't an ideal name, but since it's needed give
each libexec binary their own main() function it's the best I could come
up with.
This diff moves the env, p_*, profiling, backend_*, smtpd_process
variables, and imsg_callback, and setup_peer(), setup_proc(),
imsg_wait(), load_pki_tree(), load_pki_keys(), fork_proc_backend(),
and imsg_dispatch() functions into startup.c.
The debug variable appears to be a dead store, so can be removed.
The next step is giving each binary their own main().
OK?
martijn@
diff d010102fe4efde3ee95164581695909c7c6b672a 7c135bf813cf25880851c83cbd4734bfe1ac67c3
commit - d010102fe4efde3ee95164581695909c7c6b672a
commit + 7c135bf813cf25880851c83cbd4734bfe1ac67c3
blob - a6337c2bb329e27300a21ffa517a5a84d0f773c5
blob + 37b6919a9da103b0f3ce6bccfcb98f6dd5a47d6e
--- usr.sbin/smtpd/smtpd/Makefile
+++ usr.sbin/smtpd/smtpd/Makefile
@@ -14,7 +14,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi
dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \
resolver.c rfc5322.c ruleset.c runq.c scheduler.c \
scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \
- stat_backend.c table.c to.c tree.c util.c waitq.c \
+ startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \
compress_gzip.c table_db.c table_getpwnam.c table_proc.c \
table_static.c queue_fs.c queue_null.c queue_proc.c \
queue_ram.c scheduler_ramqueue.c scheduler_null.c \
blob - 206cd414a29ac4acbb22b6a540c5ca2751098e90
blob + a00f8c6d79b8fea6b9071776ced8a909654aefd4
--- usr.sbin/smtpd/smtpd-ca/Makefile
+++ usr.sbin/smtpd/smtpd-ca/Makefile
@@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi
dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \
resolver.c rfc5322.c ruleset.c runq.c scheduler.c \
scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \
- stat_backend.c table.c to.c tree.c util.c waitq.c \
+ startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \
compress_gzip.c table_db.c table_getpwnam.c table_proc.c \
table_static.c queue_fs.c queue_null.c queue_proc.c \
queue_ram.c scheduler_ramqueue.c scheduler_null.c \
blob - 22d7abdc025cccaec993ecec8f4ab7c4377fd8b3
blob + d289b421744c03b32a2296c421e9f3734cd44089
--- usr.sbin/smtpd/smtpd-control/Makefile
+++ usr.sbin/smtpd/smtpd-control/Makefile
@@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi
dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \
resolver.c rfc5322.c ruleset.c runq.c scheduler.c \
scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \
- stat_backend.c table.c to.c tree.c util.c waitq.c \
+ startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \
compress_gzip.c table_db.c table_getpwnam.c table_proc.c \
table_static.c queue_fs.c queue_null.c queue_proc.c \
queue_ram.c scheduler_ramqueue.c scheduler_null.c \
blob - 9aa8e1c7ceb3112f7aaba17352f5b5aa3b242bf7
blob + f4c47fd8387e2bf7ee7c22a395f5e74b099be30d
--- usr.sbin/smtpd/smtpd-dispatcher/Makefile
+++ usr.sbin/smtpd/smtpd-dispatcher/Makefile
@@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi
dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \
resolver.c rfc5322.c ruleset.c runq.c scheduler.c \
scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \
- stat_backend.c table.c to.c tree.c util.c waitq.c \
+ startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \
compress_gzip.c table_db.c table_getpwnam.c table_proc.c \
table_static.c queue_fs.c queue_null.c queue_proc.c \
queue_ram.c scheduler_ramqueue.c scheduler_null.c \
blob - 03476d16571fc4fb85105215a79543bfb9882166
blob + 0b82bec27876d79e60fa80a4a65436fe3633142e
--- usr.sbin/smtpd/smtpd-lka/Makefile
+++ usr.sbin/smtpd/smtpd-lka/Makefile
@@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi
dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \
resolver.c rfc5322.c ruleset.c runq.c scheduler.c \
scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \
- stat_backend.c table.c to.c tree.c util.c waitq.c \
+ startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \
compress_gzip.c table_db.c table_getpwnam.c table_proc.c \
table_static.c queue_fs.c queue_null.c queue_proc.c \
queue_ram.c scheduler_ramqueue.c scheduler_null.c \
blob - 6fce8a91f1035dffdd28a98bb546d0ed5c62b977
blob + 7b6651dbeda248bc110f0b655118e59e23dfd9b2
--- usr.sbin/smtpd/smtpd-queue/Makefile
+++ usr.sbin/smtpd/smtpd-queue/Makefile
@@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi
dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \
resolver.c rfc5322.c ruleset.c runq.c scheduler.c \
scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \
- stat_backend.c table.c to.c tree.c util.c waitq.c \
+ startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \
compress_gzip.c table_db.c table_getpwnam.c table_proc.c \
table_static.c queue_fs.c queue_null.c queue_proc.c \
queue_ram.c scheduler_ramqueue.c scheduler_null.c \
blob - 93076c8a5241d7202b0810b4d3d723377dbaba1d
blob + d26854ca8cd02f506b2c4ebaf93fc204f0130a2c
--- usr.sbin/smtpd/smtpd-scheduler/Makefile
+++ usr.sbin/smtpd/smtpd-scheduler/Makefile
@@ -15,7 +15,7 @@ SRCS= aliases.c bounce.c ca.c compress_backend.c confi
dispatcher.c proxy.c queue.c queue_backend.c report_smtp.c \
resolver.c rfc5322.c ruleset.c runq.c scheduler.c \
scheduler_backend.c smtp.c smtp_session.c smtpd.c srs.c ssl.c \
- stat_backend.c table.c to.c tree.c util.c waitq.c \
+ startup.c stat_backend.c table.c to.c tree.c util.c waitq.c \
compress_gzip.c table_db.c table_getpwnam.c table_proc.c \
table_static.c queue_fs.c queue_null.c queue_proc.c \
queue_ram.c scheduler_ramqueue.c scheduler_null.c \
blob - 7292b6810caaa49358b7b92ef3f26ade95d2ea42
blob + de95861f48bf015b5cc1cce1857a8318d266111b
--- usr.sbin/smtpd/smtpd.c
+++ usr.sbin/smtpd/smtpd.c
@@ -59,12 +59,8 @@ static void forkmda(struct mproc *, uint64_t, struct d
static int parent_forward_open(char *, char *, uid_t, gid_t);
static struct child *child_add(pid_t, int, const char *);
static struct mproc *start_child(int, char **, char *);
-static struct mproc *setup_peer(enum smtp_proc_type, pid_t, int);
static void setup_peers(struct mproc *, struct mproc *);
static void setup_done(struct mproc *);
-static void setup_proc(void);
-static struct mproc *setup_peer(enum smtp_proc_type, pid_t, int);
-static int imsg_wait(struct imsgbuf *, struct imsg *, int);
static void offline_scan(int, short, void *);
static int offline_add(char *, uid_t, gid_t);
@@ -73,8 +69,6 @@ static int offline_enqueue(char *, uid_t, gid_t);
static void purge_task(void);
static int parent_auth_user(const char *, const char *);
-static void load_pki_tree(void);
-static void load_pki_keys(void);
static void fork_filter_processes(void);
static void fork_filter_process(const char *, struct filter_proc *);
@@ -115,26 +109,11 @@ static struct timeval offline_timeout;
static pid_t purge_pid = -1;
extern char **environ;
-void (*imsg_callback)(struct mproc *, struct imsg *);
-enum smtp_proc_type smtpd_process;
+extern const char *backend_queue;
+extern const char *backend_scheduler;
+extern const char *backend_stat;
-struct smtpd *env = NULL;
-
-struct mproc *p_control = NULL;
-struct mproc *p_lka = NULL;
-struct mproc *p_parent = NULL;
-struct mproc *p_queue = NULL;
-struct mproc *p_scheduler = NULL;
-struct mproc *p_dispatcher = NULL;
-struct mproc *p_ca = NULL;
-
-const char *backend_queue = "fs";
-const char *backend_scheduler = "ramqueue";
-const char *backend_stat = "ram";
-
-int profiling = 0;
-int debug = 0;
int foreground = 0;
int control_socket = -1;
@@ -483,7 +462,6 @@ main(int argc, char *argv[])
flags = 0;
opts = 0;
- debug = 0;
tracing = 0;
log_init(1, LOG_MAIL);
@@ -523,7 +501,6 @@ main(int argc, char *argv[])
usage();
break;
case 'n':
- debug = 2;
opts |= SMTPD_OPT_NOACTION;
break;
case 'f':
@@ -902,136 +879,6 @@ setup_done(struct mproc *p)
imsg_free(&imsg);
}
-static void
-setup_proc(void)
-{
- struct imsgbuf *ibuf;
- struct imsg imsg;
- int setup = 1;
-
- log_procinit(proc_title(smtpd_process));
-
- p_parent = calloc(1, sizeof(*p_parent));
- if (p_parent == NULL)
- fatal("calloc");
- if((p_parent->name = strdup("parent")) == NULL)
- fatal("strdup");
- p_parent->proc = PROC_PARENT;
- p_parent->handler = imsg_dispatch;
- mproc_init(p_parent, 3);
-
- ibuf = &p_parent->imsgbuf;
-
- while (setup) {
- if (imsg_wait(ibuf, &imsg, 10000) == -1)
- fatal("imsg_wait");
-
- switch (imsg.hdr.type) {
- case IMSG_SETUP_KEY:
- env->sc_queue_key = strdup(imsg.data);
- break;
- case IMSG_SETUP_PEER:
- setup_peer(imsg.hdr.peerid, imsg.hdr.pid,
- imsg_get_fd(&imsg));
- break;
- case IMSG_SETUP_DONE:
- setup = 0;
- break;
- default:
- fatal("bad imsg %d", imsg.hdr.type);
- }
- imsg_free(&imsg);
- }
-
- if (imsg_compose(ibuf, IMSG_SETUP_DONE, 0, 0, -1, NULL, 0) == -1)
- fatal("imsg_compose");
-
- if (imsgbuf_flush(ibuf) == -1)
- fatal("imsgbuf_flush");
-
- log_debug("setup_proc: %s done", proc_title(smtpd_process));
-}
-
-static struct mproc *
-setup_peer(enum smtp_proc_type proc, pid_t pid, int sock)
-{
- struct mproc *p, **pp;
-
- log_debug("setup_peer: %s -> %s[%u] fd=%d", proc_title(smtpd_process),
- proc_title(proc), pid, sock);
-
- if (sock == -1)
- fatalx("peer socket not received");
-
- switch (proc) {
- case PROC_LKA:
- pp = &p_lka;
- break;
- case PROC_QUEUE:
- pp = &p_queue;
- break;
- case PROC_CONTROL:
- pp = &p_control;
- break;
- case PROC_SCHEDULER:
- pp = &p_scheduler;
- break;
- case PROC_DISPATCHER:
- pp = &p_dispatcher;
- break;
- case PROC_CA:
- pp = &p_ca;
- break;
- default:
- fatalx("unknown peer");
- }
-
- if (*pp)
- fatalx("peer already set");
-
- p = calloc(1, sizeof(*p));
- if (p == NULL)
- fatal("calloc");
- if((p->name = strdup(proc_title(proc))) == NULL)
- fatal("strdup");
- mproc_init(p, sock);
- p->pid = pid;
- p->proc = proc;
- p->handler = imsg_dispatch;
-
- *pp = p;
-
- return p;
-}
-
-static int
-imsg_wait(struct imsgbuf *ibuf, struct imsg *imsg, int timeout)
-{
- struct pollfd pfd[1];
- ssize_t n;
-
- pfd[0].fd = ibuf->fd;
- pfd[0].events = POLLIN;
-
- while (1) {
- if ((n = imsg_get(ibuf, imsg)) == -1)
- return -1;
- if (n)
- return 1;
-
- n = poll(pfd, 1, timeout);
- if (n == -1)
- return -1;
- if (n == 0) {
- errno = ETIMEDOUT;
- return -1;
- }
-
- if (imsgbuf_read(ibuf) != 1)
- return -1;
- }
-}
-
int
smtpd(void) {
struct event ev_sigint;
@@ -1093,111 +940,6 @@ smtpd(void) {
return (0);
}
-static void
-load_pki_tree(void)
-{
- struct pki *pki;
- struct ca *sca;
- const char *k;
- void *iter_dict;
-
- log_debug("debug: init ssl-tree");
- iter_dict = NULL;
- while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) {
- log_debug("info: loading pki information for %s", k);
- if (pki->pki_cert_file == NULL)
- fatalx("load_pki_tree: missing certificate file");
- if (pki->pki_key_file == NULL)
- fatalx("load_pki_tree: missing key file");
-
- if (!ssl_load_certificate(pki, pki->pki_cert_file))
- fatalx("load_pki_tree: failed to load certificate file");
- }
-
- log_debug("debug: init ca-tree");
- iter_dict = NULL;
- while (dict_iter(env->sc_ca_dict, &iter_dict, &k, (void **)&sca)) {
- log_debug("info: loading CA information for %s", k);
- if (!ssl_load_cafile(sca, sca->ca_cert_file))
- fatalx("load_pki_tree: failed to load CA file");
- }
-}
-
-void
-load_pki_keys(void)
-{
- struct pki *pki;
- const char *k;
- void *iter_dict;
-
- log_debug("debug: init ssl-tree");
- iter_dict = NULL;
- while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) {
- log_debug("info: loading pki keys for %s", k);
-
- if (!ssl_load_keyfile(pki, pki->pki_key_file, k))
- fatalx("load_pki_keys: failed to load key file");
- }
-}
-
-int
-fork_proc_backend(const char *key, const char *conf, const char *procname,
- int do_stdout)
-{
- pid_t pid;
- int sp[2];
- char path[PATH_MAX];
- char name[PATH_MAX];
- char *arg;
-
- if (strlcpy(name, conf, sizeof(name)) >= sizeof(name)) {
- log_warnx("warn: %s-proc: conf too long", key);
- return (-1);
- }
-
- arg = strchr(name, ':');
- if (arg)
- *arg++ = '\0';
-
- if (snprintf(path, sizeof(path), PATH_LIBEXEC "/%s-%s", key, name) >=
- (ssize_t)sizeof(path)) {
- log_warn("warn: %s-proc: exec path too long", key);
- return (-1);
- }
-
- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1) {
- log_warn("warn: %s-proc: socketpair", key);
- return (-1);
- }
-
- if ((pid = fork()) == -1) {
- log_warn("warn: %s-proc: fork", key);
- close(sp[0]);
- close(sp[1]);
- return (-1);
- }
-
- if (pid == 0) {
- /* child process */
- dup2(sp[0], STDIN_FILENO);
- if (do_stdout)
- dup2(sp[0], STDOUT_FILENO);
- if (closefrom(STDERR_FILENO + 1) == -1)
- exit(1);
-
- if (procname == NULL)
- procname = name;
-
- execl(path, procname, arg, (char *)NULL);
- fatal("execl: %s", path);
- }
-
- /* parent process */
- close(sp[0]);
-
- return (sp[1]);
-}
-
struct child *
child_add(pid_t pid, int type, const char *title)
{
@@ -1835,54 +1577,6 @@ parent_forward_open(char *username, char *directory, u
return fd;
}
-void
-imsg_dispatch(struct mproc *p, struct imsg *imsg)
-{
- struct timespec t0, t1, dt;
- int msg;
-
- if (imsg == NULL) {
- imsg_callback(p, imsg);
- return;
- }
-
- log_imsg(smtpd_process, p->proc, imsg);
-
- if (profiling & PROFILE_IMSG)
- clock_gettime(CLOCK_MONOTONIC, &t0);
-
- msg = imsg->hdr.type;
- imsg_callback(p, imsg);
-
- if (profiling & PROFILE_IMSG) {
- clock_gettime(CLOCK_MONOTONIC, &t1);
- timespecsub(&t1, &t0, &dt);
-
- log_debug("profile-imsg: %s %s %s %d %lld.%09ld",
- proc_name(smtpd_process),
- proc_name(p->proc),
- imsg_to_str(msg),
- (int)imsg->hdr.len,
- (long long)dt.tv_sec,
- dt.tv_nsec);
-
- if (profiling & PROFILE_TOSTAT) {
- char key[STAT_KEY_SIZE];
- /* can't profstat control process yet */
- if (smtpd_process == PROC_CONTROL)
- return;
-
- if (!bsnprintf(key, sizeof key,
- "profiling.imsg.%s.%s.%s",
- proc_name(smtpd_process),
- proc_name(p->proc),
- imsg_to_str(msg)))
- return;
- stat_set(key, stat_timespec(&dt));
- }
- }
-}
-
int
parent_auth_user(const char *username, const char *password)
{
blob - b8268d69c6985d4d42234b550c8cfe6086d465b3
blob + fe8bcb8204fbf40110bcecfdf4ee634876b35013
--- usr.sbin/smtpd/smtpd.h
+++ usr.sbin/smtpd/smtpd.h
@@ -1614,6 +1614,12 @@ const char *srs_encode(const char *, const char *);
const char *srs_decode(const char *);
+/* startup.c */
+void setup_proc(void);
+int imsg_wait(struct imsgbuf *, struct imsg *, int);
+void load_pki_tree(void);
+void load_pki_keys(void);
+
/* stat_backend.c */
struct stat_backend *stat_backend_lookup(const char *);
void stat_increment(const char *, size_t);
blob - /dev/null
blob + 8195f93b98fd0b9a8bd5993d675cc69cc2ce4287 (mode 644)
--- /dev/null
+++ usr.sbin/smtpd/startup.c
@@ -0,0 +1,332 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
+ * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
+ * Copyright (c) 2009 Jacek Masiulaniec <jacekm@dobremiasto.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "smtpd.h"
+#include "log.h"
+#include "ssl.h"
+
+struct smtpd *env = NULL;
+
+struct mproc *p_control = NULL;
+struct mproc *p_lka = NULL;
+struct mproc *p_parent = NULL;
+struct mproc *p_queue = NULL;
+struct mproc *p_scheduler = NULL;
+struct mproc *p_dispatcher = NULL;
+struct mproc *p_ca = NULL;
+
+int profiling = 0;
+
+enum smtp_proc_type smtpd_process;
+
+const char *backend_queue = "fs";
+const char *backend_scheduler = "ramqueue";
+const char *backend_stat = "ram";
+
+void (*imsg_callback)(struct mproc *, struct imsg *);
+
+static struct mproc *
+setup_peer(enum smtp_proc_type proc, pid_t pid, int sock)
+{
+ struct mproc *p, **pp;
+
+ log_debug("setup_peer: %s -> %s[%u] fd=%d", proc_title(smtpd_process),
+ proc_title(proc), pid, sock);
+
+ if (sock == -1)
+ fatalx("peer socket not received");
+
+ switch (proc) {
+ case PROC_LKA:
+ pp = &p_lka;
+ break;
+ case PROC_QUEUE:
+ pp = &p_queue;
+ break;
+ case PROC_CONTROL:
+ pp = &p_control;
+ break;
+ case PROC_SCHEDULER:
+ pp = &p_scheduler;
+ break;
+ case PROC_DISPATCHER:
+ pp = &p_dispatcher;
+ break;
+ case PROC_CA:
+ pp = &p_ca;
+ break;
+ default:
+ fatalx("unknown peer");
+ }
+
+ if (*pp)
+ fatalx("peer already set");
+
+ p = calloc(1, sizeof(*p));
+ if (p == NULL)
+ fatal("calloc");
+ if((p->name = strdup(proc_title(proc))) == NULL)
+ fatal("strdup");
+ mproc_init(p, sock);
+ p->pid = pid;
+ p->proc = proc;
+ p->handler = imsg_dispatch;
+
+ *pp = p;
+
+ return p;
+}
+
+void
+setup_proc(void)
+{
+ struct imsgbuf *ibuf;
+ struct imsg imsg;
+ int setup = 1;
+
+ log_procinit(proc_title(smtpd_process));
+
+ p_parent = calloc(1, sizeof(*p_parent));
+ if (p_parent == NULL)
+ fatal("calloc");
+ if((p_parent->name = strdup("parent")) == NULL)
+ fatal("strdup");
+ p_parent->proc = PROC_PARENT;
+ p_parent->handler = imsg_dispatch;
+ mproc_init(p_parent, 3);
+
+ ibuf = &p_parent->imsgbuf;
+
+ while (setup) {
+ if (imsg_wait(ibuf, &imsg, 10000) == -1)
+ fatal("imsg_wait");
+
+ switch (imsg.hdr.type) {
+ case IMSG_SETUP_KEY:
+ env->sc_queue_key = strdup(imsg.data);
+ break;
+ case IMSG_SETUP_PEER:
+ setup_peer(imsg.hdr.peerid, imsg.hdr.pid,
+ imsg_get_fd(&imsg));
+ break;
+ case IMSG_SETUP_DONE:
+ setup = 0;
+ break;
+ default:
+ fatal("bad imsg %d", imsg.hdr.type);
+ }
+ imsg_free(&imsg);
+ }
+
+ if (imsg_compose(ibuf, IMSG_SETUP_DONE, 0, 0, -1, NULL, 0) == -1)
+ fatal("imsg_compose");
+
+ if (imsgbuf_flush(ibuf) == -1)
+ fatal("imsgbuf_flush");
+
+ log_debug("setup_proc: %s done", proc_title(smtpd_process));
+}
+
+int
+imsg_wait(struct imsgbuf *ibuf, struct imsg *imsg, int timeout)
+{
+ struct pollfd pfd[1];
+ ssize_t n;
+
+ pfd[0].fd = ibuf->fd;
+ pfd[0].events = POLLIN;
+
+ while (1) {
+ if ((n = imsg_get(ibuf, imsg)) == -1)
+ return -1;
+ if (n)
+ return 1;
+
+ n = poll(pfd, 1, timeout);
+ if (n == -1)
+ return -1;
+ if (n == 0) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+
+ if (imsgbuf_read(ibuf) != 1)
+ return -1;
+ }
+}
+
+void
+load_pki_tree(void)
+{
+ struct pki *pki;
+ struct ca *sca;
+ const char *k;
+ void *iter_dict;
+
+ log_debug("debug: init ssl-tree");
+ iter_dict = NULL;
+ while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) {
+ log_debug("info: loading pki information for %s", k);
+ if (pki->pki_cert_file == NULL)
+ fatalx("load_pki_tree: missing certificate file");
+ if (pki->pki_key_file == NULL)
+ fatalx("load_pki_tree: missing key file");
+
+ if (!ssl_load_certificate(pki, pki->pki_cert_file))
+ fatalx("load_pki_tree: failed to load certificate file");
+ }
+
+ log_debug("debug: init ca-tree");
+ iter_dict = NULL;
+ while (dict_iter(env->sc_ca_dict, &iter_dict, &k, (void **)&sca)) {
+ log_debug("info: loading CA information for %s", k);
+ if (!ssl_load_cafile(sca, sca->ca_cert_file))
+ fatalx("load_pki_tree: failed to load CA file");
+ }
+}
+
+void
+load_pki_keys(void)
+{
+ struct pki *pki;
+ const char *k;
+ void *iter_dict;
+
+ log_debug("debug: init ssl-tree");
+ iter_dict = NULL;
+ while (dict_iter(env->sc_pki_dict, &iter_dict, &k, (void **)&pki)) {
+ log_debug("info: loading pki keys for %s", k);
+
+ if (!ssl_load_keyfile(pki, pki->pki_key_file, k))
+ fatalx("load_pki_keys: failed to load key file");
+ }
+}
+
+int
+fork_proc_backend(const char *key, const char *conf, const char *procname,
+ int do_stdout)
+{
+ pid_t pid;
+ int sp[2];
+ char path[PATH_MAX];
+ char name[PATH_MAX];
+ char *arg;
+
+ if (strlcpy(name, conf, sizeof(name)) >= sizeof(name)) {
+ log_warnx("warn: %s-proc: conf too long", key);
+ return (-1);
+ }
+
+ arg = strchr(name, ':');
+ if (arg)
+ *arg++ = '\0';
+
+ if (snprintf(path, sizeof(path), PATH_LIBEXEC "/%s-%s", key, name) >=
+ (ssize_t)sizeof(path)) {
+ log_warn("warn: %s-proc: exec path too long", key);
+ return (-1);
+ }
+
+ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) == -1) {
+ log_warn("warn: %s-proc: socketpair", key);
+ return (-1);
+ }
+
+ if ((pid = fork()) == -1) {
+ log_warn("warn: %s-proc: fork", key);
+ close(sp[0]);
+ close(sp[1]);
+ return (-1);
+ }
+
+ if (pid == 0) {
+ /* child process */
+ dup2(sp[0], STDIN_FILENO);
+ if (do_stdout)
+ dup2(sp[0], STDOUT_FILENO);
+ if (closefrom(STDERR_FILENO + 1) == -1)
+ exit(1);
+
+ if (procname == NULL)
+ procname = name;
+
+ execl(path, procname, arg, (char *)NULL);
+ fatal("execl: %s", path);
+ }
+
+ /* parent process */
+ close(sp[0]);
+
+ return (sp[1]);
+}
+
+void
+imsg_dispatch(struct mproc *p, struct imsg *imsg)
+{
+ struct timespec t0, t1, dt;
+ int msg;
+
+ if (imsg == NULL) {
+ imsg_callback(p, imsg);
+ return;
+ }
+
+ log_imsg(smtpd_process, p->proc, imsg);
+
+ if (profiling & PROFILE_IMSG)
+ clock_gettime(CLOCK_MONOTONIC, &t0);
+
+ msg = imsg->hdr.type;
+ imsg_callback(p, imsg);
+
+ if (profiling & PROFILE_IMSG) {
+ clock_gettime(CLOCK_MONOTONIC, &t1);
+ timespecsub(&t1, &t0, &dt);
+
+ log_debug("profile-imsg: %s %s %s %d %lld.%09ld",
+ proc_name(smtpd_process),
+ proc_name(p->proc),
+ imsg_to_str(msg),
+ (int)imsg->hdr.len,
+ (long long)dt.tv_sec,
+ dt.tv_nsec);
+
+ if (profiling & PROFILE_TOSTAT) {
+ char key[STAT_KEY_SIZE];
+ /* can't profstat control process yet */
+ if (smtpd_process == PROC_CONTROL)
+ return;
+
+ if (!bsnprintf(key, sizeof key,
+ "profiling.imsg.%s.%s.%s",
+ proc_name(smtpd_process),
+ proc_name(p->proc),
+ imsg_to_str(msg)))
+ return;
+ stat_set(key, stat_timespec(&dt));
+ }
+ }
+}
smtpd: create startup.c