diff --git a/src/chat.c b/src/chat.c index fd7c63c..ca2aa8a 100644 --- a/src/chat.c +++ b/src/chat.c @@ -1091,8 +1091,11 @@ static void chat_onInit(ToxWindow *self, Tox *m) line_info_init(ctx->hst); - if (Friends.list[self->num].logging_on) - log_enable(nick, Friends.list[self->num].pub_key, ctx->log); + log_enable(nick, Friends.list[self->num].pub_key, ctx->log); + load_chat_history(self, ctx->log); + + if (!Friends.list[self->num].logging_on) + log_disable(ctx->log); execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE); diff --git a/src/line_info.c b/src/line_info.c index 575fabf..f3e7d60 100644 --- a/src/line_info.c +++ b/src/line_info.c @@ -135,7 +135,7 @@ void line_info_add(ToxWindow *self, char *timestr, char *name1, char *name2, uin { struct history *hst = self->chatwin->hst; - if (hst->queue_sz >= MAX_QUEUE) + if (hst->queue_sz >= MAX_LINE_INFO_QUEUE) return; struct line_info *new_line = calloc(1, sizeof(struct line_info)); diff --git a/src/line_info.h b/src/line_info.h index 0524958..46d2df1 100644 --- a/src/line_info.h +++ b/src/line_info.h @@ -28,7 +28,7 @@ #define MAX_HISTORY 100000 #define MIN_HISTORY 40 -#define MAX_QUEUE 128 +#define MAX_LINE_INFO_QUEUE 512 enum { SYS_MSG, @@ -68,7 +68,7 @@ struct history { struct line_info *line_end; uint32_t start_id; /* keeps track of where line_start should be when at bottom of history */ - struct line_info *queue[MAX_QUEUE]; + struct line_info *queue[MAX_LINE_INFO_QUEUE]; int queue_sz; }; diff --git a/src/log.c b/src/log.c index c76edfa..392114d 100644 --- a/src/log.c +++ b/src/log.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "configdir.h" #include "toxic.h" @@ -30,6 +31,7 @@ #include "misc_tools.h" #include "log.h" #include "settings.h" +#include "line_info.h" extern struct user_settings *user_settings_; @@ -76,14 +78,13 @@ void init_logging_session(char *name, const char *key, struct chatlog *log) free(user_config_dir); - log->file = fopen(log_path, "a"); + log->file = fopen(log_path, "a+"); + snprintf(log->path, sizeof(log->path), "%s", log_path); if (log->file == NULL) { log->log_on = false; return; } - - fprintf(log->file, "\n*** NEW SESSION ***\n\n"); } #define LOG_FLUSH_LIMIT 1 /* limits calls to fflush to a max of one per LOG_FLUSH_LIMIT seconds */ @@ -135,3 +136,60 @@ void log_disable(struct chatlog *log) log->file = NULL; } } + +/* Loads previous history from chat log */ +void load_chat_history(ToxWindow *self, struct chatlog *log) +{ + if (log->file == NULL) + return; + + struct stat st; + + if (stat(log->path, &st) == -1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Failed to stat log file"); + return; + } + + int sz = st.st_size; + + if (sz <= 0) + return; + + char *hstbuf = malloc(sz); + + if (hstbuf == NULL) + exit_toxic_err("failed in print_prev_chat_history", FATALERR_MEMORY); + + if (fread(hstbuf, sz, 1, log->file) != 1) { + free(hstbuf); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "* Failed to read log file"); + return; + } + + /* Number of history lines to load: must not be larger than MAX_LINE_INFO_QUEUE - 2 */ + int L = MIN(MAX_LINE_INFO_QUEUE - 2, user_settings_->history_size); + int start, count = 0; + + /* start at end and backtrace L lines or to the beginning of buffer */ + for (start = sz - 1; start >= 0 && count < L; --start) { + if (hstbuf[start] == '\n') + ++count; + } + + char buf[MAX_STR_SIZE]; + const char *line = strtok(&hstbuf[start + 1], "\n"); + + if (line == NULL) { + free(hstbuf); + return; + } + + while (line != NULL) { + snprintf(buf, sizeof(buf), "%s", line); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", buf); + line = strtok(NULL, "\n"); + } + + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, ""); + free(hstbuf); +} diff --git a/src/log.h b/src/log.h index 5cca27f..2a9018b 100644 --- a/src/log.h +++ b/src/log.h @@ -26,6 +26,7 @@ struct chatlog { FILE *file; uint64_t lastwrite; + char path[MAX_STR_SIZE]; bool log_on; /* specific to current chat window */ }; @@ -41,4 +42,7 @@ void log_enable(char *name, const char *key, struct chatlog *log); /* disables logging for specified log and closes file */ void log_disable(struct chatlog *log); +/* Loads previous history from chat log */ +void load_chat_history(ToxWindow *self, struct chatlog *log); + #endif /* #define _log_h */