From 8bfb175d03925c8a468eac0660189c86093be2cd Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Wed, 11 Mar 2020 14:17:11 +0100 Subject: [PATCH 01/42] Start SQLite db module I plan to save all messages in an SQLite db. For retrieving information it's nicer than having it in a text file. We will have more info in there and easier to parse it. This will also be good for later MAM (https://github.com/profanity-im/profanity/issues/660). Regular text files will still be an option for users so that they can easily grep them and do whatever they like. Internally Profanity will only use the SQLite db. --- Makefile.am | 4 ++- configure.ac | 7 +++-- src/database.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ src/database.h | 43 ++++++++++++++++++++++++++++++ src/profanity.c | 3 +++ 5 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 src/database.c create mode 100644 src/database.h diff --git a/Makefile.am b/Makefile.am index 95b2401d..9ed8f07b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,7 @@ core_sources = \ - src/xmpp/contact.c src/xmpp/contact.h src/log.c src/common.c \ + src/xmpp/contact.c src/xmpp/contact.h \ + src/log.c src/common.c \ + src/database.h src/database.c \ src/log.h src/profanity.c src/common.h \ src/profanity.h src/xmpp/chat_session.c \ src/xmpp/chat_session.h src/xmpp/muc.c src/xmpp/muc.h src/xmpp/jid.h src/xmpp/jid.c \ diff --git a/configure.ac b/configure.ac index 0800ea0a..92db515f 100644 --- a/configure.ac +++ b/configure.ac @@ -179,6 +179,9 @@ PKG_CHECK_MODULES([curl], [libcurl], [], [AC_CHECK_LIB([curl], [main], [], [AC_MSG_ERROR([libcurl is required for profanity])])]) +PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.30.0], [], + [AC_MSG_ERROR([sqlite3 3.30.0 or higher is required for profanity profanity])]) + AS_IF([test "x$enable_icons_and_clipboard" != xno], [PKG_CHECK_MODULES([GTK], [gtk+-2.0 >= 2.24.10], [AC_DEFINE([HAVE_GTK], [1], [libgtk module])], @@ -332,9 +335,9 @@ AS_IF([test "x$PACKAGE_STATUS" = xdevelopment], AS_IF([test "x$PLATFORM" = xosx], [AM_CFLAGS="$AM_CFLAGS -Qunused-arguments"]) AM_LDFLAGS="$AM_LDFLAGS -export-dynamic" -AM_CPPFLAGS="$AM_CPPFLAGS $glib_CFLAGS $gio_CFLAGS $curl_CFLAGS $libnotify_CFLAGS $PYTHON_CPPFLAGS ${GTK_CFLAGS}" +AM_CPPFLAGS="$AM_CPPFLAGS $glib_CFLAGS $gio_CFLAGS $curl_CFLAGS $libnotify_CFLAGS $PYTHON_CPPFLAGS ${GTK_CFLAGS} ${SQLITE_CFLAGS}" AM_CPPFLAGS="$AM_CPPFLAGS -DTHEMES_PATH=\"\\\"$THEMES_PATH\\\"\" -DICONS_PATH=\"\\\"$ICONS_PATH\\\"\"" -LIBS="$glib_LIBS $gio_LIBS $curl_LIBS $libnotify_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_LDFLAGS ${GTK_LIBS} $LIBS" +LIBS="$glib_LIBS $gio_LIBS $curl_LIBS $libnotify_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_LDFLAGS ${GTK_LIBS} ${SQLITE_LIBS} $LIBS" AC_SUBST(AM_LDFLAGS) AC_SUBST(AM_CFLAGS) diff --git a/src/database.c b/src/database.c new file mode 100644 index 00000000..3ac203e3 --- /dev/null +++ b/src/database.c @@ -0,0 +1,70 @@ +/* + * database.c + * vim: expandtab:ts=4:sts=4:sw=4 + * + * Copyright (C) 2020 Michael Vetter + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see . + * + * In addition, as a special exception, the copyright holders give permission to + * link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. + * + * You must obey the GNU General Public License in all respects for all of the + * code used other than OpenSSL. If you modify file(s) with this exception, you + * may extend this exception to your version of the file(s), but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. If you delete this exception statement from all + * source files in the program, then also delete it here. + * + */ + +#include + +#include "log.h" + +static sqlite3 *g_log_database; + +bool +log_database_init(void) +{ + int ret = sqlite3_initialize(); + char *filename = "test"; + + if (ret != SQLITE_OK) { + log_error("Error initializing SQLite database: %d", ret); + return FALSE; + } + + ret = sqlite3_open(filename, &g_log_database); + if (ret != SQLITE_OK) { + const char *err_msg = sqlite3_errmsg(g_log_database); + log_error("Error opening SQLite database: %s", err_msg); + return FALSE; + } + + log_error("Initialized SQLite database: %s", filename); + return TRUE; +} + +void +log_database_close(void) +{ + sqlite3_close(g_log_database); + sqlite3_shutdown(); +} + diff --git a/src/database.h b/src/database.h new file mode 100644 index 00000000..11560385 --- /dev/null +++ b/src/database.h @@ -0,0 +1,43 @@ +/* + * database.h + * vim: expandtab:ts=4:sts=4:sw=4 + * + * Copyright (C) 2020 Michael Vetter + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see . + * + * In addition, as a special exception, the copyright holders give permission to + * link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. + * + * You must obey the GNU General Public License in all respects for all of the + * code used other than OpenSSL. If you modify file(s) with this exception, you + * may extend this exception to your version of the file(s), but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. If you delete this exception statement from all + * source files in the program, then also delete it here. + * + */ + +#ifndef DATABASE_H +#define DATABASE_H + +bool log_database_init(void); +void log_database_close(void); + +#endif // DATABASE_H + diff --git a/src/profanity.c b/src/profanity.c index dc7bf954..e6830e20 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -53,6 +53,7 @@ #include "profanity.h" #include "common.h" #include "log.h" +#include "database.h" #include "config/files.h" #include "config/tlscerts.h" #include "config/accounts.h" @@ -187,6 +188,7 @@ _init(char *log_level, char *config_file, char *log_file, char *theme_name) log_info("Starting Profanity (%s)...", PACKAGE_VERSION); } + log_database_init(); chat_log_init(); groupchat_log_init(); accounts_load(); @@ -255,6 +257,7 @@ _shutdown(void) #ifdef HAVE_OMEMO omemo_close(); #endif + log_database_close(); chat_log_close(); theme_close(); accounts_close(); From 994411d470ae3d7a7649fc43f76f180c7287ce43 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Wed, 18 Mar 2020 18:42:16 +0100 Subject: [PATCH 02/42] database: create table --- src/database.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/database.c b/src/database.c index 3ac203e3..c03c2466 100644 --- a/src/database.c +++ b/src/database.c @@ -57,7 +57,19 @@ log_database_init(void) return FALSE; } - log_error("Initialized SQLite database: %s", filename); + char *err_msg; + char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `id` INTEGER PRIMARY KEY, `jid` TEXT NOT NULL, `message` TEXT, `timestamp` TEXT)"; + if( SQLITE_OK != sqlite3_exec(g_db, query, NULL, 0, &err_msg)) { + if (err_msg) { + log_error("SQLite error: %s", err_msg); + sqlite3_free(err_msg); + } else { + log_error("Unknown SQLite error"); + } + return FALSE; + } + + log_debug("Initialized SQLite database: %s", filename); return TRUE; } @@ -67,4 +79,3 @@ log_database_close(void) sqlite3_close(g_log_database); sqlite3_shutdown(); } - From a7163b24f3822989173cfca8ad7bfc84193cc839 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Wed, 18 Mar 2020 18:56:22 +0100 Subject: [PATCH 03/42] database: Define chatlog database location --- src/config/files.c | 17 +++++++++++++++++ src/config/files.h | 1 + src/database.c | 17 +++++++++++------ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/config/files.c b/src/config/files.c index 133a270e..e77bfa30 100644 --- a/src/config/files.c +++ b/src/config/files.c @@ -3,6 +3,7 @@ * vim: expandtab:ts=4:sts=4:sw=4 * * Copyright (C) 2012 - 2019 James Booth + * Copyright (C) 2020 Michael Vetter * * This file is part of Profanity. * @@ -138,6 +139,22 @@ files_get_log_file(char *log_file) return result; } +char* +files_get_chatlog_database_path(void) +{ + gchar *xdg_data = _files_get_xdg_data_home(); + GString *logfile = g_string_new(xdg_data); + + g_string_append(logfile, "/profanity/chatlog.db"); + + char *result = strdup(logfile->str); + + free(xdg_data); + g_string_free(logfile, TRUE); + + return result; +} + char* files_get_config_path(char *config_base) { diff --git a/src/config/files.h b/src/config/files.h index 12c3f03a..124c3ac8 100644 --- a/src/config/files.h +++ b/src/config/files.h @@ -60,6 +60,7 @@ void files_create_directories(void); char* files_get_config_path(char *config_base); char* files_get_data_path(char *data_base); +char* files_get_chatlog_database_path(void); char* files_get_log_file(char *log_file); char* files_get_inputrc_file(void); diff --git a/src/database.c b/src/database.c index c03c2466..2d857d08 100644 --- a/src/database.c +++ b/src/database.c @@ -36,46 +36,51 @@ #include #include "log.h" +#include "config/files.h" -static sqlite3 *g_log_database; +static sqlite3 *g_chatlog_database; bool log_database_init(void) { int ret = sqlite3_initialize(); - char *filename = "test"; + char *filename = files_get_chatlog_database_path(); if (ret != SQLITE_OK) { + free(filename); log_error("Error initializing SQLite database: %d", ret); return FALSE; } - ret = sqlite3_open(filename, &g_log_database); + ret = sqlite3_open(filename, &g_chatlog_database); if (ret != SQLITE_OK) { - const char *err_msg = sqlite3_errmsg(g_log_database); + const char *err_msg = sqlite3_errmsg(g_chatlog_database); log_error("Error opening SQLite database: %s", err_msg); + free(filename); return FALSE; } char *err_msg; char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `id` INTEGER PRIMARY KEY, `jid` TEXT NOT NULL, `message` TEXT, `timestamp` TEXT)"; - if( SQLITE_OK != sqlite3_exec(g_db, query, NULL, 0, &err_msg)) { + if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { if (err_msg) { log_error("SQLite error: %s", err_msg); sqlite3_free(err_msg); } else { log_error("Unknown SQLite error"); } + free(filename); return FALSE; } log_debug("Initialized SQLite database: %s", filename); + free(filename); return TRUE; } void log_database_close(void) { - sqlite3_close(g_log_database); + sqlite3_close(g_chatlog_database); sqlite3_shutdown(); } From 8045a32c4a123d541c9a44d64a8ff35dca27474e Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 19 Mar 2020 12:10:54 +0100 Subject: [PATCH 04/42] database: log incoming messages First trial. Not covering all cases yet. --- src/database.c | 30 ++++++++++++++++++++++++++++++ src/database.h | 1 + src/event/server_events.c | 9 +++++++++ 3 files changed, 40 insertions(+) diff --git a/src/database.c b/src/database.c index 2d857d08..7c84ee33 100644 --- a/src/database.c +++ b/src/database.c @@ -33,10 +33,15 @@ * */ +#define _GNU_SOURCE 1 + #include +#include +#include #include "log.h" #include "config/files.h" +#include "xmpp/xmpp.h" static sqlite3 *g_chatlog_database; @@ -84,3 +89,28 @@ log_database_close(void) sqlite3_close(g_chatlog_database); sqlite3_shutdown(); } + +void +log_database_add(ProfMessage *message) { + char *err_msg; + char *query; + + //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); + gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); + if (asprintf(&query, "INSERT INTO `ChatLogs` (`jid`, `message`, `timestamp`) VALUES ('%s', '%s', '%s')", + message->jid->barejid, message->plain, date_fmt) == -1) { + log_error("log_database_add(): could not allocate memory"); + return; + } + g_free(date_fmt); + + if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { + if (err_msg) { + log_error("SQLite error: %s", err_msg); + sqlite3_free(err_msg); + } else { + log_error("Unknown SQLite error"); + } + } + free(query); +} diff --git a/src/database.h b/src/database.h index 11560385..fc95b7d0 100644 --- a/src/database.h +++ b/src/database.h @@ -38,6 +38,7 @@ bool log_database_init(void); void log_database_close(void); +void log_database_add(ProfMessage *message); #endif // DATABASE_H diff --git a/src/event/server_events.c b/src/event/server_events.c index ea4277b2..6c7d0430 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -42,6 +42,7 @@ #include "profanity.h" #include "log.h" +#include "database.h" #include "config/preferences.h" #include "config/tlscerts.h" #include "config/account.h" @@ -324,6 +325,7 @@ sv_ev_room_message(ProfMessage *message) GList *triggers = prefs_message_get_triggers(message->plain); _clean_incoming_message(message); + log_database_add(message); mucwin_incoming_msg(mucwin, message, mentions, triggers, TRUE); g_slist_free(mentions); @@ -397,6 +399,7 @@ sv_ev_incoming_private_message(ProfMessage *message) } _clean_incoming_message(message); + log_database_add(message); privwin_incoming_msg(privatewin, message); chat_log_msg_in(message); @@ -420,6 +423,7 @@ sv_ev_delayed_private_message(ProfMessage *message) } _clean_incoming_message(message); + log_database_add(message); privwin_incoming_msg(privatewin, message); chat_log_msg_in(message); @@ -532,6 +536,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message if (message->plain) { message->enc = PROF_MSG_ENC_PGP; _clean_incoming_message(message); + log_database_add(message); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_pgp_msg_in(message); @@ -547,6 +552,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message message->enc = PROF_MSG_ENC_PLAIN; message->plain = strdup(message->body); _clean_incoming_message(message); + log_database_add(message); chatwin_incoming_msg(chatwin, message, new_win); chat_log_msg_in(message); chatwin->pgp_recv = FALSE; @@ -569,6 +575,7 @@ _sv_ev_incoming_otr(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message } _clean_incoming_message(message); + log_database_add(message); chatwin_incoming_msg(chatwin, message, new_win); chat_log_otr_msg_in(message); @@ -584,6 +591,7 @@ static void _sv_ev_incoming_omemo(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message, gboolean logit) { _clean_incoming_message(message); + log_database_add(message); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_omemo_msg_in(message); @@ -599,6 +607,7 @@ _sv_ev_incoming_plain(ProfChatWin *chatwin, gboolean new_win, ProfMessage *messa message->enc = PROF_MSG_ENC_PLAIN; message->plain = strdup(message->body); _clean_incoming_message(message); + log_database_add(message); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_msg_in(message); From d1d0ad8d1a8e28690aa8723566dd64c1ccdcf9d6 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 19 Mar 2020 13:38:17 +0100 Subject: [PATCH 05/42] Add timestamp for incoming messages if none is set Timestamps are only set if a message is delayed. If none is set let's set it upon recaival so we don't have to set it when it gets displayed. This means we will also have it for logs etc in the ProfMessage. --- src/xmpp/message.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/xmpp/message.c b/src/xmpp/message.c index d9159e81..d116b8da 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -1009,6 +1009,8 @@ _handle_muc_private_message(xmpp_stanza_t *const stanza) if (message->timestamp) { sv_ev_delayed_private_message(message); } else { + message->timestamp = g_date_time_new_now_local(); + sv_ev_incoming_private_message(message); } @@ -1199,6 +1201,10 @@ _handle_chat(xmpp_stanza_t *const stanza) } message->timestamp = stanza_get_delay(stanza); + if (!message->timestamp) { + message->timestamp = g_date_time_new_now_local(); + } + if (body) { message->body = xmpp_stanza_get_text(body); } From 5cc3b469a84233cf696530fb41ee0c648f9aaa92 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 19 Mar 2020 13:56:22 +0100 Subject: [PATCH 06/42] database: log stanza_id and whether it is a muc message --- src/database.c | 8 ++++---- src/database.h | 2 +- src/event/server_events.c | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/database.c b/src/database.c index 7c84ee33..adfbe912 100644 --- a/src/database.c +++ b/src/database.c @@ -66,7 +66,7 @@ log_database_init(void) } char *err_msg; - char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `id` INTEGER PRIMARY KEY, `jid` TEXT NOT NULL, `message` TEXT, `timestamp` TEXT)"; + char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `id` INTEGER PRIMARY KEY, `jid` TEXT NOT NULL, `resource` TEXT, `message` TEXT, `timestamp` TEXT, `is_muc` INTEGER, `stanza_id` TEXT)"; if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { if (err_msg) { log_error("SQLite error: %s", err_msg); @@ -91,14 +91,14 @@ log_database_close(void) } void -log_database_add(ProfMessage *message) { +log_database_add(ProfMessage *message, gboolean is_muc) { char *err_msg; char *query; //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); - if (asprintf(&query, "INSERT INTO `ChatLogs` (`jid`, `message`, `timestamp`) VALUES ('%s', '%s', '%s')", - message->jid->barejid, message->plain, date_fmt) == -1) { + if (asprintf(&query, "INSERT INTO `ChatLogs` (`jid`, `resource`, `message`, `timestamp`, `is_muc`, `stanza_id`) VALUES ('%s', '%s', '%s', '%s', '%d', '%s')", + message->jid->barejid, message->jid->resourcepart, message->plain, date_fmt, is_muc, message->id) == -1) { log_error("log_database_add(): could not allocate memory"); return; } diff --git a/src/database.h b/src/database.h index fc95b7d0..3e393707 100644 --- a/src/database.h +++ b/src/database.h @@ -38,7 +38,7 @@ bool log_database_init(void); void log_database_close(void); -void log_database_add(ProfMessage *message); +void log_database_add(ProfMessage *message, gboolean is_muc); #endif // DATABASE_H diff --git a/src/event/server_events.c b/src/event/server_events.c index 6c7d0430..2728e811 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -325,7 +325,7 @@ sv_ev_room_message(ProfMessage *message) GList *triggers = prefs_message_get_triggers(message->plain); _clean_incoming_message(message); - log_database_add(message); + log_database_add(message, TRUE); mucwin_incoming_msg(mucwin, message, mentions, triggers, TRUE); g_slist_free(mentions); @@ -399,7 +399,7 @@ sv_ev_incoming_private_message(ProfMessage *message) } _clean_incoming_message(message); - log_database_add(message); + log_database_add(message, FALSE); privwin_incoming_msg(privatewin, message); chat_log_msg_in(message); @@ -423,7 +423,7 @@ sv_ev_delayed_private_message(ProfMessage *message) } _clean_incoming_message(message); - log_database_add(message); + log_database_add(message, FALSE); privwin_incoming_msg(privatewin, message); chat_log_msg_in(message); @@ -536,7 +536,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message if (message->plain) { message->enc = PROF_MSG_ENC_PGP; _clean_incoming_message(message); - log_database_add(message); + log_database_add(message, FALSE); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_pgp_msg_in(message); @@ -552,7 +552,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message message->enc = PROF_MSG_ENC_PLAIN; message->plain = strdup(message->body); _clean_incoming_message(message); - log_database_add(message); + log_database_add(message, FALSE); chatwin_incoming_msg(chatwin, message, new_win); chat_log_msg_in(message); chatwin->pgp_recv = FALSE; @@ -575,7 +575,7 @@ _sv_ev_incoming_otr(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message } _clean_incoming_message(message); - log_database_add(message); + log_database_add(message, FALSE); chatwin_incoming_msg(chatwin, message, new_win); chat_log_otr_msg_in(message); @@ -591,7 +591,7 @@ static void _sv_ev_incoming_omemo(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message, gboolean logit) { _clean_incoming_message(message); - log_database_add(message); + log_database_add(message, FALSE); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_omemo_msg_in(message); @@ -607,7 +607,7 @@ _sv_ev_incoming_plain(ProfChatWin *chatwin, gboolean new_win, ProfMessage *messa message->enc = PROF_MSG_ENC_PLAIN; message->plain = strdup(message->body); _clean_incoming_message(message); - log_database_add(message); + log_database_add(message, FALSE); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_msg_in(message); From 71e872c5b8cc78c97734f69eed6b6a53a16a6fb6 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Thu, 19 Mar 2020 13:57:27 +0100 Subject: [PATCH 07/42] database: dont log muc pms --- src/event/server_events.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/event/server_events.c b/src/event/server_events.c index 2728e811..348e9b74 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -399,7 +399,6 @@ sv_ev_incoming_private_message(ProfMessage *message) } _clean_incoming_message(message); - log_database_add(message, FALSE); privwin_incoming_msg(privatewin, message); chat_log_msg_in(message); @@ -423,7 +422,6 @@ sv_ev_delayed_private_message(ProfMessage *message) } _clean_incoming_message(message); - log_database_add(message, FALSE); privwin_incoming_msg(privatewin, message); chat_log_msg_in(message); From 672f3e22e87e899a38efe1a498057fe87e24be6e Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 23 Mar 2020 11:24:57 +0100 Subject: [PATCH 08/42] Add sqlite to CI dependencies --- .builds/openbsd.yml | 1 + .travis.yml | 1 + Brewfile.travis | 1 + Dockerfile.arch | 3 ++- Dockerfile.debian | 3 ++- Dockerfile.tumbleweed | 3 ++- 6 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.builds/openbsd.yml b/.builds/openbsd.yml index de318fca..ebc43e61 100644 --- a/.builds/openbsd.yml +++ b/.builds/openbsd.yml @@ -21,6 +21,7 @@ packages: - libgpg-error - libgcrypt - libsignal-protocol-c + - sqlite3 sources: - https://github.com/profanity-im/profanity diff --git a/.travis.yml b/.travis.yml index d41175ec..a40b7432 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,7 @@ matrix: - PKG_CONFIG_PATH="/usr/local/opt/curl/lib/pkgconfig:$PKG_CONFIG_PATH" - PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig:$PKG_CONFIG_PATH" - PKG_CONFIG_PATH="/usr/local/opt/libffi/lib/pkgconfig:$PKG_CONFIG_PATH" + - PKG_CONFIG_PATH="/usr/local/opt/sqlite/lib/pkgconfig:$PKG_CONFIG_PATH" before_install: - > diff --git a/Brewfile.travis b/Brewfile.travis index 601058fe..d73a973c 100644 --- a/Brewfile.travis +++ b/Brewfile.travis @@ -19,3 +19,4 @@ brew 'openssl' brew 'ossp-uuid' brew 'pkg-config' brew 'readline' +brew 'sqlite' diff --git a/Dockerfile.arch b/Dockerfile.arch index 4e0eee6d..5ef305b6 100644 --- a/Dockerfile.arch +++ b/Dockerfile.arch @@ -25,7 +25,8 @@ RUN pacman -Syu --noconfirm && pacman -S --needed --noconfirm \ openssl \ pkg-config \ python \ - wget + wget \ + sqlite RUN mkdir -p /usr/src/{stabber,profanity} diff --git a/Dockerfile.debian b/Dockerfile.debian index 29ceae80..501a0348 100644 --- a/Dockerfile.debian +++ b/Dockerfile.debian @@ -25,7 +25,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libxss-dev \ make \ pkg-config \ - python-dev + python-dev \ + libsqlite3-dev RUN mkdir -p /usr/src/{stabber,libmesode,profanity} WORKDIR /usr/src diff --git a/Dockerfile.tumbleweed b/Dockerfile.tumbleweed index 9acf4cce..67b97dae 100644 --- a/Dockerfile.tumbleweed +++ b/Dockerfile.tumbleweed @@ -33,7 +33,8 @@ RUN zypper --non-interactive in --no-recommends \ python-devel \ python3 \ python3-devel \ - readline-devel + readline-devel \ + sqlite3-devel # https://github.com/openSUSE/docker-containers-build/issues/26 ENV LANG en_US.UTF-8 From 11663625cc04cbe779e77509118872cacbd1b3e1 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 23 Mar 2020 12:18:25 +0100 Subject: [PATCH 09/42] db: Have one database per account --- src/config/files.c | 16 -------------- src/config/files.h | 2 +- src/database.c | 45 +++++++++++++++++++++++++++++++++++---- src/database.h | 2 +- src/event/common.c | 2 ++ src/event/server_events.c | 2 ++ src/profanity.c | 3 --- 7 files changed, 47 insertions(+), 25 deletions(-) diff --git a/src/config/files.c b/src/config/files.c index e77bfa30..bdaf6a93 100644 --- a/src/config/files.c +++ b/src/config/files.c @@ -139,22 +139,6 @@ files_get_log_file(char *log_file) return result; } -char* -files_get_chatlog_database_path(void) -{ - gchar *xdg_data = _files_get_xdg_data_home(); - GString *logfile = g_string_new(xdg_data); - - g_string_append(logfile, "/profanity/chatlog.db"); - - char *result = strdup(logfile->str); - - free(xdg_data); - g_string_free(logfile, TRUE); - - return result; -} - char* files_get_config_path(char *config_base) { diff --git a/src/config/files.h b/src/config/files.h index 124c3ac8..1e16802a 100644 --- a/src/config/files.h +++ b/src/config/files.h @@ -55,12 +55,12 @@ #define DIR_PGP "pgp" #define DIR_OMEMO "omemo" #define DIR_PLUGINS "plugins" +#define DIR_DATABASE "database" void files_create_directories(void); char* files_get_config_path(char *config_base); char* files_get_data_path(char *data_base); -char* files_get_chatlog_database_path(void); char* files_get_log_file(char *log_file); char* files_get_inputrc_file(void); diff --git a/src/database.c b/src/database.c index adfbe912..54005c2b 100644 --- a/src/database.c +++ b/src/database.c @@ -35,28 +35,65 @@ #define _GNU_SOURCE 1 +#include #include #include #include +#include #include "log.h" #include "config/files.h" +#include "config/account.h" #include "xmpp/xmpp.h" static sqlite3 *g_chatlog_database; +static char* +_get_db_filename(ProfAccount *account) +{ + char *databasedir = files_get_data_path(DIR_DATABASE); + GString *basedir = g_string_new(databasedir); + free(databasedir); + + g_string_append(basedir, "/"); + + gchar *account_dir = str_replace(account->jid, "@", "_at_"); + g_string_append(basedir, account_dir); + free(account_dir); + + int res = g_mkdir_with_parents(basedir->str, S_IRWXU); + if (res == -1) { + char *errmsg = strerror(errno); + if (errmsg) { + log_error("DATABASE: error creating directory: %s, %s", basedir->str, errmsg); + } else { + log_error("DATABASE: creating directory: %s", basedir->str); + } + g_string_free(basedir, TRUE); + return NULL; + } + + g_string_append(basedir, "/chatlog.db"); + char *result = strdup(basedir->str); + g_string_free(basedir, TRUE); + + return result; +} + bool -log_database_init(void) +log_database_init(ProfAccount *account) { int ret = sqlite3_initialize(); - char *filename = files_get_chatlog_database_path(); - if (ret != SQLITE_OK) { - free(filename); log_error("Error initializing SQLite database: %d", ret); return FALSE; } + char *filename = _get_db_filename(account); + if (!filename) { + return FALSE; + } + ret = sqlite3_open(filename, &g_chatlog_database); if (ret != SQLITE_OK) { const char *err_msg = sqlite3_errmsg(g_chatlog_database); diff --git a/src/database.h b/src/database.h index 3e393707..82fa6aaa 100644 --- a/src/database.h +++ b/src/database.h @@ -36,7 +36,7 @@ #ifndef DATABASE_H #define DATABASE_H -bool log_database_init(void); +bool log_database_init(ProfAccount *account); void log_database_close(void); void log_database_add(ProfMessage *message, gboolean is_muc); diff --git a/src/event/common.c b/src/event/common.c index 05c3f30b..4dc62b07 100644 --- a/src/event/common.c +++ b/src/event/common.c @@ -33,6 +33,7 @@ * */ +#include "database.h" #include "config/tlscerts.h" #include "ui/ui.h" #include "xmpp/chat_session.h" @@ -67,6 +68,7 @@ ev_disconnect_cleanup(void) #ifdef HAVE_OMEMO omemo_on_disconnect(); #endif + log_database_close(); } gboolean diff --git a/src/event/server_events.c b/src/event/server_events.c index 348e9b74..86176078 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -92,6 +92,8 @@ sv_ev_login_account_success(char *account_name, gboolean secured) omemo_on_connect(account); #endif + log_database_init(account); + avatar_pep_subscribe(); ui_handle_login_account_success(account, secured); diff --git a/src/profanity.c b/src/profanity.c index e6830e20..dc7bf954 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -53,7 +53,6 @@ #include "profanity.h" #include "common.h" #include "log.h" -#include "database.h" #include "config/files.h" #include "config/tlscerts.h" #include "config/accounts.h" @@ -188,7 +187,6 @@ _init(char *log_level, char *config_file, char *log_file, char *theme_name) log_info("Starting Profanity (%s)...", PACKAGE_VERSION); } - log_database_init(); chat_log_init(); groupchat_log_init(); accounts_load(); @@ -257,7 +255,6 @@ _shutdown(void) #ifdef HAVE_OMEMO omemo_close(); #endif - log_database_close(); chat_log_close(); theme_close(); accounts_close(); From 1155963c6c654ec79379921955b8be167c35c97f Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 23 Mar 2020 12:23:21 +0100 Subject: [PATCH 10/42] db: guard against no DB Maybe if we only use `/connect` we dont have ProfAccount. In that case we won't log anything. Only if a account is used we log. If this is the case or the init of the db didn't work we still want profanity to run but wont log anything to the db. --- src/database.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/database.c b/src/database.c index 54005c2b..de1d36fb 100644 --- a/src/database.c +++ b/src/database.c @@ -123,12 +123,20 @@ log_database_init(ProfAccount *account) void log_database_close(void) { - sqlite3_close(g_chatlog_database); - sqlite3_shutdown(); + if (g_chatlog_database) { + sqlite3_close(g_chatlog_database); + sqlite3_shutdown(); + g_chatlog_database = NULL; + } } void log_database_add(ProfMessage *message, gboolean is_muc) { + if (!g_chatlog_database) { + log_debug("log_database_add() called but db is not initialized"); + return; + } + char *err_msg; char *query; From 4a7a0f3e76314bac90fd965ff3f8932c936fd02b Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 23 Mar 2020 12:33:42 +0100 Subject: [PATCH 11/42] db: move includes --- src/database.c | 5 +---- src/database.h | 8 ++++++-- src/event/common.c | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/database.c b/src/database.c index de1d36fb..853879f6 100644 --- a/src/database.c +++ b/src/database.c @@ -38,13 +38,10 @@ #include #include #include -#include #include #include "log.h" #include "config/files.h" -#include "config/account.h" -#include "xmpp/xmpp.h" static sqlite3 *g_chatlog_database; @@ -80,7 +77,7 @@ _get_db_filename(ProfAccount *account) return result; } -bool +gboolean log_database_init(ProfAccount *account) { int ret = sqlite3_initialize(); diff --git a/src/database.h b/src/database.h index 82fa6aaa..9281e6e6 100644 --- a/src/database.h +++ b/src/database.h @@ -36,9 +36,13 @@ #ifndef DATABASE_H #define DATABASE_H -bool log_database_init(ProfAccount *account); -void log_database_close(void); +#include +#include "config/account.h" +#include "xmpp/xmpp.h" + +gboolean log_database_init(ProfAccount *account); void log_database_add(ProfMessage *message, gboolean is_muc); +void log_database_close(void); #endif // DATABASE_H diff --git a/src/event/common.c b/src/event/common.c index 4dc62b07..2d829e5c 100644 --- a/src/event/common.c +++ b/src/event/common.c @@ -33,13 +33,13 @@ * */ -#include "database.h" #include "config/tlscerts.h" #include "ui/ui.h" #include "xmpp/chat_session.h" #include "xmpp/roster_list.h" #include "xmpp/muc.h" #include "xmpp/xmpp.h" +#include "database.h" #ifdef HAVE_LIBGPGME #include "pgp/gpg.h" From 062c7b1a899ad95134f1f7ba816ab8232927991e Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 23 Mar 2020 12:39:13 +0100 Subject: [PATCH 12/42] db: add database unit test stub --- Makefile.am | 1 + tests/unittests/database/stub_database.c | 31 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/unittests/database/stub_database.c diff --git a/Makefile.am b/Makefile.am index 9ed8f07b..bab161ea 100644 --- a/Makefile.am +++ b/Makefile.am @@ -112,6 +112,7 @@ unittest_sources = \ tests/unittests/xmpp/stub_message.c \ tests/unittests/ui/stub_ui.c tests/unittests/ui/stub_ui.h \ tests/unittests/log/stub_log.c \ + tests/unittests/database/stub_database.c \ tests/unittests/config/stub_accounts.c \ tests/unittests/tools/stub_http_upload.c \ tests/unittests/helpers.c tests/unittests/helpers.h \ diff --git a/tests/unittests/database/stub_database.c b/tests/unittests/database/stub_database.c new file mode 100644 index 00000000..d10ed87a --- /dev/null +++ b/tests/unittests/database/stub_database.c @@ -0,0 +1,31 @@ +/* + * stub_database.c + * + * Copyright (C) 2020 Michael Vetter + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see . + * + */ + +#include +#include +#include + +#include "database.h" + +gboolean log_database_init(ProfAccount *account) { return TRUE; } +void log_database_add(ProfMessage *message, gboolean is_muc) {} +void log_database_close(void) {} From ac6a1222fcecfd782e8992a5771127b0a3274523 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 23 Mar 2020 15:18:55 +0100 Subject: [PATCH 13/42] db: add db version so we can later migrate. --- src/database.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/database.c b/src/database.c index 853879f6..4e28813b 100644 --- a/src/database.c +++ b/src/database.c @@ -100,7 +100,31 @@ log_database_init(ProfAccount *account) } char *err_msg; - char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `id` INTEGER PRIMARY KEY, `jid` TEXT NOT NULL, `resource` TEXT, `message` TEXT, `timestamp` TEXT, `is_muc` INTEGER, `stanza_id` TEXT)"; + char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `cl_id` INTEGER PRIMARY KEY, `jid` TEXT NOT NULL, `resource` TEXT, `message` TEXT, `timestamp` TEXT, `is_muc` INTEGER, `stanza_id` TEXT)"; + if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { + if (err_msg) { + log_error("SQLite error: %s", err_msg); + sqlite3_free(err_msg); + } else { + log_error("Unknown SQLite error"); + } + free(filename); + return FALSE; + } + + query = "CREATE TABLE IF NOT EXISTS `DbVersion` ( `dv_id` INTEGER PRIMARY KEY, `version` INTEGER UNIQUE)"; + if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { + if (err_msg) { + log_error("SQLite error: %s", err_msg); + sqlite3_free(err_msg); + } else { + log_error("Unknown SQLite error"); + } + free(filename); + return FALSE; + } + + query = "INSERT OR IGNORE INTO `DbVersion` (`version`) VALUES('1')"; if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { if (err_msg) { log_error("SQLite error: %s", err_msg); From a5a53c52deb55faef717f0472eda672a7e916305 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 23 Mar 2020 15:21:31 +0100 Subject: [PATCH 14/42] db: use goto in error case --- src/database.c | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/src/database.c b/src/database.c index 4e28813b..511a4921 100644 --- a/src/database.c +++ b/src/database.c @@ -102,43 +102,32 @@ log_database_init(ProfAccount *account) char *err_msg; char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `cl_id` INTEGER PRIMARY KEY, `jid` TEXT NOT NULL, `resource` TEXT, `message` TEXT, `timestamp` TEXT, `is_muc` INTEGER, `stanza_id` TEXT)"; if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { - if (err_msg) { - log_error("SQLite error: %s", err_msg); - sqlite3_free(err_msg); - } else { - log_error("Unknown SQLite error"); - } - free(filename); - return FALSE; + goto out; } query = "CREATE TABLE IF NOT EXISTS `DbVersion` ( `dv_id` INTEGER PRIMARY KEY, `version` INTEGER UNIQUE)"; if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { - if (err_msg) { - log_error("SQLite error: %s", err_msg); - sqlite3_free(err_msg); - } else { - log_error("Unknown SQLite error"); - } - free(filename); - return FALSE; + goto out; } query = "INSERT OR IGNORE INTO `DbVersion` (`version`) VALUES('1')"; if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { - if (err_msg) { - log_error("SQLite error: %s", err_msg); - sqlite3_free(err_msg); - } else { - log_error("Unknown SQLite error"); - } - free(filename); - return FALSE; + goto out; } log_debug("Initialized SQLite database: %s", filename); free(filename); return TRUE; + +out: + if (err_msg) { + log_error("SQLite error: %s", err_msg); + sqlite3_free(err_msg); + } else { + log_error("Unknown SQLite error"); + } + free(filename); + return FALSE; } void From dc0b7b5e91a38a9e65da440bd20668632fdde7bc Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 23 Mar 2020 15:52:13 +0100 Subject: [PATCH 15/42] db: log replace id --- src/database.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/database.c b/src/database.c index 511a4921..4a0a4406 100644 --- a/src/database.c +++ b/src/database.c @@ -100,7 +100,7 @@ log_database_init(ProfAccount *account) } char *err_msg; - char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `cl_id` INTEGER PRIMARY KEY, `jid` TEXT NOT NULL, `resource` TEXT, `message` TEXT, `timestamp` TEXT, `is_muc` INTEGER, `stanza_id` TEXT)"; + char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `cl_id` INTEGER PRIMARY KEY, `jid` TEXT NOT NULL, `resource` TEXT, `message` TEXT, `timestamp` TEXT, `is_muc` INTEGER, `stanza_id` TEXT, `replace_id` TEXT)"; if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { goto out; } @@ -152,8 +152,8 @@ log_database_add(ProfMessage *message, gboolean is_muc) { //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); - if (asprintf(&query, "INSERT INTO `ChatLogs` (`jid`, `resource`, `message`, `timestamp`, `is_muc`, `stanza_id`) VALUES ('%s', '%s', '%s', '%s', '%d', '%s')", - message->jid->barejid, message->jid->resourcepart, message->plain, date_fmt, is_muc, message->id) == -1) { + if (asprintf(&query, "INSERT INTO `ChatLogs` (`jid`, `resource`, `message`, `timestamp`, `is_muc`, `stanza_id`, `replace_id`) VALUES ('%s', '%s', '%s', '%s', '%d', '%s', '%s')", + message->jid->barejid, message->jid->resourcepart, message->plain, date_fmt, is_muc, message->id, message->replace_id) == -1) { log_error("log_database_add(): could not allocate memory"); return; } From c56443fea529b4ab78204ad4f8ada43b477ffe61 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Tue, 24 Mar 2020 11:16:04 +0100 Subject: [PATCH 16/42] db: fix inserting null in database --- src/database.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database.c b/src/database.c index 4a0a4406..09402bc5 100644 --- a/src/database.c +++ b/src/database.c @@ -153,7 +153,7 @@ log_database_add(ProfMessage *message, gboolean is_muc) { //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); if (asprintf(&query, "INSERT INTO `ChatLogs` (`jid`, `resource`, `message`, `timestamp`, `is_muc`, `stanza_id`, `replace_id`) VALUES ('%s', '%s', '%s', '%s', '%d', '%s', '%s')", - message->jid->barejid, message->jid->resourcepart, message->plain, date_fmt, is_muc, message->id, message->replace_id) == -1) { + message->jid->barejid, message->jid->resourcepart, message->plain, date_fmt, is_muc, message->id ? message->id : "", message->replace_id ? message->replace_id : "") == -1) { log_error("log_database_add(): could not allocate memory"); return; } From fe67102e716f4b1c7208c2b149a0b7be5a6d5a36 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 27 Mar 2020 18:29:03 +0100 Subject: [PATCH 17/42] db: make id autoincrement --- src/database.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database.c b/src/database.c index 09402bc5..a2be7f40 100644 --- a/src/database.c +++ b/src/database.c @@ -100,7 +100,7 @@ log_database_init(ProfAccount *account) } char *err_msg; - char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `cl_id` INTEGER PRIMARY KEY, `jid` TEXT NOT NULL, `resource` TEXT, `message` TEXT, `timestamp` TEXT, `is_muc` INTEGER, `stanza_id` TEXT, `replace_id` TEXT)"; + char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `jid` TEXT NOT NULL, `resource` TEXT, `message` TEXT, `timestamp` TEXT, `is_muc` INTEGER, `stanza_id` TEXT, `replace_id` TEXT)"; if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { goto out; } From 9278ba775b91eedef1b5ce1662681377205ff7b8 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 27 Mar 2020 19:09:29 +0100 Subject: [PATCH 18/42] db: add more needed fields DB fields should be complete now. --- src/database.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/database.c b/src/database.c index a2be7f40..2f363baf 100644 --- a/src/database.c +++ b/src/database.c @@ -81,10 +81,10 @@ gboolean log_database_init(ProfAccount *account) { int ret = sqlite3_initialize(); - if (ret != SQLITE_OK) { + if (ret != SQLITE_OK) { log_error("Error initializing SQLite database: %d", ret); return FALSE; - } + } char *filename = _get_db_filename(account); if (!filename) { @@ -100,17 +100,30 @@ log_database_init(ProfAccount *account) } char *err_msg; - char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `jid` TEXT NOT NULL, `resource` TEXT, `message` TEXT, `timestamp` TEXT, `is_muc` INTEGER, `stanza_id` TEXT, `replace_id` TEXT)"; + // id is the ID of DB the entry + // from_jid is the senders jid + // to_jid is the receivers jid + // from_resource is the senders resource + // to_jid is the receivers resource + // message is the message text + // timestamp the timestamp like "2020/03/24 11:12:14" + // type is there to distinguish: message, MUC message, muc pm + // stanza_id is the ID from XEP-0359: Unique and Stable Stanza IDs + // archive_id is the ID from XEP-0313: Message Archive Management + // replace_id is the ID from XEP-0308: Last Message Correction + // encryption is to distinguish: none, omemo, otr, pgp + // marked_read is 0/1 whether a message has been marked as read via XEP-0333: Chat Markers + char *query = "CREATE TABLE IF NOT EXISTS `ChatLogs` ( `id` INTEGER PRIMARY KEY AUTOINCREMENT, `from_jid` TEXT NOT NULL, `to_jid` TEXT NOT NULL, `from_resource` TEXT, `to_resource` TEXT, `message` TEXT, `timestamp` TEXT, `type` TEXT, `stanza_id` TEXT, `archive_id` TEXT, `replace_id` TEXT, `encryption` TEXT, `marked_read` INTEGER)"; if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { goto out; } - query = "CREATE TABLE IF NOT EXISTS `DbVersion` ( `dv_id` INTEGER PRIMARY KEY, `version` INTEGER UNIQUE)"; + query = "CREATE TABLE IF NOT EXISTS `DbVersion` ( `dv_id` INTEGER PRIMARY KEY, `version` INTEGER UNIQUE)"; if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { goto out; } - query = "INSERT OR IGNORE INTO `DbVersion` (`version`) VALUES('1')"; + query = "INSERT OR IGNORE INTO `DbVersion` (`version`) VALUES('1')"; if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { goto out; } @@ -148,11 +161,11 @@ log_database_add(ProfMessage *message, gboolean is_muc) { } char *err_msg; - char *query; + char *query; //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); - if (asprintf(&query, "INSERT INTO `ChatLogs` (`jid`, `resource`, `message`, `timestamp`, `is_muc`, `stanza_id`, `replace_id`) VALUES ('%s', '%s', '%s', '%s', '%d', '%s', '%s')", + if (asprintf(&query, "INSERT INTO `ChatLogs` (`jid`, `resource`, `message`, `timestamp`, `stanza_id`, `replace_id`) VALUES ('%s', '%s', '%s', '%d', '%s', '%s')", message->jid->barejid, message->jid->resourcepart, message->plain, date_fmt, is_muc, message->id ? message->id : "", message->replace_id ? message->replace_id : "") == -1) { log_error("log_database_add(): could not allocate memory"); return; From af2630a289cfd06c41614fd5eca5d2846adaefaa Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 27 Mar 2020 19:50:24 +0100 Subject: [PATCH 19/42] db: insert message type --- src/database.c | 18 ++++++++++++++---- src/database.h | 2 +- src/event/server_events.c | 13 +++++++------ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/database.c b/src/database.c index 2f363baf..782d3d5b 100644 --- a/src/database.c +++ b/src/database.c @@ -107,7 +107,7 @@ log_database_init(ProfAccount *account) // to_jid is the receivers resource // message is the message text // timestamp the timestamp like "2020/03/24 11:12:14" - // type is there to distinguish: message, MUC message, muc pm + // type is there to distinguish: message (chat), MUC message (muc), muc pm (mucpm) // stanza_id is the ID from XEP-0359: Unique and Stable Stanza IDs // archive_id is the ID from XEP-0313: Message Archive Management // replace_id is the ID from XEP-0308: Last Message Correction @@ -154,7 +154,7 @@ log_database_close(void) } void -log_database_add(ProfMessage *message, gboolean is_muc) { +log_database_add(ProfMessage *message, const char *const type) { if (!g_chatlog_database) { log_debug("log_database_add() called but db is not initialized"); return; @@ -163,10 +163,20 @@ log_database_add(ProfMessage *message, gboolean is_muc) { char *err_msg; char *query; + const char *jid = connection_get_fulljid(); + Jid *myjid = jid_create(jid); + //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); - if (asprintf(&query, "INSERT INTO `ChatLogs` (`jid`, `resource`, `message`, `timestamp`, `stanza_id`, `replace_id`) VALUES ('%s', '%s', '%s', '%d', '%s', '%s')", - message->jid->barejid, message->jid->resourcepart, message->plain, date_fmt, is_muc, message->id ? message->id : "", message->replace_id ? message->replace_id : "") == -1) { + if (asprintf(&query, "INSERT INTO `ChatLogs` (`from_jid`, `from_resource`, `to_jid`, `message`, `timestamp`, `stanza_id`, `replace_id`, `type`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", + message->jid->barejid, + message->jid->resourcepart, + myjid->barejid, + message->plain, + date_fmt, + message->id ? message->id : "", + message->replace_id ? message->replace_id : "", + type) == -1) { log_error("log_database_add(): could not allocate memory"); return; } diff --git a/src/database.h b/src/database.h index 9281e6e6..a0c252e7 100644 --- a/src/database.h +++ b/src/database.h @@ -41,7 +41,7 @@ #include "xmpp/xmpp.h" gboolean log_database_init(ProfAccount *account); -void log_database_add(ProfMessage *message, gboolean is_muc); +void log_database_add(ProfMessage *message, const char *const type); void log_database_close(void); #endif // DATABASE_H diff --git a/src/event/server_events.c b/src/event/server_events.c index 86176078..6e03725c 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -327,7 +327,7 @@ sv_ev_room_message(ProfMessage *message) GList *triggers = prefs_message_get_triggers(message->plain); _clean_incoming_message(message); - log_database_add(message, TRUE); + log_database_add(message, "muc"); mucwin_incoming_msg(mucwin, message, mentions, triggers, TRUE); g_slist_free(mentions); @@ -401,6 +401,7 @@ sv_ev_incoming_private_message(ProfMessage *message) } _clean_incoming_message(message); + log_database_add(message, "mucpm"); privwin_incoming_msg(privatewin, message); chat_log_msg_in(message); @@ -536,7 +537,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message if (message->plain) { message->enc = PROF_MSG_ENC_PGP; _clean_incoming_message(message); - log_database_add(message, FALSE); + log_database_add(message, "chat"); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_pgp_msg_in(message); @@ -552,7 +553,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message message->enc = PROF_MSG_ENC_PLAIN; message->plain = strdup(message->body); _clean_incoming_message(message); - log_database_add(message, FALSE); + log_database_add(message, "chat"); chatwin_incoming_msg(chatwin, message, new_win); chat_log_msg_in(message); chatwin->pgp_recv = FALSE; @@ -575,7 +576,7 @@ _sv_ev_incoming_otr(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message } _clean_incoming_message(message); - log_database_add(message, FALSE); + log_database_add(message, "chat"); chatwin_incoming_msg(chatwin, message, new_win); chat_log_otr_msg_in(message); @@ -591,7 +592,7 @@ static void _sv_ev_incoming_omemo(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message, gboolean logit) { _clean_incoming_message(message); - log_database_add(message, FALSE); + log_database_add(message, "chat"); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_omemo_msg_in(message); @@ -607,7 +608,7 @@ _sv_ev_incoming_plain(ProfChatWin *chatwin, gboolean new_win, ProfMessage *messa message->enc = PROF_MSG_ENC_PLAIN; message->plain = strdup(message->body); _clean_incoming_message(message); - log_database_add(message, FALSE); + log_database_add(message, "chat"); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_msg_in(message); From a4b53550ca302d7dab579585ac1aa5390880705c Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Mar 2020 00:04:41 +0100 Subject: [PATCH 20/42] Rename PROF_MSG_ENC_PLAIN to PROF_MSG_ENC_NONE --- src/event/client_events.c | 20 ++++++++++---------- src/event/server_events.c | 18 +++++++++--------- src/log.c | 2 +- src/otr/otr.c | 2 +- src/xmpp/message.c | 2 +- src/xmpp/xmpp.h | 2 +- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/event/client_events.c b/src/event/client_events.c index e0ea85d7..842ec362 100644 --- a/src/event/client_events.c +++ b/src/event/client_events.c @@ -145,7 +145,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (!handled) { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); - chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, request_receipt, replace_id); + chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } } @@ -165,7 +165,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (!handled) { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); - chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, request_receipt); + chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt); free(id); } @@ -188,7 +188,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * } else { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); - chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, request_receipt, replace_id); + chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } @@ -211,7 +211,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * } else { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); - chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, request_receipt, replace_id); + chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } @@ -236,7 +236,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (!handled) { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); - chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, request_receipt, replace_id); + chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } } @@ -265,7 +265,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * } else { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); - chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, request_receipt, replace_id); + chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } @@ -295,7 +295,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (!handled) { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); - chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, request_receipt, replace_id); + chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } } @@ -313,7 +313,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * #ifndef HAVE_OMEMO char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); - chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, request_receipt, replace_id); + chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); plugins_post_chat_message_send(chatwin->barejid, plugin_msg); @@ -352,7 +352,7 @@ cl_ev_send_muc_msg_corrected(ProfMucWin *mucwin, const char *const msg, const ch } else { char *id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url, replace_id); groupchat_log_msg_out(mucwin->roomjid, plugin_msg); - mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, replace_id); + mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_NONE, replace_id); free(id); } @@ -364,7 +364,7 @@ cl_ev_send_muc_msg_corrected(ProfMucWin *mucwin, const char *const msg, const ch #ifndef HAVE_OMEMO char *id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url, replace_id); groupchat_log_msg_out(mucwin->roomjid, plugin_msg); - mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_PLAIN, replace_id); + mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_NONE, replace_id); free(id); plugins_post_room_message_send(mucwin->roomjid, plugin_msg); diff --git a/src/event/server_events.c b/src/event/server_events.c index 6e03725c..f2d694a7 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -465,12 +465,12 @@ sv_ev_outgoing_carbon(ProfMessage *message) log_error("Couldn't decrypt GPG message and body was empty"); return; } - message->enc = PROF_MSG_ENC_PLAIN; + message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); chatwin_outgoing_carbon(chatwin, message); } } else { - message->enc = PROF_MSG_ENC_PLAIN; + message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); chatwin_outgoing_carbon(chatwin, message); } @@ -483,7 +483,7 @@ sv_ev_outgoing_carbon(ProfMessage *message) if (message->enc == PROF_MSG_ENC_OMEMO) { chatwin_outgoing_carbon(chatwin, message); } else { - message->enc = PROF_MSG_ENC_PLAIN; + message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); chatwin_outgoing_carbon(chatwin, message); } @@ -505,12 +505,12 @@ sv_ev_outgoing_carbon(ProfMessage *message) log_error("Couldn't decrypt GPG message and body was empty"); return; } - message->enc = PROF_MSG_ENC_PLAIN; + message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); chatwin_outgoing_carbon(chatwin, message); } } else { - message->enc = PROF_MSG_ENC_PLAIN; + message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); chatwin_outgoing_carbon(chatwin, message); } @@ -521,7 +521,7 @@ sv_ev_outgoing_carbon(ProfMessage *message) #ifndef HAVE_LIBGPGME #ifndef HAVE_OMEMO if (message->body) { - message->enc = PROF_MSG_ENC_PLAIN; + message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); chatwin_outgoing_carbon(chatwin, message); } @@ -550,7 +550,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message log_error("Couldn't decrypt GPG message and body was empty"); return; } - message->enc = PROF_MSG_ENC_PLAIN; + message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); _clean_incoming_message(message); log_database_add(message, "chat"); @@ -572,7 +572,7 @@ _sv_ev_incoming_otr(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message message->enc = PROF_MSG_ENC_OTR; chatwin->pgp_send = FALSE; } else { - message->enc = PROF_MSG_ENC_PLAIN; + message->enc = PROF_MSG_ENC_NONE; } _clean_incoming_message(message); @@ -605,7 +605,7 @@ static void _sv_ev_incoming_plain(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message, gboolean logit) { if (message->body) { - message->enc = PROF_MSG_ENC_PLAIN; + message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); _clean_incoming_message(message); log_database_add(message, "chat"); diff --git a/src/log.c b/src/log.c index 7304ed03..cd7802ef 100644 --- a/src/log.c +++ b/src/log.c @@ -355,7 +355,7 @@ chat_log_otr_msg_in(ProfMessage *message) const char *jid = connection_get_fulljid(); Jid *jidp = jid_create(jid); char *pref_otr_log = prefs_get_string(PREF_OTR_LOG); - if (message->enc == PROF_MSG_ENC_PLAIN || (strcmp(pref_otr_log, "on") == 0)) { + if (message->enc == PROF_MSG_ENC_NONE || (strcmp(pref_otr_log, "on") == 0)) { if (message->mucuser) { _chat_log_chat(jidp->barejid, message->jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, message->jid->resourcepart); } else { diff --git a/src/otr/otr.c b/src/otr/otr.c index c32e708e..ceef72fe 100644 --- a/src/otr/otr.c +++ b/src/otr/otr.c @@ -368,7 +368,7 @@ otr_on_message_send(ProfChatWin *chatwin, const char *const message, gboolean re if (policy == PROF_OTRPOLICY_OPPORTUNISTIC) { char *otr_tagged_msg = otr_tag_message(message); id = message_send_chat_otr(chatwin->barejid, otr_tagged_msg, request_receipt, replace_id); - chatwin_outgoing_msg(chatwin, message, id, PROF_MSG_ENC_PLAIN, request_receipt, replace_id); + chatwin_outgoing_msg(chatwin, message, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, message, NULL); free(otr_tagged_msg); free(id); diff --git a/src/xmpp/message.c b/src/xmpp/message.c index d116b8da..5f3b65ac 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -192,7 +192,7 @@ message_init(void) message->body = NULL; message->encrypted = NULL; message->plain = NULL; - message->enc = PROF_MSG_ENC_PLAIN; + message->enc = PROF_MSG_ENC_NONE; message->timestamp = NULL; message->trusted = true; message->mucuser = false; diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 85c49e03..fff2164f 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -120,7 +120,7 @@ typedef struct disco_item_t { } DiscoItem; typedef enum { - PROF_MSG_ENC_PLAIN, + PROF_MSG_ENC_NONE, PROF_MSG_ENC_OTR, PROF_MSG_ENC_PGP, PROF_MSG_ENC_OMEMO From 628b86f57e25a3804a6d8c1bd370e0ac69ced43d Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Mar 2020 00:18:13 +0100 Subject: [PATCH 21/42] db: add dedicated chat, muc, muc pm logging functions --- src/database.c | 21 ++++++++++++++++++++- src/database.h | 4 +++- src/event/server_events.c | 14 +++++++------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/database.c b/src/database.c index 782d3d5b..ae450f84 100644 --- a/src/database.c +++ b/src/database.c @@ -45,6 +45,9 @@ static sqlite3 *g_chatlog_database; +static void _add_incoming(ProfMessage *message, const char * const type); +static char* _get_db_filename(ProfAccount *account); + static char* _get_db_filename(ProfAccount *account) { @@ -154,7 +157,23 @@ log_database_close(void) } void -log_database_add(ProfMessage *message, const char *const type) { +log_database_add_incoming_chat(ProfMessage *message) { + _add_incoming(message, "chat"); +} + +void +log_database_add_incoming_muc(ProfMessage *message) { + _add_incoming(message, "muc"); +} + +void +log_database_add_incoming_muc_pm(ProfMessage *message) { + _add_incoming(message, "mucpm"); +} + +static void +_add_incoming(ProfMessage *message, const char * const type) +{ if (!g_chatlog_database) { log_debug("log_database_add() called but db is not initialized"); return; diff --git a/src/database.h b/src/database.h index a0c252e7..f3feb01f 100644 --- a/src/database.h +++ b/src/database.h @@ -41,7 +41,9 @@ #include "xmpp/xmpp.h" gboolean log_database_init(ProfAccount *account); -void log_database_add(ProfMessage *message, const char *const type); +void log_database_add_incoming_chat(ProfMessage *message); +void log_database_add_incoming_muc(ProfMessage *message); +void log_database_add_incoming_muc_pm(ProfMessage *message); void log_database_close(void); #endif // DATABASE_H diff --git a/src/event/server_events.c b/src/event/server_events.c index f2d694a7..6ca51bd2 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -327,7 +327,7 @@ sv_ev_room_message(ProfMessage *message) GList *triggers = prefs_message_get_triggers(message->plain); _clean_incoming_message(message); - log_database_add(message, "muc"); + log_database_add_incoming_muc(message); mucwin_incoming_msg(mucwin, message, mentions, triggers, TRUE); g_slist_free(mentions); @@ -401,7 +401,7 @@ sv_ev_incoming_private_message(ProfMessage *message) } _clean_incoming_message(message); - log_database_add(message, "mucpm"); + log_database_add_incoming_muc_pm(message); privwin_incoming_msg(privatewin, message); chat_log_msg_in(message); @@ -537,7 +537,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message if (message->plain) { message->enc = PROF_MSG_ENC_PGP; _clean_incoming_message(message); - log_database_add(message, "chat"); + log_database_add_incoming_chat(message); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_pgp_msg_in(message); @@ -553,7 +553,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); _clean_incoming_message(message); - log_database_add(message, "chat"); + log_database_add_incoming_chat(message); chatwin_incoming_msg(chatwin, message, new_win); chat_log_msg_in(message); chatwin->pgp_recv = FALSE; @@ -576,7 +576,7 @@ _sv_ev_incoming_otr(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message } _clean_incoming_message(message); - log_database_add(message, "chat"); + log_database_add_incoming_chat(message); chatwin_incoming_msg(chatwin, message, new_win); chat_log_otr_msg_in(message); @@ -592,7 +592,7 @@ static void _sv_ev_incoming_omemo(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message, gboolean logit) { _clean_incoming_message(message); - log_database_add(message, "chat"); + log_database_add_incoming_chat(message); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_omemo_msg_in(message); @@ -608,7 +608,7 @@ _sv_ev_incoming_plain(ProfChatWin *chatwin, gboolean new_win, ProfMessage *messa message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); _clean_incoming_message(message); - log_database_add(message, "chat"); + log_database_add_incoming_chat(message); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_msg_in(message); From def212321636b13a72fdff71431fc003ad791482 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Mar 2020 00:50:32 +0100 Subject: [PATCH 22/42] db: log outgoing message in one case Not all cases covered yet. --- src/database.c | 54 +++++++++++++++++++++++++++++++-------- src/database.h | 1 + src/event/client_events.c | 2 ++ 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/database.c b/src/database.c index ae450f84..a7910b4d 100644 --- a/src/database.c +++ b/src/database.c @@ -45,7 +45,7 @@ static sqlite3 *g_chatlog_database; -static void _add_incoming(ProfMessage *message, const char * const type); +static void _add_to_db(ProfMessage *message, const char * const type, const char * const from_jid, const char * const to_jid); static char* _get_db_filename(ProfAccount *account); static char* @@ -158,21 +158,56 @@ log_database_close(void) void log_database_add_incoming_chat(ProfMessage *message) { - _add_incoming(message, "chat"); + const char *jid = connection_get_fulljid(); + Jid *myjid = jid_create(jid); + + _add_to_db(message, "chat", message->jid->barejid, myjid->barejid); + + jid_destroy(myjid); } void log_database_add_incoming_muc(ProfMessage *message) { - _add_incoming(message, "muc"); + const char *jid = connection_get_fulljid(); + Jid *myjid = jid_create(jid); + + _add_to_db(message, "muc", message->jid->barejid, myjid->barejid); + + jid_destroy(myjid); } void log_database_add_incoming_muc_pm(ProfMessage *message) { - _add_incoming(message, "mucpm"); + const char *jid = connection_get_fulljid(); + Jid *myjid = jid_create(jid); + + _add_to_db(message, "mucpm", message->jid->barejid, myjid->barejid); + + jid_destroy(myjid); +} + +void +log_database_add_outgoing(const char * const id, const char * const barejid, const char * const message, const char *const replace_id) +{ + ProfMessage *msg = message_init(); + + msg->id = id ? strdup(id) : NULL; + msg->jid = jid_create(barejid); + msg->plain = message ? strdup(message) : NULL; + msg->replace_id = replace_id ? strdup(replace_id) : NULL; + msg->timestamp = g_date_time_new_now_local(); //TODO: get from outside. best to have whole ProfMessage from outside + + const char *jid = connection_get_fulljid(); + Jid *myjid = jid_create(jid); + + _add_to_db(msg, "chat", myjid->barejid, msg->jid->barejid); + + jid_destroy(myjid); + message_free(msg); } static void -_add_incoming(ProfMessage *message, const char * const type) +_add_to_db(ProfMessage *message, const char * const type, const char * const from_jid, const char * const to_jid) { if (!g_chatlog_database) { log_debug("log_database_add() called but db is not initialized"); @@ -182,15 +217,12 @@ _add_incoming(ProfMessage *message, const char * const type) char *err_msg; char *query; - const char *jid = connection_get_fulljid(); - Jid *myjid = jid_create(jid); - //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); if (asprintf(&query, "INSERT INTO `ChatLogs` (`from_jid`, `from_resource`, `to_jid`, `message`, `timestamp`, `stanza_id`, `replace_id`, `type`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", - message->jid->barejid, - message->jid->resourcepart, - myjid->barejid, + from_jid, + "test" /*message->jid->resourcepart*/, + to_jid, message->plain, date_fmt, message->id ? message->id : "", diff --git a/src/database.h b/src/database.h index f3feb01f..12425ef8 100644 --- a/src/database.h +++ b/src/database.h @@ -44,6 +44,7 @@ gboolean log_database_init(ProfAccount *account); void log_database_add_incoming_chat(ProfMessage *message); void log_database_add_incoming_muc(ProfMessage *message); void log_database_add_incoming_muc_pm(ProfMessage *message); +void log_database_add_outgoing(const char * const id, const char * const barejid, const char * const message, const char *const replace_id); void log_database_close(void); #endif // DATABASE_H diff --git a/src/event/client_events.c b/src/event/client_events.c index 842ec362..c6c1bdb4 100644 --- a/src/event/client_events.c +++ b/src/event/client_events.c @@ -40,6 +40,7 @@ #include #include "log.h" +#include "database.h" #include "config/preferences.h" #include "event/common.h" #include "plugins/plugins.h" @@ -295,6 +296,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (!handled) { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing(id, chatwin->barejid, plugin_msg, replace_id); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } From a0a4fd042648f0b936621b076694283dd577f016 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Mar 2020 01:16:31 +0100 Subject: [PATCH 23/42] db: log all incoming and outgoing messages --- src/database.c | 51 +++++++++++++++++++++++++-------------- src/database.h | 4 ++- src/event/client_events.c | 24 ++++++++++++++++-- src/otr/otr.c | 2 ++ src/xmpp/message.c | 6 ++--- src/xmpp/xmpp.h | 2 +- 6 files changed, 64 insertions(+), 25 deletions(-) diff --git a/src/database.c b/src/database.c index a7910b4d..6b94e1e5 100644 --- a/src/database.c +++ b/src/database.c @@ -156,38 +156,34 @@ log_database_close(void) } } -void -log_database_add_incoming_chat(ProfMessage *message) { +static void +_log_database_add_incoming(ProfMessage *message, const char * const type) +{ const char *jid = connection_get_fulljid(); Jid *myjid = jid_create(jid); - _add_to_db(message, "chat", message->jid->barejid, myjid->barejid); + _add_to_db(message, type, message->jid->barejid, myjid->barejid); jid_destroy(myjid); } +void +log_database_add_incoming_chat(ProfMessage *message) { + _log_database_add_incoming(message, "chat"); +} + void log_database_add_incoming_muc(ProfMessage *message) { - const char *jid = connection_get_fulljid(); - Jid *myjid = jid_create(jid); - - _add_to_db(message, "muc", message->jid->barejid, myjid->barejid); - - jid_destroy(myjid); + _log_database_add_incoming(message, "muc"); } void log_database_add_incoming_muc_pm(ProfMessage *message) { - const char *jid = connection_get_fulljid(); - Jid *myjid = jid_create(jid); - - _add_to_db(message, "mucpm", message->jid->barejid, myjid->barejid); - - jid_destroy(myjid); + _log_database_add_incoming(message, "mucpm"); } -void -log_database_add_outgoing(const char * const id, const char * const barejid, const char * const message, const char *const replace_id) +static void +_log_database_add_outgoing(const char * const type, const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc) { ProfMessage *msg = message_init(); @@ -196,16 +192,35 @@ log_database_add_outgoing(const char * const id, const char * const barejid, con msg->plain = message ? strdup(message) : NULL; msg->replace_id = replace_id ? strdup(replace_id) : NULL; msg->timestamp = g_date_time_new_now_local(); //TODO: get from outside. best to have whole ProfMessage from outside + msg->enc = enc; const char *jid = connection_get_fulljid(); Jid *myjid = jid_create(jid); - _add_to_db(msg, "chat", myjid->barejid, msg->jid->barejid); + _add_to_db(msg, type, myjid->barejid, msg->jid->barejid); jid_destroy(myjid); message_free(msg); } +void +log_database_add_outgoing_chat(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc) +{ + _log_database_add_outgoing("chat", id, barejid, message, replace_id, enc); +} + +void +log_database_add_outgoing_muc(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc) +{ + _log_database_add_outgoing("muc", id, barejid, message, replace_id, enc); +} + +void +log_database_add_outgoing_muc_pm(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc) +{ + _log_database_add_outgoing("mucpm", id, barejid, message, replace_id, enc); +} + static void _add_to_db(ProfMessage *message, const char * const type, const char * const from_jid, const char * const to_jid) { diff --git a/src/database.h b/src/database.h index 12425ef8..6361631d 100644 --- a/src/database.h +++ b/src/database.h @@ -44,7 +44,9 @@ gboolean log_database_init(ProfAccount *account); void log_database_add_incoming_chat(ProfMessage *message); void log_database_add_incoming_muc(ProfMessage *message); void log_database_add_incoming_muc_pm(ProfMessage *message); -void log_database_add_outgoing(const char * const id, const char * const barejid, const char * const message, const char *const replace_id); +void log_database_add_outgoing_chat(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); +void log_database_add_outgoing_muc(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); +void log_database_add_outgoing_muc_pm(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); void log_database_close(void); #endif // DATABASE_H diff --git a/src/event/client_events.c b/src/event/client_events.c index c6c1bdb4..a30665dc 100644 --- a/src/event/client_events.c +++ b/src/event/client_events.c @@ -139,6 +139,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (chatwin->pgp_send) { char *id = message_send_chat_pgp(chatwin->barejid, plugin_msg, request_receipt, replace_id); chat_log_pgp_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_PGP); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PGP, request_receipt, replace_id); free(id); } else { @@ -146,6 +147,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (!handled) { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } @@ -166,6 +168,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (!handled) { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt); free(id); } @@ -184,11 +187,13 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (chatwin->pgp_send) { char *id = message_send_chat_pgp(chatwin->barejid, plugin_msg, request_receipt, replace_id); chat_log_pgp_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_PGP); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PGP, request_receipt, replace_id); free(id); } else { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } @@ -207,11 +212,13 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (chatwin->is_omemo) { char *id = omemo_on_message_send((ProfWin *)chatwin, plugin_msg, request_receipt, FALSE, replace_id); chat_log_omemo_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_OMEMO); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_OMEMO, request_receipt, replace_id); free(id); } else { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } @@ -230,6 +237,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (chatwin->is_omemo) { char *id = omemo_on_message_send((ProfWin *)chatwin, plugin_msg, request_receipt, FALSE, replace_id); chat_log_omemo_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_OMEMO); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_OMEMO, request_receipt, replace_id); free(id); } else { @@ -237,6 +245,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (!handled) { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } @@ -256,16 +265,19 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (chatwin->is_omemo) { char *id = omemo_on_message_send((ProfWin *)chatwin, plugin_msg, request_receipt, FALSE, replace_id); chat_log_omemo_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_OMEMO); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_OMEMO, request_receipt, replace_id); free(id); } else if (chatwin->pgp_send) { char *id = message_send_chat_pgp(chatwin->barejid, plugin_msg, request_receipt, replace_id); chat_log_pgp_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_PGP); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PGP, request_receipt, replace_id); free(id); } else { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } @@ -284,11 +296,13 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (chatwin->is_omemo) { char *id = omemo_on_message_send((ProfWin *)chatwin, plugin_msg, request_receipt, FALSE, replace_id); chat_log_omemo_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_OMEMO); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_OMEMO, request_receipt, replace_id); free(id); } else if (chatwin->pgp_send) { char *id = message_send_chat_pgp(chatwin->barejid, plugin_msg, request_receipt, replace_id); chat_log_pgp_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_PGP); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_PGP, request_receipt, replace_id); free(id); } else { @@ -296,7 +310,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * if (!handled) { char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); - log_database_add_outgoing(id, chatwin->barejid, plugin_msg, replace_id); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); } @@ -315,6 +329,7 @@ cl_ev_send_msg_correct(ProfChatWin *chatwin, const char *const msg, const char * #ifndef HAVE_OMEMO char *id = message_send_chat(chatwin->barejid, plugin_msg, oob_url, request_receipt, replace_id); chat_log_msg_out(chatwin->barejid, plugin_msg, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); chatwin_outgoing_msg(chatwin, plugin_msg, id, PROF_MSG_ENC_NONE, request_receipt, replace_id); free(id); @@ -349,11 +364,13 @@ cl_ev_send_muc_msg_corrected(ProfMucWin *mucwin, const char *const msg, const ch if (mucwin->is_omemo) { char *id = omemo_on_message_send((ProfWin *)mucwin, plugin_msg, FALSE, TRUE, replace_id); groupchat_log_omemo_msg_out(mucwin->roomjid, plugin_msg); + log_database_add_outgoing_muc(id, mucwin->roomjid, plugin_msg, replace_id, PROF_MSG_ENC_OMEMO); mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_OMEMO, replace_id); free(id); } else { char *id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url, replace_id); groupchat_log_msg_out(mucwin->roomjid, plugin_msg); + log_database_add_outgoing_muc(id, mucwin->roomjid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_NONE, replace_id); free(id); } @@ -366,6 +383,7 @@ cl_ev_send_muc_msg_corrected(ProfMucWin *mucwin, const char *const msg, const ch #ifndef HAVE_OMEMO char *id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url, replace_id); groupchat_log_msg_out(mucwin->roomjid, plugin_msg); + log_database_add_outgoing_muc(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_NONE, replace_id); free(id); @@ -392,9 +410,11 @@ cl_ev_send_priv_msg(ProfPrivateWin *privwin, const char *const msg, const char * char *plugin_msg = plugins_pre_priv_message_send(privwin->fulljid, msg); Jid *jidp = jid_create(privwin->fulljid); - message_send_private(privwin->fulljid, plugin_msg, oob_url); + char *id = message_send_private(privwin->fulljid, plugin_msg, oob_url); chat_log_msg_out(jidp->barejid, plugin_msg, jidp->resourcepart); + log_database_add_outgoing_muc_pm(id, privwin->fulljid, plugin_msg, NULL, PROF_MSG_ENC_NONE); privwin_outgoing_msg(privwin, plugin_msg); + free(id); plugins_post_priv_message_send(privwin->fulljid, plugin_msg); diff --git a/src/otr/otr.c b/src/otr/otr.c index ceef72fe..3c3ed618 100644 --- a/src/otr/otr.c +++ b/src/otr/otr.c @@ -40,6 +40,7 @@ #include #include "log.h" +#include "database.h" #include "config/preferences.h" #include "config/files.h" #include "otr/otr.h" @@ -348,6 +349,7 @@ otr_on_message_send(ProfChatWin *chatwin, const char *const message, gboolean re if (encrypted) { id = message_send_chat_otr(chatwin->barejid, encrypted, request_receipt, replace_id); chat_log_otr_msg_out(chatwin->barejid, message, NULL); + log_database_add_outgoing_chat(id, chatwin->barejid, message, replace_id, PROF_MSG_ENC_OTR); chatwin_outgoing_msg(chatwin, message, id, PROF_MSG_ENC_OTR, request_receipt, replace_id); otr_free_message(encrypted); free(id); diff --git a/src/xmpp/message.c b/src/xmpp/message.c index 5f3b65ac..d482f258 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -508,7 +508,7 @@ message_send_chat_omemo(const char *const jid, uint32_t sid, GList *keys, } #endif -void +char* message_send_private(const char *const fulljid, const char *const msg, const char *const oob_url) { xmpp_ctx_t * const ctx = connection_get_ctx(); @@ -517,14 +517,14 @@ message_send_private(const char *const fulljid, const char *const msg, const cha xmpp_stanza_t *message = xmpp_message_new(ctx, STANZA_TYPE_CHAT, fulljid, id); xmpp_message_set_body(message, msg); - free(id); - if (oob_url) { stanza_attach_x_oob_url(ctx, message, oob_url); } _send_message_stanza(message); xmpp_stanza_release(message); + + return id; } char* diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index fff2164f..4d5d8279 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -175,7 +175,7 @@ char* message_send_chat(const char *const barejid, const char *const msg, const char* message_send_chat_otr(const char *const barejid, const char *const msg, gboolean request_receipt, const char *const replace_id); char* message_send_chat_pgp(const char *const barejid, const char *const msg, gboolean request_receipt, const char *const replace_id); char* message_send_chat_omemo(const char *const jid, uint32_t sid, GList *keys, const unsigned char *const iv, size_t iv_len, const unsigned char *const ciphertext, size_t ciphertext_len, gboolean request_receipt, gboolean muc, const char *const replace_id); -void message_send_private(const char *const fulljid, const char *const msg, const char *const oob_url); +char* message_send_private(const char *const fulljid, const char *const msg, const char *const oob_url); char* message_send_groupchat(const char *const roomjid, const char *const msg, const char *const oob_url, const char *const replace_id); void message_send_groupchat_subject(const char *const roomjid, const char *const subject); void message_send_inactive(const char *const jid); From 58bef8e5923a25ec2d91e157b04479500b76e971 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Mar 2020 01:19:39 +0100 Subject: [PATCH 24/42] db: dont log reflected MUC messages --- src/event/server_events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event/server_events.c b/src/event/server_events.c index 6ca51bd2..d1223082 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -301,6 +301,7 @@ static void _log_muc(ProfMessage *message) } else { groupchat_log_msg_in(message->jid->barejid, message->jid->resourcepart, message->plain); } + log_database_add_incoming_muc(message); } void @@ -327,7 +328,6 @@ sv_ev_room_message(ProfMessage *message) GList *triggers = prefs_message_get_triggers(message->plain); _clean_incoming_message(message); - log_database_add_incoming_muc(message); mucwin_incoming_msg(mucwin, message, mentions, triggers, TRUE); g_slist_free(mentions); From 6803fb5c3a1e5a28b57886fc8cdcac861c1cd412 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 28 Mar 2020 12:05:33 +0100 Subject: [PATCH 25/42] Fix message_send_private unittest stub --- tests/unittests/xmpp/stub_xmpp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c index 7ba1d428..2fa619af 100644 --- a/tests/unittests/xmpp/stub_xmpp.c +++ b/tests/unittests/xmpp/stub_xmpp.c @@ -116,11 +116,16 @@ char* message_send_chat_pgp(const char * const barejid, const char * const msg, return NULL; } -void message_send_private(const char * const fulljid, const char * const msg, const char *const oob_url) {} +char* message_send_private(const char *const fulljid, const char *const msg, const char *const oob_url) +{ + return NULL; +} + char* message_send_groupchat(const char *const roomjid, const char *const msg, const char *const oob_url, const char *const replace_id) { return NULL; } + void message_send_groupchat_subject(const char * const roomjid, const char * const subject) {} void message_send_inactive(const char * const barejid) {} From 4cc8df5929d2290cbb862d5faff6310aea5b7f86 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sun, 29 Mar 2020 18:51:12 +0200 Subject: [PATCH 26/42] Add log_database_add_*() test stubs --- tests/unittests/database/stub_database.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/unittests/database/stub_database.c b/tests/unittests/database/stub_database.c index d10ed87a..57ae408a 100644 --- a/tests/unittests/database/stub_database.c +++ b/tests/unittests/database/stub_database.c @@ -27,5 +27,10 @@ #include "database.h" gboolean log_database_init(ProfAccount *account) { return TRUE; } -void log_database_add(ProfMessage *message, gboolean is_muc) {} +void log_database_add_incoming_chat(ProfMessage *message) {} +void log_database_add_incoming_muc(ProfMessage *message) {} +void log_database_add_incoming_muc_pm(ProfMessage *message) {} +void log_database_add_outgoing_chat(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc) {} +void log_database_add_outgoing_muc(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc) {} +void log_database_add_outgoing_muc_pm(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc) {} void log_database_close(void) {} From 9224331df31fcc60e1906e06a4640b955d762a7a Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sun, 29 Mar 2020 19:56:25 +0200 Subject: [PATCH 27/42] Fix copy paste error --- src/event/client_events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event/client_events.c b/src/event/client_events.c index a30665dc..e57f3875 100644 --- a/src/event/client_events.c +++ b/src/event/client_events.c @@ -383,7 +383,7 @@ cl_ev_send_muc_msg_corrected(ProfMucWin *mucwin, const char *const msg, const ch #ifndef HAVE_OMEMO char *id = message_send_groupchat(mucwin->roomjid, plugin_msg, oob_url, replace_id); groupchat_log_msg_out(mucwin->roomjid, plugin_msg); - log_database_add_outgoing_muc(id, chatwin->barejid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); + log_database_add_outgoing_muc(id, mucwin->roomjid, plugin_msg, replace_id, PROF_MSG_ENC_NONE); mucwin_outgoing_msg(mucwin, plugin_msg, id, PROF_MSG_ENC_NONE, replace_id); free(id); From db502d7054139247fdf2b9145ce6621288c9785f Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 3 Apr 2020 11:56:30 +0200 Subject: [PATCH 28/42] db: log "from" resource --- src/database.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/database.c b/src/database.c index 6b94e1e5..d65565b2 100644 --- a/src/database.c +++ b/src/database.c @@ -45,7 +45,7 @@ static sqlite3 *g_chatlog_database; -static void _add_to_db(ProfMessage *message, const char * const type, const char * const from_jid, const char * const to_jid); +static void _add_to_db(ProfMessage *message, const char * const type, const Jid * const from_jid, const char * const to_jid); static char* _get_db_filename(ProfAccount *account); static char* @@ -162,7 +162,7 @@ _log_database_add_incoming(ProfMessage *message, const char * const type) const char *jid = connection_get_fulljid(); Jid *myjid = jid_create(jid); - _add_to_db(message, type, message->jid->barejid, myjid->barejid); + _add_to_db(message, type, message->jid, myjid->barejid); jid_destroy(myjid); } @@ -197,7 +197,7 @@ _log_database_add_outgoing(const char * const type, const char * const id, const const char *jid = connection_get_fulljid(); Jid *myjid = jid_create(jid); - _add_to_db(msg, type, myjid->barejid, msg->jid->barejid); + _add_to_db(msg, type, myjid, msg->jid->barejid); jid_destroy(myjid); message_free(msg); @@ -222,7 +222,7 @@ log_database_add_outgoing_muc_pm(const char * const id, const char * const barej } static void -_add_to_db(ProfMessage *message, const char * const type, const char * const from_jid, const char * const to_jid) +_add_to_db(ProfMessage *message, const char * const type, const Jid * const from_jid, const char * const to_jid) { if (!g_chatlog_database) { log_debug("log_database_add() called but db is not initialized"); @@ -235,8 +235,9 @@ _add_to_db(ProfMessage *message, const char * const type, const char * const fro //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); if (asprintf(&query, "INSERT INTO `ChatLogs` (`from_jid`, `from_resource`, `to_jid`, `message`, `timestamp`, `stanza_id`, `replace_id`, `type`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", - from_jid, - "test" /*message->jid->resourcepart*/, + from_jid->barejid, + from_jid->resourcepart, + //"test" /*message->jid->resourcepart*/, to_jid, message->plain, date_fmt, From 9b1aac04813423c27a5d1057b38c760219799809 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 3 Apr 2020 12:00:54 +0200 Subject: [PATCH 29/42] db: log "to" resource --- src/database.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/database.c b/src/database.c index d65565b2..6715356a 100644 --- a/src/database.c +++ b/src/database.c @@ -45,7 +45,7 @@ static sqlite3 *g_chatlog_database; -static void _add_to_db(ProfMessage *message, const char * const type, const Jid * const from_jid, const char * const to_jid); +static void _add_to_db(ProfMessage *message, const char * const type, const Jid * const from_jid, const Jid * const to_jid); static char* _get_db_filename(ProfAccount *account); static char* @@ -162,7 +162,7 @@ _log_database_add_incoming(ProfMessage *message, const char * const type) const char *jid = connection_get_fulljid(); Jid *myjid = jid_create(jid); - _add_to_db(message, type, message->jid, myjid->barejid); + _add_to_db(message, type, message->jid, myjid); jid_destroy(myjid); } @@ -197,7 +197,7 @@ _log_database_add_outgoing(const char * const type, const char * const id, const const char *jid = connection_get_fulljid(); Jid *myjid = jid_create(jid); - _add_to_db(msg, type, myjid, msg->jid->barejid); + _add_to_db(msg, type, myjid, msg->jid); jid_destroy(myjid); message_free(msg); @@ -222,7 +222,7 @@ log_database_add_outgoing_muc_pm(const char * const id, const char * const barej } static void -_add_to_db(ProfMessage *message, const char * const type, const Jid * const from_jid, const char * const to_jid) +_add_to_db(ProfMessage *message, const char * const type, const Jid * const from_jid, const Jid * const to_jid) { if (!g_chatlog_database) { log_debug("log_database_add() called but db is not initialized"); @@ -234,11 +234,11 @@ _add_to_db(ProfMessage *message, const char * const type, const Jid * const from //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); - if (asprintf(&query, "INSERT INTO `ChatLogs` (`from_jid`, `from_resource`, `to_jid`, `message`, `timestamp`, `stanza_id`, `replace_id`, `type`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", + if (asprintf(&query, "INSERT INTO `ChatLogs` (`from_jid`, `from_resource`, `to_jid`, `to_resource`, `message`, `timestamp`, `stanza_id`, `replace_id`, `type`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", from_jid->barejid, - from_jid->resourcepart, - //"test" /*message->jid->resourcepart*/, - to_jid, + from_jid->resourcepart ? from_jid->resourcepart : "", + to_jid->barejid, + to_jid->resourcepart ? to_jid->resourcepart : "", message->plain, date_fmt, message->id ? message->id : "", From 20850eb4db580ea9cb6193f420b9724a29ee63ea Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Fri, 3 Apr 2020 12:09:16 +0200 Subject: [PATCH 30/42] db: log encryption type --- src/database.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/database.c b/src/database.c index 6715356a..988bfeae 100644 --- a/src/database.c +++ b/src/database.c @@ -229,12 +229,28 @@ _add_to_db(ProfMessage *message, const char * const type, const Jid * const from return; } + char *enc; + switch (message->enc) { + case PROF_MSG_ENC_PGP: + enc = "pgp"; + break; + case PROF_MSG_ENC_OTR: + enc = "otr"; + break; + case PROF_MSG_ENC_OMEMO: + enc = "omemo"; + break; + case PROF_MSG_ENC_NONE: + default: + enc = "none"; + } + char *err_msg; char *query; //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); - if (asprintf(&query, "INSERT INTO `ChatLogs` (`from_jid`, `from_resource`, `to_jid`, `to_resource`, `message`, `timestamp`, `stanza_id`, `replace_id`, `type`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", + if (asprintf(&query, "INSERT INTO `ChatLogs` (`from_jid`, `from_resource`, `to_jid`, `to_resource`, `message`, `timestamp`, `stanza_id`, `replace_id`, `type`, `encryption`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", from_jid->barejid, from_jid->resourcepart ? from_jid->resourcepart : "", to_jid->barejid, @@ -243,7 +259,8 @@ _add_to_db(ProfMessage *message, const char * const type, const Jid * const from date_fmt, message->id ? message->id : "", message->replace_id ? message->replace_id : "", - type) == -1) { + type, + enc) == -1) { log_error("log_database_add(): could not allocate memory"); return; } From 5d54bb228f4ef750edefdd9423f8f672d045ff6c Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 12:11:08 +0200 Subject: [PATCH 31/42] Get regular chat history out of sql backend --- src/database.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- src/database.h | 1 + src/ui/chatwin.c | 27 ++++++++------------------- 3 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/database.c b/src/database.c index 988bfeae..f72ea5a0 100644 --- a/src/database.c +++ b/src/database.c @@ -247,9 +247,14 @@ _add_to_db(ProfMessage *message, const char * const type, const Jid * const from char *err_msg; char *query; + gchar *date_fmt; + + if (message->timestamp) { + date_fmt = g_date_time_format_iso8601(message->timestamp); + } else { + date_fmt = g_date_time_format_iso8601(g_date_time_new_now_local()); + } - //gchar *date_fmt = g_date_time_format_iso8601(message->timestamp); - gchar *date_fmt = g_date_time_format(message->timestamp, "%Y/%m/%d %H:%M:%S"); if (asprintf(&query, "INSERT INTO `ChatLogs` (`from_jid`, `from_resource`, `to_jid`, `to_resource`, `message`, `timestamp`, `stanza_id`, `replace_id`, `type`, `encryption`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", from_jid->barejid, from_jid->resourcepart ? from_jid->resourcepart : "", @@ -276,3 +281,40 @@ _add_to_db(ProfMessage *message, const char * const type, const Jid * const from } free(query); } + +GSList* +log_database_get_previous_chat(const gchar *const login, const gchar *const recipient) +{ + sqlite3_stmt *stmt = NULL; + char *query; + + if (asprintf(&query, "SELECT `message`, `timestamp`, `from_jid` from `ChatLogs` WHERE `from_jid` = '%s' OR `to_jid` = '%s' ORDER BY `id` ASC LIMIT 10", recipient, recipient) == -1) { + log_error("log_database_get_previous_chat(): could not allocate memory"); + return NULL; + } + + int rc = sqlite3_prepare_v2(g_chatlog_database, query, -1, &stmt, NULL); + if( rc!=SQLITE_OK ) { + log_error("log_database_get_previous_chat(): unknown SQLite error"); + return NULL; + } + + GSList *history = NULL; + + while( sqlite3_step(stmt) == SQLITE_ROW ) { + char *message = (char*)sqlite3_column_text(stmt, 0); + char *date = (char*)sqlite3_column_text(stmt, 1); + char *from = (char*)sqlite3_column_text(stmt, 2); + + ProfMessage *msg = message_init(); + msg->jid = jid_create(from); + msg->plain = strdup(message); + msg->timestamp = g_date_time_new_from_iso8601(date, NULL); + // TODO: later we can get more fields like 'enc'. then we can display the history like regular chats with all info the user enabled. + + history = g_slist_append(history, msg); + } + sqlite3_finalize(stmt); + + return history; +} diff --git a/src/database.h b/src/database.h index 6361631d..d0f6eb69 100644 --- a/src/database.h +++ b/src/database.h @@ -47,6 +47,7 @@ void log_database_add_incoming_muc_pm(ProfMessage *message); void log_database_add_outgoing_chat(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc_pm(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); +GSList* log_database_get_previous_chat(const gchar *const login, const gchar *const recipient); void log_database_close(void); #endif // DATABASE_H diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 9ebc8d76..41e70b40 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -44,6 +44,7 @@ #include "window_list.h" #include "xmpp/roster_list.h" #include "log.h" +#include "database.h" #include "config/preferences.h" #include "ui/ui.h" #include "ui/window.h" @@ -481,33 +482,21 @@ _chatwin_history(ProfChatWin *chatwin, const char *const contact) { if (!chatwin->history_shown) { Jid *jid = jid_create(connection_get_fulljid()); - GSList *history = chat_log_get_previous(jid->barejid, contact); + //GSList *history = chat_log_get_previous(jid->barejid, contact); + // TODO: jid not needed + GSList *history = log_database_get_previous_chat(jid->barejid, contact); jid_destroy(jid); GSList *curr = history; - int idd = 0; - int imo = 0; - int iyy = 0; while (curr) { - char *line = curr->data; - // entry, containing the actual entries with date followed by text - if (line[2] == ':') { - char hh[3]; memcpy(hh, &line[0], 2); hh[2] = '\0'; int ihh = atoi(hh); - char mm[3]; memcpy(mm, &line[3], 2); mm[2] = '\0'; int imm = atoi(mm); - char ss[3]; memcpy(ss, &line[6], 2); ss[2] = '\0'; int iss = atoi(ss); - GDateTime *timestamp = g_date_time_new_local(iyy, imo, idd, ihh, imm, iss); - win_print_history((ProfWin*)chatwin, timestamp, curr->data+11); - g_date_time_unref(timestamp); - // header, containing the date from filename "21/10/2019:" - } else { - char dd[3]; memcpy(dd, &line[0], 2); dd[2] = '\0'; idd = atoi(dd); - char mm[3]; memcpy(mm, &line[3], 2); mm[2] = '\0'; imo = atoi(mm); - char yy[5]; memcpy(yy, &line[6], 4); yy[4] = '\0'; iyy = atoi(yy); - } + ProfMessage *msg = curr->data; + // TODO: sender is lost right now + win_print_history((ProfWin*)chatwin, msg->timestamp, msg->plain); curr = g_slist_next(curr); } chatwin->history_shown = TRUE; + //TODO: message_free g_slist_free_full(history, free); } } From 0942d98c6116dc4b9b608e7483f1d6a8f62c84d7 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 14:42:52 +0200 Subject: [PATCH 32/42] Remove chat_log_get_previous() We now dont get the log files from the text files via chat_log_get_previous() anymore. We use the sql backend via log_database_get_previous_chat(). So far it just has the same behaviour like chat_log_get_previous(), except that in _chatwin_history() we don't pass the sender to win_print_history() which should be fixed in a commit soon. And log_database_get_previous_chat() can later easily be expanded to fix https://github.com/profanity-im/profanity/issues/205. --- src/database.c | 4 +-- src/database.h | 2 +- src/log.c | 48 ---------------------------------- src/log.h | 1 - src/ui/chatwin.c | 10 +++---- tests/unittests/log/stub_log.c | 5 ---- 6 files changed, 6 insertions(+), 64 deletions(-) diff --git a/src/database.c b/src/database.c index f72ea5a0..52403805 100644 --- a/src/database.c +++ b/src/database.c @@ -283,12 +283,12 @@ _add_to_db(ProfMessage *message, const char * const type, const Jid * const from } GSList* -log_database_get_previous_chat(const gchar *const login, const gchar *const recipient) +log_database_get_previous_chat(const gchar *const contact_barejid) { sqlite3_stmt *stmt = NULL; char *query; - if (asprintf(&query, "SELECT `message`, `timestamp`, `from_jid` from `ChatLogs` WHERE `from_jid` = '%s' OR `to_jid` = '%s' ORDER BY `id` ASC LIMIT 10", recipient, recipient) == -1) { + if (asprintf(&query, "SELECT `message`, `timestamp`, `from_jid` from `ChatLogs` WHERE `from_jid` = '%s' OR `to_jid` = '%s' ORDER BY `id` ASC LIMIT 10", contact_barejid, contact_barejid) == -1) { log_error("log_database_get_previous_chat(): could not allocate memory"); return NULL; } diff --git a/src/database.h b/src/database.h index d0f6eb69..4401e430 100644 --- a/src/database.h +++ b/src/database.h @@ -47,7 +47,7 @@ void log_database_add_incoming_muc_pm(ProfMessage *message); void log_database_add_outgoing_chat(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc_pm(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); -GSList* log_database_get_previous_chat(const gchar *const login, const gchar *const recipient); +GSList* log_database_get_previous_chat(const gchar *const contact_barejid); void log_database_close(void); #endif // DATABASE_H diff --git a/src/log.c b/src/log.c index cd7802ef..e35fb460 100644 --- a/src/log.c +++ b/src/log.c @@ -619,54 +619,6 @@ _groupchat_log_chat(const gchar *const login, const gchar *const room, const gch g_date_time_unref(dt); } -GSList* -chat_log_get_previous(const gchar *const login, const gchar *const recipient) -{ - GSList *history = NULL; - GDateTime *now = g_date_time_new_now_local(); - GDateTime *log_date = g_date_time_new(tz, - g_date_time_get_year(session_started), - g_date_time_get_month(session_started), - g_date_time_get_day_of_month(session_started), - g_date_time_get_hour(session_started), - g_date_time_get_minute(session_started), - g_date_time_get_second(session_started)); - - // get data from all logs from the day the session was started to today - while (g_date_time_compare(log_date, now) != 1) { - char *filename = _get_log_filename(recipient, login, log_date, FALSE); - - FILE *logp = fopen(filename, "r"); - if (logp) { - GString *header = g_string_new(""); - g_string_append_printf(header, "%d/%d/%d:", - g_date_time_get_day_of_month(log_date), - g_date_time_get_month(log_date), - g_date_time_get_year(log_date)); - history = g_slist_append(history, header->str); - g_string_free(header, FALSE); - - char *line; - while ((line = file_getline(logp)) != NULL) { - history = g_slist_append(history, line); - } - - fclose(logp); - } - - free(filename); - - GDateTime *next = g_date_time_add_days(log_date, 1); - g_date_time_unref(log_date); - log_date = next; - } - - g_date_time_unref(log_date); - g_date_time_unref(now); - - return history; -} - void chat_log_close(void) { diff --git a/src/log.h b/src/log.h index 592c4039..3e29e8ca 100644 --- a/src/log.h +++ b/src/log.h @@ -82,7 +82,6 @@ void chat_log_pgp_msg_in(ProfMessage *message); void chat_log_omemo_msg_in(ProfMessage *message); void chat_log_close(void); -GSList* chat_log_get_previous(const gchar *const login, const gchar *const recipient); void groupchat_log_init(void); diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 41e70b40..93cc9525 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -57,7 +57,7 @@ #include "omemo/omemo.h" #endif -static void _chatwin_history(ProfChatWin *chatwin, const char *const contact); +static void _chatwin_history(ProfChatWin *chatwin, const char *const contact_barejid); static void _chatwin_set_last_message(ProfChatWin *chatwin, const char *const id, const char *const message); ProfChatWin* @@ -478,14 +478,10 @@ chatwin_unset_outgoing_char(ProfChatWin *chatwin) } static void -_chatwin_history(ProfChatWin *chatwin, const char *const contact) +_chatwin_history(ProfChatWin *chatwin, const char *const contact_barejid) { if (!chatwin->history_shown) { - Jid *jid = jid_create(connection_get_fulljid()); - //GSList *history = chat_log_get_previous(jid->barejid, contact); - // TODO: jid not needed - GSList *history = log_database_get_previous_chat(jid->barejid, contact); - jid_destroy(jid); + GSList *history = log_database_get_previous_chat(contact_barejid); GSList *curr = history; while (curr) { diff --git a/tests/unittests/log/stub_log.c b/tests/unittests/log/stub_log.c index ecf415d0..5861a895 100644 --- a/tests/unittests/log/stub_log.c +++ b/tests/unittests/log/stub_log.c @@ -67,11 +67,6 @@ void chat_log_pgp_msg_in(ProfMessage *message) {} void chat_log_omemo_msg_in(ProfMessage *message) {} void chat_log_close(void) {} -GSList * chat_log_get_previous(const gchar * const login, - const gchar * const recipient) -{ - return mock_ptr_type(GSList *); -} void groupchat_log_init(void) {} void groupchat_log_msg_in(const gchar *const room, const gchar *const nick, const gchar *const msg) {} From 067bc690f28f32b59714579608a5f1469b1f5212 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 15:21:45 +0200 Subject: [PATCH 33/42] Adapt win_print_history() to work with muc too --- src/ui/chatwin.c | 3 +-- src/ui/mucwin.c | 17 +---------------- src/ui/window.c | 28 +++++++++++++++++++++++----- src/ui/window.h | 2 +- src/xmpp/xmpp.h | 1 + 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 93cc9525..34bf3902 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -486,8 +486,7 @@ _chatwin_history(ProfChatWin *chatwin, const char *const contact_barejid) while (curr) { ProfMessage *msg = curr->data; - // TODO: sender is lost right now - win_print_history((ProfWin*)chatwin, msg->timestamp, msg->plain); + win_print_history((ProfWin*)chatwin, msg, FALSE); curr = g_slist_next(curr); } chatwin->history_shown = TRUE; diff --git a/src/ui/mucwin.c b/src/ui/mucwin.c index 79a82a61..620ac704 100644 --- a/src/ui/mucwin.c +++ b/src/ui/mucwin.c @@ -373,22 +373,7 @@ mucwin_history(ProfMucWin *mucwin, const ProfMessage *const message) char *muc_history_color = prefs_get_string(PREF_HISTORY_COLOR_MUC); if (g_strcmp0(muc_history_color, "unanimous") == 0) { - GString *line = g_string_new(""); - - if (strncmp(message->plain, "/me ", 4) == 0) { - g_string_append(line, "*"); - g_string_append(line, nick); - g_string_append(line, " "); - g_string_append(line, message->plain + 4); - } else { - g_string_append(line, nick); - g_string_append(line, ": "); - g_string_append(line, message->plain); - } - - win_print_history(window, message->timestamp, line->str); - - g_string_free(line, TRUE); + win_print_history(window, message, TRUE); } else { char *mynick = muc_nick(mucwin->roomjid); GSList *mentions = get_mentions(prefs_get_boolean(PREF_NOTIFY_MENTION_WHOLE_WORD), prefs_get_boolean(PREF_NOTIFY_MENTION_CASE_SENSITIVE), message->plain, mynick); diff --git a/src/ui/window.c b/src/ui/window.c index fdf5d3f9..21f0f724 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -1218,15 +1218,33 @@ win_print_outgoing(ProfWin *window, const char *show_char, const char *const id, } void -win_print_history(ProfWin *window, GDateTime *timestamp, const char *const message) +win_print_history(ProfWin *window, const ProfMessage *const message, gboolean is_muc) { - g_date_time_ref(timestamp); + g_date_time_ref(message->timestamp); - buffer_append(window->layout->buffer, "-", 0, timestamp, 0, THEME_TEXT_HISTORY, "", NULL, message, NULL, NULL); - _win_print_internal(window, "-", 0, timestamp, 0, THEME_TEXT_HISTORY, "", message, NULL); + int flags = 0; + + // TODO: ProfMessage needs a 'type' field like we have in sql db. then we can know whether each message is a chat, muc, mucpm + char *display_name; + if (is_muc) { + display_name = strdup(message->jid->resourcepart); + + char *muc_history_color = prefs_get_string(PREF_HISTORY_COLOR_MUC); + if (g_strcmp0(muc_history_color, "unanimous") == 0) { + flags = NO_COLOUR_FROM; + } + g_free(muc_history_color); + } else { + display_name = roster_get_msg_display_name(message->jid->barejid, message->jid->resourcepart); + } + + buffer_append(window->layout->buffer, "-", 0, message->timestamp, flags, THEME_TEXT_HISTORY, display_name, NULL, message->plain, NULL, NULL); + _win_print_internal(window, "-", 0, message->timestamp, flags, THEME_TEXT_HISTORY, display_name, message->plain, NULL); + + free(display_name); inp_nonblocking(TRUE); - g_date_time_unref(timestamp); + g_date_time_unref(message->timestamp); } void diff --git a/src/ui/window.h b/src/ui/window.h index d17560bc..378dae24 100644 --- a/src/ui/window.h +++ b/src/ui/window.h @@ -68,7 +68,7 @@ void win_print_outgoing(ProfWin *window, const char *show_char, const char *cons void win_print_outgoing_with_receipt(ProfWin *window, const char *show_char, const char *const from, const char *const message, char *id, const char *const replace_id); void win_println_incoming_muc_msg(ProfWin *window, char *show_char, int flags, const ProfMessage *const message); void win_print_outgoing_muc_msg(ProfWin *window, char *show_char, const char *const me, const char *const id, const char *const replace_id, const char *const message); -void win_print_history(ProfWin *window, GDateTime *timestamp, const char *const message); +void win_print_history(ProfWin *window, const ProfMessage *const message, gboolean is_muc); void win_print_http_upload(ProfWin *window, const char *const message, char *url); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 4d5d8279..02d62d01 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -126,6 +126,7 @@ typedef enum { PROF_MSG_ENC_OMEMO } prof_enc_t; +// TODO: ProfMessage needs a 'type' field like we have in sql db. then we can know whether each message is a chat, muc, mucpm typedef struct prof_message_t { Jid *jid; char *id; From bd116e6ad9d8beaae14de12668c71ea736f43324 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 15:48:23 +0200 Subject: [PATCH 34/42] win_print_history() print 'me' on regular chats if we wrote the message Same behaviour like when we used to get it from the text files. --- src/ui/window.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ui/window.c b/src/ui/window.c index 21f0f724..5b0aec8b 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -1235,7 +1235,15 @@ win_print_history(ProfWin *window, const ProfMessage *const message, gboolean is } g_free(muc_history_color); } else { - display_name = roster_get_msg_display_name(message->jid->barejid, message->jid->resourcepart); + const char *jid = connection_get_fulljid(); + Jid *jidp = jid_create(jid); + + if (g_strcmp0(jidp->barejid, message->jid->barejid) == 0) { + display_name = strdup("me"); + } else { + display_name = roster_get_msg_display_name(message->jid->barejid, message->jid->resourcepart); + } + jid_destroy(jidp); } buffer_append(window->layout->buffer, "-", 0, message->timestamp, flags, THEME_TEXT_HISTORY, display_name, NULL, message->plain, NULL, NULL); From 1afb708533b5dd1cf73c945f7c8a13baccb1644f Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 15:55:22 +0200 Subject: [PATCH 35/42] Add sql to error log so we can more easily grep for it. --- src/database.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/database.c b/src/database.c index 52403805..b343f18d 100644 --- a/src/database.c +++ b/src/database.c @@ -266,7 +266,7 @@ _add_to_db(ProfMessage *message, const char * const type, const Jid * const from message->replace_id ? message->replace_id : "", type, enc) == -1) { - log_error("log_database_add(): could not allocate memory"); + log_error("log_database_add(): SQL query. could not allocate memory"); return; } g_free(date_fmt); @@ -289,7 +289,7 @@ log_database_get_previous_chat(const gchar *const contact_barejid) char *query; if (asprintf(&query, "SELECT `message`, `timestamp`, `from_jid` from `ChatLogs` WHERE `from_jid` = '%s' OR `to_jid` = '%s' ORDER BY `id` ASC LIMIT 10", contact_barejid, contact_barejid) == -1) { - log_error("log_database_get_previous_chat(): could not allocate memory"); + log_error("log_database_get_previous_chat(): SQL query. could not allocate memory"); return NULL; } From 5862e5b159bae4fdf75388067a0a9ae6869a255e Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 16:04:34 +0200 Subject: [PATCH 36/42] db: Fix memleaks --- src/database.c | 1 + src/ui/chatwin.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/database.c b/src/database.c index b343f18d..c48f2f95 100644 --- a/src/database.c +++ b/src/database.c @@ -315,6 +315,7 @@ log_database_get_previous_chat(const gchar *const contact_barejid) history = g_slist_append(history, msg); } sqlite3_finalize(stmt); + free(query); return history; } diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 34bf3902..5e2ac8c2 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -491,8 +491,7 @@ _chatwin_history(ProfChatWin *chatwin, const char *const contact_barejid) } chatwin->history_shown = TRUE; - //TODO: message_free - g_slist_free_full(history, free); + g_slist_free_full(history, (GDestroyNotify)message_free); } } From 3524a53c7c61783f021111755a5617b56bfaa234 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 18:37:39 +0200 Subject: [PATCH 37/42] Add type field to ProfMessage The mucuser boolean is not now needed anymore. --- src/event/server_events.c | 2 +- src/log.c | 14 +++++++------- src/xmpp/message.c | 12 ++++++++---- src/xmpp/xmpp.h | 13 +++++++++++-- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/event/server_events.c b/src/event/server_events.c index d1223082..e75db88e 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -445,7 +445,7 @@ sv_ev_outgoing_carbon(ProfMessage *message) chat_state_active(chatwin->state); if (message->plain) { - if (message->mucuser) { + if (message->type == PROF_MSG_TYPE_MUCPM) { // MUC PM, should have resource (nick) in filename chat_log_msg_out(message->jid->barejid, message->plain, message->jid->resourcepart); } else { diff --git a/src/log.c b/src/log.c index e35fb460..ae8f1542 100644 --- a/src/log.c +++ b/src/log.c @@ -356,13 +356,13 @@ chat_log_otr_msg_in(ProfMessage *message) Jid *jidp = jid_create(jid); char *pref_otr_log = prefs_get_string(PREF_OTR_LOG); if (message->enc == PROF_MSG_ENC_NONE || (strcmp(pref_otr_log, "on") == 0)) { - if (message->mucuser) { + if (message->type == PROF_MSG_TYPE_MUCPM) { _chat_log_chat(jidp->barejid, message->jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, message->jid->resourcepart); } else { _chat_log_chat(jidp->barejid, message->jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, NULL); } } else if (strcmp(pref_otr_log, "redact") == 0) { - if (message->mucuser) { + if (message->type == PROF_MSG_TYPE_MUCPM) { _chat_log_chat(jidp->barejid, message->jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, message->jid->resourcepart); } else { _chat_log_chat(jidp->barejid, message->jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, NULL); @@ -381,13 +381,13 @@ chat_log_pgp_msg_in(ProfMessage *message) Jid *jidp = jid_create(jid); char *pref_pgp_log = prefs_get_string(PREF_PGP_LOG); if (strcmp(pref_pgp_log, "on") == 0) { - if (message->mucuser) { + if (message->type == PROF_MSG_TYPE_MUCPM) { _chat_log_chat(jidp->barejid, message->jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, message->jid->resourcepart); } else { _chat_log_chat(jidp->barejid, message->jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, NULL); } } else if (strcmp(pref_pgp_log, "redact") == 0) { - if (message->mucuser) { + if (message->type == PROF_MSG_TYPE_MUCPM) { _chat_log_chat(jidp->barejid, message->jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, message->jid->resourcepart); } else { _chat_log_chat(jidp->barejid, message->jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, NULL); @@ -406,13 +406,13 @@ chat_log_omemo_msg_in(ProfMessage *message) Jid *jidp = jid_create(jid); char *pref_omemo_log = prefs_get_string(PREF_OMEMO_LOG); if (strcmp(pref_omemo_log, "on") == 0) { - if (message->mucuser) { + if (message->type == PROF_MSG_TYPE_MUCPM) { _chat_log_chat(jidp->barejid, message->jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, message->jid->resourcepart); } else { _chat_log_chat(jidp->barejid, message->jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, NULL); } } else if (strcmp(pref_omemo_log, "redact") == 0) { - if (message->mucuser) { + if (message->type == PROF_MSG_TYPE_MUCPM) { _chat_log_chat(jidp->barejid, message->jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, message->jid->resourcepart); } else { _chat_log_chat(jidp->barejid, message->jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, message->jid->resourcepart); @@ -430,7 +430,7 @@ chat_log_msg_in(ProfMessage *message) const char *jid = connection_get_fulljid(); Jid *jidp = jid_create(jid); - if (message->mucuser) { + if (message->type == PROF_MSG_TYPE_MUCPM) { _chat_log_chat(jidp->barejid, message->jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, message->jid->resourcepart); } else { _chat_log_chat(jidp->barejid, message->jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, NULL); diff --git a/src/xmpp/message.c b/src/xmpp/message.c index d482f258..81928d90 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -110,6 +110,7 @@ _message_handler(xmpp_conn_t *const conn, xmpp_stanza_t *const stanza, void *con _handle_error(stanza); } + // if muc if (g_strcmp0(type, STANZA_TYPE_GROUPCHAT) == 0) { _handle_groupchat(stanza); } @@ -195,7 +196,7 @@ message_init(void) message->enc = PROF_MSG_ENC_NONE; message->timestamp = NULL; message->trusted = true; - message->mucuser = false; + message->type = PROF_MSG_TYPE_UNINITIALIZED; return message; } @@ -831,6 +832,7 @@ _handle_groupchat(xmpp_stanza_t *const stanza) ProfMessage *message = message_init(); message->jid = jid; + message->type = PROF_MSG_TYPE_MUC; if (id) { message->id = strdup(id); @@ -977,7 +979,7 @@ _handle_muc_private_message(xmpp_stanza_t *const stanza) { // standard chat message, use jid without resource ProfMessage *message = message_init(); - message->mucuser = TRUE; + message->type = PROF_MSG_TYPE_MUCPM; const gchar *from = xmpp_stanza_get_from(stanza); message->jid = jid_create(from); @@ -1062,11 +1064,12 @@ _handle_carbons(xmpp_stanza_t *const stanza) } ProfMessage *message = message_init(); + message->type = PROF_MSG_TYPE_CHAT; // check whether message was a MUC PM xmpp_stanza_t *mucuser = xmpp_stanza_get_child_by_ns(message_stanza, STANZA_NS_MUC_USER); if (mucuser) { - message->mucuser = TRUE; + message->type = PROF_MSG_TYPE_MUCPM; } // id @@ -1181,6 +1184,7 @@ _handle_chat(xmpp_stanza_t *const stanza) // standard chat message, use jid without resource ProfMessage *message = message_init(); message->jid = jid; + message->type = PROF_MSG_TYPE_CHAT; // message stanza id const char *id = xmpp_stanza_get_id(stanza); @@ -1197,7 +1201,7 @@ _handle_chat(xmpp_stanza_t *const stanza) } if (mucuser) { - message->mucuser = TRUE; + message->type = PROF_MSG_TYPE_MUCPM; } message->timestamp = stanza_get_delay(stanza); diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 02d62d01..e6f5c13e 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -126,7 +126,16 @@ typedef enum { PROF_MSG_ENC_OMEMO } prof_enc_t; -// TODO: ProfMessage needs a 'type' field like we have in sql db. then we can know whether each message is a chat, muc, mucpm +typedef enum { + PROF_MSG_TYPE_UNINITIALIZED, + // regular 1:1 chat + PROF_MSG_TYPE_CHAT, + // groupchats to whole group + PROF_MSG_TYPE_MUC, + // groupchat private message + PROF_MSG_TYPE_MUCPM +} prof_msg_type_t; + typedef struct prof_message_t { Jid *jid; char *id; @@ -143,7 +152,7 @@ typedef struct prof_message_t { GDateTime *timestamp; prof_enc_t enc; gboolean trusted; - gboolean mucuser; + prof_msg_type_t type; } ProfMessage; void session_init(void); From 3b2976c9cb740c5cbd45547e26e725f2bae847a2 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 18:55:20 +0200 Subject: [PATCH 38/42] db: Use type from message struct instead of having individual functions --- src/database.c | 166 +++++++++++++++++++------------------- src/database.h | 4 +- src/event/server_events.c | 14 ++-- 3 files changed, 93 insertions(+), 91 deletions(-) diff --git a/src/database.c b/src/database.c index c48f2f95..e3026ea1 100644 --- a/src/database.c +++ b/src/database.c @@ -45,7 +45,7 @@ static sqlite3 *g_chatlog_database; -static void _add_to_db(ProfMessage *message, const char * const type, const Jid * const from_jid, const Jid * const to_jid); +static void _add_to_db(ProfMessage *message, char *type, const Jid * const from_jid, const Jid * const to_jid); static char* _get_db_filename(ProfAccount *account); static char* @@ -156,34 +156,19 @@ log_database_close(void) } } -static void -_log_database_add_incoming(ProfMessage *message, const char * const type) +void +log_database_add_incoming(ProfMessage *message) { const char *jid = connection_get_fulljid(); Jid *myjid = jid_create(jid); - _add_to_db(message, type, message->jid, myjid); + _add_to_db(message, NULL, message->jid, myjid); jid_destroy(myjid); } -void -log_database_add_incoming_chat(ProfMessage *message) { - _log_database_add_incoming(message, "chat"); -} - -void -log_database_add_incoming_muc(ProfMessage *message) { - _log_database_add_incoming(message, "muc"); -} - -void -log_database_add_incoming_muc_pm(ProfMessage *message) { - _log_database_add_incoming(message, "mucpm"); -} - static void -_log_database_add_outgoing(const char * const type, const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc) +_log_database_add_outgoing(char *type, const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc) { ProfMessage *msg = message_init(); @@ -221,67 +206,6 @@ log_database_add_outgoing_muc_pm(const char * const id, const char * const barej _log_database_add_outgoing("mucpm", id, barejid, message, replace_id, enc); } -static void -_add_to_db(ProfMessage *message, const char * const type, const Jid * const from_jid, const Jid * const to_jid) -{ - if (!g_chatlog_database) { - log_debug("log_database_add() called but db is not initialized"); - return; - } - - char *enc; - switch (message->enc) { - case PROF_MSG_ENC_PGP: - enc = "pgp"; - break; - case PROF_MSG_ENC_OTR: - enc = "otr"; - break; - case PROF_MSG_ENC_OMEMO: - enc = "omemo"; - break; - case PROF_MSG_ENC_NONE: - default: - enc = "none"; - } - - char *err_msg; - char *query; - gchar *date_fmt; - - if (message->timestamp) { - date_fmt = g_date_time_format_iso8601(message->timestamp); - } else { - date_fmt = g_date_time_format_iso8601(g_date_time_new_now_local()); - } - - if (asprintf(&query, "INSERT INTO `ChatLogs` (`from_jid`, `from_resource`, `to_jid`, `to_resource`, `message`, `timestamp`, `stanza_id`, `replace_id`, `type`, `encryption`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", - from_jid->barejid, - from_jid->resourcepart ? from_jid->resourcepart : "", - to_jid->barejid, - to_jid->resourcepart ? to_jid->resourcepart : "", - message->plain, - date_fmt, - message->id ? message->id : "", - message->replace_id ? message->replace_id : "", - type, - enc) == -1) { - log_error("log_database_add(): SQL query. could not allocate memory"); - return; - } - g_free(date_fmt); - - if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { - if (err_msg) { - log_error("SQLite error: %s", err_msg); - sqlite3_free(err_msg); - } else { - log_error("Unknown SQLite error"); - } - } - free(query); -} - GSList* log_database_get_previous_chat(const gchar *const contact_barejid) { @@ -319,3 +243,83 @@ log_database_get_previous_chat(const gchar *const contact_barejid) return history; } + +static const char* _get_message_type_str(prof_msg_type_t type) { + switch (type) { + case PROF_MSG_TYPE_CHAT: + return "chat"; + case PROF_MSG_TYPE_MUC: + return "muc"; + case PROF_MSG_TYPE_MUCPM: + return "mucpm"; + case PROF_MSG_TYPE_UNINITIALIZED: + return NULL; + } + return NULL; +} + +static const char* _get_message_enc_str(prof_enc_t enc) { + switch (enc) { + case PROF_MSG_ENC_PGP: + return "pgp"; + case PROF_MSG_ENC_OTR: + return "otr"; + case PROF_MSG_ENC_OMEMO: + return "omemo"; + case PROF_MSG_ENC_NONE: + return "none"; + } + + return "none"; +} + +static void +_add_to_db(ProfMessage *message, char *type, const Jid * const from_jid, const Jid * const to_jid) +{ + if (!g_chatlog_database) { + log_debug("log_database_add() called but db is not initialized"); + return; + } + + char *err_msg; + char *query; + gchar *date_fmt; + + if (message->timestamp) { + date_fmt = g_date_time_format_iso8601(message->timestamp); + } else { + date_fmt = g_date_time_format_iso8601(g_date_time_new_now_local()); + } + + const char *enc = _get_message_enc_str(message->enc); + + if (!type) { + type = (char*)_get_message_type_str(message->type); + } + + if (asprintf(&query, "INSERT INTO `ChatLogs` (`from_jid`, `from_resource`, `to_jid`, `to_resource`, `message`, `timestamp`, `stanza_id`, `replace_id`, `type`, `encryption`) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')", + from_jid->barejid, + from_jid->resourcepart ? from_jid->resourcepart : "", + to_jid->barejid, + to_jid->resourcepart ? to_jid->resourcepart : "", + message->plain, + date_fmt, + message->id ? message->id : "", + message->replace_id ? message->replace_id : "", + type, + enc) == -1) { + log_error("log_database_add(): SQL query. could not allocate memory"); + return; + } + g_free(date_fmt); + + if( SQLITE_OK != sqlite3_exec(g_chatlog_database, query, NULL, 0, &err_msg)) { + if (err_msg) { + log_error("SQLite error: %s", err_msg); + sqlite3_free(err_msg); + } else { + log_error("Unknown SQLite error"); + } + } + free(query); +} diff --git a/src/database.h b/src/database.h index 4401e430..4ad3fc9c 100644 --- a/src/database.h +++ b/src/database.h @@ -41,9 +41,7 @@ #include "xmpp/xmpp.h" gboolean log_database_init(ProfAccount *account); -void log_database_add_incoming_chat(ProfMessage *message); -void log_database_add_incoming_muc(ProfMessage *message); -void log_database_add_incoming_muc_pm(ProfMessage *message); +void log_database_add_incoming(ProfMessage *message); void log_database_add_outgoing_chat(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc_pm(const char * const id, const char * const barejid, const char * const message, const char *const replace_id, prof_enc_t enc); diff --git a/src/event/server_events.c b/src/event/server_events.c index e75db88e..b63af3b6 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -301,7 +301,7 @@ static void _log_muc(ProfMessage *message) } else { groupchat_log_msg_in(message->jid->barejid, message->jid->resourcepart, message->plain); } - log_database_add_incoming_muc(message); + log_database_add_incoming(message); } void @@ -401,7 +401,7 @@ sv_ev_incoming_private_message(ProfMessage *message) } _clean_incoming_message(message); - log_database_add_incoming_muc_pm(message); + log_database_add_incoming(message); privwin_incoming_msg(privatewin, message); chat_log_msg_in(message); @@ -537,7 +537,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message if (message->plain) { message->enc = PROF_MSG_ENC_PGP; _clean_incoming_message(message); - log_database_add_incoming_chat(message); + log_database_add_incoming(message); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_pgp_msg_in(message); @@ -553,7 +553,7 @@ _sv_ev_incoming_pgp(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); _clean_incoming_message(message); - log_database_add_incoming_chat(message); + log_database_add_incoming(message); chatwin_incoming_msg(chatwin, message, new_win); chat_log_msg_in(message); chatwin->pgp_recv = FALSE; @@ -576,7 +576,7 @@ _sv_ev_incoming_otr(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message } _clean_incoming_message(message); - log_database_add_incoming_chat(message); + log_database_add_incoming(message); chatwin_incoming_msg(chatwin, message, new_win); chat_log_otr_msg_in(message); @@ -592,7 +592,7 @@ static void _sv_ev_incoming_omemo(ProfChatWin *chatwin, gboolean new_win, ProfMessage *message, gboolean logit) { _clean_incoming_message(message); - log_database_add_incoming_chat(message); + log_database_add_incoming(message); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_omemo_msg_in(message); @@ -608,7 +608,7 @@ _sv_ev_incoming_plain(ProfChatWin *chatwin, gboolean new_win, ProfMessage *messa message->enc = PROF_MSG_ENC_NONE; message->plain = strdup(message->body); _clean_incoming_message(message); - log_database_add_incoming_chat(message); + log_database_add_incoming(message); chatwin_incoming_msg(chatwin, message, new_win); if (logit) { chat_log_msg_in(message); From 015c5d83d02c2e9300ac799671fb4a237fe37751 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 19:05:23 +0200 Subject: [PATCH 39/42] db: get last messages sorted by timestamp --- src/database.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database.c b/src/database.c index e3026ea1..340f59b2 100644 --- a/src/database.c +++ b/src/database.c @@ -212,7 +212,7 @@ log_database_get_previous_chat(const gchar *const contact_barejid) sqlite3_stmt *stmt = NULL; char *query; - if (asprintf(&query, "SELECT `message`, `timestamp`, `from_jid` from `ChatLogs` WHERE `from_jid` = '%s' OR `to_jid` = '%s' ORDER BY `id` ASC LIMIT 10", contact_barejid, contact_barejid) == -1) { + if (asprintf(&query, "SELECT `message`, `timestamp`, `from_jid` from `ChatLogs` WHERE `from_jid` = '%s' OR `to_jid` = '%s' ORDER BY `timestamp` ASC LIMIT 10", contact_barejid, contact_barejid) == -1) { log_error("log_database_get_previous_chat(): SQL query. could not allocate memory"); return NULL; } From fb4f82b82c81a9b05be8709f41602c8711f1cae9 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 19:44:03 +0200 Subject: [PATCH 40/42] db: actually display the last 10 entries in correct order --- src/database.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/database.c b/src/database.c index 340f59b2..714c4b1a 100644 --- a/src/database.c +++ b/src/database.c @@ -212,7 +212,7 @@ log_database_get_previous_chat(const gchar *const contact_barejid) sqlite3_stmt *stmt = NULL; char *query; - if (asprintf(&query, "SELECT `message`, `timestamp`, `from_jid` from `ChatLogs` WHERE `from_jid` = '%s' OR `to_jid` = '%s' ORDER BY `timestamp` ASC LIMIT 10", contact_barejid, contact_barejid) == -1) { + if (asprintf(&query, "SELECT * FROM (SELECT `message`, `timestamp`, `from_jid` from `ChatLogs` WHERE `from_jid` = '%s' OR `to_jid` = '%s' ORDER BY `timestamp` DESC LIMIT 10) ORDER BY `timestamp` ASC;", contact_barejid, contact_barejid) == -1) { log_error("log_database_get_previous_chat(): SQL query. could not allocate memory"); return NULL; } From 0becb683410eb31ba080968ff5d1db31b1166083 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 21:15:51 +0200 Subject: [PATCH 41/42] Add comment what id is about --- src/xmpp/xmpp.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index e6f5c13e..10b1a724 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -138,6 +138,7 @@ typedef enum { typedef struct prof_message_t { Jid *jid; + /* regular */ char *id; /* XEP-0359 */ char *originid; From 6218a537276ca9c5e6ca3f6956759421c9425c23 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Mon, 6 Apr 2020 21:17:42 +0200 Subject: [PATCH 42/42] Add hint about future ProfMessage Id needs --- src/xmpp/xmpp.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 10b1a724..c83869a5 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -144,6 +144,7 @@ typedef struct prof_message_t { char *originid; /* XEP-0308 LMC */ char *replace_id; + /* for MAM we will need archive_id (also XEP-0359) (see database.c) /* The raw body from xmpp message, either plaintext or OTR encrypted text */ char *body; /* The encrypted message as for PGP */