int main(int argc, char *argv[]) { /* Process command line options. */ process_opts(argc, argv); /* Verify that the scoreboard file is useable. */ verify_scoreboard_file(); /* Install signal handlers. */ signal(SIGINT, finish); signal(SIGTERM, finish); #if defined(PR_USE_NLS) && defined(HAVE_LOCALE_H) (void) setlocale(LC_ALL, ""); #endif /* Initialize the display. */ initscr(); cbreak(); noecho(); #ifndef HAVE_NCURSES nodelay(stdscr, TRUE); #endif curs_set(0); /* Paint the initial display. */ show_sessions(); /* Loop endlessly. */ for (;;) { int c = -1; #ifdef HAVE_NCURSES if (halfdelay(delay * 10) != ERR) c = getch(); #else sleep(delay); c = getch(); #endif if (c != -1) { if (tolower(c) == 'q') { break; } if (tolower(c) == 't') { toggle_mode(); } } show_sessions(); } /* done */ finish(0); return 0; }
/* ARGSUSED */ void control_dispatch_imsg(int fd, short event, void *arg) { struct control_sock *cs = arg; struct ctl_conn *c; struct imsg imsg; struct ctl_id id; int n; int verbose; struct relayd *env = cs->cs_env; 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 && errno != EAGAIN) || 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; if (c->waiting) { log_debug("%s: unexpected imsg %d", __func__, imsg.hdr.type); imsg_free(&imsg); control_close(fd, cs); return; } switch (imsg.hdr.type) { case IMSG_CTL_SHOW_SUM: show(c); break; case IMSG_CTL_SESSION: show_sessions(c); break; case IMSG_CTL_RDR_DISABLE: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (disable_rdr(c, &id)) imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_RDR_ENABLE: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (enable_rdr(c, &id)) imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_TABLE_DISABLE: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (disable_table(c, &id)) imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_TABLE_ENABLE: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (enable_table(c, &id)) imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_HOST_DISABLE: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (disable_host(c, &id, NULL)) imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_HOST_ENABLE: if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id)) fatalx("invalid imsg header len"); memcpy(&id, imsg.data, sizeof(id)); if (enable_host(c, &id, NULL)) imsg_compose_event(&c->iev, IMSG_CTL_FAIL, 0, 0, -1, NULL, 0); else { memcpy(imsg.data, &id, sizeof(id)); control_imsg_forward(&imsg); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); } break; case IMSG_CTL_SHUTDOWN: case IMSG_CTL_RELOAD: proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1); break; case IMSG_CTL_POLL: proc_compose(env->sc_ps, PROC_HCE, IMSG_CTL_POLL, NULL, 0); imsg_compose_event(&c->iev, IMSG_CTL_OK, 0, 0, -1, NULL, 0); break; 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, &verbose); memcpy(&verbose, imsg.data, sizeof(verbose)); proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1); proc_forward_imsg(env->sc_ps, &imsg, PROC_HCE, -1); proc_forward_imsg(env->sc_ps, &imsg, PROC_RELAY, -1); memcpy(imsg.data, &verbose, sizeof(verbose)); control_imsg_forward(&imsg); log_verbose(verbose); break; default: log_debug("%s: error handling imsg %d", __func__, imsg.hdr.type); break; } imsg_free(&imsg); } imsg_event_add(&c->iev); }