summaryrefslogtreecommitdiff
path: root/menu.c
diff options
context:
space:
mode:
authorsinanmohd <sinan@firemail.cc>2023-05-22 15:25:25 +0530
committersinanmohd <sinan@firemail.cc>2023-06-26 12:59:10 +0530
commitd7ce046606ce05dd8a37e83fc48667bbe4c20093 (patch)
tree7e8d44431998e8c9d80f39165b6525866ddb5856 /menu.c
initial commitHEADmaster
Diffstat (limited to 'menu.c')
-rw-r--r--menu.c117
1 files changed, 117 insertions, 0 deletions
diff --git a/menu.c b/menu.c
new file mode 100644
index 0000000..b73c745
--- /dev/null
+++ b/menu.c
@@ -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;
+}