ifixed buffer errors (reading, empty) - iomenu - interactive terminal-based selection menu Err bitreich.org 70 hgit clone git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu URL:git://bitreich.org/iomenu git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/iomenu bitreich.org 70 1Log /scm/iomenu/log.gph bitreich.org 70 1Files /scm/iomenu/files.gph bitreich.org 70 1Refs /scm/iomenu/refs.gph bitreich.org 70 1Tags /scm/iomenu/tag bitreich.org 70 1README /scm/iomenu/file/README.gph bitreich.org 70 1LICENSE /scm/iomenu/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit 9bdaa10a695ec2d8a9890c980bd5b44d5ff6f48c /scm/iomenu/commit/9bdaa10a695ec2d8a9890c980bd5b44d5ff6f48c.gph bitreich.org 70 1parent 8be3cf653dc554954a4170bd057a33cf2e8a0244 /scm/iomenu/commit/8be3cf653dc554954a4170bd057a33cf2e8a0244.gph bitreich.org 70 hAuthor: Josuah Demangeonā  ā µ URL:mailto:mail@josuah.net bitreich.org 70 iDate: Sat, 18 Mar 2017 10:06:42 +0100 Err bitreich.org 70 i Err bitreich.org 70 ifixed buffer errors (reading, empty) Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M iomenu.c | 108 ++++++++++++++----------------- Err bitreich.org 70 i Err bitreich.org 70 i1 file changed, 48 insertions(+), 60 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/iomenu.c b/iomenu.c /scm/iomenu/file/iomenu.c.gph bitreich.org 70 i@@ -18,8 +18,8 @@ Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i struct line { Err bitreich.org 70 i- char *text; /* sent as output and matched by input */ Err bitreich.org 70 i- int match; /* whether it matches linev's input */ Err bitreich.org 70 i+ char text[BUFSIZ]; Err bitreich.org 70 i+ int match; Err bitreich.org 70 i }; Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i@@ -33,10 +33,8 @@ char *opt_prompt = ""; Err bitreich.org 70 i void Err bitreich.org 70 i free_linev(struct line **linev) Err bitreich.org 70 i { Err bitreich.org 70 i- for (; linec > 0; linec--) { Err bitreich.org 70 i- free(linev[linec - 1]->text); Err bitreich.org 70 i+ for (; linec > 0; linec--) Err bitreich.org 70 i free(linev[linec - 1]); Err bitreich.org 70 i- } Err bitreich.org 70 i Err bitreich.org 70 i free(linev); Err bitreich.org 70 i } Err bitreich.org 70 i@@ -75,19 +73,19 @@ read_lines(void) Err bitreich.org 70 i extern struct line **linev; Err bitreich.org 70 i extern size_t linec, matching; Err bitreich.org 70 i Err bitreich.org 70 i- char s[BUFSIZ]; Err bitreich.org 70 i- size_t size = 1 << 4; Err bitreich.org 70 i+ char buffer[BUFSIZ]; Err bitreich.org 70 i+ size_t size = 1 << 6; Err bitreich.org 70 i Err bitreich.org 70 i if (!(linev = malloc(sizeof(struct line *) * size))) Err bitreich.org 70 i die("malloc"); Err bitreich.org 70 i linev[0] = NULL; Err bitreich.org 70 i Err bitreich.org 70 i /* read the file into an array of lines */ Err bitreich.org 70 i- for (; fgets(s, BUFSIZ, stdin); linec++, matching++) { Err bitreich.org 70 i- size_t len = strlen(s); Err bitreich.org 70 i+ for (; fgets(buffer, sizeof buffer, stdin); linec++, matching++) { Err bitreich.org 70 i+ size_t len = strlen(buffer); Err bitreich.org 70 i Err bitreich.org 70 i- if (len > 0 && s[len - 1] == '\n') Err bitreich.org 70 i- s[len - 1] = '\0'; Err bitreich.org 70 i+ if (len > 0 && buffer[len - 1] == '\n') Err bitreich.org 70 i+ buffer[len - 1] = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i if (linec > size) { Err bitreich.org 70 i size *= 2; Err bitreich.org 70 i@@ -99,17 +97,15 @@ read_lines(void) Err bitreich.org 70 i Err bitreich.org 70 i if (!(linev[linec] = malloc(sizeof(struct line)))) Err bitreich.org 70 i die("malloc"); Err bitreich.org 70 i- if (!(linev[linec]->text = malloc(len))) Err bitreich.org 70 i- die("malloc"); Err bitreich.org 70 i- strcpy(linev[linec]->text, s); Err bitreich.org 70 i Err bitreich.org 70 i+ strcpy(linev[linec]->text, buffer); Err bitreich.org 70 i linev[linec]->match = 1; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i-line_matches(struct line *line, char **tokv, size_t tokc) Err bitreich.org 70 i+match_line(struct line *line, char **tokv, size_t tokc) Err bitreich.org 70 i { Err bitreich.org 70 i for (size_t i = 0; i < tokc; i++) Err bitreich.org 70 i if (strstr(line->text, tokv[i]) == NULL) Err bitreich.org 70 i@@ -119,20 +115,16 @@ line_matches(struct line *line, char **tokv, size_t tokc) Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i-/* Err bitreich.org 70 i- * If inc is 1, it will only check already matching lines. Err bitreich.org 70 i- * If inc is 0, it will only check non-matching lines. Err bitreich.org 70 i- */ Err bitreich.org 70 i void Err bitreich.org 70 i-filter_lines(int inc) Err bitreich.org 70 i+filter_lines(void) Err bitreich.org 70 i { Err bitreich.org 70 i char **tokv = NULL; Err bitreich.org 70 i- char *s, buf[sizeof(input)]; Err bitreich.org 70 i+ char *s, buffer[sizeof(input)]; Err bitreich.org 70 i size_t n = 0, tokc = 0; Err bitreich.org 70 i Err bitreich.org 70 i /* tokenize input from space characters, this comes from dmenu */ Err bitreich.org 70 i- strcpy(buf, input); Err bitreich.org 70 i- for (s = strtok(buf, " "); s; s = strtok(NULL, " "), tokc++) { Err bitreich.org 70 i+ strcpy(buffer, input); Err bitreich.org 70 i+ for (s = strtok(buffer, " "); s; s = strtok(NULL, " "), tokc++) { Err bitreich.org 70 i Err bitreich.org 70 i if (tokc >= n) { Err bitreich.org 70 i tokv = realloc(tokv, ++n * sizeof(*tokv)); Err bitreich.org 70 i@@ -144,12 +136,8 @@ filter_lines(int inc) Err bitreich.org 70 i tokv[tokc] = s; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- /* match lines */ Err bitreich.org 70 i- matching = 0; Err bitreich.org 70 i- for (size_t i = 0; i < linec; i++) Err bitreich.org 70 i- /* if (!(inc ^ linev[i]->match)) */ Err bitreich.org 70 i- matching += linev[i]->match = Err bitreich.org 70 i- line_matches(linev[i], tokv, tokc); Err bitreich.org 70 i+ for (size_t i = 0, matching = 0; i < linec; i++) Err bitreich.org 70 i+ matching += linev[i]->match = match_line(linev[i], tokv, tokc); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i@@ -175,7 +163,7 @@ matching_next(size_t pos) Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-draw_line(size_t pos, const size_t cols) Err bitreich.org 70 i+print_line(size_t pos, const size_t cols) Err bitreich.org 70 i { Err bitreich.org 70 i fprintf(stderr, pos == current ? Err bitreich.org 70 i "\n\033[30;47m\033[K%s\033[m" : "\n\033[K%s", Err bitreich.org 70 i@@ -185,13 +173,13 @@ draw_line(size_t pos, const size_t cols) Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-draw_lines(size_t count, size_t cols) Err bitreich.org 70 i+print_lines(size_t count, size_t cols) Err bitreich.org 70 i { Err bitreich.org 70 i size_t printed = 0; Err bitreich.org 70 i Err bitreich.org 70 i for (size_t i = offset; printed < count && i < linec; i++) { Err bitreich.org 70 i if (linev[i]->match) { Err bitreich.org 70 i- draw_line(i, cols); Err bitreich.org 70 i+ print_line(i, cols); Err bitreich.org 70 i printed++; Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i@@ -202,7 +190,7 @@ draw_lines(size_t count, size_t cols) Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i int Err bitreich.org 70 i-draw_column(size_t pos, size_t col, size_t cols) Err bitreich.org 70 i+print_column(size_t pos, size_t col, size_t cols) Err bitreich.org 70 i { Err bitreich.org 70 i fputs(pos == current ? "\033[30;47m " : " ", stderr); Err bitreich.org 70 i Err bitreich.org 70 i@@ -229,17 +217,17 @@ draw_column(size_t pos, size_t col, size_t cols) Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-draw_columns(size_t cols) Err bitreich.org 70 i+print_columns(size_t cols) Err bitreich.org 70 i { Err bitreich.org 70 i size_t col = 20; Err bitreich.org 70 i Err bitreich.org 70 i for (size_t i = offset; col < cols; i++) Err bitreich.org 70 i- col = draw_column(i, col, cols); Err bitreich.org 70 i+ col = print_column(i, col, cols); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-draw_prompt(size_t cols) Err bitreich.org 70 i+print_prompt(size_t cols) Err bitreich.org 70 i { Err bitreich.org 70 i size_t limit = opt_lines ? cols : 20; Err bitreich.org 70 i Err bitreich.org 70 i@@ -252,7 +240,7 @@ draw_prompt(size_t cols) Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-draw_screen(int tty_fd) Err bitreich.org 70 i+print_screen(int tty_fd) Err bitreich.org 70 i { Err bitreich.org 70 i struct winsize w; Err bitreich.org 70 i size_t count; Err bitreich.org 70 i@@ -263,18 +251,18 @@ draw_screen(int tty_fd) Err bitreich.org 70 i count = MIN(opt_lines, w.ws_row - 2); Err bitreich.org 70 i Err bitreich.org 70 i if (opt_lines) { Err bitreich.org 70 i- draw_lines(count, w.ws_col); Err bitreich.org 70 i+ print_lines(count, w.ws_col); Err bitreich.org 70 i fprintf(stderr, "\033[%ldA", count); Err bitreich.org 70 i } else { Err bitreich.org 70 i- draw_columns(w.ws_col); Err bitreich.org 70 i+ print_columns(w.ws_col); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- draw_prompt(w.ws_col); Err bitreich.org 70 i+ print_prompt(w.ws_col); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i void Err bitreich.org 70 i-draw_clear(size_t lines) Err bitreich.org 70 i+print_clear(size_t lines) Err bitreich.org 70 i { Err bitreich.org 70 i for (size_t i = 0; i < lines + 1; i++) Err bitreich.org 70 i fputs("\r\033[K\n", stderr); Err bitreich.org 70 i@@ -306,9 +294,9 @@ add_character(char key) Err bitreich.org 70 i input[len + 1] = '\0'; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i- filter_lines(1); Err bitreich.org 70 i+ filter_lines(); Err bitreich.org 70 i Err bitreich.org 70 i- current = linev[0]->match ? 0 : matching_next(0); Err bitreich.org 70 i+ current = linec == 0 || linev[0]->match ? 0 : matching_next(0); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i Err bitreich.org 70 i@@ -316,15 +304,14 @@ add_character(char key) Err bitreich.org 70 i * Send the selection to stdout. Err bitreich.org 70 i */ Err bitreich.org 70 i void Err bitreich.org 70 i-print_selection(int return_input) Err bitreich.org 70 i+print_selection(void) Err bitreich.org 70 i { Err bitreich.org 70 i fputs("\r\033[K", stderr); Err bitreich.org 70 i Err bitreich.org 70 i- if (return_input || !matching) { Err bitreich.org 70 i- puts(input); Err bitreich.org 70 i- Err bitreich.org 70 i- } else if (matching > 0) { Err bitreich.org 70 i+ if (matching > 0) { Err bitreich.org 70 i puts(linev[current]->text); Err bitreich.org 70 i+ } else { Err bitreich.org 70 i+ puts(input); Err bitreich.org 70 i } Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -340,32 +327,32 @@ input_key(FILE *tty_fp) Err bitreich.org 70 i char key = fgetc(tty_fp); Err bitreich.org 70 i Err bitreich.org 70 i if (key == '\n') { Err bitreich.org 70 i- print_selection(0); Err bitreich.org 70 i+ print_selection(); Err bitreich.org 70 i return EXIT_SUCCESS; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i switch (key) { Err bitreich.org 70 i Err bitreich.org 70 i case CONTROL('C'): Err bitreich.org 70 i- draw_clear(opt_lines); Err bitreich.org 70 i+ print_clear(opt_lines); Err bitreich.org 70 i return EXIT_FAILURE; Err bitreich.org 70 i Err bitreich.org 70 i case CONTROL('U'): Err bitreich.org 70 i input[0] = '\0'; Err bitreich.org 70 i current = 0; Err bitreich.org 70 i- filter_lines(0); Err bitreich.org 70 i+ filter_lines(); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i case CONTROL('W'): Err bitreich.org 70 i remove_word_input(); Err bitreich.org 70 i- filter_lines(0); Err bitreich.org 70 i+ filter_lines(); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i case 127: Err bitreich.org 70 i case CONTROL('H'): /* backspace */ Err bitreich.org 70 i input[strlen(input) - 1] = '\0'; Err bitreich.org 70 i- filter_lines(0); Err bitreich.org 70 i- current = linev[0]->match ? 0 : matching_next(0); Err bitreich.org 70 i+ filter_lines(); Err bitreich.org 70 i+ current = linec == 0 || linev[0]->match ? 0 : matching_next(0); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i case CONTROL('N'): Err bitreich.org 70 i@@ -377,13 +364,14 @@ input_key(FILE *tty_fp) Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i case CONTROL('I'): /* tab */ Err bitreich.org 70 i- strcpy(input, linev[current]->text); Err bitreich.org 70 i- filter_lines(1); Err bitreich.org 70 i+ if (linec > 0) Err bitreich.org 70 i+ strcpy(input, linev[current]->text); Err bitreich.org 70 i+ filter_lines(); Err bitreich.org 70 i break; Err bitreich.org 70 i Err bitreich.org 70 i case CONTROL('J'): Err bitreich.org 70 i case CONTROL('M'): /* enter */ Err bitreich.org 70 i- print_selection(0); Err bitreich.org 70 i+ print_selection(); Err bitreich.org 70 i return EXIT_SUCCESS; Err bitreich.org 70 i Err bitreich.org 70 i default: Err bitreich.org 70 i@@ -407,7 +395,7 @@ input_get(int tty_fd) Err bitreich.org 70 i input[0] = '\0'; Err bitreich.org 70 i Err bitreich.org 70 i while ((exit_code = input_key(tty_fp)) == CONTINUE) Err bitreich.org 70 i- draw_screen(tty_fd); Err bitreich.org 70 i+ print_screen(tty_fd); Err bitreich.org 70 i Err bitreich.org 70 i /* resets the terminal to the previous state. */ Err bitreich.org 70 i tcsetattr(tty_fd, TCSANOW, &termio_old); Err bitreich.org 70 i@@ -456,12 +444,12 @@ main(int argc, char *argv[]) Err bitreich.org 70 i read_lines(); Err bitreich.org 70 i Err bitreich.org 70 i /* set the interface */ Err bitreich.org 70 i- draw_screen(tty_fd); Err bitreich.org 70 i+ print_screen(tty_fd); Err bitreich.org 70 i Err bitreich.org 70 i /* listen and interact to input */ Err bitreich.org 70 i exit_code = input_get(tty_fd); Err bitreich.org 70 i Err bitreich.org 70 i- draw_clear(opt_lines); Err bitreich.org 70 i+ print_clear(opt_lines); Err bitreich.org 70 i Err bitreich.org 70 i /* close files descriptors and pointers, and free memory */ Err bitreich.org 70 i close(tty_fd); Err bitreich.org 70 .