static int queue_proc_init(struct passwd *pw, int server, const char *conf) { uint32_t version; int fd; fd = fork_proc_backend("queue", conf, "queue-proc"); if (fd == -1) fatalx("queue-proc: exiting"); imsg_init(&ibuf, fd); version = PROC_QUEUE_API_VERSION; imsg_compose(&ibuf, PROC_QUEUE_INIT, 0, 0, -1, &version, sizeof(version)); queue_api_on_close(queue_proc_close); queue_api_on_message_create(queue_proc_message_create); queue_api_on_message_commit(queue_proc_message_commit); queue_api_on_message_delete(queue_proc_message_delete); queue_api_on_message_fd_r(queue_proc_message_fd_r); queue_api_on_message_corrupt(queue_proc_message_corrupt); queue_api_on_envelope_create(queue_proc_envelope_create); queue_api_on_envelope_delete(queue_proc_envelope_delete); queue_api_on_envelope_update(queue_proc_envelope_update); queue_api_on_envelope_load(queue_proc_envelope_load); queue_api_on_envelope_walk(queue_proc_envelope_walk); queue_proc_call(); queue_proc_end(); return (1); }
static void * table_proc_open(struct table *table) { struct table_proc_priv *priv; struct table_open_params op; int fd; priv = xcalloc(1, sizeof(*priv), "table_proc_open"); fd = fork_proc_backend("table", table->t_config, table->t_name); if (fd == -1) fatalx("table-proc: exiting"); imsg_init(&priv->ibuf, fd); memset(&op, 0, sizeof op); op.version = PROC_TABLE_API_VERSION; (void)strlcpy(op.name, table->t_name, sizeof op.name); imsg_compose(&priv->ibuf, PROC_TABLE_OPEN, 0, 0, -1, &op, sizeof op); table_proc_call(priv); table_proc_end(); return (priv); }
void client_send_identify(int flags) { struct msg_identify_data data; struct winsize ws; char *term; int fd; if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) fatal("ioctl(TIOCGWINSZ)"); data.flags = flags; if (getcwd(data.cwd, sizeof data.cwd) == NULL) *data.cwd = '\0'; term = getenv("TERM"); if (term == NULL || strlcpy(data.term, term, sizeof data.term) >= sizeof data.term) *data.term = '\0'; if ((fd = dup(STDIN_FILENO)) == -1) fatal("dup failed"); imsg_compose(&client_ibuf, MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd, &data, sizeof data); }
static int queue_proc_envelope_walk(uint64_t *evpid, char *buf, size_t len) { int r; imsg_compose(&ibuf, PROC_QUEUE_ENVELOPE_WALK, 0, 0, -1, NULL, 0); queue_proc_call(); queue_proc_read(&r, sizeof(r)); if (r > 0) { queue_proc_read(evpid, sizeof(*evpid)); if (rlen > len) { log_warnx("warn: queue-proc: buf too small"); fatalx("queue-proc: exiting"); } if (r != (int)rlen) { log_warnx("warn: queue-proc: len mismatch"); fatalx("queue-proc: exiting"); } queue_proc_read(buf, rlen); } queue_proc_end(); return (r); }
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_close(void *arg) { struct table_proc_priv *priv = arg; imsg_compose(&priv->ibuf, PROC_TABLE_CLOSE, 0, 0, -1, NULL, 0); imsg_flush(&priv->ibuf); }
static int queue_proc_init(struct passwd *pw, int server) { int sp[2]; uint32_t version; errno = 0; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) { log_warn("warn: queue-proc: socketpair"); return (0); } if ((pid = fork()) == -1) { log_warn("warn: queue-proc: fork"); goto err; } if (pid == 0) { /* child process */ dup2(sp[0], STDIN_FILENO); if (closefrom(STDERR_FILENO + 1) < 0) exit(1); execl(execpath, "queue_ramproc", NULL); err(1, "execl"); } /* parent process */ close(sp[0]); imsg_init(&ibuf, sp[1]); version = PROC_QUEUE_API_VERSION; imsg_compose(&ibuf, PROC_QUEUE_INIT, 0, 0, -1, &version, sizeof(version)); queue_api_on_message_create(queue_proc_message_create); queue_api_on_message_commit(queue_proc_message_commit); queue_api_on_message_delete(queue_proc_message_delete); queue_api_on_message_fd_r(queue_proc_message_fd_r); queue_api_on_message_corrupt(queue_proc_message_corrupt); queue_api_on_envelope_create(queue_proc_envelope_create); queue_api_on_envelope_delete(queue_proc_envelope_delete); queue_api_on_envelope_update(queue_proc_envelope_update); queue_api_on_envelope_load(queue_proc_envelope_load); queue_api_on_envelope_walk(queue_proc_envelope_walk); queue_proc_call(); queue_proc_end(); return (1); err: close(sp[0]); close(sp[1]); return (0); }
static void dispatch(struct imsgbuf* ibuf, enum exec_type program, char* msg) { int32_t status = EXEC_RESPONSE_OK; char iface[IF_NAMESIZE] = {0}; static char* buf = NULL; if(buf == NULL) { buf = malloc(EXEC_BUF_LEN); } if(buf == NULL) { die("Failed to allocate buffer"); } buf[0] = '\0'; // Check if we were provided an interface on which to operate bool have_iface = (msg != NULL) && (msg = (char*)flatjson_next(msg, iface, sizeof(iface), NULL)) != NULL && validate_iface(iface); switch(program) { case EXEC_IFCONFIG_LIST_INTERFACES: { char* const args[] = {"/sbin/ifconfig", NULL}; if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; } break; } case EXEC_IFCONFIG_LIST_PSEUDO_INTERFACES: { char* const args[] = {"/sbin/ifconfig", "-C", NULL}; if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; } break; } case EXEC_IFCONFIG_DOWN: { if(!have_iface) { status = EXEC_RESPONSE_ERROR; break; } char* const args[] = {"/sbin/ifconfig", iface, "down", NULL}; if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; } break; } case EXEC_NETSTART: { if(!have_iface) { status = EXEC_RESPONSE_ERROR; break; } char* const args[] = {"/bin/sh", "/etc/netstart", iface, NULL}; if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; } break; } case EXEC_LOGEVENT: { char* const args[] = {"/usr/libexec/loghwevent", msg, NULL}; if(run_and_read(args, buf) > 0) { status = EXEC_RESPONSE_ERROR; } break; } default: warn("Unknown exec mode"); break; } imsg_compose(ibuf, status, 0, 0, -1, buf, strlen(buf) + 1); imsg_flush(ibuf); }
void server_write_client( struct client *c, enum msgtype type, const void *buf, size_t len) { struct imsgbuf *ibuf = &c->ibuf; if (c->flags & CLIENT_BAD) return; log_debug("writing %d to client %d", type, c->ibuf.fd); imsg_compose(ibuf, type, PROTOCOL_VERSION, -1, -1, (void *) buf, len); }
static void * table_proc_open(struct table *table) { int sp[2]; struct table_proc_priv *priv; char *environ_new[2]; struct table_open_params op; errno = 0; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) { log_warn("warn: table-proc: socketpair"); return (NULL); } priv = xcalloc(1, sizeof(*priv), "table_proc_open"); if ((priv->pid = fork()) == -1) { log_warn("warn: table-proc: fork"); goto err; } if (priv->pid == 0) { /* child process */ dup2(sp[0], STDIN_FILENO); if (closefrom(STDERR_FILENO + 1) < 0) exit(1); environ_new[0] = "PATH=" _PATH_DEFPATH; environ_new[1] = (char *)NULL; environ = environ_new; execle("/bin/sh", "/bin/sh", "-c", table->t_config, (char *)NULL, environ_new); fatal("execl"); } /* parent process */ close(sp[0]); imsg_init(&priv->ibuf, sp[1]); memset(&op, 0, sizeof op); op.version = PROC_TABLE_API_VERSION; (void)strlcpy(op.name, table->t_name, sizeof op.name); imsg_compose(&priv->ibuf, PROC_TABLE_OPEN, 0, 0, -1, &op, sizeof op); table_proc_call(priv); table_proc_end(); return (priv); err: free(priv); close(sp[0]); close(sp[1]); return (NULL); }
static int queue_proc_message_fd_r(uint32_t msgid) { imsg_compose(&ibuf, PROC_QUEUE_MESSAGE_FD_R, 0, 0, -1, &msgid, sizeof(msgid)); queue_proc_call(); queue_proc_end(); return (imsg.fd); }
void control_imsg_forward(struct imsg *imsg) { struct ctl_conn *c; TAILQ_FOREACH(c, &ctl_conns, entry) if (c->flags & CTL_CONN_NOTIFY) imsg_compose(&c->iev.ibuf, imsg->hdr.type, 0, imsg->hdr.pid, -1, imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE); }
int imsgev_compose(struct imsgev *iev, u_int16_t type, u_int32_t peerid, uint32_t pid, int fd, void *data, u_int16_t datalen) { int r; r = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen); if (r != -1) imsgev_add(iev); return (r); }
int imsg_compose_event(struct imsgev *iev, u_int16_t type, u_int32_t peerid, pid_t pid, int fd, void *data, u_int16_t datalen) { int ret; if ((ret = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data, datalen)) == -1) return (ret); imsg_event_add(iev); return (ret); }
static int queue_proc_close(void) { int r; imsg_compose(&ibuf, PROC_QUEUE_MESSAGE_CORRUPT, 0, 0, -1, NULL, 0); queue_proc_call(); queue_proc_read(&r, sizeof(r)); queue_proc_end(); return (r); }
static int table_proc_update(struct table *table) { struct table_proc_priv *priv = table->t_handle; int r; imsg_compose(&priv->ibuf, PROC_TABLE_UPDATE, 0, 0, -1, NULL, 0); table_proc_call(priv); table_proc_read(&r, sizeof(r)); table_proc_end(); return (r); }
static int queue_proc_message_corrupt(uint32_t msgid) { int r; imsg_compose(&ibuf, PROC_QUEUE_MESSAGE_CORRUPT, 0, 0, -1, &msgid, sizeof(msgid)); queue_proc_call(); queue_proc_read(&r, sizeof(r)); queue_proc_end(); return (r); }
static int queue_proc_envelope_delete(uint64_t evpid) { int r; imsg_compose(&ibuf, PROC_QUEUE_ENVELOPE_DELETE, 0, 0, -1, &evpid, sizeof(evpid)); queue_proc_call(); queue_proc_read(&r, sizeof(r)); queue_proc_end(); return (r); }
static int scheduler_proc_init(void) { int sp[2], r; uint32_t version; errno = 0; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) < 0) { log_warn("warn: scheduler-proc: socketpair"); goto err; } if ((pid = fork()) == -1) { log_warn("warn: scheduler-proc: fork"); goto err; } if (pid == 0) { /* child process */ dup2(sp[0], STDIN_FILENO); if (closefrom(STDERR_FILENO + 1) < 0) exit(1); execl(execpath, "scheduler-proc", NULL); err(1, "execl"); } /* parent process */ close(sp[0]); imsg_init(&ibuf, sp[1]); version = PROC_SCHEDULER_API_VERSION; imsg_compose(&ibuf, PROC_SCHEDULER_INIT, 0, 0, -1, &version, sizeof(version)); scheduler_proc_call(); scheduler_proc_read(&r, sizeof(r)); scheduler_proc_end(); return (r); err: close(sp[0]); close(sp[1]); fatalx("scheduler-proc: exiting"); return (0); }
static int scheduler_proc_insert(struct scheduler_info *si) { int r; log_debug("debug: scheduler-proc: PROC_SCHEDULER_INSERT"); imsg_compose(&ibuf, PROC_SCHEDULER_INSERT, 0, 0, -1, si, sizeof(*si)); scheduler_proc_call(); scheduler_proc_read(&r, sizeof(r)); scheduler_proc_end(); return (r); }
static int queue_proc_message_create(uint32_t *msgid) { int r; imsg_compose(&ibuf, PROC_QUEUE_MESSAGE_CREATE, 0, 0, -1, NULL, 0); queue_proc_call(); queue_proc_read(&r, sizeof(r)); if (r == 1) queue_proc_read(msgid, sizeof(*msgid)); queue_proc_end(); return (r); }
void m_close(struct mproc *p) { if (imsg_compose(&p->imsgbuf, p->m_type, p->m_peerid, p->m_pid, p->m_fd, p->m_buf, p->m_pos) == -1) fatal("imsg_compose"); log_trace(TRACE_MPROC, "mproc: %s -> %s : %zu %s", proc_name(smtpd_process), proc_name(p->proc), p->m_pos, imsg_to_str(p->m_type)); mproc_event_add(p); }
void m_compose(struct mproc *p, uint32_t type, uint32_t peerid, pid_t pid, int fd, void *data, size_t len) { imsg_compose(&p->imsgbuf, type, peerid, pid, fd, data, len); if (type != IMSG_STAT_DECREMENT && type != IMSG_STAT_INCREMENT) log_trace(TRACE_MPROC, "mproc: %s -> %s : %zu %s", proc_name(smtpd_process), proc_name(p->proc), len, imsg_to_str(type)); mproc_event_add(p); }
static int scheduler_proc_delete(uint64_t evpid) { int r; log_debug("debug: scheduler-proc: PROC_SCHEDULER_DELETE"); imsg_compose(&ibuf, PROC_SCHEDULER_DELETE, 0, 0, -1, &evpid, sizeof(evpid)); scheduler_proc_call(); scheduler_proc_read(&r, sizeof(r)); scheduler_proc_end(); return (r); }
static size_t scheduler_proc_rollback(uint32_t msgid) { size_t s; log_debug("debug: scheduler-proc: PROC_SCHEDULER_ROLLBACK"); imsg_compose(&ibuf, PROC_SCHEDULER_ROLLBACK, 0, 0, -1, &msgid, sizeof(msgid)); scheduler_proc_call(); scheduler_proc_read(&s, sizeof(s)); scheduler_proc_end(); return (s); }
void m_flush(struct mproc *p) { if (imsg_compose(&p->imsgbuf, p->m_type, p->m_peerid, p->m_pid, p->m_fd, p->m_buf, p->m_pos) == -1) fatal("imsg_compose"); log_trace(TRACE_MPROC, "mproc: %s -> %s : %zu %s (flush)", proc_name(smtpd_process), proc_name(p->proc), p->m_pos, imsg_to_str(p->m_type)); p->m_pos = 0; imsg_flush(&p->imsgbuf); }
void m_forward(struct mproc *p, struct imsg *imsg) { imsg_compose(&p->imsgbuf, imsg->hdr.type, imsg->hdr.peerid, imsg->hdr.pid, imsg->fd, imsg->data, imsg->hdr.len - sizeof(imsg->hdr)); if (imsg->hdr.type != IMSG_STAT_DECREMENT && imsg->hdr.type != IMSG_STAT_INCREMENT) log_trace(TRACE_MPROC, "mproc: %s -> %s : %zu %s (forward)", proc_name(smtpd_process), proc_name(p->proc), imsg->hdr.len - sizeof(imsg->hdr), imsg_to_str(imsg->hdr.type)); mproc_event_add(p); }
static int scheduler_proc_update(struct scheduler_info *si) { int r; log_debug("debug: scheduler-proc: PROC_SCHEDULER_UPDATE"); imsg_compose(&ibuf, PROC_SCHEDULER_UPDATE, 0, 0, -1, si, sizeof(*si)); scheduler_proc_call(); scheduler_proc_read(&r, sizeof(r)); if (r == 1) scheduler_proc_read(si, sizeof(*si)); scheduler_proc_end(); return (r); }
int proc_send(struct tmuxpeer *peer, enum msgtype type, int fd, const void *buf, size_t len) { struct imsgbuf *ibuf = &peer->ibuf; void *vp = (void *)buf; int retval; if (peer->flags & PEER_BAD) return (-1); log_debug("sending message %d to peer %p (%zu bytes)", type, peer, len); retval = imsg_compose(ibuf, type, PROTOCOL_VERSION, -1, fd, vp, len); if (retval != 1) return (-1); proc_update_event(peer); return (0); }
/* * 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; }