diff options
author | sinanmohd <sinan@firemail.cc> | 2023-05-22 15:25:25 +0530 |
---|---|---|
committer | sinanmohd <sinan@firemail.cc> | 2023-06-26 12:59:10 +0530 |
commit | d7ce046606ce05dd8a37e83fc48667bbe4c20093 (patch) | |
tree | 7e8d44431998e8c9d80f39165b6525866ddb5856 /menu.c |
Diffstat (limited to 'menu.c')
-rw-r--r-- | menu.c | 117 |
1 files changed, 117 insertions, 0 deletions
@@ -0,0 +1,117 @@ +#include <ctype.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <unistd.h> + +#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; +} |