From 0fb4f1a4435b238fafd3f9dc351a0a93c61843ff Mon Sep 17 00:00:00 2001 From: Aaron Cook Date: Mon, 6 Jun 2022 10:45:21 -0500 Subject: [PATCH] Untested session resume feature --- src/bytenuts.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/bytenuts.h | 1 + src/cheerios.c | 19 ++++++++++++++-- src/cheerios.h | 1 + src/ingest.c | 33 +++++++++++++++++++++++++++ src/ingest.h | 5 ++++ 6 files changed, 119 insertions(+), 2 deletions(-) diff --git a/src/bytenuts.c b/src/bytenuts.c index de3b57b..1382f3e 100644 --- a/src/bytenuts.c +++ b/src/bytenuts.c @@ -29,6 +29,7 @@ static int parse_args(int argc, char **argv); static int load_configs(); +static int load_state(); static speed_t string_to_speed(const char *speed); static const char *speed_to_string(speed_t speed); @@ -106,6 +107,10 @@ bytenuts_run(int argc, char **argv) cheerios_info(info); } + if (bytenuts.resume) { + load_state(); + } + pthread_mutex_lock(&bytenuts.lock); pthread_cond_wait(&bytenuts.stop_cond, &bytenuts.lock); pthread_mutex_unlock(&bytenuts.lock); @@ -334,6 +339,9 @@ parse_args(int argc, char **argv) bytenuts.config.escape = argv[i][9]; bytenuts.config_overrides[3] = 1; } + else if (!strcmp(argv[i], "--resume")) { + bytenuts.resume = 1; + } else { return -1; } @@ -383,6 +391,60 @@ load_configs() return 0; } +static int +load_state() +{ + struct stat st; + char *buf; + char *home = getenv("HOME"); + FILE *fd; + + buf = calloc(1, snprintf(NULL, 0, "%s/.config/bytenuts/inbuf.log", home) + 1); + sprintf(buf, "%s/.config/bytenuts/inbuf.log", home); + fd = fopen(buf, "r"); + stat(buf, &st); + free(buf); + + if (fd) { + char **history = NULL; + int history_len = 0; + + buf = calloc(1, st.st_size + 1); + while (fgets(buf, st.st_size+1, fd)) { + history_len++; + history = realloc(history, sizeof(char *) * history_len); + history[history_len-1] = strdup(buf); + } + fclose(fd); + + if (history) { + ingest_set_history(history); + for (int i = 0; i < history_len; i++) { + free(history[i]); + } + free(history); + } + + free(buf); + } + + buf = calloc(1, snprintf(NULL, 0, "%s/.config/bytenuts/outbuf.log", home) + 1); + sprintf(buf, "%s/.config/bytenuts/outbuf.log", home); + fd = fopen(buf, "r"); + stat(buf, &st); + free(buf); + + if (fd) { + buf = malloc(st.st_size); + fread(buf, 1, st.st_size, fd); + cheerios_insert(buf, st.st_size); + free(buf); + fclose(fd); + } + + return 0; +} + static speed_t string_to_speed(const char *speed) { diff --git a/src/bytenuts.h b/src/bytenuts.h index 12d2487..364e5b2 100644 --- a/src/bytenuts.h +++ b/src/bytenuts.h @@ -37,6 +37,7 @@ typedef struct bytenuts_struct { int serial_fd; bytenuts_config_t config; int config_overrides[4]; + int resume; WINDOW *status_win; WINDOW *out_win; WINDOW *in_win; diff --git a/src/cheerios.c b/src/cheerios.c index b41f51a..557ebae 100644 --- a/src/cheerios.c +++ b/src/cheerios.c @@ -24,6 +24,9 @@ static int newline(line_buffer_t *lines); int cheerios_start(bytenuts_t *bytenuts) { + char *home; + char *cwd; + memset(&cheerios, 0, sizeof(cheerios_t)); cheerios.output = bytenuts->out_win; @@ -40,6 +43,12 @@ cheerios_start(bytenuts_t *bytenuts) } } + cwd = getcwd(NULL, 0); + chdir(home); + cheerios.backup = fopen(".config/bytenuts/outbuf.log", "w"); + chdir(cwd); + free(cwd); + pthread_cond_init(&cheerios.cond, NULL); pthread_mutex_init(&cheerios.lock, NULL); cheerios.running = 1; @@ -321,6 +330,8 @@ cheerios_thread(void *arg) if (cheerios.log) fclose(cheerios.log); + if (cheerios.backup) + fclose(cheerios.backup); pthread_exit(NULL); return NULL; } @@ -332,8 +343,12 @@ insert_buf(line_buffer_t *lines, const char *buf, size_t len) newline(lines); for (size_t i = 0; i < len; i++) { - if (cheerios.log && cheerios.mode == CHEERIOS_MODE_NORMAL) - fwrite(&buf[i], 1, 1, cheerios.log); + if (cheerios.mode == CHEERIOS_MODE_NORMAL) { + if (cheerios.log) + fwrite(&buf[i], 1, 1, cheerios.log); + if (cheerios.backup) + fwrite(&buf[i], 1, 1, cheerios.backup); + } /* line feed starts a new row */ if (buf[i] == '\n') { diff --git a/src/cheerios.h b/src/cheerios.h index d9fc2c9..a07a3a0 100644 --- a/src/cheerios.h +++ b/src/cheerios.h @@ -35,6 +35,7 @@ typedef struct cheerios_struct { int ser_fd; line_buffer_t lines; FILE *log; + FILE *backup; bytenuts_config_t *config; volatile int mode; pthread_cond_t cond; diff --git a/src/ingest.c b/src/ingest.c index 9271a0e..56f122c 100644 --- a/src/ingest.c +++ b/src/ingest.c @@ -49,6 +49,8 @@ ingest_start(bytenuts_t *bytenuts) idx++; } + ingest.history_fd = fopen(".config/bytenuts/inbuf.log", "w"); + chdir(cwd); free(cwd); } @@ -71,6 +73,33 @@ ingest_stop() { ingest.running = 0; pthread_join(ingest.thr, NULL); + + if (ingest.history_fd) + fclose(ingest.history_fd); + + return 0; +} + +int +ingest_set_history(char **history) +{ + if (ingest.history) { + for (int i = 0; ingest.history[i] != NULL; i++) { + free(ingest.history[i]); + } + free(ingest.history); + } + + ingest.history = calloc(1, sizeof(char *)); + for (int i = 0; history[i] != NULL; i++) { + ingest.history = realloc( + ingest.history, + (i+2) * sizeof(char *) + ); + ingest.history[i] = strdup(history[i]); + ingest.history[i+1] = NULL; + } + return 0; } @@ -319,6 +348,10 @@ mode_normal(int ch) ingest.history = realloc(ingest.history, ingest.history_len * sizeof(char *)); ingest.history[ingest.history_pos] = strdup(ingest.inbuf); ingest.history_pos++; + if (ingest.history_fd) { + fwrite(ingest.inbuf, 1, strlen(ingest.inbuf), ingest.history_fd); + fwrite("\n", 1, 1, ingest.history_fd); + } } memset(ingest.inbuf, 0, sizeof(ingest.inbuf)); diff --git a/src/ingest.h b/src/ingest.h index b9fcda2..66235ad 100644 --- a/src/ingest.h +++ b/src/ingest.h @@ -3,6 +3,7 @@ #include #include +#include #include "bytenuts.h" @@ -22,6 +23,7 @@ typedef struct ingest_struct { int inpos; /* cursor position within the inbuf itself */ int inlen; /* length of the input buffer */ char **history; /* array of strings representing the command history */ + FILE *history_fd; char tmp_history[1024]; /* copy of inbuf before we load in history */ int history_len; int history_pos; /* where we currently reside in the history */ @@ -44,4 +46,7 @@ int ingest_start(bytenuts_t *bytenuts); /* stop the input window thread */ int ingest_stop(); +/* Set the the command history directly. Values are copied */ +int ingest_set_history(char **history); + #endif /* _INGEST_H_ */