diff --git a/src/chat.c b/src/chat.c index 32419d2..eee0d5f 100644 --- a/src/chat.c +++ b/src/chat.c @@ -1330,6 +1330,29 @@ static void chat_onDraw(ToxWindow *self, Tox *m) pthread_mutex_unlock(&Winthread.lock); } +static void chat_init_log(ToxWindow *self, Tox *m, const char *self_nick) +{ + ChatContext *ctx = self->chatwin; + + char myid[TOX_ADDRESS_SIZE]; + tox_self_get_address(m, (uint8_t *) myid); + + if (log_init(ctx->log, self_nick, myid, Friends.list[self->num].pub_key, LOG_TYPE_CHAT) != 0) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to initialize chat log."); + return; + } + + if (load_chat_history(self, ctx->log) != 0) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to load chat history."); + } + + if (Friends.list[self->num].logging_on) { + if (log_enable(ctx->log) != 0) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to enable chat log."); + } + } +} + static void chat_onInit(ToxWindow *self, Tox *m) { curs_set(1); @@ -1380,19 +1403,9 @@ static void chat_onInit(ToxWindow *self, Tox *m) line_info_init(ctx->hst); - char myid[TOX_ADDRESS_SIZE]; - tox_self_get_address(m, (uint8_t *) myid); + chat_init_log(self, m, nick); - int log_ret = log_enable(nick, myid, Friends.list[self->num].pub_key, ctx->log, LOG_CHAT); - load_chat_history(self, ctx->log); - - if (!Friends.list[self->num].logging_on) { - log_disable(ctx->log); - } else if (log_ret == -1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Warning: Log failed to initialize."); - } - - execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE); + execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE); // Print log status to screen scrollok(ctx->history, 0); wmove(self->window, y2 - CURS_Y_OFFSET, 0); diff --git a/src/conference.c b/src/conference.c index 863b85f..2a3263c 100644 --- a/src/conference.c +++ b/src/conference.c @@ -114,6 +114,25 @@ static const char *conference_cmd_list[] = { static ToxWindow *new_conference_chat(uint32_t conferencenum); +void conference_set_title(ToxWindow *self, uint32_t conferencesnum, const char *title, size_t length) +{ + ConferenceChat *chat = &conferences[conferencesnum]; + + if (!chat->active) { + return; + } + + if (length > CONFERENCE_MAX_TITLE_LENGTH) { + length = CONFERENCE_MAX_TITLE_LENGTH; + } + + memcpy(chat->title, title, length); + chat->title[length] = 0; + chat->title_length = length; + + set_window_title(self, title, length); +} + static void kill_conference_window(ToxWindow *self) { ChatContext *ctx = self->chatwin; @@ -130,8 +149,35 @@ static void kill_conference_window(ToxWindow *self) del_window(self); } -int init_conference_win(Tox *m, uint32_t conferencenum, uint8_t type, const char *title, - size_t title_length) +static void init_conference_logging(ToxWindow *self, Tox *m, uint32_t conferencenum) +{ + ChatContext *ctx = self->chatwin; + + char my_id[TOX_ADDRESS_SIZE]; + tox_self_get_address(m, (uint8_t *) my_id); + + char conference_id[TOX_CONFERENCE_ID_SIZE]; + tox_conference_get_id(m, conferencenum, (uint8_t *) conference_id); + + if (log_init(ctx->log, conferences[conferencenum].title, my_id, conference_id, LOG_TYPE_CHAT) != 0) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Warning: Log failed to initialize."); + return; + } + + if (load_chat_history(self, ctx->log) != 0) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to load chat history."); + } + + if (user_settings->autolog == AUTOLOG_ON) { + if (log_enable(ctx->log) != 0) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to enable chat log."); + } + } + + execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE); // print log state to screen +} + +int init_conference_win(Tox *m, uint32_t conferencenum, uint8_t type, const char *title, size_t length) { if (conferencenum > MAX_CONFERENCE_NUM) { return -1; @@ -155,7 +201,10 @@ int init_conference_win(Tox *m, uint32_t conferencenum, uint8_t type, const char conferences[i].last_sent_audio = 0; set_active_window_index(conferences[i].chatwin); - set_window_title(self, title, title_length); + + conference_set_title(self, conferencenum, title, length); + + init_conference_logging(self, m, conferencenum); if (i == max_conference_index) { ++max_conference_index; @@ -225,6 +274,25 @@ static void delete_conference(ToxWindow *self, Tox *m, uint32_t conferencenum) free_conference(self, conferencenum); } +void conference_rename_log_path(Tox *m, uint32_t conferencenum, const char *new_title) +{ + ConferenceChat *chat = &conferences[conferencenum]; + + if (!chat->active) { + return; + } + + char myid[TOX_ADDRESS_SIZE]; + tox_self_get_address(m, (uint8_t *) myid); + + char conference_id[TOX_CONFERENCE_ID_SIZE]; + tox_conference_get_id(m, conferencenum, (uint8_t *) conference_id); + + if (rename_logfile(chat->title, new_title, myid, conference_id, chat->chatwin) != 0) { + fprintf(stderr, "Failed to rename conference log to `%s`\n", new_title); + } +} + /* destroys and re-creates conference window with or without the peerlist */ void redraw_conference_win(ToxWindow *self) { @@ -319,13 +387,21 @@ static void conference_onConferenceTitleChange(ToxWindow *self, Tox *m, uint32_t return; } - set_window_title(self, title, length); + ConferenceChat *chat = &conferences[conferencenum]; + + if (!chat->active) { + return; + } + + conference_rename_log_path(m, conferencenum, title); // must be called first + + conference_set_title(self, conferencenum, title, length); char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); /* don't announce title when we join the room */ - if (!timed_out(conferences[self->num].start_time, CONFERENCE_EVENT_WAIT)) { + if (!timed_out(conferences[conferencenum].start_time, CONFERENCE_EVENT_WAIT)) { return; } @@ -1038,17 +1114,6 @@ static void conference_onInit(ToxWindow *self, Tox *m) line_info_init(ctx->hst); - if (user_settings->autolog == AUTOLOG_ON) { - char myid[TOX_ADDRESS_SIZE]; - tox_self_get_address(m, (uint8_t *) myid); - - if (log_enable(self->name, myid, NULL, ctx->log, LOG_CONFERENCE) == -1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Warning: Log failed to initialize."); - } - } - - execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE); - scrollok(ctx->history, 0); wmove(self->window, y2 - CURS_Y_OFFSET, 0); } diff --git a/src/conference.h b/src/conference.h index 6a12684..726fb36 100644 --- a/src/conference.h +++ b/src/conference.h @@ -27,8 +27,9 @@ #include "windows.h" #define SIDEBAR_WIDTH 16 -#define MAX_CONFERENCE_NUM MAX_WINDOWS_NUM - 2 +#define MAX_CONFERENCE_NUM (MAX_WINDOWS_NUM - 2) #define CONFERENCE_EVENT_WAIT 3 +#define CONFERENCE_MAX_TITLE_LENGTH TOX_MAX_NAME_LENGTH typedef struct ConferencePeer { bool active; @@ -64,6 +65,9 @@ typedef struct { int side_pos; /* current position of the sidebar - used for scrolling up and down */ time_t start_time; + char title[CONFERENCE_MAX_TITLE_LENGTH + 1]; + size_t title_length; + ConferencePeer *peer_list; uint32_t max_idx; @@ -79,11 +83,15 @@ typedef struct { /* Frees all Toxic associated data structures for a conference (does not call tox_conference_delete() ) */ void free_conference(ToxWindow *self, uint32_t conferencenum); -int init_conference_win(Tox *m, uint32_t conferencenum, uint8_t type, const char *title, size_t title_length); +int init_conference_win(Tox *m, uint32_t conferencenum, uint8_t type, const char *title, size_t length); /* destroys and re-creates conference window with or without the peerlist */ void redraw_conference_win(ToxWindow *self); +void conference_set_title(ToxWindow *self, uint32_t conferencesnum, const char *title, size_t length); +void conference_rename_log_path(Tox *m, uint32_t conferencenum, const char *new_title); +int conference_enable_logging(ToxWindow *self, Tox *m, uint32_t conferencenum, struct chatlog *log); + /* Puts `(NameListEntry *)`s in `entries` for each matched peer, up to a maximum * of `maxpeers`. * Maches each peer whose name or pubkey begins with `prefix`. diff --git a/src/conference_commands.c b/src/conference_commands.c index 4bd9f2d..e9ad7e9 100644 --- a/src/conference_commands.c +++ b/src/conference_commands.c @@ -40,7 +40,7 @@ void cmd_conference_set_title(WINDOW *window, ToxWindow *self, Tox *m, int argc, UNUSED_VAR(window); Tox_Err_Conference_Title err; - char title[MAX_STR_SIZE]; + char title[CONFERENCE_MAX_TITLE_LENGTH + 1]; if (argc < 1) { size_t tlen = tox_conference_get_title_size(m, self->num, &err); @@ -61,15 +61,23 @@ void cmd_conference_set_title(WINDOW *window, ToxWindow *self, Tox *m, int argc, return; } + size_t len = strlen(argv[1]); + + if (len >= sizeof(title)) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set title: max length exceeded."); + return; + } + snprintf(title, sizeof(title), "%s", argv[1]); - int len = strlen(title); if (!tox_conference_set_title(m, self->num, (uint8_t *) title, len, &err)) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set title (error %d)", err); return; } - set_window_title(self, title, len); + conference_rename_log_path(m, self->num, title); // must be called first + + conference_set_title(self, self->num, title, len); char timefrmt[TIME_STR_SIZE]; char selfnick[TOX_MAX_NAME_LENGTH]; diff --git a/src/friendlist.c b/src/friendlist.c index 42a88f5..60821e5 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -453,7 +453,9 @@ static void friendlist_onNickChange(ToxWindow *self, Tox *m, uint32_t num, const tox_self_get_address(m, (uint8_t *) myid); if (strcmp(oldname, newnamecpy) != 0) { - rename_logfile(oldname, newnamecpy, myid, Friends.list[num].pub_key, Friends.list[num].chatwin); + if (rename_logfile(oldname, newnamecpy, myid, Friends.list[num].pub_key, Friends.list[num].chatwin) != 0) { + fprintf(stderr, "Failed to rename friend chat log from `%s` to `%s`\n", oldname, newnamecpy); + } } sort_friendlist_index(); diff --git a/src/global_commands.c b/src/global_commands.c index 6918465..bc017cb 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -434,21 +434,7 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX const char *swch = argv[1]; if (!strcmp(swch, "1") || !strcmp(swch, "on")) { - char myid[TOX_ADDRESS_SIZE]; - tox_self_get_address(m, (uint8_t *) myid); - - int log_ret = -1; - - if (self->type == WINDOW_TYPE_CHAT) { - Friends.list[self->num].logging_on = true; - log_ret = log_enable(self->name, myid, Friends.list[self->num].pub_key, log, LOG_CHAT); - } else if (self->type == WINDOW_TYPE_PROMPT) { - log_ret = log_enable(self->name, myid, NULL, log, LOG_PROMPT); - } else if (self->type == WINDOW_TYPE_CONFERENCE) { - log_ret = log_enable(self->name, myid, NULL, log, LOG_CONFERENCE); - } - - msg = log_ret == 0 ? "Logging enabled." : "Warning: Log failed to initialize."; + msg = log_enable(log) == 0 ? "Logging enabled." : "Warning: Failed to enable log."; line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg); return; } else if (!strcmp(swch, "0") || !strcmp(swch, "off")) { diff --git a/src/log.c b/src/log.c index 0d0eab7..4460500 100644 --- a/src/log.c +++ b/src/log.c @@ -35,29 +35,33 @@ extern struct user_settings *user_settings; -/* There are three types of logs: chat logs, conference logs, and prompt logs (see LOG_TYPE in log.h) - A prompt log is in the format: LOGDIR/selfkey-home.log - A chat log is in the format: LOGDIR/selfkey-friendname-otherkey.log - A conference log is in the format: LOGDIR/selfkey-conferencename-date[time].log - - Only the first (KEY_IDENT_DIGITS * 2) numbers of the key are used. - - Returns 0 on success, -1 if the path is too long */ -static int get_log_path(char *dest, int destsize, char *name, const char *selfkey, const char *otherkey, int logtype) +/* Creates a log path and puts it in `dest. + * + * There are two types of logs: chat logs and prompt logs (see LOG_TYPE in log.h) + * A prompt log is in the format: LOGDIR/selfkey-home.log + * A chat log is in the format: LOGDIR/selfkey-name-otherkey.log + * + * For friend chats `otherkey` is the first 6 bytes of the friend's Tox ID. + * For Conferences/groups `otherkey` is the first 6 bytes of the group's unique ID. + * + * Return path length on success. + * Return -1 if the path is too long. + */ +static int get_log_path(char *dest, int destsize, const char *name, const char *selfkey, const char *otherkey) { if (!valid_nick(name)) { name = UNKNOWN_NAME; } - const char *namedash = logtype == LOG_PROMPT ? "" : "-"; + const char *namedash = otherkey ? "-" : ""; const char *set_path = user_settings->chatlogs_path; char *user_config_dir = get_user_config_dir(); int path_len = strlen(name) + strlen(".log") + strlen("-") + strlen(namedash); path_len += strlen(set_path) ? *set_path : strlen(user_config_dir) + strlen(LOGDIR); - /* first 6 digits of selfkey */ - char self_id[32]; + /* first 6 bytes of selfkey */ + char self_id[32] = {0}; path_len += KEY_IDENT_DIGITS * 2; sprintf(&self_id[0], "%02X", selfkey[0] & 0xff); sprintf(&self_id[2], "%02X", selfkey[1] & 0xff); @@ -66,19 +70,13 @@ static int get_log_path(char *dest, int destsize, char *name, const char *selfke char other_id[32] = {0}; - switch (logtype) { - case LOG_CHAT: - path_len += KEY_IDENT_DIGITS * 2; - sprintf(&other_id[0], "%02X", otherkey[0] & 0xff); - sprintf(&other_id[2], "%02X", otherkey[1] & 0xff); - sprintf(&other_id[4], "%02X", otherkey[2] & 0xff); - other_id[KEY_IDENT_DIGITS * 2] = '\0'; - break; - - case LOG_CONFERENCE: - strftime(other_id, sizeof(other_id), "%Y-%m-%d[%H:%M:%S]", get_time()); - path_len += strlen(other_id); - break; + if (otherkey) { + /* first 6 bytes of otherkey */ + path_len += KEY_IDENT_DIGITS * 2; + sprintf(&other_id[0], "%02X", otherkey[0] & 0xff); + sprintf(&other_id[2], "%02X", otherkey[1] & 0xff); + sprintf(&other_id[4], "%02X", otherkey[2] & 0xff); + other_id[KEY_IDENT_DIGITS * 2] = '\0'; } if (path_len >= destsize) { @@ -94,28 +92,35 @@ static int get_log_path(char *dest, int destsize, char *name, const char *selfke free(user_config_dir); - return 0; + return path_len; } -/* Opens log file or creates a new one */ -static int init_logging_session(char *name, const char *selfkey, const char *otherkey, struct chatlog *log, int logtype) +/* Initializes log path for `log`. + * + * Return 0 on success. + * Return -1 on failure. + */ +static int init_logging_session(const char *name, const char *selfkey, const char *otherkey, struct chatlog *log, + LOG_TYPE type) { - if (selfkey == NULL || (logtype == LOG_CHAT && otherkey == NULL)) { + if (log == NULL) { + return -1; + } + + if (selfkey == NULL || (type == LOG_TYPE_CHAT && otherkey == NULL)) { return -1; } char log_path[MAX_STR_SIZE]; - if (get_log_path(log_path, sizeof(log_path), name, selfkey, otherkey, logtype) == -1) { + int path_len = get_log_path(log_path, sizeof(log_path), name, selfkey, otherkey); + + if (path_len == -1 || path_len >= sizeof(log->path)) { return -1; } - log->file = fopen(log_path, "a+"); - snprintf(log->path, sizeof(log->path), "%s", log_path); - - if (log->file == NULL) { - return -1; - } + memcpy(log->path, log_path, path_len); + log->path[path_len] = 0; return 0; } @@ -124,6 +129,10 @@ static int init_logging_session(char *name, const char *selfkey, const char *oth void write_to_log(const char *msg, const char *name, struct chatlog *log, bool event) { + if (log == NULL) { + return; + } + if (!log->log_on) { return; } @@ -154,94 +163,162 @@ void write_to_log(const char *msg, const char *name, struct chatlog *log, bool e void log_disable(struct chatlog *log) { - if (log->file != NULL) { - fclose(log->file); + if (log == NULL) { + return; } - *log = (struct chatlog) { - 0 - }; + if (log->file != NULL) { + fclose(log->file); + log->file = NULL; + } + + log->lastwrite = 0; + log->log_on = false; } -int log_enable(char *name, const char *selfkey, const char *otherkey, struct chatlog *log, int logtype) +int log_enable(struct chatlog *log) { - log->log_on = true; + if (log == NULL) { + return -1; + } - if (log->file != NULL) { + if (log->log_on) { return 0; } - if (init_logging_session(name, selfkey, otherkey, log, logtype) == -1) { - log_disable(log); + if (*log->path == 0) { return -1; } + if (log->file != NULL) { + return -1; + } + + log->file = fopen(log->path, "a+"); + + if (log->file == NULL) { + return -1; + } + + log->log_on = true; + return 0; } -/* Loads previous history from chat log */ -void load_chat_history(ToxWindow *self, struct chatlog *log) +/* Initializes a log. This function must be called before any other logging operations. + * + * Return 0 on success. + * Return -1 on failure. + */ +int log_init(struct chatlog *log, const char *name, const char *selfkey, const char *otherkey, LOG_TYPE type) { - if (log->file == NULL) { - return; + if (log == NULL) { + return -1; + } + + if (log->file != NULL || log->log_on) { + fprintf(stderr, "Warning: Called log_init() on an already initialized log\n"); + return -1; + } + + if (init_logging_session(name, selfkey, otherkey, log, type) == -1) { + return -1; + } + + log_disable(log); + + return 0; +} + +/* Loads chat log history and prints it to `self` window. + * + * Return 0 on success or if log file doesn't exist. + * Return -1 on failure. + */ +int load_chat_history(ToxWindow *self, struct chatlog *log) +{ + if (log == NULL) { + return -1; + } + + if (*log->path == 0) { + return -1; } off_t sz = file_size(log->path); if (sz <= 0) { - return; + return 0; } - char *hstbuf = malloc(sz + 1); + FILE *fp = fopen(log->path, "r"); - if (hstbuf == NULL) { - exit_toxic_err("failed in load_chat_history", FATALERR_MEMORY); + if (fp == NULL) { + return -1; } - if (fseek(log->file, 0L, SEEK_SET) == -1) { - free(hstbuf); - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, " * Failed to read log file"); - return; + char *buf = malloc(sz + 1); + + if (buf == NULL) { + fclose(fp); + return -1; } - 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; + if (fseek(fp, 0L, SEEK_SET) == -1) { + free(buf); + fclose(fp); + return -1; } - hstbuf[sz] = '\0'; + if (fread(buf, sz, 1, fp) != 1) { + free(buf); + fclose(fp); + return -1; + } + + fclose(fp); + + buf[sz] = 0; /* 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; + + int start = 0; + int 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') { + if (buf[start] == '\n') { ++count; } } - const char *line = strtok(&hstbuf[start + 1], "\n"); + char *tmp = NULL; + const char *line = strtok_r(&buf[start + 1], "\n", &tmp); if (line == NULL) { - free(hstbuf); - return; + free(buf); + return -1; } while (line != NULL && count--) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", line); - line = strtok(NULL, "\n"); + line = strtok_r(NULL, "\n", &tmp); } line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, ""); - free(hstbuf); + + free(buf); + + return 0; } -/* renames chatlog file replacing src with dest. - Returns 0 on success or if no log exists, -1 on failure. */ -int rename_logfile(char *src, char *dest, const char *selfkey, const char *otherkey, int winnum) +/* Renames chatlog file `src` to `dest`. + * + * Return 0 on success or if no log exists. + * Return -1 on failure. + */ +int rename_logfile(const char *src, const char *dest, const char *selfkey, const char *otherkey, int winnum) { ToxWindow *toxwin = get_window_ptr(winnum); struct chatlog *log = NULL; @@ -250,6 +327,11 @@ int rename_logfile(char *src, char *dest, const char *selfkey, const char *other /* disable log if necessary and save its state */ if (toxwin != NULL) { log = toxwin->chatwin->log; + + if (log == NULL) { + return -1; + } + log_on = log->log_on; } @@ -260,24 +342,38 @@ int rename_logfile(char *src, char *dest, const char *selfkey, const char *other char newpath[MAX_STR_SIZE]; char oldpath[MAX_STR_SIZE]; - if (get_log_path(oldpath, sizeof(oldpath), src, selfkey, otherkey, LOG_CHAT) == -1) { + if (get_log_path(oldpath, sizeof(oldpath), src, selfkey, otherkey) == -1) { goto on_error; } if (!file_exists(oldpath)) { + init_logging_session(dest, selfkey, otherkey, log, LOG_TYPE_CHAT); // still need to rename path return 0; } - if (get_log_path(newpath, sizeof(newpath), dest, selfkey, otherkey, LOG_CHAT) == -1) { + int new_path_len = get_log_path(newpath, sizeof(newpath), dest, selfkey, otherkey); + + if (new_path_len == -1 || new_path_len >= MAX_STR_SIZE) { goto on_error; } - if (rename(oldpath, newpath) != 0) { - goto on_error; + if (file_exists(newpath)) { + if (remove(oldpath) != 0) { + fprintf(stderr, "Failed to remove old path `%s`\n", oldpath); + } + } else { + if (rename(oldpath, newpath) != 0) { + goto on_error; + } } - if (log_on) { - log_enable(dest, selfkey, otherkey, log, LOG_CHAT); + if (log != NULL) { + memcpy(log->path, newpath, new_path_len); + log->path[new_path_len] = 0; + + if (log_on) { + log_enable(log); + } } return 0; @@ -285,7 +381,7 @@ int rename_logfile(char *src, char *dest, const char *selfkey, const char *other on_error: if (log_on) { - log_enable(src, selfkey, otherkey, log, LOG_CHAT); + log_enable(log); } return -1; diff --git a/src/log.h b/src/log.h index 6c4c61d..eb1c965 100644 --- a/src/log.h +++ b/src/log.h @@ -30,30 +30,43 @@ struct chatlog { bool log_on; /* specific to current chat window */ }; -typedef enum { - LOG_CONFERENCE, - LOG_PROMPT, - LOG_CHAT, +typedef enum LOG_TYPE { + LOG_TYPE_PROMPT, + LOG_TYPE_CHAT, } LOG_TYPE; +/* Initializes a log. This function must be called before any other logging operations. + * + * Return 0 on success. + * Return -1 on failure. + */ +int log_init(struct chatlog *log, const char *name, const char *selfkey, const char *otherkey, LOG_TYPE type); + /* formats/writes line to log file */ void write_to_log(const char *msg, const char *name, struct chatlog *log, bool event); -/* enables logging for specified log and creates/fetches file if necessary. +/* enables logging for specified log. * * Returns 0 on success. * Returns -1 on failure. */ -int log_enable(char *name, const char *selfkey, const char *otherkey, struct chatlog *log, int logtype); +int log_enable(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); +/* Loads chat log history and prints it to `self` window. + * + * Return 0 on success or if log file doesn't exist. + * Return -1 on failure. + */ +int load_chat_history(ToxWindow *self, struct chatlog *log); -/* renames chatlog file replacing src with dest. - Returns 0 on success or if no log exists, -1 on failure. */ -int rename_logfile(char *src, char *dest, const char *selfkey, const char *otherkey, int winnum); +/* Renames chatlog file `src` to `dest`. + * + * Return 0 on success or if no log exists. + * Return -1 on failure. + */ +int rename_logfile(const char *src, const char *dest, const char *selfkey, const char *otherkey, int winnum); #endif /* LOG_H */ diff --git a/src/prompt.c b/src/prompt.c index b5960ae..8cdedb1 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -554,6 +554,25 @@ static void print_welcome_msg(ToxWindow *self) line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, ""); } +static void prompt_init_log(ToxWindow *self, Tox *m, const char *self_name) +{ + ChatContext *ctx = self->chatwin; + + char myid[TOX_ADDRESS_SIZE]; + tox_self_get_address(m, (uint8_t *) myid); + + if (log_init(ctx->log, self->name, myid, NULL, LOG_TYPE_PROMPT) != 0) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Warning: Log failed to initialize."); + return; + } + + if (user_settings->autolog == AUTOLOG_ON) { + if (log_enable(ctx->log) == -1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Warning: Failed to enable log."); + } + } +} + static void prompt_onInit(ToxWindow *self, Tox *m) { curs_set(1); @@ -577,14 +596,7 @@ static void prompt_onInit(ToxWindow *self, Tox *m) line_info_init(ctx->hst); - if (user_settings->autolog == AUTOLOG_ON) { - char myid[TOX_ADDRESS_SIZE]; - tox_self_get_address(m, (uint8_t *) myid); - - if (log_enable(self->name, myid, NULL, ctx->log, LOG_PROMPT) == -1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Warning: Log failed to initialize."); - } - } + prompt_init_log(self, m, self->name); scrollok(ctx->history, 0); wmove(self->window, y2 - CURS_Y_OFFSET, 0);