#include #include #include #include #include #include #include #include "menu.h" #include "ui.h" #include "util.h" #define MAX_PASS 128 #define NO_OPT 0 static char pass[MAX_PASS]; static int getip(const State *state, int fd); static pid_t run(const char *cmd); static void updatestat(const State *state, unsigned typ, int pos); int menuinit(const State *state, int fd) { int rc, wfd = -1, status = 0; pid_t pid; if (state->floc) if ((wfd = open(state->floc, O_WRONLY | O_CREAT)) == -1) die ("can't open %s", state->floc); do { if (WEXITSTATUS(status)) pui(state->headerr, state->statfail); else pui(state->cmds[PASS].name, state->statstr[0]); rc = getip(state, fd); if (wfd >= 0 && rc == PASS) write(wfd, pass, strlen(pass)); pid = run(state->cmds[rc].cmd); if (rc == PASS) { pui(state->headverf, state->statverf); waitpid(pid, &status, NO_OPT); } } while (WEXITSTATUS(status) || rc != PASS); if (wfd >= 0) close(wfd); return rc; } static int getip(const State *state, int fd) { unsigned i; int rc, floor, ceil; rc = floor = ceil = PASS; if (state->cmds[DOWN].name) floor = DOWN; if (state->cmds[UP].name) ceil = UP; for (i = 0; i + 1 < MAX_PASS; ) { read(fd, pass + i, 1); if (pass[i] == DEL) { if (i > 0) --i; } else if (pass[i] == NL) { break; } else if (i >= 2 && pass[i-2] == ESC && pass[i-1] == '[' ) { if (pass[i] == 'A' && rc < ceil) ++rc; else if (pass[i] == 'B' && rc > floor) --rc; i -= 2; } else { ++i; } pheader(state->cmds[rc].name); updatestat(state, rc, i); } pass[i] = '\0'; return rc; } static void updatestat(const State *state, unsigned typ, int pos) { if (typ == PASS) { if (pos) genrandstat(state->cmds[PASS].name, state->statstr); else pstaticstat(state->cmds[PASS].name, state->statstr[0]); } else { pstaticstat(state->cmds[typ].name, state->statverf); } } static pid_t run(const char *cmd) { pid_t pid; if ((pid = fork()) == 0) { close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); execlp("sh", "sh", "-c", cmd, NULL); die("run: fork(): %s", cmd); } return pid; }