diff --git a/src/chat.c b/src/chat.c
index a4d782b..7666215 100644
--- a/src/chat.c
+++ b/src/chat.c
@@ -94,6 +94,7 @@ static void chat_onMessage(ToxWindow *self, Tox *m, int num, uint8_t *msg, uint1
} else
wprintw(ctx->history, "%s\n", msg);
+ add_to_log_buf(msg, nick, ctx);
alert_window(self, WINDOW_ALERT_1, true);
}
@@ -137,6 +138,7 @@ static void chat_onAction(ToxWindow *self, Tox *m, int num, uint8_t *action, uin
wprintw(ctx->history, "* %s %s\n", nick, action);
wattroff(ctx->history, COLOR_PAIR(YELLOW));
+ add_to_log_buf(action, nick, ctx);
alert_window(self, WINDOW_ALERT_1, true);
}
@@ -263,7 +265,6 @@ static void chat_onFileData(ToxWindow *self, Tox *m, int num, uint8_t filenum, u
uint8_t *filename = friends[num].file_receiver.filenames[filenum];
FILE *file_to_save = fopen(filename, "a");
- // we have a problem here, but don't let it segfault
if (file_to_save == NULL) {
wattron(ctx->history, COLOR_PAIR(RED));
wprintw(ctx->history, "* Error writing to file.\n");
@@ -319,6 +320,8 @@ static void send_action(ToxWindow *self, ChatContext *ctx, Tox *m, uint8_t *acti
wprintw(ctx->history, " * Failed to send action\n");
wattroff(ctx->history, COLOR_PAIR(RED));
}
+
+ add_to_log_buf(action, selfname, ctx);
}
static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
@@ -478,6 +481,7 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
if (line[0] == '/') {
if (close_win = !strcmp(line, "/close")) {
+ write_to_log(ctx);
int f_num = self->num;
delwin(ctx->linewin);
delwin(statusbar->topline);
@@ -503,6 +507,8 @@ static void chat_onKey(ToxWindow *self, Tox *m, wint_t key)
} else
wprintw(ctx->history, "%s\n", line);
+ add_to_log_buf(line, selfname, ctx);
+
if (!statusbar->is_online || tox_send_message(m, self->num, line, strlen(line) + 1) == 0) {
wattron(ctx->history, COLOR_PAIR(RED));
wprintw(ctx->history, " * Failed to send message.\n");
@@ -653,6 +659,11 @@ static void chat_onInit(ToxWindow *self, Tox *m)
wprintw(ctx->history, "\n\n");
execute(ctx->history, self, m, "/help", CHAT_COMMAND_MODE);
wmove(self->window, y2 - CURS_Y_OFFSET, 0);
+
+ if (self->name) {
+ ctx->log.log_on = true;
+ init_logging_session(self->name, friends[self->num].pub_key, ctx);
+ }
}
ToxWindow new_chat(Tox *m, int friendnum)
diff --git a/src/log.c b/src/log.c
new file mode 100644
index 0000000..0b127e8
--- /dev/null
+++ b/src/log.c
@@ -0,0 +1,100 @@
+/* ctx->log.c
+ *
+ *
+ * Copyright (C) 2014 Toxic All Rights Reserved.
+ *
+ * This file is part of Toxic.
+ *
+ * Toxic is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Toxic is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Toxic. If not, see .
+ *
+ */
+
+#include
+#include
+#include
+
+#include "configdir.h"
+#include "toxic_windows.h"
+#include "misc_tools.h"
+
+/* gets the log path by appending to the config dir the name and first 4 chars of key */
+void init_logging_session(uint8_t *name, uint8_t *key, ChatContext *ctx)
+{
+ if (!ctx->log.log_on)
+ return;
+
+ char *user_config_dir = get_user_config_dir();
+ int path_len = strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(name) + (KEY_IDENT_DIGITS * 2) + 5;
+
+ if (path_len > MAX_STR_SIZE)
+ return;
+
+ uint8_t ident[KEY_IDENT_DIGITS*2+1];
+ sprintf(&ident[0], "%02X", key[0] & 0xff);
+ sprintf(&ident[2], "%02X", key[2] & 0xff);
+ ident[KEY_IDENT_DIGITS*2+1] = '\0';
+
+ snprintf(ctx->log.log_path, MAX_STR_SIZE, "%s%s%s-%s.log", user_config_dir, CONFIGDIR, name, ident);
+
+ FILE *logfile = fopen(ctx->log.log_path, "a");
+
+ if (logfile == NULL) {
+ ctx->log.log_on = false;
+ return;
+ }
+
+ fprintf(logfile, "\n***NEW SESSION***\n\n");
+
+ fclose(logfile);
+ free(user_config_dir);
+}
+
+/* writes contents from a chatcontext's log buffer to respective log file and resets log pos.
+ This is triggered when the log buffer is full, but may be forced. */
+void write_to_log(ChatContext *ctx)
+{
+ if (!ctx->log.log_on)
+ return;
+
+ FILE *logfile = fopen(ctx->log.log_path, "a");
+
+ if (logfile == NULL) {
+ ctx->log.log_on = false;
+ return;
+ }
+
+ int i;
+
+ for (i = 0; i < ctx->log.pos; ++i)
+ fprintf(logfile, "%s", ctx->log.log_buf[i]);
+
+ ctx->log.pos = 0;
+ fclose(logfile);
+}
+
+/* Adds msg to log_buf with timestamp and name.
+ If buf is full, triggers write_to_log (which sets buf pos to 0) */
+void add_to_log_buf(uint8_t *msg, uint8_t *name, ChatContext *ctx)
+{
+ if (!ctx->log.log_on)
+ return;
+
+ struct tm *tminfo = get_time();
+ snprintf(ctx->log.log_buf[ctx->log.pos], MAX_LOG_LINE_SIZE, "%04d/%02d/%02d [%02d:%02d:%02d] %s: %s\n",
+ tminfo->tm_year + 1900, tminfo->tm_mon + 1, tminfo->tm_mday,
+ tminfo->tm_hour, tminfo->tm_min, tminfo->tm_sec, name, msg);
+
+ if (++(ctx->log.pos) >= MAX_LOG_BUF_LINES)
+ write_to_log(ctx);
+}
diff --git a/src/log.h b/src/log.h
new file mode 100644
index 0000000..01734af
--- /dev/null
+++ b/src/log.h
@@ -0,0 +1,33 @@
+/* log.h
+ *
+ *
+ * Copyright (C) 2014 Toxic All Rights Reserved.
+ *
+ * This file is part of Toxic.
+ *
+ * Toxic is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Toxic is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Toxic. If not, see .
+ *
+ */
+
+/* gets a log path by appending to the config dir the name and first 4 chars of the pub_key,
+ writes current date/time to log file. */
+void init_logging_session(uint8_t *name, uint8_t *pub_key, ChatContext *ctx);
+
+/* Adds msg to log_buf with timestamp and name.
+ If buf is full, triggers write_to_log (which sets buf pos to 0) */
+void add_to_log_buf(uint8_t *msg, uint8_t *name, ChatContext *ctx);
+
+/* writes contents from a chatcontext's log buffer to respective log file and resets log pos.
+ This is triggered automatically when the log buffer is full, but may be forced. */
+void write_to_log(ChatContext *ctx);
diff --git a/src/toxic_strings.c b/src/toxic_strings.c
index 78abaae..efebc03 100644
--- a/src/toxic_strings.c
+++ b/src/toxic_strings.c
@@ -146,12 +146,12 @@ void fetch_hist_item(wchar_t *buf, size_t *pos, size_t *len, wchar_t (*hst)[MAX_
{
if (key_dir == LN_HIST_MV_UP) {
if (--(*hst_pos) < 0) {
- (*hst_pos) = 0;
+ *hst_pos = 0;
beep();
}
} else {
if (++(*hst_pos) >= hst_tot) {
- (*hst_pos) = hst_tot;
+ *hst_pos = hst_tot;
reset_buf(buf, pos, len);
return;
}
diff --git a/src/toxic_windows.h b/src/toxic_windows.h
index 67b28f0..89ffbba 100644
--- a/src/toxic_windows.h
+++ b/src/toxic_windows.h
@@ -131,6 +131,16 @@ struct StatusBar {
bool is_online;
};
+#define MAX_LOG_BUF_LINES 10 /* write log_buf contents to log file after this many lines */
+#define MAX_LOG_LINE_SIZE MAX_STR_SIZE + TOXIC_MAX_NAME_LENGTH + 24 /* extra room for time/date */
+
+struct chatlog {
+ uint8_t log_path[MAX_STR_SIZE];
+ uint8_t log_buf[MAX_LOG_BUF_LINES][MAX_LOG_LINE_SIZE];
+ int pos;
+ bool log_on;
+};
+
#define MAX_LINE_HIST 128
/* chat and groupchat window/buffer holder */
@@ -145,6 +155,8 @@ struct ChatContext {
bool self_is_typing;
+ struct chatlog log;
+
WINDOW *history;
WINDOW *linewin;
WINDOW *sidebar;