static void proc_event_cb(unused int fd, short events, void *arg) { struct tmuxpeer *peer = arg; ssize_t n; struct imsg imsg; int v; if (!(peer->flags & PEER_BAD) && (events & EV_READ)) { if ((n = imsg_read(&peer->ibuf)) == -1 || n == 0) { peer->dispatchcb(NULL, peer->arg); return; } for (;;) { if ((n = imsg_get(&peer->ibuf, &imsg)) == -1) { peer->dispatchcb(NULL, peer->arg); return; } if (n == 0) break; log_debug("peer %p message %d", peer, imsg.hdr.type); v = imsg.hdr.peerid; if (imsg.hdr.type != MSG_VERSION && v != PROTOCOL_VERSION) { log_debug("peer %p bad version %d", peer, v); proc_send(peer, MSG_VERSION, -1, NULL, 0); peer->flags |= PEER_BAD; if (imsg.fd != -1) close(imsg.fd); imsg_free(&imsg); break; } peer->dispatchcb(&imsg, peer->arg); imsg_free(&imsg); } } if (events & EV_WRITE) { if (msgbuf_write(&peer->ibuf.w) <= 0 && errno != EAGAIN) { peer->dispatchcb(NULL, peer->arg); return; } } if ((peer->flags & PEER_BAD) && peer->ibuf.w.queued == 0) { peer->dispatchcb(NULL, peer->arg); return; } proc_update_event(peer); }
static void proc_event_cb(__unused int fd, short events, void *arg) { struct tmuxpeer *peer = arg; ssize_t n; struct imsg imsg; if (!(peer->flags & PEER_BAD) && (events & EV_READ)) { if (((n = imsg_read(&peer->ibuf)) == -1 && errno != EAGAIN) || n == 0) { peer->dispatchcb(NULL, peer->arg); return; } for (;;) { if ((n = imsg_get(&peer->ibuf, &imsg)) == -1) { peer->dispatchcb(NULL, peer->arg); return; } if (n == 0) break; log_debug("peer %p message %d", peer, imsg.hdr.type); if (peer_check_version(peer, &imsg) != 0) { if (imsg.fd != -1) close(imsg.fd); imsg_free(&imsg); break; } peer->dispatchcb(&imsg, peer->arg); imsg_free(&imsg); } } if (events & EV_WRITE) { if (msgbuf_write(&peer->ibuf.w) <= 0 && errno != EAGAIN) { peer->dispatchcb(NULL, peer->arg); return; } } if ((peer->flags & PEER_BAD) && peer->ibuf.w.queued == 0) { peer->dispatchcb(NULL, peer->arg); return; } proc_update_event(peer); }
void control_close(struct ctl_conn *c, const char *msg, struct imsg *imsg) { struct control_sock *cs = c->cs; if (imsg) { log_debug("%s: fd %d: %s, imsg %d datalen %zu", __func__, c->iev.ibuf.fd, msg, imsg->hdr.type, IMSG_DATA_SIZE(imsg)); imsg_free(imsg); } else log_debug("%s: fd %d: %s", __func__, c->iev.ibuf.fd, msg); msgbuf_clear(&c->iev.ibuf.w); TAILQ_REMOVE(&ctl_conns, c, entry); event_del(&c->iev.ev); close(c->iev.ibuf.fd); /* Some file descriptors are available again. */ if (evtimer_pending(&cs->cs_evt, NULL)) { evtimer_del(&cs->cs_evt); event_add(&cs->cs_ev, NULL); } free(c); }
int dispatch_imsg(struct ntpd_conf *lconf) { struct imsg imsg; int n; double d; if ((n = imsg_read(ibuf)) == -1) return (-1); if (n == 0) { /* connection closed */ log_warnx("dispatch_imsg in main: pipe closed"); return (-1); } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) return (-1); if (n == 0) break; switch (imsg.hdr.type) { case IMSG_ADJTIME: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d)) fatalx("invalid IMSG_ADJTIME received"); memcpy(&d, imsg.data, sizeof(d)); n = ntpd_adjtime(d); imsg_compose(ibuf, IMSG_ADJTIME, 0, 0, -1, &n, sizeof(n)); break; case IMSG_ADJFREQ: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d)) fatalx("invalid IMSG_ADJFREQ received"); memcpy(&d, imsg.data, sizeof(d)); ntpd_adjfreq(d, 1); break; case IMSG_SETTIME: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d)) fatalx("invalid IMSG_SETTIME received"); if (!lconf->settime) break; log_init(lconf->debug); memcpy(&d, imsg.data, sizeof(d)); ntpd_settime(d); /* daemonize now */ if (!lconf->debug) if (daemon(1, 0)) fatal("daemon"); lconf->settime = 0; timeout = INFTIM; break; default: break; } imsg_free(&imsg); } return (0); }
static void table_proc_end(void) { if (rlen) { log_warnx("warn: table-proc: bogus data"); fatalx("table-proc: exiting"); } imsg_free(&imsg); }
static void queue_msg_end(void) { if (rlen) { log_warnx("warn: queue-proc: bogus data"); fatalx("queue-proc: exiting"); } imsg_free(&imsg); }
void imsgev_dispatch(int fd, short ev, void *humppa) { struct imsgev *iev = humppa; struct imsgbuf *ibuf = &iev->ibuf; struct imsg imsg; ssize_t n; iev->events = 0; if (ev & EV_READ) { if ((n = imsg_read(ibuf)) == -1) { imsgev_disconnect(iev, IMSGEV_EREAD); return; } if (n == 0) { /* * Connection is closed for reading, and we assume * it is also closed for writing, so we error out * if write data is pending. */ imsgev_disconnect(iev, (iev->ibuf.w.queued) ? IMSGEV_EWRITE : IMSGEV_DONE); return; } } if (ev & EV_WRITE) { /* * We wanted to write data out but the connection is either * closed, or some error occured. Both case are not recoverable * from the imsg perspective, so we treat it as a WRITE error. */ if ((n = msgbuf_write(&ibuf->w)) != 0) { imsgev_disconnect(iev, IMSGEV_EWRITE); return; } } while (iev->terminate == 0) { if ((n = imsg_get(ibuf, &imsg)) == -1) { imsgev_disconnect(iev, IMSGEV_EIMSG); return; } if (n == 0) break; iev->callback(iev, IMSGEV_IMSG, &imsg); imsg_free(&imsg); } if (iev->terminate && iev->ibuf.w.queued == 0) { imsgev_disconnect(iev, IMSGEV_DONE); return; } imsgev_add(iev); }
static void scheduler_msg_end(void) { if (rlen) { log_warnx("warn: scheduler-proc: bogus data"); fatalx("scheduler-proc: exiting"); } imsg_free(&imsg); }
void service_exec(struct imsgbuf* ibuf) { pledge("stdio proc exec", NULL); while(1) { int n = imsg_read(ibuf); if(n < 0) { die("Error reading ibuf"); } if(n == 0) { break; } while(1) { struct imsg imsg; n = imsg_get(ibuf, &imsg); if(n <= 0) { break; } dispatch(ibuf, imsg.hdr.type, (char* const)imsg.data); imsg_free(&imsg); } } }
/* * The purpose of this function is to handle requests sent by the * root privileged process. */ int tnt_dispatch_imsg(struct imsg_data *data) { struct imsg imsg; ssize_t n; int device_fd; struct imsgbuf *ibuf = data->ibuf; n = imsg_read(ibuf); if (n == -1) { log_warnx("loose some imsgs"); imsg_clear(ibuf); return -1; } if (n == 0) { log_warnx("pipe closed"); return -1; } /* Loops through the queue created by imsg_read */ while ((n = imsg_get(ibuf, &imsg)) != 0 && n != -1) { switch (imsg.hdr.type) { case IMSG_CREATE_DEV: device_fd = imsg.fd; log_info("receive IMSG_CREATE_DEV: fd %i", device_fd); server_set_device(data->server, device_fd); /* directly ask to configure the tun device */ imsg_compose(ibuf, IMSG_SET_IP, 0, 0, -1, serv_opts.addr , strlen(serv_opts.addr)); break; default: break; } imsg_free(&imsg); } if (n == -1) { log_warnx("imsg_get"); return -1; } return 0; }
static int open_connection(void) { struct imsg imsg; int fd; int n; imsg_compose(ibuf, IMSG_SMTP_ENQUEUE, 0, 0, -1, NULL, 0); while (ibuf->w.queued) if (msgbuf_write(&ibuf->w) < 0) err(1, "write error"); while (1) { if ((n = imsg_read(ibuf)) == -1) errx(1, "imsg_read error"); if (n == 0) errx(1, "pipe closed"); if ((n = imsg_get(ibuf, &imsg)) == -1) errx(1, "imsg_get error"); if (n == 0) continue; switch (imsg.hdr.type) { case IMSG_CTL_OK: break; case IMSG_CTL_FAIL: errx(1, "server disallowed submission request"); default: errx(1, "unexpected imsg reply type"); } fd = imsg.fd; imsg_free(&imsg); break; } return fd; }
int snmp_getsock(struct imsgev *iev) { struct imsg imsg; int n, s = -1, done = 0; imsg_compose_event(iev, IMSG_SNMPSOCK, 0, 0, -1, NULL, 0); imsg_flush(&iev->ibuf); while (!done) { if ((n = imsg_read(&iev->ibuf)) == -1) fatal("snmp_getsock: failed to read imsg"); if (n == 0) fatal("snmp_getsock: pipe closed"); while (!done) { if ((n = imsg_get(&iev->ibuf, &imsg)) == -1) fatal("snmp_getsock: failed to get imsg"); if (n == 0) break; done = 1; switch (imsg.hdr.type) { case IMSG_SNMPSOCK: s = imsg.fd; break; default: break; } imsg_free(&imsg); } } if (s != -1) { log_debug("%s: got new snmp socket %d", __func__, s); if (iev_snmp == NULL && (iev_snmp = (struct imsgev *) calloc(1, sizeof(struct imsgev))) == NULL) fatal("snmp_getsock: calloc"); imsg_init(&iev_snmp->ibuf, s); } return (s); }
int32_t service_pop(struct imsgbuf* ibuf, char* buf, size_t buf_len) { if(buf != NULL) { buf[0] = '\0'; } int n = imsg_read(ibuf); if(n < 0) { die("Error reading"); } if(n == 0) { return -1; } struct imsg imsg; n = imsg_get(ibuf, &imsg); if(n <= 0) { die("Got no message"); } if(buf != NULL && imsg.data != NULL) { // We should only ever pass strings, but just to be safe, always // make sure that the buffer we return is nul-terminated. const size_t data_len = imsg.hdr.len - IMSG_HEADER_SIZE; strlcpy(buf, imsg.data, min(buf_len, data_len)); } u_int32_t type = imsg.hdr.type; imsg_free(&imsg); return type; }
/* ARGSUSED */ void control_dispatch_imsg(int fd, short event, void *arg) { struct control_sock *cs = arg; struct iked *env = cs->cs_env; struct ctl_conn *c; struct imsg imsg; int n, v; if ((c = control_connbyfd(fd)) == NULL) { log_warn("%s: fd %d: not found", __func__, fd); return; } if (event & EV_READ) { if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) { control_close(fd, cs); return; } } if (event & EV_WRITE) { if (msgbuf_write(&c->iev.ibuf.w) <= 0 && errno != EAGAIN) { control_close(fd, cs); return; } } for (;;) { if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) { control_close(fd, cs); return; } if (n == 0) break; control_imsg_forward(&imsg); switch (imsg.hdr.type) { case IMSG_CTL_NOTIFY: if (c->flags & CTL_CONN_NOTIFY) { log_debug("%s: " "client requested notify more than once", __func__); imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } c->flags |= CTL_CONN_NOTIFY; break; case IMSG_CTL_VERBOSE: IMSG_SIZE_CHECK(&imsg, &v); memcpy(&v, imsg.data, sizeof(v)); log_verbose(v); proc_forward_imsg(&env->sc_ps, &imsg, PROC_PARENT, -1); proc_forward_imsg(&env->sc_ps, &imsg, PROC_IKEV2, -1); proc_forward_imsg(&env->sc_ps, &imsg, PROC_IKEV1, -1); break; case IMSG_CTL_RELOAD: case IMSG_CTL_RESET: case IMSG_CTL_COUPLE: case IMSG_CTL_DECOUPLE: case IMSG_CTL_ACTIVE: case IMSG_CTL_PASSIVE: proc_forward_imsg(&env->sc_ps, &imsg, PROC_PARENT, -1); break; default: log_debug("%s: error handling imsg %d", __func__, imsg.hdr.type); break; } imsg_free(&imsg); } imsg_event_add(&c->iev); }
/* ARGSUSED */ void control_dispatch_imsg(int fd, short event, void *bula) { struct ctl_conn *c; struct imsg imsg; ssize_t n; unsigned int ifidx; int verbose; if ((c = control_connbyfd(fd)) == NULL) { log_warn("control_dispatch_imsg: fd %d: not found", fd); return; } if (event & EV_READ) { if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) { control_close(fd); return; } } if (event & EV_WRITE) { if (msgbuf_write(&c->iev.ibuf.w) == -1) { control_close(fd); return; } } for (;;) { if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) { control_close(fd); return; } if (n == 0) break; switch (imsg.hdr.type) { case IMSG_CTL_FIB_COUPLE: case IMSG_CTL_FIB_DECOUPLE: ospfe_fib_update(imsg.hdr.type); /* FALLTHROUGH */ case IMSG_CTL_FIB_RELOAD: case IMSG_CTL_RELOAD: c->iev.ibuf.pid = imsg.hdr.pid; ospfe_imsg_compose_parent(imsg.hdr.type, 0, NULL, 0); break; case IMSG_CTL_KROUTE: case IMSG_CTL_KROUTE_ADDR: case IMSG_CTL_IFINFO: c->iev.ibuf.pid = imsg.hdr.pid; ospfe_imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid, imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); break; case IMSG_CTL_SHOW_INTERFACE: if (imsg.hdr.len == IMSG_HEADER_SIZE + sizeof(ifidx)) { memcpy(&ifidx, imsg.data, sizeof(ifidx)); ospfe_iface_ctl(c, ifidx); imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_SHOW_DATABASE: case IMSG_CTL_SHOW_DB_EXT: case IMSG_CTL_SHOW_DB_NET: case IMSG_CTL_SHOW_DB_RTR: case IMSG_CTL_SHOW_DB_SELF: case IMSG_CTL_SHOW_DB_SUM: case IMSG_CTL_SHOW_DB_ASBR: case IMSG_CTL_SHOW_DB_OPAQ: case IMSG_CTL_SHOW_RIB: case IMSG_CTL_SHOW_SUM: c->iev.ibuf.pid = imsg.hdr.pid; ospfe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid, imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); break; case IMSG_CTL_SHOW_NBR: ospfe_nbr_ctl(c); break; case IMSG_CTL_LOG_VERBOSE: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(verbose)) break; /* forward to other processes */ ospfe_imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid, imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); ospfe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid, imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); memcpy(&verbose, imsg.data, sizeof(verbose)); log_verbose(verbose); break; default: log_debug("control_dispatch_imsg: " "error handling imsg %d", imsg.hdr.type); break; } imsg_free(&imsg); } imsg_event_add(&c->iev); }
/* ARGSUSED */ void control_dispatch_imsg(int fd, short event, void *arg) { struct control_sock *cs = (struct control_sock *)arg; struct ctl_conn *c; struct imsg imsg; int n, retval; if ((c = control_connbyfd(fd)) == NULL) { log_warn("control_dispatch_imsg: fd %d: not found", fd); return; } if (event & EV_WRITE) { if (msgbuf_write(&c->iev.ibuf.w) < 0) { control_close(fd, cs); return; } if (!c->iev.ibuf.w.queued) npppd_ctl_imsg_compose(c->ctx, &c->iev.ibuf); imsg_event_add(&c->iev); if (!(event & EV_READ)) return; } if (event & EV_READ) { if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) { control_close(fd, cs); return; } } else fatalx("unknown event"); for (;;) { if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) { control_close(fd, cs); return; } if (n == 0) break; if (cs->cs_restricted || (c->flags & CTL_CONN_LOCKED)) { switch (imsg.hdr.type) { default: log_debug("control_dispatch_imsg: " "client requested restricted command"); imsg_free(&imsg); control_close(fd, cs); return; } } switch (imsg.hdr.type) { case IMSG_CTL_NOP: imsg_compose(&c->iev.ibuf, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; case IMSG_CTL_WHO: case IMSG_CTL_MONITOR: case IMSG_CTL_WHO_AND_MONITOR: if (imsg.hdr.type == IMSG_CTL_WHO) retval = npppd_ctl_who(c->ctx); else if (imsg.hdr.type == IMSG_CTL_MONITOR) retval = npppd_ctl_monitor(c->ctx); else retval = npppd_ctl_who_and_monitor(c->ctx); imsg_compose(&c->iev.ibuf, (retval == 0)? IMSG_CTL_OK : IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; case IMSG_CTL_DISCONNECT: { struct npppd_disconnect_request *req; struct npppd_disconnect_response res; req = (struct npppd_disconnect_request *)imsg.data; retval = npppd_ctl_disconnect(c->ctx, req->ppp_id, req->count); res.count = retval; imsg_compose(&c->iev.ibuf, IMSG_CTL_OK, 0, 0, -1, &res, sizeof(res)); break; } default: imsg_compose(&c->iev.ibuf, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } imsg_free(&imsg); } if (!c->iev.ibuf.w.queued) npppd_ctl_imsg_compose(c->ctx, &c->iev.ibuf); imsg_event_add(&c->iev); }
void dispatch_imsg(struct imsgbuf *ibuf) { struct imsg imsg; struct imsg_write_file *wfimsg; ssize_t n; size_t len; for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) error("dispatch_imsg: imsg_get failure: %s", strerror(errno)); if (n == 0) break; switch (imsg.hdr.type) { case IMSG_DELETE_ADDRESS: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(struct imsg_delete_address)) warning("bad IMSG_DELETE_ADDRESS"); else priv_delete_address(imsg.data); break; case IMSG_ADD_ADDRESS: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(struct imsg_add_address)) warning("bad IMSG_ADD_ADDRESS"); else priv_add_address(imsg.data); break; case IMSG_FLUSH_ROUTES: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(struct imsg_flush_routes)) warning("bad IMSG_FLUSH_ROUTES"); else priv_flush_routes(imsg.data); break; case IMSG_ADD_ROUTE: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(struct imsg_add_route)) warning("bad IMSG_ADD_ROUTE"); else priv_add_route(imsg.data); break; case IMSG_HUP: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(struct imsg_hup)) warning("bad IMSG_HUP"); else { ifi->flags |= IFI_HUP; quit = SIGHUP; } break; case IMSG_WRITE_FILE: if (imsg.hdr.len < IMSG_HEADER_SIZE + sizeof(struct imsg_write_file)) warning("short IMSG_WRITE_FILE"); else { wfimsg = (struct imsg_write_file *)imsg.data; len = imsg.hdr.len; len -= IMSG_HEADER_SIZE; len -= sizeof(struct imsg_write_file); len -= wfimsg->len; if (len == 0) priv_write_file(wfimsg); else warning("bad IMSG_WRITE_FILE (%zu)", len); } break; default: warning("received unknown message, code %u", imsg.hdr.type); } imsg_free(&imsg); } }
/* ARGSUSED */ void control_dispatch_ext(int fd, short event, void *arg) { struct ctl_conn *c; struct imsg imsg; int n; uid_t euid; gid_t egid; if (getpeereid(fd, &euid, &egid) == -1) fatal("getpeereid"); if ((c = control_connbyfd(fd)) == NULL) { log_warn("control_dispatch_ext: fd %d: not found", fd); return; } if (event & EV_READ) { if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) { control_close(fd); return; } } if (event & EV_WRITE) { if (msgbuf_write(&c->iev.ibuf.w) < 0) { control_close(fd); return; } } for (;;) { if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) { control_close(fd); return; } if (n == 0) break; switch (imsg.hdr.type) { case IMSG_SMTP_ENQUEUE: if (env->sc_flags & (SMTPD_SMTP_PAUSED | SMTPD_CONFIGURING | SMTPD_EXITING)) { imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_SMTP_ENQUEUE, fd, 0, -1, &euid, sizeof(euid)); break; case IMSG_STATS: if (euid) goto badcred; imsg_compose_event(&c->iev, IMSG_STATS, 0, 0, -1, env->stats, sizeof(struct stats)); break; case IMSG_CTL_SHUTDOWN: /* NEEDS_FIX */ log_debug("received shutdown request"); if (euid) goto badcred; if (env->sc_flags & SMTPD_EXITING) { imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags |= SMTPD_EXITING; imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; case IMSG_CTL_VERBOSE: { int verbose; if (euid) goto badcred; if (IMSG_DATA_SIZE(&imsg) != sizeof(verbose)) goto badcred; memcpy(&verbose, imsg.data, sizeof(verbose)); log_verbose(verbose); imsg_compose_event(env->sc_ievs[PROC_PARENT], IMSG_CTL_VERBOSE, 0, 0, -1, &verbose, sizeof(verbose)); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; } case IMSG_QUEUE_PAUSE_MDA: if (euid) goto badcred; if (env->sc_flags & SMTPD_MDA_PAUSED) { imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags |= SMTPD_MDA_PAUSED; imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_PAUSE_MDA, 0, 0, -1, NULL, 0); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; case IMSG_QUEUE_PAUSE_MTA: if (euid) goto badcred; if (env->sc_flags & SMTPD_MTA_PAUSED) { imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags |= SMTPD_MTA_PAUSED; imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_PAUSE_MTA, 0, 0, -1, NULL, 0); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; case IMSG_SMTP_PAUSE: if (euid) goto badcred; if (env->sc_flags & SMTPD_SMTP_PAUSED) { imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags |= SMTPD_SMTP_PAUSED; imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_SMTP_PAUSE, 0, 0, -1, NULL, 0); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; case IMSG_QUEUE_RESUME_MDA: if (euid) goto badcred; if (! (env->sc_flags & SMTPD_MDA_PAUSED)) { imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags &= ~SMTPD_MDA_PAUSED; imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_RESUME_MDA, 0, 0, -1, NULL, 0); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; case IMSG_QUEUE_RESUME_MTA: if (euid) goto badcred; if (!(env->sc_flags & SMTPD_MTA_PAUSED)) { imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags &= ~SMTPD_MTA_PAUSED; imsg_compose_event(env->sc_ievs[PROC_QUEUE], IMSG_QUEUE_RESUME_MTA, 0, 0, -1, NULL, 0); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; case IMSG_SMTP_RESUME: if (euid) goto badcred; if (!(env->sc_flags & SMTPD_SMTP_PAUSED)) { imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); break; } env->sc_flags &= ~SMTPD_SMTP_PAUSED; imsg_compose_event(env->sc_ievs[PROC_SMTP], IMSG_SMTP_RESUME, 0, 0, -1, NULL, 0); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; case IMSG_RUNNER_SCHEDULE: { u_int64_t ullval; if (euid) goto badcred; ullval = *(u_int64_t *)imsg.data; imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_RUNNER_SCHEDULE, 0, 0, -1, &ullval, sizeof(ullval)); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; } case IMSG_RUNNER_REMOVE: { u_int64_t ullval; if (euid) goto badcred; ullval = *(u_int64_t *)imsg.data; imsg_compose_event(env->sc_ievs[PROC_RUNNER], IMSG_RUNNER_REMOVE, 0, 0, -1, &ullval, sizeof(ullval)); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; } default: log_debug("control_dispatch_ext: " "error handling %s imsg", imsg_to_str(imsg.hdr.type)); break; } imsg_free(&imsg); continue; badcred: imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); } imsg_event_add(&c->iev); }
int main(int argc, char *argv[]) { struct sockaddr_un sun; struct parse_result *res = NULL; struct imsg imsg; struct smtpd smtpd; int ctl_sock; int done = 0; int n, verbose = 0; /* parse options */ if (strcmp(__progname, "sendmail") == 0 || strcmp(__progname, "send-mail") == 0) sendmail = 1; else if (strcmp(__progname, "mailq") == 0) { if (geteuid()) errx(1, "need root privileges"); setup_env(&smtpd); show_queue(0); return 0; } else if (strcmp(__progname, "smtpctl") == 0) { /* check for root privileges */ if (geteuid()) errx(1, "need root privileges"); setup_env(&smtpd); if ((res = parse(argc - 1, argv + 1)) == NULL) exit(1); /* handle "disconnected" commands */ switch (res->action) { case SHOW_QUEUE: show_queue(0); break; case SHOW_RUNQUEUE: break; default: goto connected; } return 0; } else errx(1, "unsupported mode"); connected: /* connect to smtpd control socket */ if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) err(1, "socket"); bzero(&sun, sizeof(sun)); sun.sun_family = AF_UNIX; strlcpy(sun.sun_path, SMTPD_SOCKET, sizeof(sun.sun_path)); if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) { if (sendmail) return enqueue_offline(argc, argv); err(1, "connect: %s", SMTPD_SOCKET); } if ((ibuf = calloc(1, sizeof(struct imsgbuf))) == NULL) err(1, NULL); imsg_init(ibuf, ctl_sock); if (sendmail) return enqueue(argc, argv); /* process user request */ switch (res->action) { case NONE: usage(); /* not reached */ case SCHEDULE: case REMOVE: { u_int64_t ulval; char *ep; errno = 0; ulval = strtoull(res->data, &ep, 16); if (res->data[0] == '\0' || *ep != '\0') errx(1, "invalid msgid/evpid"); if (errno == ERANGE && ulval == ULLONG_MAX) errx(1, "invalid msgid/evpid"); if (ulval == 0) errx(1, "invalid msgid/evpid"); if (res->action == SCHEDULE) imsg_compose(ibuf, IMSG_SCHEDULER_SCHEDULE, 0, 0, -1, &ulval, sizeof(ulval)); if (res->action == REMOVE) imsg_compose(ibuf, IMSG_SCHEDULER_REMOVE, 0, 0, -1, &ulval, sizeof(ulval)); break; } case SCHEDULE_ALL: { u_int64_t ulval = 0; imsg_compose(ibuf, IMSG_SCHEDULER_SCHEDULE, 0, 0, -1, &ulval, sizeof(ulval)); break; } case SHUTDOWN: imsg_compose(ibuf, IMSG_CTL_SHUTDOWN, 0, 0, -1, NULL, 0); break; case PAUSE_MDA: imsg_compose(ibuf, IMSG_QUEUE_PAUSE_MDA, 0, 0, -1, NULL, 0); break; case PAUSE_MTA: imsg_compose(ibuf, IMSG_QUEUE_PAUSE_MTA, 0, 0, -1, NULL, 0); break; case PAUSE_SMTP: imsg_compose(ibuf, IMSG_SMTP_PAUSE, 0, 0, -1, NULL, 0); break; case RESUME_MDA: imsg_compose(ibuf, IMSG_QUEUE_RESUME_MDA, 0, 0, -1, NULL, 0); break; case RESUME_MTA: imsg_compose(ibuf, IMSG_QUEUE_RESUME_MTA, 0, 0, -1, NULL, 0); break; case RESUME_SMTP: imsg_compose(ibuf, IMSG_SMTP_RESUME, 0, 0, -1, NULL, 0); break; case SHOW_STATS: imsg_compose(ibuf, IMSG_STATS, 0, 0, -1, NULL, 0); break; case MONITOR: /* XXX */ break; case LOG_VERBOSE: verbose = 1; /* FALLTHROUGH */ case LOG_BRIEF: imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1, &verbose, sizeof(verbose)); printf("logging request sent.\n"); done = 1; break; default: errx(1, "unknown request (%d)", res->action); } while (ibuf->w.queued) if (msgbuf_write(&ibuf->w) < 0) err(1, "write error"); while (!done) { if ((n = imsg_read(ibuf)) == -1) errx(1, "imsg_read error"); if (n == 0) errx(1, "pipe closed"); while (!done) { if ((n = imsg_get(ibuf, &imsg)) == -1) errx(1, "imsg_get error"); if (n == 0) break; switch(res->action) { case REMOVE: case SCHEDULE: case SCHEDULE_ALL: case SHUTDOWN: case PAUSE_MDA: case PAUSE_MTA: case PAUSE_SMTP: case RESUME_MDA: case RESUME_MTA: case RESUME_SMTP: case LOG_VERBOSE: case LOG_BRIEF: done = show_command_output(&imsg); break; case SHOW_STATS: done = show_stats_output(&imsg); break; case NONE: break; case MONITOR: break; default: err(1, "unexpected reply (%d)", res->action); } /* insert imsg replies switch here */ imsg_free(&imsg); } } close(ctl_sock); free(ibuf); return (0); }
int main(int argc, char *argv[]) { struct sockaddr_un sun; struct parse_result *res; struct imsg imsg; unsigned int ifidx = 0; int ctl_sock; int done = 0, verbose = 0; int n; int ch; char *sockname; sockname = OSPF6D_SOCKET; while ((ch = getopt(argc, argv, "s:")) != -1) { switch (ch) { case 's': sockname = optarg; break; default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; /* parse options */ if ((res = parse(argc, argv)) == NULL) exit(1); /* connect to ospf6d control socket */ if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) err(1, "socket"); bzero(&sun, sizeof(sun)); sun.sun_family = AF_UNIX; strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path)); if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) err(1, "connect: %s", sockname); if (pledge("stdio", NULL) == -1) err(1, "pledge"); if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) err(1, NULL); imsg_init(ibuf, ctl_sock); done = 0; /* process user request */ switch (res->action) { case NONE: usage(); /* not reached */ case SHOW: case SHOW_SUM: imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); break; case SHOW_IFACE: printf("%-11s %-29s %-6s %-10s %-10s %-8s\n", "Interface", "Address", "State", "HelloTimer", "Linkstate", "Uptime"); /*FALLTHROUGH*/ case SHOW_IFACE_DTAIL: if (*res->ifname) { ifidx = if_nametoindex(res->ifname); if (ifidx == 0) errx(1, "no such interface %s", res->ifname); } imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, &ifidx, sizeof(ifidx)); break; case SHOW_NBR: printf("%-15s %-3s %-12s %-9s %-11s %s\n", "ID", "Pri", "State", "DeadTime", "Iface","Uptime"); /*FALLTHROUGH*/ case SHOW_NBR_DTAIL: imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0); break; case SHOW_DB: imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0); break; case SHOW_DBBYAREA: imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, &res->addr, sizeof(res->addr)); break; case SHOW_DBEXT: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0); break; case SHOW_DBLINK: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_LINK, 0, 0, -1, NULL, 0); break; case SHOW_DBNET: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0); break; case SHOW_DBRTR: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0); break; case SHOW_DBINTRA: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_INTRA, 0, 0, -1, NULL, 0); break; case SHOW_DBSELF: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0); break; case SHOW_DBSUM: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0); break; case SHOW_DBASBR: imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0); break; case SHOW_RIB: printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination", "Nexthop", "Path Type", "Type", "Cost", "Uptime"); /*FALLTHROUGH*/ case SHOW_RIB_DTAIL: imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0); break; case SHOW_FIB: if (IN6_IS_ADDR_UNSPECIFIED(&res->addr)) imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1, &res->flags, sizeof(res->flags)); else imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1, &res->addr, sizeof(res->addr)); show_fib_head(); break; case FIB: errx(1, "fib couple|decouple"); break; case FIB_COUPLE: imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0); printf("couple request sent.\n"); done = 1; break; case FIB_DECOUPLE: imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0); printf("decouple request sent.\n"); done = 1; break; case LOG_VERBOSE: verbose = 1; /* FALLTHROUGH */ case LOG_BRIEF: imsg_compose(ibuf, IMSG_CTL_LOG_VERBOSE, 0, 0, -1, &verbose, sizeof(verbose)); printf("logging request sent.\n"); done = 1; break; case RELOAD: imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); printf("reload request sent.\n"); done = 1; break; } while (ibuf->w.queued) if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) err(1, "write error"); while (!done) { if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) errx(1, "imsg_read error"); if (n == 0) errx(1, "pipe closed"); while (!done) { if ((n = imsg_get(ibuf, &imsg)) == -1) errx(1, "imsg_get error"); if (n == 0) break; switch (res->action) { case SHOW: case SHOW_SUM: done = show_summary_msg(&imsg); break; case SHOW_IFACE: done = show_interface_msg(&imsg); break; case SHOW_IFACE_DTAIL: done = show_interface_detail_msg(&imsg); break; case SHOW_NBR: done = show_nbr_msg(&imsg); break; case SHOW_NBR_DTAIL: done = show_nbr_detail_msg(&imsg); break; case SHOW_DB: case SHOW_DBBYAREA: case SHOW_DBSELF: done = show_database_msg(&imsg); break; case SHOW_DBEXT: case SHOW_DBLINK: case SHOW_DBNET: case SHOW_DBRTR: case SHOW_DBINTRA: case SHOW_DBSUM: case SHOW_DBASBR: done = show_db_msg_detail(&imsg); break; case SHOW_RIB: done = show_rib_msg(&imsg); break; case SHOW_RIB_DTAIL: done = show_rib_detail_msg(&imsg); break; case SHOW_FIB: done = show_fib_msg(&imsg); break; case NONE: case FIB: case FIB_COUPLE: case FIB_DECOUPLE: case LOG_VERBOSE: case LOG_BRIEF: case RELOAD: break; } imsg_free(&imsg); } } close(ctl_sock); free(ibuf); return (0); }
int main(int argc, char *argv[]) { struct sockaddr_un sun; struct parse_result *res; struct imsg imsg; int ctl_sock; int done = 0; int n, verbose = 0; /* parse options */ if ((res = parse(argc - 1, argv + 1)) == NULL) exit(1); /* connect to relayd control socket */ if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) err(1, "socket"); bzero(&sun, sizeof(sun)); sun.sun_family = AF_UNIX; strlcpy(sun.sun_path, RELAYD_SOCKET, sizeof(sun.sun_path)); reconnect: if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) { /* Keep retrying if running in monitor mode */ if (res->action == MONITOR && (errno == ENOENT || errno == ECONNREFUSED)) { usleep(100); goto reconnect; } err(1, "connect: %s", RELAYD_SOCKET); } if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) err(1, NULL); imsg_init(ibuf, ctl_sock); done = 0; /* process user request */ switch (res->action) { case NONE: usage(); /* not reached */ case SHOW_SUM: case SHOW_HOSTS: case SHOW_RDRS: case SHOW_RELAYS: case SHOW_ROUTERS: imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); printf("%-4s\t%-8s\t%-24s\t%-7s\tStatus\n", "Id", "Type", "Name", "Avlblty"); break; case SHOW_SESSIONS: imsg_compose(ibuf, IMSG_CTL_SESSION, 0, 0, -1, NULL, 0); break; case RDR_ENABLE: imsg_compose(ibuf, IMSG_CTL_RDR_ENABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case RDR_DISABLE: imsg_compose(ibuf, IMSG_CTL_RDR_DISABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case TABLE_ENABLE: imsg_compose(ibuf, IMSG_CTL_TABLE_ENABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case TABLE_DISABLE: imsg_compose(ibuf, IMSG_CTL_TABLE_DISABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case HOST_ENABLE: imsg_compose(ibuf, IMSG_CTL_HOST_ENABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case HOST_DISABLE: imsg_compose(ibuf, IMSG_CTL_HOST_DISABLE, 0, 0, -1, &res->id, sizeof(res->id)); break; case SHUTDOWN: imsg_compose(ibuf, IMSG_CTL_SHUTDOWN, 0, 0, -1, NULL, 0); break; case POLL: imsg_compose(ibuf, IMSG_CTL_POLL, 0, 0, -1, NULL, 0); break; case LOAD: imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, res->path, strlen(res->path)); done = 1; break; case RELOAD: imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); done = 1; break; case MONITOR: imsg_compose(ibuf, IMSG_CTL_NOTIFY, 0, 0, -1, NULL, 0); break; case LOG_VERBOSE: verbose = 2; /* FALLTHROUGH */ case LOG_BRIEF: imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1, &verbose, sizeof(verbose)); printf("logging request sent.\n"); done = 1; break; } while (ibuf->w.queued) if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) err(1, "write error"); while (!done) { if ((n = imsg_read(ibuf)) == -1) errx(1, "imsg_read error"); if (n == 0) errx(1, "pipe closed"); while (!done) { if ((n = imsg_get(ibuf, &imsg)) == -1) errx(1, "imsg_get error"); if (n == 0) break; switch (res->action) { case SHOW_SUM: case SHOW_HOSTS: case SHOW_RDRS: case SHOW_RELAYS: case SHOW_ROUTERS: done = show_summary_msg(&imsg, res->action); break; case SHOW_SESSIONS: done = show_session_msg(&imsg); break; case RDR_DISABLE: case RDR_ENABLE: case TABLE_DISABLE: case TABLE_ENABLE: case HOST_DISABLE: case HOST_ENABLE: case POLL: case SHUTDOWN: done = show_command_output(&imsg); break; case NONE: case LOG_VERBOSE: case LOG_BRIEF: case RELOAD: case LOAD: break; case MONITOR: done = monitor(&imsg); break; } imsg_free(&imsg); } } close(ctl_sock); free(ibuf); return (error ? 1 : 0); }
/* ARGSUSED */ void control_dispatch_imsg(int fd, short event, void *bula) { struct ctl_conn *c; struct imsg imsg; int n; unsigned int ifidx; int verbose; if ((c = control_connbyfd(fd)) == NULL) { log_warn("control_dispatch_imsg: fd %d: not found", fd); return; } if (event & EV_READ) { if ((n = imsg_read(&c->iev.ibuf)) == -1 || n == 0) { control_close(fd); return; } } if (event & EV_WRITE) { if (msgbuf_write(&c->iev.ibuf.w) == -1 && errno != EAGAIN) { control_close(fd); return; } } for (;;) { if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) { control_close(fd); return; } if (n == 0) break; switch (imsg.hdr.type) { case IMSG_CTL_MFC_COUPLE: case IMSG_CTL_MFC_DECOUPLE: case IMSG_CTL_RELOAD: dvmrpe_imsg_compose_parent(imsg.hdr.type, 0, NULL, 0); break; case IMSG_CTL_SHOW_IFACE: if (imsg.hdr.len == IMSG_HEADER_SIZE + sizeof(ifidx)) { memcpy(&ifidx, imsg.data, sizeof(ifidx)); dvmrpe_iface_ctl(c, ifidx); imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_SHOW_IGMP: if (imsg.hdr.len == IMSG_HEADER_SIZE + sizeof(ifidx)) { memcpy(&ifidx, imsg.data, sizeof(ifidx)); dvmrpe_iface_igmp_ctl(c, ifidx); imsg_compose_event(&c->iev, IMSG_CTL_END, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_SHOW_NBR: dvmrpe_nbr_ctl(c); break; case IMSG_CTL_SHOW_RIB: case IMSG_CTL_SHOW_MFC: case IMSG_CTL_SHOW_SUM: c->iev.ibuf.pid = imsg.hdr.pid; dvmrpe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid, imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); break; case IMSG_CTL_LOG_VERBOSE: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(verbose)) break; /* forward to other processes */ dvmrpe_imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid, imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); dvmrpe_imsg_compose_rde(imsg.hdr.type, 0, imsg.hdr.pid, imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE); memcpy(&verbose, imsg.data, sizeof(verbose)); log_verbose(verbose); break; default: log_debug("control_dispatch_imsg: " "error handling imsg %d", imsg.hdr.type); break; } imsg_free(&imsg); } imsg_event_add(&c->iev); }
void dns_dispatch_imsg(int fd, short events, void *p) { struct imsg imsg; int n, cnt; char *name; struct ypldap_addr_list hn = TAILQ_HEAD_INITIALIZER(hn); struct ypldap_addr *h; struct ibuf *buf; struct env *env = p; struct imsgev *iev = env->sc_iev; struct imsgbuf *ibuf = &iev->ibuf; int shut = 0; if ((events & (EV_READ | EV_WRITE)) == 0) fatalx("unknown event"); if (events & EV_READ) { if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) fatal("imsg_read error"); if (n == 0) shut = 1; } if (events & EV_WRITE) { if ((n = msgbuf_write(&ibuf->w)) == -1 && errno != EAGAIN) fatal("msgbuf_write"); if (n == 0) shut = 1; goto done; } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) fatal("client_dispatch_imsg: imsg_get error"); if (n == 0) break; switch (imsg.hdr.type) { case IMSG_HOST_DNS: name = imsg.data; if (imsg.hdr.len < 1 + IMSG_HEADER_SIZE) fatalx("invalid IMSG_HOST_DNS received"); imsg.hdr.len -= 1 + IMSG_HEADER_SIZE; if (name[imsg.hdr.len] != '\0' || strlen(name) != imsg.hdr.len) fatalx("invalid IMSG_HOST_DNS received"); if ((cnt = host_dns(name, &hn)) == -1) break; buf = imsg_create(ibuf, IMSG_HOST_DNS, imsg.hdr.peerid, 0, cnt * sizeof(struct sockaddr_storage)); if (buf == NULL) break; if (cnt > 0) { while(!TAILQ_EMPTY(&hn)) { h = TAILQ_FIRST(&hn); TAILQ_REMOVE(&hn, h, next); imsg_add(buf, &h->ss, sizeof(h->ss)); free(h); } } imsg_close(ibuf, buf); break; default: break; } imsg_free(&imsg); } done: if (!shut) imsg_event_add(iev); else { /* this pipe is dead, so remove the event handler */ event_del(&iev->ev); event_loopexit(NULL); } }
int client_dispatch(void) { struct imsg imsg; struct msg_lock_data lockdata; struct sigaction sigact; ssize_t n, datalen; for (;;) { if ((n = imsg_get(&client_ibuf, &imsg)) == -1) fatalx("imsg_get failed"); if (n == 0) return (0); datalen = imsg.hdr.len - IMSG_HEADER_SIZE; log_debug("client got %d", imsg.hdr.type); switch (imsg.hdr.type) { case MSG_DETACH: if (datalen != 0) fatalx("bad MSG_DETACH size"); client_write_server(MSG_EXITING, NULL, 0); client_exitmsg = "detached"; break; case MSG_EXIT: if (datalen != 0) fatalx("bad MSG_EXIT size"); client_write_server(MSG_EXITING, NULL, 0); client_exitmsg = "exited"; break; case MSG_EXITED: if (datalen != 0) fatalx("bad MSG_EXITED size"); imsg_free(&imsg); return (-1); case MSG_SHUTDOWN: if (datalen != 0) fatalx("bad MSG_SHUTDOWN size"); client_write_server(MSG_EXITING, NULL, 0); client_exitmsg = "server exited"; client_exitval = 1; break; case MSG_SUSPEND: if (datalen != 0) fatalx("bad MSG_SUSPEND size"); memset(&sigact, 0, sizeof sigact); sigemptyset(&sigact.sa_mask); sigact.sa_flags = SA_RESTART; sigact.sa_handler = SIG_DFL; if (sigaction(SIGTSTP, &sigact, NULL) != 0) fatal("sigaction failed"); kill(getpid(), SIGTSTP); break; case MSG_LOCK: if (datalen != sizeof lockdata) fatalx("bad MSG_LOCK size"); memcpy(&lockdata, imsg.data, sizeof lockdata); lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0'; system(lockdata.cmd); client_write_server(MSG_UNLOCK, NULL, 0); break; default: fatalx("unexpected message"); } imsg_free(&imsg); } }
static void filter_handler(int fd, short event, void *p) { struct imsg imsg; ssize_t n; short evflags = EV_READ; enum filter_status ret; struct filter_msg fm; if (event & EV_READ) { n = imsg_read(&fi.ibuf); if (n == -1) err(1, "imsg_read"); if (n == 0) { event_del(&fi.ev); event_loopexit(NULL); return; } } if (event & EV_WRITE) { if (msgbuf_write(&fi.ibuf.w) == -1) err(1, "msgbuf_write"); if (fi.ibuf.w.queued) evflags |= EV_WRITE; } for (;;) { n = imsg_get(&fi.ibuf, &imsg); if (n == -1) errx(1, "imsg_get"); if (n == 0) break; if ((imsg.hdr.len - IMSG_HEADER_SIZE) != sizeof(fm)) errx(1, "corrupted imsg"); memcpy(&fm, imsg.data, sizeof (fm)); if (fm.version != FILTER_API_VERSION) errx(1, "API version mismatch"); switch (imsg.hdr.type) { case FILTER_CONNECT: if (fi.connect_cb == NULL) goto ignore; ret = fi.connect_cb(fm.cl_id, &fm.u.connect, fi.connect_cb_arg); break; case FILTER_HELO: if (fi.helo_cb == NULL) goto ignore; ret = fi.helo_cb(fm.cl_id, &fm.u.helo, fi.helo_cb_arg); break; case FILTER_EHLO: if (fi.ehlo_cb == NULL) goto ignore; ret = fi.ehlo_cb(fm.cl_id, &fm.u.helo, fi.ehlo_cb_arg); break; case FILTER_MAIL: if (fi.mail_cb == NULL) goto ignore; ret = fi.mail_cb(fm.cl_id, &fm.u.mail, fi.mail_cb_arg); break; case FILTER_RCPT: if (fi.rcpt_cb == NULL) goto ignore; ret = fi.rcpt_cb(fm.cl_id, &fm.u.rcpt, fi.rcpt_cb_arg); break; case FILTER_DATALINE: if (fi.dataline_cb == NULL) goto ignore; ret = fi.dataline_cb(fm.cl_id, &fm.u.dataline, fi.dataline_cb_arg); break; case FILTER_QUIT: if (fi.quit_cb == NULL) goto ignore; ret = fi.quit_cb(fm.cl_id, fi.quit_cb_arg); break; case FILTER_CLOSE: if (fi.close_cb == NULL) goto ignore; ret = fi.close_cb(fm.cl_id, fi.close_cb_arg); break; case FILTER_RSET: if (fi.rset_cb == NULL) goto ignore; ret = fi.rset_cb(fm.cl_id, fi.rset_cb_arg); break; default: errx(1, "unsupported imsg"); } switch (ret) { case STATUS_ACCEPT: case STATUS_REJECT: fm.code = ret; imsg_compose(&fi.ibuf, imsg.hdr.type, 0, 0, -1, &fm, sizeof fm); evflags |= EV_WRITE; break; case STATUS_WAITING: /* waiting for asynchronous call ... */ break; } imsg_free(&imsg); } event_set(&fi.ev, 0, evflags, filter_handler, &fi); event_add(&fi.ev, NULL); return; ignore: imsg_free(&imsg); fm.code = STATUS_IGNORE; imsg_compose(&fi.ibuf, imsg.hdr.type, 0, 0, -1, &fm, sizeof fm); evflags |= EV_WRITE; event_set(&fi.ev, 0, evflags, filter_handler, &fi); event_add(&fi.ev, NULL); }
void ctl_main(int argc, char *argv[]) { struct sockaddr_un sa; struct imsg imsg; struct imsgbuf *ibuf_ctl; int fd, n, done, ch, action; char *sockname; sockname = CTLSOCKET; if (argc < 2) { usage(); /* NOTREACHED */ } while ((ch = getopt(argc, argv, "s:")) != -1) { switch (ch) { case 's': showopt = ctl_lookup_option(optarg, ctl_showopt_list); if (showopt == NULL) { warnx("Unknown show modifier '%s'", optarg); usage(); } break; default: usage(); /* NOTREACHED */ } } action = -1; if (showopt != NULL) { switch (*showopt) { case 'p': action = CTL_SHOW_PEERS; break; case 's': action = CTL_SHOW_STATUS; break; case 'S': action = CTL_SHOW_SENSORS; break; case 'a': action = CTL_SHOW_ALL; break; } } if (action == -1) usage(); /* NOTREACHED */ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) err(1, "ntpctl: socket"); bzero(&sa, sizeof(sa)); sa.sun_family = AF_UNIX; if (strlcpy(sa.sun_path, sockname, sizeof(sa.sun_path)) >= sizeof(sa.sun_path)) errx(1, "ctl socket name too long"); if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) err(1, "connect: %s", sockname); if ((ibuf_ctl = malloc(sizeof(struct imsgbuf))) == NULL) err(1, NULL); imsg_init(ibuf_ctl, fd); switch (action) { case CTL_SHOW_STATUS: imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_STATUS, 0, 0, -1, NULL, 0); break; case CTL_SHOW_PEERS: imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_PEERS, 0, 0, -1, NULL, 0); break; case CTL_SHOW_SENSORS: imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_SENSORS, 0, 0, -1, NULL, 0); break; case CTL_SHOW_ALL: imsg_compose(ibuf_ctl, IMSG_CTL_SHOW_ALL, 0, 0, -1, NULL, 0); break; default: errx(1, "invalid action"); break; /* NOTREACHED */ } while (ibuf_ctl->w.queued) if (msgbuf_write(&ibuf_ctl->w) <= 0 && errno != EAGAIN) err(1, "ibuf_ctl: msgbuf_write error"); done = 0; while (!done) { if ((n = imsg_read(ibuf_ctl)) == -1) err(1, "ibuf_ctl: imsg_read error"); if (n == 0) errx(1, "ntpctl: pipe closed"); while (!done) { if ((n = imsg_get(ibuf_ctl, &imsg)) == -1) err(1, "ibuf_ctl: imsg_get error"); if (n == 0) break; switch (action) { case CTL_SHOW_STATUS: show_status_msg(&imsg); done = 1; break; case CTL_SHOW_PEERS: show_peer_msg(&imsg, 0); if (imsg.hdr.type == IMSG_CTL_SHOW_PEERS_END) done = 1; break; case CTL_SHOW_SENSORS: show_sensor_msg(&imsg, 0); if (imsg.hdr.type == IMSG_CTL_SHOW_SENSORS_END) done = 1; break; case CTL_SHOW_ALL: switch (imsg.hdr.type) { case IMSG_CTL_SHOW_STATUS: show_status_msg(&imsg); break; case IMSG_CTL_SHOW_PEERS: show_peer_msg(&imsg, 1); break; case IMSG_CTL_SHOW_SENSORS: show_sensor_msg(&imsg, 1); break; case IMSG_CTL_SHOW_PEERS_END: case IMSG_CTL_SHOW_SENSORS_END: /* do nothing */ break; case IMSG_CTL_SHOW_ALL_END: done=1; break; default: /* no action taken */ break; } default: /* no action taken */ break; } imsg_free(&imsg); } } close(fd); free(ibuf_ctl); exit(0); }
int main(int argc, char *argv[]) { struct sockaddr_un sun; struct parse_result *res; struct imsg imsg; int ctl_sock; int done = 0; int n; int ch; const char *sock = SNMPD_SOCKET; if ((env = calloc(1, sizeof(struct snmpd))) == NULL) err(1, "calloc"); gettimeofday(&env->sc_starttime, NULL); while ((ch = getopt(argc, argv, "ns:")) != -1) { switch (ch) { case 'n': env->sc_flags |= SNMPD_F_NONAMES; break; case 's': sock = optarg; break; default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; smi_init(); /* parse options */ if ((res = parse(argc, argv)) == NULL) exit(1); switch (res->action) { case NONE: usage(); break; case SHOW_MIB: show_mib(); break; case WALK: case GET: case BULKWALK: snmpclient(res); break; default: goto connect; } free(env); return (0); connect: /* connect to snmpd control socket */ if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) err(1, "socket"); bzero(&sun, sizeof(sun)); sun.sun_family = AF_UNIX; strlcpy(sun.sun_path, sock, sizeof(sun.sun_path)); reconnect: if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) { /* Keep retrying if running in monitor mode */ if (res->action == MONITOR && (errno == ENOENT || errno == ECONNREFUSED)) { usleep(100); goto reconnect; } err(1, "connect: %s", sock); } imsg_init(&ibuf, ctl_sock); done = 0; /* process user request */ switch (res->action) { case MONITOR: imsg_compose(&ibuf, IMSG_CTL_NOTIFY, 0, 0, -1, NULL, 0); break; case NONE: case SHOW_MIB: case WALK: case GET: case BULKWALK: break; case TRAP: /* explicitly downgrade the socket */ imsg_compose(&ibuf, IMSG_SNMP_AGENTX, 0, 0, -1, NULL, 0); break; } while (ibuf.w.queued) if (msgbuf_write(&ibuf.w) <= 0 && errno != EAGAIN) err(1, "write error"); while (!done) { if ((n = imsg_read(&ibuf)) == -1) errx(1, "imsg_read error"); if (n == 0) errx(1, "pipe closed"); while (!done) { if ((n = imsg_get(&ibuf, &imsg)) == -1) errx(1, "imsg_get error"); if (n == 0) break; switch (res->action) { case MONITOR: done = monitor(&imsg); break; case TRAP: if (imsg.hdr.type == IMSG_CTL_OK) { snmpctl_trap(ctl_sock, res); done = 1; } else errx(1, "snmpd refused connection"); break; case NONE: case SHOW_MIB: case WALK: case GET: case BULKWALK: break; } imsg_free(&imsg); } } close(ctl_sock); return (0); }
int main(int argc, char *argv[]) { struct sockaddr_un sun; struct parse_result *res; struct imsg imsg; int ctl_sock; int done = 1; int n; int ch; int v = 0; int quiet = 0; const char *sock = IKED_SOCKET; while ((ch = getopt(argc, argv, "qs:")) != -1) { switch (ch) { case 'q': quiet = 1; break; case 's': sock = optarg; break; default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; /* parse options */ if ((res = parse(argc, argv)) == NULL) exit(1); res->quiet = quiet; switch (res->action) { case CA_CREATE: case CA_DELETE: case CA_INSTALL: case CA_EXPORT: case CA_CERT_CREATE: case CA_CLIENT: case CA_SERVER: case CA_OCSP: case CA_CERT_DELETE: case CA_CERT_INSTALL: case CA_CERT_EXPORT: case CA_CERT_REVOKE: case SHOW_CA: case SHOW_CA_CERTIFICATES: case CA_KEY_CREATE: case CA_KEY_DELETE: case CA_KEY_INSTALL: case CA_KEY_IMPORT: case CA_SUBCA_CREATE: case CA_SUBCA_REVOKE: if (pledge("stdio proc exec rpath wpath cpath fattr tty", NULL) == -1) err(1, "pledge"); ca_opt(res); break; case NONE: usage(); break; default: goto connect; } return (0); connect: /* connect to iked control socket */ if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) err(1, "socket"); bzero(&sun, sizeof(sun)); sun.sun_family = AF_UNIX; strlcpy(sun.sun_path, sock, sizeof(sun.sun_path)); reconnect: if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1) { /* Keep retrying if running in monitor mode */ if (res->action == MONITOR && (errno == ENOENT || errno == ECONNREFUSED)) { usleep(100); goto reconnect; } err(1, "connect: %s", sock); } if (pledge("stdio", NULL) == -1) err(1, "pledge"); if (res->ibuf != NULL) ibuf = res->ibuf; else if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) err(1, "malloc"); imsg_init(ibuf, ctl_sock); /* process user request */ switch (res->action) { case RESETALL: v = RESET_ALL; break; case RESETCA: v = RESET_CA; break; case RESETPOLICY: v = RESET_POLICY; break; case RESETSA: v = RESET_SA; break; case RESETUSER: v = RESET_USER; break; case LOG_VERBOSE: v = 2; break; case LOG_BRIEF: default: v = 0; break; } switch (res->action) { case NONE: usage(); /* NOTREACHED */ break; case RESETALL: case RESETCA: case RESETPOLICY: case RESETSA: case RESETUSER: imsg_compose(ibuf, IMSG_CTL_RESET, 0, 0, -1, &v, sizeof(v)); printf("reset request sent.\n"); break; case LOAD: imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, res->path, strlen(res->path)); break; case RELOAD: imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0); break; case MONITOR: imsg_compose(ibuf, IMSG_CTL_NOTIFY, 0, 0, -1, NULL, 0); done = 0; break; case COUPLE: imsg_compose(ibuf, IMSG_CTL_COUPLE, 0, 0, -1, NULL, 0); break; case DECOUPLE: imsg_compose(ibuf, IMSG_CTL_DECOUPLE, 0, 0, -1, NULL, 0); break; case ACTIVE: imsg_compose(ibuf, IMSG_CTL_ACTIVE, 0, 0, -1, NULL, 0); break; case PASSIVE: imsg_compose(ibuf, IMSG_CTL_PASSIVE, 0, 0, -1, NULL, 0); break; case LOG_VERBOSE: case LOG_BRIEF: imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1, &v, sizeof(v)); printf("logging request sent.\n"); break; default: break; } while (ibuf->w.queued) if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) err(1, "write error"); while (!done) { if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) errx(1, "imsg_read error"); if (n == 0) errx(1, "pipe closed"); while (!done) { if ((n = imsg_get(ibuf, &imsg)) == -1) errx(1, "imsg_get error"); if (n == 0) break; switch (res->action) { case MONITOR: done = monitor(&imsg); break; default: break; } imsg_free(&imsg); } } close(ctl_sock); free(ibuf); return (0); }
static void mproc_dispatch(int fd, short event, void *arg) { struct mproc *p = arg; struct imsg imsg; ssize_t n; p->events = 0; if (event & EV_READ) { if (p->proc == PROC_CLIENT) n = imsg_read_nofd(&p->imsgbuf); else n = imsg_read(&p->imsgbuf); switch (n) { case -1: if (errno == EAGAIN) break; log_warn("warn: %s -> %s: imsg_read", proc_name(smtpd_process), p->name); fatal("exiting"); /* NOTREACHED */ case 0: /* this pipe is dead, so remove the event handler */ log_debug("debug: %s -> %s: pipe closed", proc_name(smtpd_process), p->name); p->handler(p, NULL); return; default: break; } } if (event & EV_WRITE) { n = msgbuf_write(&p->imsgbuf.w); if (n == 0 || (n == -1 && errno != EAGAIN)) { /* this pipe is dead, so remove the event handler */ log_debug("debug: %s -> %s: pipe closed", proc_name(smtpd_process), p->name); p->handler(p, NULL); return; } } for (;;) { if ((n = imsg_get(&p->imsgbuf, &imsg)) == -1) { if (smtpd_process == PROC_CONTROL && p->proc == PROC_CLIENT) { log_warnx("warn: client sent invalid imsg " "over control socket"); p->handler(p, NULL); return; } log_warn("fatal: %s: error in imsg_get for %s", proc_name(smtpd_process), p->name); fatalx(NULL); } if (n == 0) break; p->handler(p, &imsg); imsg_free(&imsg); } mproc_event_add(p); }
void proc_dispatch(int fd, short event, void *arg) { struct privsep_proc *p = (struct privsep_proc *)arg; struct privsep *ps = p->p_ps; struct imsgev *iev; struct imsgbuf *ibuf; struct imsg imsg; ssize_t n; int verbose; const char *title; title = ps->ps_title[privsep_process]; iev = &ps->ps_ievs[p->p_id]; ibuf = &iev->ibuf; if (event & EV_READ) { if ((n = imsg_read(ibuf)) == -1) fatal(title); 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) <= 0 && errno != EAGAIN) fatal(title); } for (;;) { if ((n = imsg_get(ibuf, &imsg)) == -1) fatal(title); if (n == 0) break; /* * Check the message with the program callback */ if ((p->p_cb)(fd, p, &imsg) == 0) { /* Message was handled by the callback, continue */ imsg_free(&imsg); continue; } /* * Generic message handling */ switch (imsg.hdr.type) { case IMSG_CTL_VERBOSE: IMSG_SIZE_CHECK(&imsg, &verbose); memcpy(&verbose, imsg.data, sizeof(verbose)); log_verbose(verbose); break; default: log_warnx("%s: %s got imsg %d", __func__, p->p_title, imsg.hdr.type); fatalx(title); } imsg_free(&imsg); } imsg_event_add(iev); }