Re: smtpd: create startup.c

"Theo de Raadt" <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
I think this is the right approach.  It will take a few steps to see
clearly how to split this (it is not going to split the way sshd did).

> 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 <[email protected]>
> + * Copyright (c) 2008 Pierre-Yves Ritschard <[email protected]>
> + * Copyright (c) 2009 Jacek Masiulaniec <[email protected]>
> + *
> + * 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));
> +		}
> +	}
> +}
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.