diff options
Diffstat (limited to 'smtpd/control.c')
-rw-r--r-- | smtpd/control.c | 817 |
1 files changed, 0 insertions, 817 deletions
diff --git a/smtpd/control.c b/smtpd/control.c deleted file mode 100644 index 0e35bbd1..00000000 --- a/smtpd/control.c +++ /dev/null @@ -1,817 +0,0 @@ -/* $OpenBSD: control.c,v 1.123 2018/05/31 21:06:12 gilles Exp $ */ - -/* - * Copyright (c) 2012 Gilles Chehade <gilles@poolp.org> - * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> - * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> - * - * 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 "includes.h" - -#include <sys/types.h> -#include <sys/queue.h> -#include <sys/tree.h> -#include <sys/stat.h> -#include <sys/socket.h> -#include <sys/un.h> - -#include <err.h> -#include <errno.h> -#include <event.h> -#include <fcntl.h> -#include <grp.h> /* needed for setgroups */ -#include <imsg.h> -#include <pwd.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#include <limits.h> - -#include "smtpd.h" -#include "log.h" - -#define CONTROL_BACKLOG 5 - -struct ctl_conn { - uint32_t id; - uint8_t flags; -#define CTL_CONN_NOTIFY 0x01 - struct mproc mproc; - uid_t euid; - gid_t egid; -}; - -struct { - struct event ev; - int fd; -} control_state; - -static void control_imsg(struct mproc *, struct imsg *); -static void control_shutdown(void); -static void control_listen(void); -static void control_accept(int, short, void *); -static void control_close(struct ctl_conn *); -static void control_dispatch_ext(struct mproc *, struct imsg *); -static void control_digest_update(const char *, size_t, int); -static void control_broadcast_verbose(int, int); - -static struct stat_backend *stat_backend = NULL; -extern const char *backend_stat; - -static uint64_t connid = 0; -static struct tree ctl_conns; -static struct tree ctl_count; -static struct stat_digest digest; - -#define CONTROL_FD_RESERVE 5 -#define CONTROL_MAXCONN_PER_CLIENT 32 - -static void -control_imsg(struct mproc *p, struct imsg *imsg) -{ - struct ctl_conn *c; - struct stat_value val; - struct msg m; - const char *key; - const void *data; - size_t sz; - - if (imsg == NULL) { - if (p->proc != PROC_CLIENT) - control_shutdown(); - return; - } - - switch (imsg->hdr.type) { - case IMSG_CTL_OK: - case IMSG_CTL_FAIL: - case IMSG_CTL_LIST_MESSAGES: - case IMSG_CTL_LIST_ENVELOPES: - case IMSG_CTL_DISCOVER_EVPID: - case IMSG_CTL_DISCOVER_MSGID: - case IMSG_CTL_MTA_SHOW_HOSTS: - case IMSG_CTL_MTA_SHOW_RELAYS: - case IMSG_CTL_MTA_SHOW_ROUTES: - case IMSG_CTL_MTA_SHOW_HOSTSTATS: - case IMSG_CTL_MTA_SHOW_BLOCK: - c = tree_get(&ctl_conns, imsg->hdr.peerid); - if (c == NULL) - return; - imsg->hdr.peerid = 0; - m_forward(&c->mproc, imsg); - return; - - case IMSG_CTL_SMTP_SESSION: - c = tree_get(&ctl_conns, imsg->hdr.peerid); - if (c == NULL) - return; - m_compose(&c->mproc, IMSG_CTL_OK, 0, 0, imsg->fd, NULL, 0); - return; - - case IMSG_STAT_INCREMENT: - m_msg(&m, imsg); - m_get_string(&m, &key); - m_get_data(&m, &data, &sz); - m_end(&m); - if (sz != sizeof(val)) - fatalx("control: IMSG_STAT_INCREMENT size mismatch"); - memmove(&val, data, sz); - if (stat_backend) - stat_backend->increment(key, val.u.counter); - control_digest_update(key, val.u.counter, 1); - return; - - case IMSG_STAT_DECREMENT: - m_msg(&m, imsg); - m_get_string(&m, &key); - m_get_data(&m, &data, &sz); - m_end(&m); - if (sz != sizeof(val)) - fatalx("control: IMSG_STAT_DECREMENT size mismatch"); - memmove(&val, data, sz); - if (stat_backend) - stat_backend->decrement(key, val.u.counter); - control_digest_update(key, val.u.counter, 0); - return; - - case IMSG_STAT_SET: - m_msg(&m, imsg); - m_get_string(&m, &key); - m_get_data(&m, &data, &sz); - m_end(&m); - if (sz != sizeof(val)) - fatalx("control: IMSG_STAT_SET size mismatch"); - memmove(&val, data, sz); - if (stat_backend) - stat_backend->set(key, &val); - return; - } - - errx(1, "control_imsg: unexpected %s imsg", - imsg_to_str(imsg->hdr.type)); -} - -int -control_create_socket(void) -{ - struct sockaddr_un s_un; - int fd; - mode_t old_umask; - - if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) - fatal("control: socket"); - - memset(&s_un, 0, sizeof(s_un)); - s_un.sun_family = AF_UNIX; - if (strlcpy(s_un.sun_path, SMTPD_SOCKET, - sizeof(s_un.sun_path)) >= sizeof(s_un.sun_path)) - fatal("control: socket name too long"); - - if (connect(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == 0) - fatalx("control socket already listening"); - - if (unlink(SMTPD_SOCKET) == -1) - if (errno != ENOENT) - fatal("control: cannot unlink socket"); - - old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH); - if (bind(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) { - (void)umask(old_umask); - fatal("control: bind"); - } - (void)umask(old_umask); - - if (chmod(SMTPD_SOCKET, - S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) == -1) { - (void)unlink(SMTPD_SOCKET); - fatal("control: chmod"); - } - - io_set_nonblocking(fd); - control_state.fd = fd; - - return fd; -} - -int -control(void) -{ - struct passwd *pw; - - purge_config(PURGE_EVERYTHING); - - if ((pw = getpwnam(SMTPD_USER)) == NULL) - fatalx("unknown user " SMTPD_USER); - - stat_backend = env->sc_stat; - stat_backend->init(); - - if (chroot(PATH_CHROOT) == -1) - fatal("control: chroot"); - if (chdir("/") == -1) - fatal("control: chdir(\"/\")"); - - config_process(PROC_CONTROL); - - if (setgroups(1, &pw->pw_gid) || - setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || - setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) - fatal("control: cannot drop privileges"); - - imsg_callback = control_imsg; - event_init(); - - signal(SIGINT, SIG_IGN); - signal(SIGTERM, SIG_IGN); - signal(SIGPIPE, SIG_IGN); - signal(SIGHUP, SIG_IGN); - - tree_init(&ctl_conns); - tree_init(&ctl_count); - - memset(&digest, 0, sizeof digest); - digest.startup = time(NULL); - - config_peer(PROC_SCHEDULER); - config_peer(PROC_QUEUE); - config_peer(PROC_PARENT); - config_peer(PROC_LKA); - config_peer(PROC_PONY); - config_peer(PROC_CA); - - control_listen(); - -#if HAVE_PLEDGE - if (pledge("stdio unix recvfd sendfd", NULL) == -1) - err(1, "pledge"); -#endif - - event_dispatch(); - fatalx("exited event loop"); - - return (0); -} - -static void -control_shutdown(void) -{ - log_debug("debug: control agent exiting"); - _exit(0); -} - -static void -control_listen(void) -{ - if (listen(control_state.fd, CONTROL_BACKLOG) == -1) - fatal("control_listen"); - - event_set(&control_state.ev, control_state.fd, EV_READ|EV_PERSIST, - control_accept, NULL); - event_add(&control_state.ev, NULL); -} - -/* ARGSUSED */ -static void -control_accept(int listenfd, short event, void *arg) -{ - int connfd; - socklen_t len; - struct sockaddr_un s_un; - struct ctl_conn *c; - size_t *count; - uid_t euid; - gid_t egid; - -#if defined(HAVE_GETDTABLESIZE) && defined(HAVE_GETDTABLECOUNT) - if (getdtablesize() - getdtablecount() < CONTROL_FD_RESERVE) - goto pause; -#else - if (available_fds(CONTROL_FD_RESERVE)) - goto pause; -#endif - - len = sizeof(s_un); - if ((connfd = accept(listenfd, (struct sockaddr *)&s_un, &len)) == -1) { - if (errno == ENFILE || errno == EMFILE) - goto pause; - if (errno == EINTR || errno == EWOULDBLOCK || - errno == ECONNABORTED) - return; - fatal("control_accept: accept"); - } - - io_set_nonblocking(connfd); - - if (getpeereid(connfd, &euid, &egid) == -1) - fatal("getpeereid"); - - count = tree_get(&ctl_count, euid); - if (count == NULL) { - count = xcalloc(1, sizeof *count); - tree_xset(&ctl_count, euid, count); - } - - if (*count == CONTROL_MAXCONN_PER_CLIENT) { - close(connfd); - log_warnx("warn: too many connections to control socket " - "from user with uid %lu", (unsigned long int)euid); - return; - } - (*count)++; - - do { - ++connid; - } while (tree_get(&ctl_conns, connid)); - - c = xcalloc(1, sizeof(*c)); - c->euid = euid; - c->egid = egid; - c->id = connid; - c->mproc.proc = PROC_CLIENT; - c->mproc.handler = control_dispatch_ext; - c->mproc.data = c; - if ((c->mproc.name = strdup(proc_title(c->mproc.proc))) == NULL) - fatal("strdup"); - mproc_init(&c->mproc, connfd); - mproc_enable(&c->mproc); - tree_xset(&ctl_conns, c->id, c); - - stat_backend->increment("control.session", 1); - return; - -pause: - log_warnx("warn: ctl client limit hit, disabling new connections"); - event_del(&control_state.ev); -} - -static void -control_close(struct ctl_conn *c) -{ - size_t *count; - - count = tree_xget(&ctl_count, c->euid); - (*count)--; - if (*count == 0) { - tree_xpop(&ctl_count, c->euid); - free(count); - } - tree_xpop(&ctl_conns, c->id); - mproc_clear(&c->mproc); - free(c); - - stat_backend->decrement("control.session", 1); - -#if defined(HAVE_GETDTABLESIZE) && defined(HAVE_GETDTABLECOUNT) - if (getdtablesize() - getdtablecount() < CONTROL_FD_RESERVE) - return; -#else - if (available_fds(CONTROL_FD_RESERVE)) - return; -#endif - - if (!event_pending(&control_state.ev, EV_READ, NULL)) { - log_warnx("warn: re-enabling ctl connections"); - event_add(&control_state.ev, NULL); - } -} - -static void -control_digest_update(const char *key, size_t value, int incr) -{ - size_t *p; - - p = NULL; - - if (!strcmp(key, "smtp.session")) { - if (incr) - p = &digest.clt_connect; - else - digest.clt_disconnect += value; - } - else if (!strcmp(key, "scheduler.envelope")) { - if (incr) - p = &digest.evp_enqueued; - else - digest.evp_dequeued += value; - } - else if (!strcmp(key, "scheduler.envelope.expired")) - p = &digest.evp_expired; - else if (!strcmp(key, "scheduler.envelope.removed")) - p = &digest.evp_removed; - else if (!strcmp(key, "scheduler.delivery.ok")) - p = &digest.dlv_ok; - else if (!strcmp(key, "scheduler.delivery.permfail")) - p = &digest.dlv_permfail; - else if (!strcmp(key, "scheduler.delivery.tempfail")) - p = &digest.dlv_tempfail; - else if (!strcmp(key, "scheduler.delivery.loop")) - p = &digest.dlv_loop; - - else if (!strcmp(key, "queue.bounce")) - p = &digest.evp_bounce; - - if (p) { - if (incr) - *p = *p + value; - else - *p = *p - value; - } -} - -/* ARGSUSED */ -static void -control_dispatch_ext(struct mproc *p, struct imsg *imsg) -{ - struct sockaddr_storage ss; - struct ctl_conn *c; - int v; - struct stat_kv *kvp; - char *key; - struct stat_value val; - size_t len; - uint64_t evpid; - uint32_t msgid; - - c = p->data; - - if (imsg == NULL) { - control_close(c); - return; - } - - if (imsg->hdr.peerid != IMSG_VERSION) { - m_compose(p, IMSG_CTL_FAIL, IMSG_VERSION, 0, -1, NULL, 0); - return; - } - - switch (imsg->hdr.type) { - case IMSG_CTL_SMTP_SESSION: - if (env->sc_flags & SMTPD_SMTP_PAUSED) { - m_compose(p, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); - return; - } - m_compose(p_pony, IMSG_CTL_SMTP_SESSION, c->id, 0, -1, - &c->euid, sizeof(c->euid)); - return; - - case IMSG_CTL_GET_DIGEST: - if (c->euid) - goto badcred; - digest.timestamp = time(NULL); - m_compose(p, IMSG_CTL_GET_DIGEST, 0, 0, -1, &digest, sizeof digest); - return; - - case IMSG_CTL_GET_STATS: - if (c->euid) - goto badcred; - kvp = imsg->data; - if (!stat_backend->iter(&kvp->iter, &key, &val)) - kvp->iter = NULL; - else { - (void)strlcpy(kvp->key, key, sizeof kvp->key); - kvp->val = val; - } - m_compose(p, IMSG_CTL_GET_STATS, 0, 0, -1, kvp, sizeof *kvp); - return; - - case IMSG_CTL_VERBOSE: - if (c->euid) - goto badcred; - - if (imsg->hdr.len - IMSG_HEADER_SIZE != sizeof(v)) - goto badcred; - - memcpy(&v, imsg->data, sizeof(v)); - log_trace_verbose(v); - - control_broadcast_verbose(IMSG_CTL_VERBOSE, v); - - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_TRACE_ENABLE: - if (c->euid) - goto badcred; - - if (imsg->hdr.len - IMSG_HEADER_SIZE != sizeof(v)) - goto badcred; - - memcpy(&v, imsg->data, sizeof(v)); - tracing |= v; - log_trace_verbose(tracing); - - control_broadcast_verbose(IMSG_CTL_VERBOSE, tracing); - - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_TRACE_DISABLE: - if (c->euid) - goto badcred; - - if (imsg->hdr.len - IMSG_HEADER_SIZE != sizeof(v)) - goto badcred; - - memcpy(&v, imsg->data, sizeof(v)); - tracing &= ~v; - log_trace_verbose(tracing); - - control_broadcast_verbose(IMSG_CTL_VERBOSE, tracing); - - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_PROFILE_ENABLE: - if (c->euid) - goto badcred; - - if (imsg->hdr.len - IMSG_HEADER_SIZE != sizeof(v)) - goto badcred; - - memcpy(&v, imsg->data, sizeof(v)); - profiling |= v; - - control_broadcast_verbose(IMSG_CTL_PROFILE, profiling); - - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_PROFILE_DISABLE: - if (c->euid) - goto badcred; - - if (imsg->hdr.len - IMSG_HEADER_SIZE != sizeof(v)) - goto badcred; - - memcpy(&v, imsg->data, sizeof(v)); - profiling &= ~v; - - control_broadcast_verbose(IMSG_CTL_PROFILE, profiling); - - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_PAUSE_EVP: - if (c->euid) - goto badcred; - - imsg->hdr.peerid = c->id; - m_forward(p_scheduler, imsg); - return; - - case IMSG_CTL_PAUSE_MDA: - if (c->euid) - goto badcred; - - if (env->sc_flags & SMTPD_MDA_PAUSED) { - m_compose(p, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); - return; - } - log_info("info: mda paused"); - env->sc_flags |= SMTPD_MDA_PAUSED; - m_compose(p_queue, IMSG_CTL_PAUSE_MDA, 0, 0, -1, NULL, 0); - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_PAUSE_MTA: - if (c->euid) - goto badcred; - - if (env->sc_flags & SMTPD_MTA_PAUSED) { - m_compose(p, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); - return; - } - log_info("info: mta paused"); - env->sc_flags |= SMTPD_MTA_PAUSED; - m_compose(p_queue, IMSG_CTL_PAUSE_MTA, 0, 0, -1, NULL, 0); - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_PAUSE_SMTP: - if (c->euid) - goto badcred; - - if (env->sc_flags & SMTPD_SMTP_PAUSED) { - m_compose(p, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); - return; - } - log_info("info: smtp paused"); - env->sc_flags |= SMTPD_SMTP_PAUSED; - m_compose(p_pony, IMSG_CTL_PAUSE_SMTP, 0, 0, -1, NULL, 0); - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_RESUME_EVP: - if (c->euid) - goto badcred; - - imsg->hdr.peerid = c->id; - m_forward(p_scheduler, imsg); - return; - - case IMSG_CTL_RESUME_MDA: - if (c->euid) - goto badcred; - - if (!(env->sc_flags & SMTPD_MDA_PAUSED)) { - m_compose(p, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); - return; - } - log_info("info: mda resumed"); - env->sc_flags &= ~SMTPD_MDA_PAUSED; - m_compose(p_queue, IMSG_CTL_RESUME_MDA, 0, 0, -1, NULL, 0); - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_RESUME_MTA: - if (c->euid) - goto badcred; - - if (!(env->sc_flags & SMTPD_MTA_PAUSED)) { - m_compose(p, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); - return; - } - log_info("info: mta resumed"); - env->sc_flags &= ~SMTPD_MTA_PAUSED; - m_compose(p_queue, IMSG_CTL_RESUME_MTA, 0, 0, -1, NULL, 0); - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_RESUME_SMTP: - if (c->euid) - goto badcred; - - if (!(env->sc_flags & SMTPD_SMTP_PAUSED)) { - m_compose(p, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); - return; - } - log_info("info: smtp resumed"); - env->sc_flags &= ~SMTPD_SMTP_PAUSED; - m_forward(p_pony, imsg); - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_RESUME_ROUTE: - if (c->euid) - goto badcred; - - m_forward(p_pony, imsg); - m_compose(p, IMSG_CTL_OK, 0, 0, -1, NULL, 0); - return; - - case IMSG_CTL_LIST_MESSAGES: - if (c->euid) - goto badcred; - m_compose(p_scheduler, IMSG_CTL_LIST_MESSAGES, c->id, 0, -1, - imsg->data, imsg->hdr.len - sizeof(imsg->hdr)); - return; - - case IMSG_CTL_LIST_ENVELOPES: - if (c->euid) - goto badcred; - m_compose(p_scheduler, IMSG_CTL_LIST_ENVELOPES, c->id, 0, -1, - imsg->data, imsg->hdr.len - sizeof(imsg->hdr)); - return; - - case IMSG_CTL_MTA_SHOW_HOSTS: - case IMSG_CTL_MTA_SHOW_RELAYS: - case IMSG_CTL_MTA_SHOW_ROUTES: - case IMSG_CTL_MTA_SHOW_HOSTSTATS: - case IMSG_CTL_MTA_SHOW_BLOCK: - if (c->euid) - goto badcred; - - imsg->hdr.peerid = c->id; - m_forward(p_pony, imsg); - return; - - case IMSG_CTL_SHOW_STATUS: - if (c->euid) - goto badcred; - - m_compose(p, IMSG_CTL_SHOW_STATUS, 0, 0, -1, &env->sc_flags, - sizeof(env->sc_flags)); - return; - - case IMSG_CTL_MTA_BLOCK: - case IMSG_CTL_MTA_UNBLOCK: - if (c->euid) - goto badcred; - - if (imsg->hdr.len - IMSG_HEADER_SIZE <= sizeof(ss)) - goto invalid; - memmove(&ss, imsg->data, sizeof(ss)); - m_create(p_pony, imsg->hdr.type, c->id, 0, -1); - m_add_sockaddr(p_pony, (struct sockaddr *)&ss); - m_add_string(p_pony, (char *)imsg->data + sizeof(ss)); - m_close(p_pony); - return; - - case IMSG_CTL_SCHEDULE: - if (c->euid) - goto badcred; - - imsg->hdr.peerid = c->id; - m_forward(p_scheduler, imsg); - return; - - case IMSG_CTL_REMOVE: - if (c->euid) - goto badcred; - - imsg->hdr.peerid = c->id; - m_forward(p_scheduler, imsg); - return; - - case IMSG_CTL_UPDATE_TABLE: - if (c->euid) - goto badcred; - - /* table name too long */ - len = strlen(imsg->data); - if (len >= LINE_MAX) - goto invalid; - - imsg->hdr.peerid = c->id; - m_forward(p_lka, imsg); - return; - - case IMSG_CTL_DISCOVER_EVPID: - if (c->euid) - goto badcred; - - if (imsg->hdr.len - IMSG_HEADER_SIZE != sizeof evpid) - goto invalid; - - memmove(&evpid, imsg->data, sizeof evpid); - m_create(p_queue, imsg->hdr.type, c->id, 0, -1); - m_add_evpid(p_queue, evpid); - m_close(p_queue); - return; - - case IMSG_CTL_DISCOVER_MSGID: - if (c->euid) - goto badcred; - - if (imsg->hdr.len - IMSG_HEADER_SIZE != sizeof msgid) - goto invalid; - - memmove(&msgid, imsg->data, sizeof msgid); - m_create(p_queue, imsg->hdr.type, c->id, 0, -1); - m_add_msgid(p_queue, msgid); - m_close(p_queue); - return; - - default: - log_debug("debug: control_dispatch_ext: " - "error handling %s imsg", - imsg_to_str(imsg->hdr.type)); - return; - } -badcred: -invalid: - m_compose(p, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); -} - -static void -control_broadcast_verbose(int msg, int v) -{ - m_create(p_lka, msg, 0, 0, -1); - m_add_int(p_lka, v); - m_close(p_lka); - - m_create(p_pony, msg, 0, 0, -1); - m_add_int(p_pony, v); - m_close(p_pony); - - m_create(p_queue, msg, 0, 0, -1); - m_add_int(p_queue, v); - m_close(p_queue); - - m_create(p_ca, msg, 0, 0, -1); - m_add_int(p_ca, v); - m_close(p_ca); - - m_create(p_scheduler, msg, 0, 0, -1); - m_add_int(p_scheduler, v); - m_close(p_scheduler); - - m_create(p_parent, msg, 0, 0, -1); - m_add_int(p_parent, v); - m_close(p_parent); -} |