diff options
Diffstat (limited to 'src')
38 files changed, 313 insertions, 477 deletions
diff --git a/src/chatlog.c b/src/chatlog.c index c154d916..90cac638 100644 --- a/src/chatlog.c +++ b/src/chatlog.c @@ -96,13 +96,12 @@ chat_log_otr_msg_out(const char* const barejid, const char* const msg, const cha { if (prefs_get_boolean(PREF_CHLOG)) { char* mybarejid = connection_get_barejid(); - char* pref_otr_log = prefs_get_string(PREF_OTR_LOG); + auto_gchar gchar* pref_otr_log = prefs_get_string(PREF_OTR_LOG); if (strcmp(pref_otr_log, "on") == 0) { _chat_log_chat(mybarejid, barejid, msg, PROF_OUT_LOG, NULL, resource); } else if (strcmp(pref_otr_log, "redact") == 0) { _chat_log_chat(mybarejid, barejid, "[redacted]", PROF_OUT_LOG, NULL, resource); } - g_free(pref_otr_log); free(mybarejid); } } @@ -112,13 +111,12 @@ chat_log_pgp_msg_out(const char* const barejid, const char* const msg, const cha { if (prefs_get_boolean(PREF_CHLOG)) { char* mybarejid = connection_get_barejid(); - char* pref_pgp_log = prefs_get_string(PREF_PGP_LOG); + auto_gchar gchar* pref_pgp_log = prefs_get_string(PREF_PGP_LOG); if (strcmp(pref_pgp_log, "on") == 0) { _chat_log_chat(mybarejid, barejid, msg, PROF_OUT_LOG, NULL, resource); } else if (strcmp(pref_pgp_log, "redact") == 0) { _chat_log_chat(mybarejid, barejid, "[redacted]", PROF_OUT_LOG, NULL, resource); } - g_free(pref_pgp_log); free(mybarejid); } } @@ -128,13 +126,12 @@ chat_log_omemo_msg_out(const char* const barejid, const char* const msg, const c { if (prefs_get_boolean(PREF_CHLOG)) { char* mybarejid = connection_get_barejid(); - char* pref_omemo_log = prefs_get_string(PREF_OMEMO_LOG); + auto_gchar gchar* pref_omemo_log = prefs_get_string(PREF_OMEMO_LOG); if (strcmp(pref_omemo_log, "on") == 0) { _chat_log_chat(mybarejid, barejid, msg, PROF_OUT_LOG, NULL, resource); } else if (strcmp(pref_omemo_log, "redact") == 0) { _chat_log_chat(mybarejid, barejid, "[redacted]", PROF_OUT_LOG, NULL, resource); } - g_free(pref_omemo_log); free(mybarejid); } } @@ -144,7 +141,7 @@ chat_log_otr_msg_in(ProfMessage* message) { if (prefs_get_boolean(PREF_CHLOG)) { char* mybarejid = connection_get_barejid(); - char* pref_otr_log = prefs_get_string(PREF_OTR_LOG); + auto_gchar gchar* pref_otr_log = prefs_get_string(PREF_OTR_LOG); if (message->enc == PROF_MSG_ENC_NONE || (strcmp(pref_otr_log, "on") == 0)) { if (message->type == PROF_MSG_TYPE_MUCPM) { _chat_log_chat(mybarejid, message->from_jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, message->from_jid->resourcepart); @@ -158,7 +155,6 @@ chat_log_otr_msg_in(ProfMessage* message) _chat_log_chat(mybarejid, message->from_jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, NULL); } } - g_free(pref_otr_log); free(mybarejid); } } @@ -168,7 +164,7 @@ chat_log_pgp_msg_in(ProfMessage* message) { if (prefs_get_boolean(PREF_CHLOG)) { char* mybarejid = connection_get_barejid(); - char* pref_pgp_log = prefs_get_string(PREF_PGP_LOG); + auto_gchar gchar* pref_pgp_log = prefs_get_string(PREF_PGP_LOG); if (strcmp(pref_pgp_log, "on") == 0) { if (message->type == PROF_MSG_TYPE_MUCPM) { _chat_log_chat(mybarejid, message->from_jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, message->from_jid->resourcepart); @@ -182,7 +178,6 @@ chat_log_pgp_msg_in(ProfMessage* message) _chat_log_chat(mybarejid, message->from_jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, NULL); } } - g_free(pref_pgp_log); free(mybarejid); } } @@ -192,7 +187,7 @@ chat_log_omemo_msg_in(ProfMessage* message) { if (prefs_get_boolean(PREF_CHLOG)) { char* mybarejid = connection_get_barejid(); - char* pref_omemo_log = prefs_get_string(PREF_OMEMO_LOG); + auto_gchar gchar* pref_omemo_log = prefs_get_string(PREF_OMEMO_LOG); if (strcmp(pref_omemo_log, "on") == 0) { if (message->type == PROF_MSG_TYPE_MUCPM) { _chat_log_chat(mybarejid, message->from_jid->barejid, message->plain, PROF_IN_LOG, message->timestamp, message->from_jid->resourcepart); @@ -206,7 +201,6 @@ chat_log_omemo_msg_in(ProfMessage* message) _chat_log_chat(mybarejid, message->from_jid->barejid, "[redacted]", PROF_IN_LOG, message->timestamp, message->from_jid->resourcepart); } } - g_free(pref_omemo_log); free(mybarejid); } } @@ -272,7 +266,7 @@ _chat_log_chat(const char* const login, const char* const other, const char* con g_date_time_ref(timestamp); } - gchar* date_fmt = g_date_time_format_iso8601(timestamp); + auto_gchar gchar* date_fmt = g_date_time_format_iso8601(timestamp); FILE* chatlogp = fopen(dated_log->filename, "a"); g_chmod(dated_log->filename, S_IRUSR | S_IWUSR); if (chatlogp) { @@ -304,7 +298,6 @@ _chat_log_chat(const char* const login, const char* const other, const char* con } } - g_free(date_fmt); g_date_time_unref(timestamp); } @@ -342,7 +335,7 @@ groupchat_log_omemo_msg_out(const gchar* const room, const gchar* const msg) { if (prefs_get_boolean(PREF_CHLOG)) { char* mybarejid = connection_get_barejid(); - char* pref_omemo_log = prefs_get_string(PREF_OMEMO_LOG); + auto_gchar gchar* pref_omemo_log = prefs_get_string(PREF_OMEMO_LOG); char* mynick = muc_nick(room); if (strcmp(pref_omemo_log, "on") == 0) { @@ -351,7 +344,6 @@ groupchat_log_omemo_msg_out(const gchar* const room, const gchar* const msg) _groupchat_log_chat(mybarejid, room, mynick, "[redacted]"); } - g_free(pref_omemo_log); free(mybarejid); } } @@ -360,17 +352,14 @@ void groupchat_log_omemo_msg_in(const gchar* const room, const gchar* const nick, const gchar* const msg) { if (prefs_get_boolean(PREF_CHLOG)) { - char* mybarejid = connection_get_barejid(); - char* pref_omemo_log = prefs_get_string(PREF_OMEMO_LOG); + auto_char char* mybarejid = connection_get_barejid(); + auto_gchar gchar* pref_omemo_log = prefs_get_string(PREF_OMEMO_LOG); if (strcmp(pref_omemo_log, "on") == 0) { _groupchat_log_chat(mybarejid, room, nick, msg); } else if (strcmp(pref_omemo_log, "redact") == 0) { _groupchat_log_chat(mybarejid, room, nick, "[redacted]"); } - - g_free(pref_omemo_log); - free(mybarejid); } } @@ -393,7 +382,7 @@ _groupchat_log_chat(const gchar* const login, const gchar* const room, const gch GDateTime* dt_tmp = g_date_time_new_now_local(); - gchar* date_fmt = g_date_time_format_iso8601(dt_tmp); + auto_gchar gchar* date_fmt = g_date_time_format_iso8601(dt_tmp); FILE* grpchatlogp = fopen(dated_log->filename, "a"); g_chmod(dated_log->filename, S_IRUSR | S_IWUSR); @@ -411,7 +400,6 @@ _groupchat_log_chat(const gchar* const login, const gchar* const room, const gch } } - g_free(date_fmt); g_date_time_unref(dt_tmp); } @@ -425,21 +413,16 @@ chat_log_close(void) static char* _get_log_filename(const char* const other, const char* const login, GDateTime* dt, gboolean is_room) { - gchar* chatlogs_dir = files_file_in_account_data_path(DIR_CHATLOGS, login, is_room ? "rooms" : NULL); - gchar* logfile_name = g_date_time_format(dt, "%Y_%m_%d.log"); - gchar* other_ = str_replace(other, "@", "_at_"); - gchar* logs_path = g_strdup_printf("%s/%s", chatlogs_dir, other_); + auto_gchar gchar* chatlogs_dir = files_file_in_account_data_path(DIR_CHATLOGS, login, is_room ? "rooms" : NULL); + auto_gchar gchar* logfile_name = g_date_time_format(dt, "%Y_%m_%d.log"); + auto_gchar gchar* other_ = str_replace(other, "@", "_at_"); + auto_gchar gchar* logs_path = g_strdup_printf("%s/%s", chatlogs_dir, other_); gchar* logfile_path = NULL; if (create_dir(logs_path)) { logfile_path = g_strdup_printf("%s/%s", logs_path, logfile_name); } - g_free(logs_path); - g_free(other_); - g_free(logfile_name); - g_free(chatlogs_dir); - return logfile_path; } diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c index deda8abe..48d712e4 100644 --- a/src/command/cmd_ac.c +++ b/src/command/cmd_ac.c @@ -125,7 +125,7 @@ static char* _logging_autocomplete(ProfWin* window, const char* const input, gbo static char* _color_autocomplete(ProfWin* window, const char* const input, gboolean previous); static char* _avatar_autocomplete(ProfWin* window, const char* const input, gboolean previous); static char* _correction_autocomplete(ProfWin* window, const char* const input, gboolean previous); -static char* _correct_autocomplete(ProfWin* window, const char* const input, gboolean previous); +static gchar* _correct_autocomplete(ProfWin* window, const char* const input, gboolean previous); static char* _software_autocomplete(ProfWin* window, const char* const input, gboolean previous); static char* _url_autocomplete(ProfWin* window, const char* const input, gboolean previous); static char* _executable_autocomplete(ProfWin* window, const char* const input, gboolean previous); @@ -277,6 +277,7 @@ static Autocomplete correction_ac; static Autocomplete avatar_ac; static Autocomplete url_ac; static Autocomplete executable_ac; +static Autocomplete executable_param_ac; static Autocomplete intype_ac; static Autocomplete mood_ac; static Autocomplete mood_type_ac; @@ -1115,6 +1116,11 @@ cmd_ac_init(void) autocomplete_add(executable_ac, "urlopen"); autocomplete_add(executable_ac, "urlsave"); autocomplete_add(executable_ac, "editor"); + autocomplete_add(executable_ac, "vcard_photo"); + + executable_param_ac = autocomplete_new(); + autocomplete_add(executable_param_ac, "set"); + autocomplete_add(executable_param_ac, "default"); intype_ac = autocomplete_new(); autocomplete_add(intype_ac, "console"); @@ -1701,6 +1707,7 @@ cmd_ac_reset(ProfWin* window) autocomplete_reset(avatar_ac); autocomplete_reset(url_ac); autocomplete_reset(executable_ac); + autocomplete_reset(executable_param_ac); autocomplete_reset(intype_ac); autocomplete_reset(mood_ac); autocomplete_reset(mood_type_ac); @@ -1888,6 +1895,7 @@ cmd_ac_uninit(void) autocomplete_free(avatar_ac); autocomplete_free(url_ac); autocomplete_free(executable_ac); + autocomplete_free(executable_param_ac); autocomplete_free(intype_ac); autocomplete_free(adhoc_cmd_ac); autocomplete_free(lastactivity_ac); @@ -4291,17 +4299,15 @@ _avatar_autocomplete(ProfWin* window, const char* const input, gboolean previous static char* _correction_autocomplete(ProfWin* window, const char* const input, gboolean previous) { - char* result = NULL; - - result = autocomplete_param_with_ac(input, "/correction", correction_ac, TRUE, previous); + char* result = autocomplete_param_with_ac(input, "/correction", correction_ac, TRUE, previous); return result; } -static char* +static gchar* _correct_autocomplete(ProfWin* window, const char* const input, gboolean previous) { - char* result = g_strdup_printf("/correct %s", win_get_last_sent_message(window)); + gchar* result = g_strdup_printf("/correct %s", win_get_last_sent_message(window)); return result; } @@ -4381,6 +4387,31 @@ _executable_autocomplete(ProfWin* window, const char* const input, gboolean prev { char* result = NULL; + result = autocomplete_param_with_ac(input, "/executable avatar", executable_param_ac, TRUE, previous); + if (result) { + return result; + } + + result = autocomplete_param_with_ac(input, "/executable urlopen", executable_param_ac, TRUE, previous); + if (result) { + return result; + } + + result = autocomplete_param_with_ac(input, "/executable urlsave", executable_param_ac, TRUE, previous); + if (result) { + return result; + } + + result = autocomplete_param_with_ac(input, "/executable vcard_photo", executable_param_ac, TRUE, previous); + if (result) { + return result; + } + + result = autocomplete_param_with_ac(input, "/executable editor", executable_param_ac, TRUE, previous); + if (result) { + return result; + } + result = autocomplete_param_with_ac(input, "/executable", executable_ac, TRUE, previous); return result; diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 3b9fccfd..e8a97398 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -2438,7 +2438,7 @@ static const struct cmd_t command_defs[] = { { "set <path>", "Set avatar to the image at <path>." }, { "disable", "Disable avatar publishing; your avatar will not display to others." }, { "get <barejid>", "Download the avatar. barejid is the JID to download avatar from." }, - { "open <barejid>", "Download avatar and open it with command." }) + { "open <barejid>", "Download avatar and open it with command. See /executable." }) CMD_EXAMPLES( "/avatar set ~/images/avatar.png", "/avatar disable", @@ -2535,23 +2535,27 @@ static const struct cmd_t command_defs[] = { CMD_TAGS( CMD_TAG_DISCOVERY) CMD_SYN( - "/executable avatar <cmd>", + "/executable avatar set <cmdtemplate>", + "/executable avatar default", "/executable urlopen set <cmdtemplate>", "/executable urlopen default", "/executable urlsave set <cmdtemplate>", "/executable urlsave default", "/executable editor set <cmdtemplate>", + "/executable editor default", "/executable vcard_photo set <cmdtemplate>", "/executable vcard_photo default") CMD_DESC( "Configure executable that should be called upon a certain command.") CMD_ARGS( - { "avatar", "Set executable that is run by /avatar open. Use your favorite image viewer." }, + { "avatar set", "Set executable that is run by /avatar open. Use your favorite image viewer." }, + { "avatar default", "Restore to default settings." }, { "urlopen set", "Set executable that is run by /url open. Takes a command template that replaces %u and %p with the URL and path respectively." }, { "urlopen default", "Restore to default settings." }, { "urlsave set", "Set executable that is run by /url save. Takes a command template that replaces %u and %p with the URL and path respectively." }, { "urlsave default", "Use the built-in download method for saving." }, { "editor set", "Set editor to be used with /editor. Needs a terminal editor or a script to run a graphical editor." }, + { "editor default", "Restore to default settings." }, { "vcard_photo set", "Set executable that is run by /vcard photo open. Takes a command template that replaces %p with the path" }, { "vcard_photo default", "Restore to default settings." }) CMD_EXAMPLES( @@ -2578,10 +2582,10 @@ static const struct cmd_t command_defs[] = { "/url open <url>", "/url save <url> [<path>]") CMD_DESC( - "Deal with URLs") + "Open or save URLs. This works with OMEMO encrypted files as well.") CMD_ARGS( { "open", "Open URL with predefined executable." }, - { "save", "Save URL to optional path, default path is current directory" }) + { "save", "Save URL to optional path, default path is current directory." }) CMD_EXAMPLES( "/url open https://profanity-im.github.io", "/url save https://profanity-im.github.io/guide/latest/userguide.html /home/user/Download/") diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c index 70546a0b..e5ff8116 100644 --- a/src/command/cmd_funcs.c +++ b/src/command/cmd_funcs.c @@ -6578,7 +6578,8 @@ cmd_reconnect(ProfWin* window, const char* const command, gchar** args) int intval = 0; char* err_msg = NULL; if (g_strcmp0(value, "now") == 0) { - session_reconnect_now(); + cons_show("Reconnecting now."); + cl_ev_reconnect(); } else if (strtoi_range(value, &intval, 0, INT_MAX, &err_msg)) { prefs_set_reconnect(intval); if (intval == 0) { @@ -9343,9 +9344,6 @@ cmd_avatar(ProfWin* window, const char* const command, gchar** args) avatar_get_by_nick(args[1], false); } else if (g_strcmp0(args[0], "open") == 0) { avatar_get_by_nick(args[1], true); - } else if (g_strcmp0(args[0], "cmd") == 0) { - prefs_set_string(PREF_AVATAR_CMD, args[1]); - cons_show("Avatar cmd set to: %s", args[1]); } else { cons_bad_cmd_usage(command); } @@ -9645,15 +9643,7 @@ cmd_url_save(ProfWin* window, const char* const command, gchar** args) } gboolean -cmd_executable_avatar(ProfWin* window, const char* const command, gchar** args) -{ - prefs_set_string(PREF_AVATAR_CMD, args[1]); - cons_show("`avatar` command set to invoke '%s'", args[1]); - return TRUE; -} - -gboolean -cmd_executable_urlopen(ProfWin* window, const char* const command, gchar** args) +_cmd_executable_template(const preference_t setting, const char* command, gchar** args) { guint num_args = g_strv_length(args); if (num_args < 2) { @@ -9663,14 +9653,17 @@ cmd_executable_urlopen(ProfWin* window, const char* const command, gchar** args) if (g_strcmp0(args[1], "set") == 0 && num_args >= 3) { gchar* str = g_strjoinv(" ", &args[2]); - prefs_set_string(PREF_URL_OPEN_CMD, str); - cons_show("`url open` command set to invoke '%s'", str); + prefs_set_string(setting, str); + cons_show("`%s` command set to invoke '%s'", command, str); g_free(str); } else if (g_strcmp0(args[1], "default") == 0) { - prefs_set_string(PREF_URL_OPEN_CMD, NULL); - gchar* def = prefs_get_string(PREF_URL_OPEN_CMD); - cons_show("`url open` command set to invoke %s (default)", def); + prefs_set_string(setting, NULL); + gchar* def = prefs_get_string(setting); + if (def == NULL) { + def = g_strdup("built-in method"); + } + cons_show("`%s` command set to invoke %s (default)", command, def); g_free(def); } else { cons_bad_cmd_usage(command); @@ -9680,63 +9673,35 @@ cmd_executable_urlopen(ProfWin* window, const char* const command, gchar** args) } gboolean -cmd_executable_urlsave(ProfWin* window, const char* const command, gchar** args) +cmd_executable_avatar(ProfWin* window, const char* const command, gchar** args) { + return _cmd_executable_template(PREF_AVATAR_CMD, args[0], args); +} - guint num_args = g_strv_length(args); - if (num_args < 2) { - cons_bad_cmd_usage(command); - return TRUE; - } - - if (g_strcmp0(args[1], "set") == 0 && num_args >= 3) { - gchar* str = g_strjoinv(" ", &args[2]); - prefs_set_string(PREF_URL_SAVE_CMD, str); - cons_show("`url save` command set to invoke '%s'", str); - g_free(str); - - } else if (g_strcmp0(args[1], "default") == 0) { - prefs_set_string(PREF_URL_SAVE_CMD, NULL); - cons_show("`url save` will use built-in download method (default)"); - } else { - cons_bad_cmd_usage(command); - } +gboolean +cmd_executable_urlopen(ProfWin* window, const char* const command, gchar** args) +{ + return _cmd_executable_template(PREF_URL_OPEN_CMD, args[0], args); +} - return TRUE; +gboolean +cmd_executable_urlsave(ProfWin* window, const char* const command, gchar** args) +{ + return _cmd_executable_template(PREF_URL_SAVE_CMD, args[0], args); } gboolean cmd_executable_editor(ProfWin* window, const char* const command, gchar** args) { - guint num_args = g_strv_length(args); - - if (g_strcmp0(args[1], "set") == 0 && num_args >= 3) { - prefs_set_string(PREF_COMPOSE_EDITOR, args[2]); - cons_show("`editor` command set to invoke '%s'", args[2]); - } else { - cons_bad_cmd_usage(command); - } - - return TRUE; + return _cmd_executable_template(PREF_COMPOSE_EDITOR, args[0], args); } gboolean cmd_executable_vcard_photo(ProfWin* window, const char* const command, gchar** args) { - if (g_strcmp0(args[1], "set") == 0 && args[2] != NULL) { - prefs_set_string(PREF_VCARD_PHOTO_CMD, args[2]); - cons_show("`vcard photo open` command set to invoke '%s'", args[2]); - } else if (g_strcmp0(args[1], "default") == 0) { - prefs_set_string(PREF_VCARD_PHOTO_CMD, NULL); - char* cmd = prefs_get_string(PREF_VCARD_PHOTO_CMD); - cons_show("`vcard photo open` command set to invoke '%s' (default)", cmd); - g_free(cmd); - } else { - cons_bad_cmd_usage(command); - } - - return TRUE; + return _cmd_executable_template(PREF_VCARD_PHOTO_CMD, args[0], args); } + gboolean cmd_mam(ProfWin* window, const char* const command, gchar** args) { diff --git a/src/common.c b/src/common.c index 1ba27a63..c1a47c2d 100644 --- a/src/common.c +++ b/src/common.c @@ -457,14 +457,11 @@ GSList* get_mentions(gboolean whole_word, gboolean case_sensitive, const char* const message, const char* const nick) { GSList* mentions = NULL; - gchar* message_search = case_sensitive ? g_strdup(message) : g_utf8_strdown(message, -1); - gchar* mynick_search = case_sensitive ? g_strdup(nick) : g_utf8_strdown(nick, -1); + auto_gchar gchar* message_search = case_sensitive ? g_strdup(message) : g_utf8_strdown(message, -1); + auto_gchar gchar* mynick_search = case_sensitive ? g_strdup(nick) : g_utf8_strdown(nick, -1); mentions = prof_occurrences(mynick_search, message_search, 0, whole_word, &mentions); - g_free(message_search); - g_free(mynick_search); - return mentions; } @@ -483,11 +480,10 @@ call_external(gchar** argv) NULL, NULL, NULL, &spawn_error); if (!is_successful) { - gchar* cmd = g_strjoinv(" ", argv); + auto_gchar gchar* cmd = g_strjoinv(" ", argv); log_error("Spawning '%s' failed with error '%s'", cmd, spawn_error ? spawn_error->message : "Unknown, spawn_error is NULL"); g_error_free(spawn_error); - g_free(cmd); } return is_successful; @@ -579,7 +575,7 @@ get_expanded_path(const char* path) gchar* unique_filename_from_url(const char* url, const char* path) { - gchar* realpath; + auto_gchar gchar* realpath = NULL; // Default to './' as path when none has been provided. if (path == NULL) { @@ -590,7 +586,7 @@ unique_filename_from_url(const char* url, const char* path) // Resolves paths such as './../.' for path. GFile* target = g_file_new_for_commandline_arg(realpath); - gchar* filename = NULL; + auto_gchar gchar* filename = NULL; if (_has_directory_suffix(realpath) || g_file_test(realpath, G_FILE_TEST_IS_DIR)) { // The target should be used as a directory. Assume that the basename @@ -605,14 +601,10 @@ unique_filename_from_url(const char* url, const char* path) gchar* unique_filename = _unique_filename(filename); if (unique_filename == NULL) { - g_free(filename); - g_free(realpath); return NULL; } g_object_unref(target); - g_free(filename); - g_free(realpath); return unique_filename; } diff --git a/src/common.h b/src/common.h index e9a3d0cd..da6bd2b6 100644 --- a/src/common.h +++ b/src/common.h @@ -47,6 +47,9 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) +#define PROF_STRINGIFY_(n) #n +#define PROF_STRINGIFY(n) PROF_STRINGIFY_(n) + void auto_free_gchar(gchar** str); #define auto_gchar __attribute__((__cleanup__(auto_free_gchar))) void auto_free_gcharv(gchar*** args); @@ -60,6 +63,9 @@ void auto_free_char(char** str); #define STR_MAYBE_NULL(p) (p) #endif +/* Our own define of MB_CUR_MAX but this time at compile time */ +#define PROF_MB_CUR_MAX 8 + // assume malloc stores at most 8 bytes for size of allocated memory // and page size is at least 4KB #define READ_BUF_SIZE 4088 diff --git a/src/config/files.c b/src/config/files.c index e88ae687..75940c90 100644 --- a/src/config/files.c +++ b/src/config/files.c @@ -114,7 +114,7 @@ files_get_inputrc_file(void) return NULL; } -char* +gchar* files_get_log_file(const char* const log_file) { gchar* xdg_data = _files_get_xdg_data_home(); @@ -139,7 +139,7 @@ files_get_log_file(const char* const log_file) g_string_append(logfile, ".log"); } - char* result = g_strdup(logfile->str); + gchar* result = g_strdup(logfile->str); free(xdg_data); g_string_free(logfile, TRUE); diff --git a/src/config/preferences.c b/src/config/preferences.c index 2d975e39..c10f4d83 100644 --- a/src/config/preferences.c +++ b/src/config/preferences.c @@ -101,21 +101,15 @@ _prefs_load(void) // move pre 0.5.0 autoaway.message to autoaway.awaymessage if (g_key_file_has_key(prefs, PREF_GROUP_PRESENCE, "autoaway.message", NULL)) { - char* message = g_key_file_get_string(prefs, PREF_GROUP_PRESENCE, "autoaway.message", NULL); + auto_gchar gchar* message = g_key_file_get_string(prefs, PREF_GROUP_PRESENCE, "autoaway.message", NULL); g_key_file_set_string(prefs, PREF_GROUP_PRESENCE, "autoaway.awaymessage", message); g_key_file_remove_key(prefs, PREF_GROUP_PRESENCE, "autoaway.message", NULL); - g_free(message); } // migrate pre 0.5.0 time settings if (g_key_file_has_key(prefs, PREF_GROUP_UI, "time", NULL)) { - char* time = g_key_file_get_string(prefs, PREF_GROUP_UI, "time", NULL); - char* val = NULL; - if (time) { - val = time; - } else { - val = "off"; - } + auto_gchar gchar* time = g_key_file_get_string(prefs, PREF_GROUP_UI, "time", NULL); + char* val = time ? time : "off"; g_key_file_set_string(prefs, PREF_GROUP_UI, "time.console", val); g_key_file_set_string(prefs, PREF_GROUP_UI, "time.chat", val); g_key_file_set_string(prefs, PREF_GROUP_UI, "time.muc", val); @@ -123,12 +117,11 @@ _prefs_load(void) g_key_file_set_string(prefs, PREF_GROUP_UI, "time.private", val); g_key_file_set_string(prefs, PREF_GROUP_UI, "time.xmlconsole", val); g_key_file_remove_key(prefs, PREF_GROUP_UI, "time", NULL); - g_free(time); } // move pre 0.5.0 notify settings if (g_key_file_has_key(prefs, PREF_GROUP_NOTIFICATIONS, "room", NULL)) { - char* value = g_key_file_get_string(prefs, PREF_GROUP_NOTIFICATIONS, "room", NULL); + auto_gchar gchar* value = g_key_file_get_string(prefs, PREF_GROUP_NOTIFICATIONS, "room", NULL); if (g_strcmp0(value, "on") == 0) { g_key_file_set_boolean(prefs, PREF_GROUP_NOTIFICATIONS, "room", TRUE); } else if (g_strcmp0(value, "off") == 0) { @@ -137,7 +130,6 @@ _prefs_load(void) g_key_file_set_boolean(prefs, PREF_GROUP_NOTIFICATIONS, "room", FALSE); g_key_file_set_boolean(prefs, PREF_GROUP_NOTIFICATIONS, "room.mention", TRUE); } - g_free(value); } // move pre 0.6.0 titlebar settings to wintitle @@ -154,7 +146,7 @@ _prefs_load(void) // after 0.8.1: titlebar use jid|name -> titlebar show|hide jid|name if (g_key_file_has_key(prefs, PREF_GROUP_UI, "titlebar.muc.title", NULL)) { - char* value = g_key_file_get_string(prefs, PREF_GROUP_UI, "titlebar.muc.title", NULL); + auto_gchar gchar* value = g_key_file_get_string(prefs, PREF_GROUP_UI, "titlebar.muc.title", NULL); if (g_strcmp0(value, "name") == 0) { g_key_file_set_boolean(prefs, PREF_GROUP_UI, "titlebar.muc.title.name", TRUE); } else if (g_strcmp0(value, "jid") == 0) { @@ -164,7 +156,7 @@ _prefs_load(void) // 0.9.0 introduced /urlopen. It was saved under "logging" section. Now we have a new "executables" section. if (g_key_file_has_key(prefs, PREF_GROUP_LOGGING, "urlopen.cmd", NULL)) { - char* val = g_key_file_get_string(prefs, PREF_GROUP_LOGGING, "urlopen.cmd", NULL); + auto_gchar gchar* val = g_key_file_get_string(prefs, PREF_GROUP_LOGGING, "urlopen.cmd", NULL); GString* value = g_string_new("false;"); value = g_string_append(value, val); @@ -178,7 +170,7 @@ _prefs_load(void) // 0.9.0 introduced configurable /avatar. It was saved under "logging" section. Now we have a new "executables" section. if (g_key_file_has_key(prefs, PREF_GROUP_LOGGING, "avatar.cmd", NULL)) { - char* value = g_key_file_get_string(prefs, PREF_GROUP_LOGGING, "avatar.cmd", NULL); + auto_gchar gchar* value = g_key_file_get_string(prefs, PREF_GROUP_LOGGING, "avatar.cmd", NULL); g_key_file_set_string(prefs, PREF_GROUP_EXECUTABLES, "avatar.cmd", value); g_key_file_remove_key(prefs, PREF_GROUP_LOGGING, "avatar.cmd", NULL); } @@ -192,7 +184,7 @@ _prefs_load(void) // file type or scheme matching. Move value saved under 'DEF' locale to a // simple key-value string not under any locale. { - char** values = g_key_file_get_locale_string_list(prefs, PREF_GROUP_EXECUTABLES, "url.open.cmd", "DEF", NULL, NULL); + auto_gcharv gchar** values = g_key_file_get_locale_string_list(prefs, PREF_GROUP_EXECUTABLES, "url.open.cmd", "DEF", NULL, NULL); if (values && !g_key_file_has_key(prefs, PREF_GROUP_EXECUTABLES, "url.open.cmd", NULL)) { // First value in array is `require_save` option -- we ignore that // one as there is no such option anymore. @@ -201,16 +193,13 @@ _prefs_load(void) g_key_file_set_string(prefs, PREF_GROUP_EXECUTABLES, "url.open.cmd", executable); g_key_file_set_comment(prefs, PREF_GROUP_EXECUTABLES, "url.open.cmd", " Migrated from url.open.cmd[DEF]. `require_save` option has been removed in v0.10 and was discarded.", NULL); g_key_file_remove_key(prefs, PREF_GROUP_EXECUTABLES, "url.open.cmd[DEF]", NULL); - - g_strfreev(values); } - char* value = g_key_file_get_locale_string(prefs, PREF_GROUP_EXECUTABLES, "url.save.cmd", "DEF", NULL); + auto_gchar gchar* value = g_key_file_get_locale_string(prefs, PREF_GROUP_EXECUTABLES, "url.save.cmd", "DEF", NULL); if (value && !g_key_file_has_key(prefs, PREF_GROUP_EXECUTABLES, "url.save.cmd", NULL)) { g_key_file_set_string(prefs, PREF_GROUP_EXECUTABLES, "url.save.cmd", value); g_key_file_set_comment(prefs, PREF_GROUP_EXECUTABLES, "url.save.cmd", " Migrated from url.save.cmd[DEF].", NULL); g_key_file_remove_key(prefs, PREF_GROUP_EXECUTABLES, "url.save.cmd[DEF]", NULL); - g_free(value); } } @@ -342,20 +331,18 @@ prefs_message_get_triggers(const char* const message) { GList* result = NULL; - char* message_lower = g_utf8_strdown(message, -1); + auto_gchar gchar* message_lower = g_utf8_strdown(message, -1); gsize len = 0; gchar** triggers = g_key_file_get_string_list(prefs, PREF_GROUP_NOTIFICATIONS, "room.trigger.list", &len, NULL); for (int i = 0; i < len; i++) { - char* trigger_lower = g_utf8_strdown(triggers[i], -1); + auto_gchar gchar* trigger_lower = g_utf8_strdown(triggers[i], -1); if (g_strrstr(message_lower, trigger_lower)) { result = g_list_append(result, strdup(triggers[i])); } - g_free(trigger_lower); } g_strfreev(triggers); - g_free(message_lower); return result; } @@ -540,7 +527,7 @@ prefs_get_string(preference_t pref) const char* key = _get_key(pref); char* def = _get_default_string(pref); - char* result = g_key_file_get_string(prefs, group, key, NULL); + gchar* result = g_key_file_get_string(prefs, group, key, NULL); if (result == NULL) { if (def) { @@ -632,10 +619,9 @@ prefs_get_tls_certpath(void) const char* group = _get_group(PREF_TLS_CERTPATH); const char* key = _get_key(PREF_TLS_CERTPATH); - char* setting = g_key_file_get_string(prefs, group, key, NULL); + auto_gchar gchar* setting = g_key_file_get_string(prefs, group, key, NULL); if (g_strcmp0(setting, "none") == 0) { - g_free(setting); return NULL; } @@ -660,7 +646,6 @@ prefs_get_tls_certpath(void) } char* result = strdup(setting); - g_free(setting); return result; } @@ -1684,15 +1669,13 @@ prefs_get_aliases(void) for (int i = 0; i < len; i++) { char* name = keys[i]; - char* value = g_key_file_get_string(prefs, PREF_GROUP_ALIAS, name, NULL); + auto_gchar gchar* value = g_key_file_get_string(prefs, PREF_GROUP_ALIAS, name, NULL); if (value) { ProfAlias* alias = malloc(sizeof(struct prof_alias_t)); alias->name = strdup(name); alias->value = strdup(value); - free(value); - result = g_list_insert_sorted(result, alias, (GCompareFunc)_alias_cmp); } } @@ -2314,7 +2297,7 @@ _get_default_string(preference_t pref) case PREF_COLOR_NICK: return "false"; case PREF_AVATAR_CMD: - return "xdg-open"; + return "xdg-open %p"; case PREF_URL_OPEN_CMD: return "xdg-open %u"; case PREF_VCARD_PHOTO_CMD: diff --git a/src/config/theme.c b/src/config/theme.c index a39362fb..4909f6b7 100644 --- a/src/config/theme.c +++ b/src/config/theme.c @@ -686,7 +686,7 @@ _theme_prep_fgnd(char* setting, GString* lookup_str, gboolean* bold) char* theme_get_string(char* str) { - char* res = g_key_file_get_string(theme, "colours", str, NULL); + gchar* res = g_key_file_get_string(theme, "colours", str, NULL); if (!res) { return strdup(g_hash_table_lookup(defaults, str)); } else { diff --git a/src/config/tlscerts.c b/src/config/tlscerts.c index 008d28f6..d2f053fa 100644 --- a/src/config/tlscerts.c +++ b/src/config/tlscerts.c @@ -121,26 +121,17 @@ tlscerts_list(void) for (int i = 0; i < g_strv_length(groups); i++) { char* fingerprint = strdup(groups[i]); int version = g_key_file_get_integer(tlscerts, fingerprint, "version", NULL); - char* serialnumber = g_key_file_get_string(tlscerts, fingerprint, "serialnumber", NULL); - char* subjectname = g_key_file_get_string(tlscerts, fingerprint, "subjectname", NULL); - char* issuername = g_key_file_get_string(tlscerts, fingerprint, "issuername", NULL); - char* notbefore = g_key_file_get_string(tlscerts, fingerprint, "start", NULL); - char* notafter = g_key_file_get_string(tlscerts, fingerprint, "end", NULL); - char* keyalg = g_key_file_get_string(tlscerts, fingerprint, "keyalg", NULL); - char* signaturealg = g_key_file_get_string(tlscerts, fingerprint, "signaturealg", NULL); + auto_gchar gchar* serialnumber = g_key_file_get_string(tlscerts, fingerprint, "serialnumber", NULL); + auto_gchar gchar* subjectname = g_key_file_get_string(tlscerts, fingerprint, "subjectname", NULL); + auto_gchar gchar* issuername = g_key_file_get_string(tlscerts, fingerprint, "issuername", NULL); + auto_gchar gchar* notbefore = g_key_file_get_string(tlscerts, fingerprint, "start", NULL); + auto_gchar gchar* notafter = g_key_file_get_string(tlscerts, fingerprint, "end", NULL); + auto_gchar gchar* keyalg = g_key_file_get_string(tlscerts, fingerprint, "keyalg", NULL); + auto_gchar gchar* signaturealg = g_key_file_get_string(tlscerts, fingerprint, "signaturealg", NULL); TLSCertificate* cert = tlscerts_new(fingerprint, version, serialnumber, subjectname, issuername, notbefore, notafter, keyalg, signaturealg, NULL); - free(fingerprint); - free(serialnumber); - free(subjectname); - free(issuername); - free(notbefore); - free(notafter); - free(keyalg); - free(signaturealg); - res = g_list_append(res, cert); } @@ -316,25 +307,16 @@ tlscerts_get_trusted(const char* const fingerprint) } int version = g_key_file_get_integer(tlscerts, fingerprint, "version", NULL); - char* serialnumber = g_key_file_get_string(tlscerts, fingerprint, "serialnumber", NULL); - char* subjectname = g_key_file_get_string(tlscerts, fingerprint, "subjectname", NULL); - char* issuername = g_key_file_get_string(tlscerts, fingerprint, "issuername", NULL); - char* notbefore = g_key_file_get_string(tlscerts, fingerprint, "start", NULL); - char* notafter = g_key_file_get_string(tlscerts, fingerprint, "end", NULL); - char* keyalg = g_key_file_get_string(tlscerts, fingerprint, "keyalg", NULL); - char* signaturealg = g_key_file_get_string(tlscerts, fingerprint, "signaturealg", NULL); + auto_gchar gchar* serialnumber = g_key_file_get_string(tlscerts, fingerprint, "serialnumber", NULL); + auto_gchar gchar* subjectname = g_key_file_get_string(tlscerts, fingerprint, "subjectname", NULL); + auto_gchar gchar* issuername = g_key_file_get_string(tlscerts, fingerprint, "issuername", NULL); + auto_gchar gchar* notbefore = g_key_file_get_string(tlscerts, fingerprint, "start", NULL); + auto_gchar gchar* notafter = g_key_file_get_string(tlscerts, fingerprint, "end", NULL); + auto_gchar gchar* keyalg = g_key_file_get_string(tlscerts, fingerprint, "keyalg", NULL); + auto_gchar gchar* signaturealg = g_key_file_get_string(tlscerts, fingerprint, "signaturealg", NULL); TLSCertificate* cert = tlscerts_new(fingerprint, version, serialnumber, subjectname, issuername, notbefore, notafter, keyalg, signaturealg, NULL); - - free(serialnumber); - free(subjectname); - free(issuername); - free(notbefore); - free(notafter); - free(keyalg); - free(signaturealg); - return cert; } diff --git a/src/database.c b/src/database.c index ce936170..80439b9a 100644 --- a/src/database.c +++ b/src/database.c @@ -250,7 +250,7 @@ log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_las // null the current time is used. from_start gets first few messages if true // otherwise the last ones. Flip flips the order of the results GSList* -log_database_get_previous_chat(const gchar* const contact_barejid, char* start_time, char* end_time, gboolean from_start, gboolean flip) +log_database_get_previous_chat(const gchar* const contact_barejid, const char* start_time, char* end_time, gboolean from_start, gboolean flip) { sqlite3_stmt* stmt = NULL; const char* jid = connection_get_fulljid(); diff --git a/src/database.h b/src/database.h index 3b5fd647..1e73c874 100644 --- a/src/database.h +++ b/src/database.h @@ -47,7 +47,7 @@ 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); -GSList* log_database_get_previous_chat(const gchar* const contact_barejid, char* start_time, char* end_time, gboolean from_start, gboolean flip); +GSList* log_database_get_previous_chat(const gchar* const contact_barejid, const char* start_time, char* end_time, gboolean from_start, gboolean flip); ProfMessage* log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_last); void log_database_close(void); diff --git a/src/event/client_events.c b/src/event/client_events.c index 67ffec20..c393ccd4 100644 --- a/src/event/client_events.c +++ b/src/event/client_events.c @@ -47,6 +47,7 @@ #include "plugins/plugins.h" #include "ui/window_list.h" #include "xmpp/chat_session.h" +#include "xmpp/session.h" #include "xmpp/xmpp.h" #ifdef HAVE_LIBOTR @@ -85,9 +86,8 @@ cl_ev_connect_account(ProfAccount* account) void cl_ev_disconnect(void) { - char* mybarejid = connection_get_barejid(); + auto_char char* mybarejid = connection_get_barejid(); cons_show("%s logged out successfully.", mybarejid); - free(mybarejid); ui_close_all_wins(); ev_disconnect_cleanup(); @@ -96,6 +96,18 @@ cl_ev_disconnect(void) } void +cl_ev_reconnect(void) +{ + if (connection_get_status() != JABBER_DISCONNECTED) { + connection_disconnect(); + ev_disconnect_cleanup(); + // on intentional disconnect reset the counter + ev_reset_connection_counter(); + } + session_reconnect_now(); +} + +void cl_ev_presence_send(const resource_presence_t presence_type, const int idle_secs) { char* signed_status = NULL; diff --git a/src/event/client_events.h b/src/event/client_events.h index fed2bb37..a35e97b5 100644 --- a/src/event/client_events.h +++ b/src/event/client_events.h @@ -42,6 +42,7 @@ jabber_conn_status_t cl_ev_connect_jid(const char* const jid, const char* const jabber_conn_status_t cl_ev_connect_account(ProfAccount* account); void cl_ev_disconnect(void); +void cl_ev_reconnect(void); void cl_ev_presence_send(const resource_presence_t presence_type, const int idle_secs); diff --git a/src/event/server_events.c b/src/event/server_events.c index 0f6df2ac..c10f69c3 100644 --- a/src/event/server_events.c +++ b/src/event/server_events.c @@ -1332,8 +1332,8 @@ sv_ev_bookmark_autojoin(Bookmark* bookmark) log_debug("Autojoin %s with nick=%s", bookmark->barejid, nick); if (!muc_active(bookmark->barejid)) { - presence_join_room(bookmark->barejid, nick, bookmark->password); muc_join(bookmark->barejid, nick, bookmark->password, TRUE); + presence_join_room(bookmark->barejid, nick, bookmark->password); iq_room_affiliation_list(bookmark->barejid, "member", false); iq_room_affiliation_list(bookmark->barejid, "admin", false); iq_room_affiliation_list(bookmark->barejid, "owner", false); @@ -1346,7 +1346,7 @@ static void _cut(ProfMessage* message, const char* cut) { if (strstr(message->plain, cut)) { - char** split = g_strsplit(message->plain, cut, -1); + gchar** split = g_strsplit(message->plain, cut, -1); free(message->plain); message->plain = g_strjoinv("", split); g_strfreev(split); diff --git a/src/main.c b/src/main.c index 6cbca667..6edfd3c8 100644 --- a/src/main.c +++ b/src/main.c @@ -160,9 +160,8 @@ main(int argc, char** argv) #endif #ifdef HAVE_PYTHON - gchar* python_version = python_get_version_number(); + auto_gchar gchar* python_version = python_get_version_number(); g_print("Python plugins: Enabled (%s)\n", python_version); - g_free(python_version); #else g_print("Python plugins: Disabled\n"); #endif diff --git a/src/omemo/omemo.c b/src/omemo/omemo.c index 69a9fc30..303fa689 100644 --- a/src/omemo/omemo.c +++ b/src/omemo/omemo.c @@ -350,14 +350,12 @@ omemo_generate_crypto_materials(ProfAccount* account) signal_protocol_key_helper_generate_identity_key_pair(&omemo_ctx.identity_key_pair, omemo_ctx.signal); ec_public_key_serialize(&omemo_ctx.identity_key_store.public, ratchet_identity_key_pair_get_public(omemo_ctx.identity_key_pair)); - char* identity_key_public = g_base64_encode(signal_buffer_data(omemo_ctx.identity_key_store.public), signal_buffer_len(omemo_ctx.identity_key_store.public)); + auto_gchar gchar* identity_key_public = g_base64_encode(signal_buffer_data(omemo_ctx.identity_key_store.public), signal_buffer_len(omemo_ctx.identity_key_store.public)); g_key_file_set_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PUBLIC, identity_key_public); - g_free(identity_key_public); ec_private_key_serialize(&omemo_ctx.identity_key_store.private, ratchet_identity_key_pair_get_private(omemo_ctx.identity_key_pair)); - char* identity_key_private = g_base64_encode(signal_buffer_data(omemo_ctx.identity_key_store.private), signal_buffer_len(omemo_ctx.identity_key_store.private)); + auto_gchar gchar* identity_key_private = g_base64_encode(signal_buffer_data(omemo_ctx.identity_key_store.private), signal_buffer_len(omemo_ctx.identity_key_store.private)); g_key_file_set_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PRIVATE, identity_key_private); - g_free(identity_key_private); /* Registration ID */ signal_protocol_key_helper_generate_registration_id(&omemo_ctx.registration_id, 0, omemo_ctx.signal); @@ -1322,19 +1320,19 @@ omemo_untrust(const char* const jid, const char* const fingerprint_formatted) } free(identity); - char* fingerprint = _omemo_unformat_fingerprint(fingerprint_formatted); + auto_char char* fingerprint = _omemo_unformat_fingerprint(fingerprint_formatted); /* Remove existing session */ GHashTable* known_identities = g_hash_table_lookup(omemo_ctx.known_devices, jid); if (!known_identities) { log_error("[OMEMO] cannot find known device while untrusting a fingerprint"); - goto out; + return; } uint32_t device_id = GPOINTER_TO_INT(g_hash_table_lookup(known_identities, fingerprint)); if (!device_id) { log_error("[OMEMO] cannot find device id while untrusting a fingerprint"); - goto out; + return; } signal_protocol_address address = { .name = jid, @@ -1345,13 +1343,9 @@ omemo_untrust(const char* const jid, const char* const fingerprint_formatted) delete_session(&address, omemo_ctx.session_store); /* Remove from keyfile */ - char* device_id_str = g_strdup_printf("%d", device_id); + auto_gchar gchar* device_id_str = g_strdup_printf("%d", device_id); g_key_file_remove_key(omemo_ctx.trust_keyfile, jid, device_id_str, NULL); - g_free(device_id_str); omemo_trust_keyfile_save(); - -out: - free(fingerprint); } static void @@ -1540,7 +1534,7 @@ _load_identity(void) /* Identity key */ error = NULL; - char* identity_key_public_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PUBLIC, &error); + auto_gchar gchar* identity_key_public_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PUBLIC, &error); if (!identity_key_public_b64) { log_error("[OMEMO] cannot load identity public key: %s", error->message); return FALSE; @@ -1548,11 +1542,10 @@ _load_identity(void) size_t identity_key_public_len; unsigned char* identity_key_public = g_base64_decode(identity_key_public_b64, &identity_key_public_len); - g_free(identity_key_public_b64); omemo_ctx.identity_key_store.public = signal_buffer_create(identity_key_public, identity_key_public_len); error = NULL; - char* identity_key_private_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PRIVATE, &error); + auto_gchar gchar* identity_key_private_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_IDENTITY, OMEMO_STORE_KEY_IDENTITY_KEY_PRIVATE, &error); if (!identity_key_private_b64) { log_error("[OMEMO] cannot load identity private key: %s", error->message); return FALSE; @@ -1560,7 +1553,6 @@ _load_identity(void) size_t identity_key_private_len; unsigned char* identity_key_private = g_base64_decode(identity_key_private_b64, &identity_key_private_len); - g_free(identity_key_private_b64); omemo_ctx.identity_key_store.private = signal_buffer_create(identity_key_private, identity_key_private_len); ec_public_key* public_key; @@ -1579,10 +1571,9 @@ _load_identity(void) keys = g_key_file_get_keys(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_PREKEYS, NULL, NULL); if (keys) { for (i = 0; keys[i] != NULL; i++) { - char* pre_key_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_PREKEYS, keys[i], NULL); + auto_gchar gchar* pre_key_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_PREKEYS, keys[i], NULL); size_t pre_key_len; unsigned char* pre_key = g_base64_decode(pre_key_b64, &pre_key_len); - g_free(pre_key_b64); signal_buffer* buffer = signal_buffer_create(pre_key, pre_key_len); g_free(pre_key); g_hash_table_insert(omemo_ctx.pre_key_store, GINT_TO_POINTER(strtoul(keys[i], NULL, 10)), buffer); @@ -1601,10 +1592,9 @@ _load_identity(void) keys = g_key_file_get_keys(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_SIGNED_PREKEYS, NULL, NULL); if (keys) { for (i = 0; keys[i] != NULL; i++) { - char* signed_pre_key_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_SIGNED_PREKEYS, keys[i], NULL); + auto_gchar gchar* signed_pre_key_b64 = g_key_file_get_string(omemo_ctx.identity_keyfile, OMEMO_STORE_GROUP_SIGNED_PREKEYS, keys[i], NULL); size_t signed_pre_key_len; unsigned char* signed_pre_key = g_base64_decode(signed_pre_key_b64, &signed_pre_key_len); - g_free(signed_pre_key_b64); signal_buffer* buffer = signal_buffer_create(signed_pre_key, signed_pre_key_len); g_free(signed_pre_key); g_hash_table_insert(omemo_ctx.signed_pre_key_store, GINT_TO_POINTER(strtoul(keys[i], NULL, 10)), buffer); @@ -1629,7 +1619,7 @@ static void _load_trust(void) { char** keys = NULL; - char** groups = g_key_file_get_groups(omemo_ctx.trust_keyfile, NULL); + gchar** groups = g_key_file_get_groups(omemo_ctx.trust_keyfile, NULL); if (groups) { int i; for (i = 0; groups[i] != NULL; i++) { @@ -1644,10 +1634,9 @@ _load_trust(void) keys = g_key_file_get_keys(omemo_ctx.trust_keyfile, groups[i], NULL, NULL); int j; for (j = 0; keys[j] != NULL; j++) { - char* key_b64 = g_key_file_get_string(omemo_ctx.trust_keyfile, groups[i], keys[j], NULL); + auto_gchar gchar* key_b64 = g_key_file_get_string(omemo_ctx.trust_keyfile, groups[i], keys[j], NULL); size_t key_len; unsigned char* key = g_base64_decode(key_b64, &key_len); - g_free(key_b64); signal_buffer* buffer = signal_buffer_create(key, key_len); g_free(key); uint32_t device_id = strtoul(keys[j], NULL, 10); @@ -1663,7 +1652,7 @@ static void _load_sessions(void) { int i; - char** groups = g_key_file_get_groups(omemo_ctx.sessions_keyfile, NULL); + auto_gcharv gchar** groups = g_key_file_get_groups(omemo_ctx.sessions_keyfile, NULL); if (groups) { for (i = 0; groups[i] != NULL; i++) { int j; @@ -1675,20 +1664,17 @@ _load_sessions(void) g_hash_table_insert(omemo_ctx.session_store, strdup(groups[i]), device_store); } - char** keys = g_key_file_get_keys(omemo_ctx.sessions_keyfile, groups[i], NULL, NULL); + auto_gcharv gchar** keys = g_key_file_get_keys(omemo_ctx.sessions_keyfile, groups[i], NULL, NULL); for (j = 0; keys[j] != NULL; j++) { uint32_t id = strtoul(keys[j], NULL, 10); - char* record_b64 = g_key_file_get_string(omemo_ctx.sessions_keyfile, groups[i], keys[j], NULL); + auto_gchar gchar* record_b64 = g_key_file_get_string(omemo_ctx.sessions_keyfile, groups[i], keys[j], NULL); size_t record_len; unsigned char* record = g_base64_decode(record_b64, &record_len); - g_free(record_b64); signal_buffer* buffer = signal_buffer_create(record, record_len); g_free(record); g_hash_table_insert(device_store, GINT_TO_POINTER(id), buffer); } - g_strfreev(keys); } - g_strfreev(groups); } } @@ -1696,7 +1682,7 @@ static void _load_known_devices(void) { int i; - char** groups = g_key_file_get_groups(omemo_ctx.known_devices_keyfile, NULL); + auto_gcharv gchar** groups = g_key_file_get_groups(omemo_ctx.known_devices_keyfile, NULL); if (groups) { for (i = 0; groups[i] != NULL; i++) { int j; @@ -1708,16 +1694,13 @@ _load_known_devices(void) g_hash_table_insert(omemo_ctx.known_devices, strdup(groups[i]), known_identities); } - char** keys = g_key_file_get_keys(omemo_ctx.known_devices_keyfile, groups[i], NULL, NULL); + auto_gcharv gchar** keys = g_key_file_get_keys(omemo_ctx.known_devices_keyfile, groups[i], NULL, NULL); for (j = 0; keys[j] != NULL; j++) { uint32_t device_id = strtoul(keys[j], NULL, 10); - char* fingerprint = g_key_file_get_string(omemo_ctx.known_devices_keyfile, groups[i], keys[j], NULL); + auto_gchar gchar* fingerprint = g_key_file_get_string(omemo_ctx.known_devices_keyfile, groups[i], keys[j], NULL); g_hash_table_insert(known_identities, strdup(fingerprint), GINT_TO_POINTER(device_id)); - g_free(fingerprint); } - g_strfreev(keys); } - g_strfreev(groups); } } @@ -1734,9 +1717,8 @@ _cache_device_identity(const char* const jid, uint32_t device_id, ec_public_key* log_debug("[OMEMO] cache identity for %s:%d: %s", jid, device_id, fingerprint); g_hash_table_insert(known_identities, strdup(fingerprint), GINT_TO_POINTER(device_id)); - char* device_id_str = g_strdup_printf("%d", device_id); + auto_gchar gchar* device_id_str = g_strdup_printf("%d", device_id); g_key_file_set_string(omemo_ctx.known_devices_keyfile, jid, device_id_str, fingerprint); - g_free(device_id_str); omemo_known_devices_keyfile_save(); Autocomplete ac = g_hash_table_lookup(omemo_ctx.fingerprint_ac, jid); diff --git a/src/omemo/store.c b/src/omemo/store.c index 3825c95d..08291460 100644 --- a/src/omemo/store.c +++ b/src/omemo/store.c @@ -143,11 +143,9 @@ store_session(const signal_protocol_address* address, signal_buffer* buffer = signal_buffer_create(record, record_len); g_hash_table_insert(device_store, GINT_TO_POINTER(address->device_id), buffer); - char* record_b64 = g_base64_encode(record, record_len); - char* device_id = g_strdup_printf("%d", address->device_id); + auto_gchar gchar* record_b64 = g_base64_encode(record, record_len); + auto_gchar gchar* device_id = g_strdup_printf("%d", address->device_id); g_key_file_set_string(omemo_sessions_keyfile(), address->name, device_id, record_b64); - free(device_id); - g_free(record_b64); omemo_sessions_keyfile_save(); @@ -187,9 +185,8 @@ delete_session(const signal_protocol_address* address, void* user_data) g_hash_table_remove(device_store, GINT_TO_POINTER(address->device_id)); - char* device_id_str = g_strdup_printf("%d", address->device_id); + auto_gchar gchar* device_id_str = g_strdup_printf("%d", address->device_id); g_key_file_remove_key(omemo_sessions_keyfile(), address->name, device_id_str, NULL); - g_free(device_id_str); omemo_sessions_keyfile_save(); return SG_SUCCESS; @@ -238,11 +235,9 @@ store_pre_key(uint32_t pre_key_id, uint8_t* record, size_t record_len, g_hash_table_insert(pre_key_store, GINT_TO_POINTER(pre_key_id), buffer); /* Long term storage */ - char* pre_key_id_str = g_strdup_printf("%d", pre_key_id); - char* record_b64 = g_base64_encode(record, record_len); + auto_gchar gchar* pre_key_id_str = g_strdup_printf("%d", pre_key_id); + auto_gchar gchar* record_b64 = g_base64_encode(record, record_len); g_key_file_set_string(omemo_identity_keyfile(), OMEMO_STORE_GROUP_PREKEYS, pre_key_id_str, record_b64); - g_free(pre_key_id_str); - g_free(record_b64); omemo_identity_keyfile_save(); @@ -265,9 +260,8 @@ remove_pre_key(uint32_t pre_key_id, void* user_data) int ret = g_hash_table_remove(pre_key_store, GINT_TO_POINTER(pre_key_id)); /* Long term storage */ - char* pre_key_id_str = g_strdup_printf("%d", pre_key_id); + auto_gchar gchar* pre_key_id_str = g_strdup_printf("%d", pre_key_id); g_key_file_remove_key(omemo_identity_keyfile(), OMEMO_STORE_GROUP_PREKEYS, pre_key_id_str, NULL); - g_free(pre_key_id_str); omemo_identity_keyfile_save(); @@ -306,11 +300,9 @@ store_signed_pre_key(uint32_t signed_pre_key_id, uint8_t* record, g_hash_table_insert(signed_pre_key_store, GINT_TO_POINTER(signed_pre_key_id), buffer); /* Long term storage */ - char* signed_pre_key_id_str = g_strdup_printf("%d", signed_pre_key_id); - char* record_b64 = g_base64_encode(record, record_len); + auto_gchar gchar* signed_pre_key_id_str = g_strdup_printf("%d", signed_pre_key_id); + auto_gchar gchar* record_b64 = g_base64_encode(record, record_len); g_key_file_set_string(omemo_identity_keyfile(), OMEMO_STORE_GROUP_SIGNED_PREKEYS, signed_pre_key_id_str, record_b64); - g_free(signed_pre_key_id_str); - g_free(record_b64); omemo_identity_keyfile_save(); @@ -333,9 +325,8 @@ remove_signed_pre_key(uint32_t signed_pre_key_id, void* user_data) int ret = g_hash_table_remove(signed_pre_key_store, GINT_TO_POINTER(signed_pre_key_id)); /* Long term storage */ - char* signed_pre_key_id_str = g_strdup_printf("%d", signed_pre_key_id); + auto_gchar gchar* signed_pre_key_id_str = g_strdup_printf("%d", signed_pre_key_id); g_key_file_remove_key(omemo_identity_keyfile(), OMEMO_STORE_GROUP_PREKEYS, signed_pre_key_id_str, NULL); - g_free(signed_pre_key_id_str); omemo_identity_keyfile_save(); @@ -393,11 +384,9 @@ save_identity(const signal_protocol_address* address, uint8_t* key_data, g_hash_table_insert(trusted, GINT_TO_POINTER(address->device_id), buffer); /* Long term storage */ - char* key_b64 = g_base64_encode(key_data, key_len); - char* device_id = g_strdup_printf("%d", address->device_id); + auto_gchar gchar* key_b64 = g_base64_encode(key_data, key_len); + auto_gchar gchar* device_id = g_strdup_printf("%d", address->device_id); g_key_file_set_string(omemo_trust_keyfile(), address->name, device_id, key_b64); - g_free(device_id); - g_free(key_b64); omemo_trust_keyfile_save(); diff --git a/src/plugins/python_plugins.c b/src/plugins/python_plugins.c index c32d177c..cf1e4a87 100644 --- a/src/plugins/python_plugins.c +++ b/src/plugins/python_plugins.c @@ -874,9 +874,8 @@ static void _python_undefined_error(ProfPlugin* plugin, char* hook, char* type) { GString* err_msg = g_string_new("Plugin error - "); - char* module_name = g_strndup(plugin->name, strlen(plugin->name) - 2); + auto_gchar gchar* module_name = g_strndup(plugin->name, strlen(plugin->name) - 2); g_string_append(err_msg, module_name); - free(module_name); g_string_append(err_msg, hook); g_string_append(err_msg, "(): return value undefined, expected "); g_string_append(err_msg, type); @@ -889,9 +888,8 @@ static void _python_type_error(ProfPlugin* plugin, char* hook, char* type) { GString* err_msg = g_string_new("Plugin error - "); - char* module_name = g_strndup(plugin->name, strlen(plugin->name) - 2); + auto_gchar gchar* module_name = g_strndup(plugin->name, strlen(plugin->name) - 2); g_string_append(err_msg, module_name); - free(module_name); g_string_append(err_msg, hook); g_string_append(err_msg, "(): incorrect return type, expected "); g_string_append(err_msg, type); diff --git a/src/profanity.c b/src/profanity.c index 2c6ad12d..42983993 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -151,10 +151,9 @@ _connect_default(const char* const account) if (account) { cmd_execute_connect(window, account); } else { - char* pref_connect_account = prefs_get_string(PREF_CONNECT_ACCOUNT); + auto_gchar gchar* pref_connect_account = prefs_get_string(PREF_CONNECT_ACCOUNT); if (pref_connect_account) { cmd_execute_connect(window, pref_connect_account); - g_free(pref_connect_account); } } } @@ -198,9 +197,8 @@ _init(char* log_level, char* config_file, char* log_file, char* theme_name) if (theme_name) { theme_init(theme_name); } else { - char* theme = prefs_get_string(PREF_THEME); + auto_gchar gchar* theme = prefs_get_string(PREF_THEME); theme_init(theme); - g_free(theme); } ui_init(); diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c index 27532081..8c7818e7 100644 --- a/src/tools/autocomplete.c +++ b/src/tools/autocomplete.c @@ -315,7 +315,7 @@ static char* _autocomplete_param_common(const char* const input, char* command, autocomplete_func func, Autocomplete ac, gboolean quote, gboolean previous, void* context) { int len; - auto_char char* command_cpy = g_strdup_printf("%s ", command); + auto_gchar gchar* command_cpy = g_strdup_printf("%s ", command); if (!command_cpy) { return NULL; } diff --git a/src/tools/editor.c b/src/tools/editor.c index 0efb4d6b..4cd70d9d 100644 --- a/src/tools/editor.c +++ b/src/tools/editor.c @@ -54,19 +54,18 @@ get_message_from_editor(gchar* message, gchar** returned_message) /* Make sure that there's no junk in the return-pointer in error cases */ *returned_message = NULL; - gchar* filename = NULL; + auto_gchar gchar* filename = NULL; GError* glib_error = NULL; auto_char char* jid = connection_get_barejid(); if (jid) { filename = files_file_in_account_data_path(DIR_EDITOR, jid, "compose.md"); } else { log_debug("[Editor] could not get JID"); - gchar* data_dir = files_get_data_path(DIR_EDITOR); + auto_gchar gchar* data_dir = files_get_data_path(DIR_EDITOR); if (!create_dir(data_dir)) { return TRUE; } filename = g_strdup_printf("%s/compose.md", data_dir); - g_free(data_dir); } if (!filename) { log_error("[Editor] something went wrong while creating compose file"); @@ -83,21 +82,17 @@ get_message_from_editor(gchar* message, gchar** returned_message) if (glib_error) { g_error_free(glib_error); } - g_free(filename); return TRUE; } - char* editor = prefs_get_string(PREF_COMPOSE_EDITOR); - gchar* editor_with_filename = g_strdup_printf("%s %s", editor, filename); - gchar** editor_argv = g_strsplit(editor_with_filename, " ", 0); - - g_free(editor_with_filename); + auto_gchar gchar* editor = prefs_get_string(PREF_COMPOSE_EDITOR); + auto_gchar gchar* editor_with_filename = g_strdup_printf("%s %s", editor, filename); + auto_gcharv gchar** editor_argv = g_strsplit(editor_with_filename, " ", 0); // Fork / exec pid_t pid = fork(); if (pid == 0) { int x = execvp(editor_argv[0], editor_argv); - g_strfreev(editor_argv); if (x == -1) { log_error("[Editor] Failed to exec %s", editor); } @@ -115,8 +110,6 @@ get_message_from_editor(gchar* message, gchar** returned_message) if (glib_error) { g_error_free(glib_error); } - g_free(filename); - g_free(editor); return TRUE; } /* Remove all trailing new-line characters */ @@ -127,10 +120,7 @@ get_message_from_editor(gchar* message, gchar** returned_message) } else { log_debug("[Editor] deleted file: %s", filename); } - g_free(filename); } - g_free(editor); - return FALSE; } diff --git a/src/tools/http_upload.c b/src/tools/http_upload.c index 4dae41c5..289dba15 100644 --- a/src/tools/http_upload.c +++ b/src/tools/http_upload.c @@ -399,15 +399,13 @@ file_mime_type(const char* const filename) size_t file_header_size = fread(file_header, 1, FILE_HEADER_BYTES, fh); fclose(fh); - char* content_type = g_content_type_guess(filename, (unsigned char*)file_header, file_header_size, NULL); + auto_gchar gchar* content_type = g_content_type_guess(filename, (unsigned char*)file_header, file_header_size, NULL); if (content_type != NULL) { - char* mime_type = g_content_type_get_mime_type(content_type); + auto_gchar gchar* mime_type = g_content_type_get_mime_type(content_type); out_mime_type = strdup(mime_type); - g_free(mime_type); } else { return strdup(FALLBACK_MIMETYPE); } - g_free(content_type); return out_mime_type; } diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index 0c540998..b470dbd6 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -598,7 +598,7 @@ _chatwin_history(ProfChatWin* chatwin, const char* const contact_barejid) // first entry's timestamp in the buffer is used. Flip true to prepend to buffer. // Timestamps should be in iso8601 gboolean -chatwin_db_history(ProfChatWin* chatwin, char* start_time, char* end_time, gboolean flip) +chatwin_db_history(ProfChatWin* chatwin, const char* start_time, char* end_time, gboolean flip) { if (!end_time) { end_time = buffer_size(((ProfWin*)chatwin)->layout->buffer) == 0 ? NULL : g_date_time_format_iso8601(buffer_get_entry(((ProfWin*)chatwin)->layout->buffer, 0)->time); diff --git a/src/ui/confwin.c b/src/ui/confwin.c index 85abe748..a49b7010 100644 --- a/src/ui/confwin.c +++ b/src/ui/confwin.c @@ -70,7 +70,7 @@ confwin_show_form(ProfConfWin* confwin) win_println(window, THEME_DEFAULT, "-", "%s", value); } } else if (g_strcmp0(field->type, "hidden") != 0 && field->var) { - char* tag = g_hash_table_lookup(confwin->form->var_to_tag, field->var); + gchar* tag = g_hash_table_lookup(confwin->form->var_to_tag, field->var); _confwin_form_field(window, tag, field); } diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c index bc689d5f..9b652f1c 100644 --- a/src/ui/inputwin.c +++ b/src/ui/inputwin.c @@ -36,6 +36,7 @@ #define _XOPEN_SOURCE_EXTENDED #include "config.h" +#include <assert.h> #include <stdio.h> #include <sys/select.h> #include <stdlib.h> @@ -140,6 +141,11 @@ static int _inp_rl_send_to_editor(int count, int key); void create_input_window(void) { + /* MB_CUR_MAX is evaluated at runtime depending on the current + * locale, therefore we check that our own version is big enough + * and bail out if it isn't. + */ + assert(MB_CUR_MAX <= PROF_MB_CUR_MAX); #ifdef NCURSES_REENTRANT set_escdelay(25); #else @@ -331,7 +337,7 @@ _inp_write(char* line, int offset) for (size_t i = 0; line[i] != '\0'; i++) { char* c = &line[i]; - char retc[MB_CUR_MAX]; + char retc[PROF_MB_CUR_MAX] = { 0 }; size_t ch_len = mbrlen(c, MB_CUR_MAX, NULL); if ((ch_len == (size_t)-2) || (ch_len == (size_t)-1)) { diff --git a/src/ui/mucwin.c b/src/ui/mucwin.c index 550b05e2..a2c31421 100644 --- a/src/ui/mucwin.c +++ b/src/ui/mucwin.c @@ -391,7 +391,7 @@ _mucwin_print_mention(ProfWin* window, const char* const message, const char* co while (curr) { pos = GPOINTER_TO_INT(curr->data); - char* before_str = g_utf8_substring(message, last_pos, pos); + auto_gchar gchar* before_str = g_utf8_substring(message, last_pos, pos); if (last_pos == 0 && strncmp(before_str, "/me ", 4) == 0) { win_print_them(window, THEME_ROOMMENTION, ch, flags, ""); @@ -404,11 +404,9 @@ _mucwin_print_mention(ProfWin* window, const char* const message, const char* co } win_append_highlight(window, THEME_ROOMMENTION, "%s", before_str); } - g_free(before_str); - char* mynick_str = g_utf8_substring(message, pos, pos + mynick_len); + auto_gchar gchar* mynick_str = g_utf8_substring(message, pos, pos + mynick_len); win_append_highlight(window, THEME_ROOMMENTION_TERM, "%s", mynick_str); - g_free(mynick_str); last_pos = pos + mynick_len; @@ -418,7 +416,7 @@ _mucwin_print_mention(ProfWin* window, const char* const message, const char* co glong message_len = g_utf8_strlen(message, -1); if (last_pos < message_len) { // get tail without allocating a new string - char* rest = g_utf8_offset_to_pointer(message, last_pos); + gchar* rest = g_utf8_offset_to_pointer(message, last_pos); win_appendln_highlight(window, THEME_ROOMMENTION, "%s", rest); } else { win_appendln_highlight(window, THEME_ROOMMENTION, ""); @@ -449,15 +447,15 @@ _mucwin_print_triggers(ProfWin* window, const char* const message, GList* trigge curr = g_list_next(curr); } - char* message_lower = g_utf8_strdown(message, -1); + auto_gchar gchar* message_lower = g_utf8_strdown(message, -1); // find earliest trigger in message int first_trigger_pos = -1; int first_trigger_len = -1; curr = weighted_triggers; while (curr) { - char* trigger_lower = g_utf8_strdown(curr->data, -1); - char* trigger_ptr = g_strstr_len(message_lower, -1, trigger_lower); + auto_gchar gchar* trigger_lower = g_utf8_strdown(curr->data, -1); + gchar* trigger_ptr = g_strstr_len(message_lower, -1, trigger_lower); // not found, try next if (trigger_ptr == NULL) { @@ -472,11 +470,9 @@ _mucwin_print_triggers(ProfWin* window, const char* const message, GList* trigge first_trigger_len = strlen(trigger_lower); } - g_free(trigger_lower); curr = g_list_next(curr); } - g_free(message_lower); g_list_free(weighted_triggers); // no triggers found diff --git a/src/ui/ui.h b/src/ui/ui.h index d9534ed5..79fafd75 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -145,7 +145,7 @@ void chatwin_set_incoming_char(ProfChatWin* chatwin, const char* const ch); void chatwin_unset_incoming_char(ProfChatWin* chatwin); void chatwin_set_outgoing_char(ProfChatWin* chatwin, const char* const ch); void chatwin_unset_outgoing_char(ProfChatWin* chatwin); -gboolean chatwin_db_history(ProfChatWin* chatwin, char* start_time, char* end_time, gboolean flip); +gboolean chatwin_db_history(ProfChatWin* chatwin, const char* start_time, char* end_time, gboolean flip); // MUC window ProfMucWin* mucwin_new(const char* const barejid); diff --git a/src/xmpp/capabilities.c b/src/xmpp/capabilities.c index 638b2c90..3bd567cd 100644 --- a/src/xmpp/capabilities.c +++ b/src/xmpp/capabilities.c @@ -368,14 +368,14 @@ _caps_by_ver(const char* const ver) return NULL; } - char* category = g_key_file_get_string(cache, ver, "category", NULL); - char* type = g_key_file_get_string(cache, ver, "type", NULL); - char* name = g_key_file_get_string(cache, ver, "name", NULL); + auto_gchar gchar* category = g_key_file_get_string(cache, ver, "category", NULL); + auto_gchar gchar* type = g_key_file_get_string(cache, ver, "type", NULL); + auto_gchar gchar* name = g_key_file_get_string(cache, ver, "name", NULL); - char* software = g_key_file_get_string(cache, ver, "software", NULL); - char* software_version = g_key_file_get_string(cache, ver, "software_version", NULL); - char* os = g_key_file_get_string(cache, ver, "os", NULL); - char* os_version = g_key_file_get_string(cache, ver, "os_version", NULL); + auto_gchar gchar* software = g_key_file_get_string(cache, ver, "software", NULL); + auto_gchar gchar* software_version = g_key_file_get_string(cache, ver, "software_version", NULL); + auto_gchar gchar* os = g_key_file_get_string(cache, ver, "os", NULL); + auto_gchar gchar* os_version = g_key_file_get_string(cache, ver, "os_version", NULL); gsize features_len = 0; gchar** features_list = g_key_file_get_string_list(cache, ver, "features", &features_len, NULL); @@ -391,13 +391,6 @@ _caps_by_ver(const char* const ver) software, software_version, os, os_version, features); - g_free(category); - g_free(type); - g_free(name); - g_free(software); - g_free(software_version); - g_free(os); - g_free(os_version); if (features_list) { g_strfreev(features_list); } diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c index eef395f1..2a022cc4 100644 --- a/src/xmpp/connection.c +++ b/src/xmpp/connection.c @@ -964,6 +964,7 @@ _connection_handler(xmpp_conn_t* const xmpp_conn, const xmpp_conn_event_t status conn.domain = strdup(my_jid->domainpart); jid_destroy(my_jid); + connection_clear_data(); conn.features_by_jid = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)g_hash_table_destroy); g_hash_table_insert(conn.features_by_jid, strdup(conn.domain), g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL)); @@ -990,6 +991,7 @@ _connection_handler(xmpp_conn_t* const xmpp_conn, const xmpp_conn_event_t status conn.domain = strdup(my_raw_jid->domainpart); jid_destroy(my_raw_jid); + connection_clear_data(); conn.features_by_jid = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)g_hash_table_destroy); g_hash_table_insert(conn.features_by_jid, strdup(conn.domain), g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL)); diff --git a/src/xmpp/connection.h b/src/xmpp/connection.h index 79bee1d4..d4ade03a 100644 --- a/src/xmpp/connection.h +++ b/src/xmpp/connection.h @@ -48,7 +48,6 @@ jabber_conn_status_t connection_connect(const char* const fulljid, const char* c const char* const tls_policy, const char* const auth_policy); jabber_conn_status_t connection_register(const char* const altdomain, int port, const char* const tls_policy, const char* const username, const char* const password); -void connection_disconnect(void); void connection_set_disconnected(void); void connection_set_priority(const int priority); diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index f09deead..159ba609 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -265,6 +265,7 @@ iq_handlers_init(void) xmpp_timed_handler_add(conn, _autoping_timed_send, millis, ctx); } + iq_rooms_cache_clear(); iq_handlers_clear(); id_handlers = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)_iq_id_handler_free); @@ -1614,6 +1615,7 @@ _version_get_handler(xmpp_stanza_t* const stanza) const char* from = xmpp_stanza_get_from(stanza); ProfAccount* account = accounts_get_account(session_get_account_name()); auto_char char* client = account->client != NULL ? strdup(account->client) : NULL; + account_free(account); bool is_custom_client = client != NULL; gchar* custom_version_str = NULL; if (is_custom_client) { @@ -2651,6 +2653,18 @@ iq_mam_request_older(ProfChatWin* win) return; } +static void +_mam_userdata_free(MamRsmUserdata* data) +{ + free(data->end_datestr); + data->end_datestr = NULL; + free(data->start_datestr); + data->start_datestr = NULL; + free(data->barejid); + data->barejid = NULL; + free(data); +} + void _iq_mam_request(ProfChatWin* win, GDateTime* startdate, GDateTime* enddate) { @@ -2694,7 +2708,7 @@ _iq_mam_request(ProfChatWin* win, GDateTime* startdate, GDateTime* enddate) data->fetch_next = fetch_next; data->win = win; - iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, NULL, data); + iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, (ProfIqFreeCallback)_mam_userdata_free, data); } iq_send_stanza(iq); @@ -2714,9 +2728,11 @@ iq_mam_request(ProfChatWin* win, GDateTime* enddate) if (!received_disco_items) { LateDeliveryUserdata* cur_del_data = malloc(sizeof(LateDeliveryUserdata)); cur_del_data->win = win; - cur_del_data->enddate = g_date_time_ref(enddate); - cur_del_data->startdate = g_date_time_ref(startdate); + cur_del_data->enddate = enddate; + cur_del_data->startdate = startdate; late_delivery_windows = g_slist_append(late_delivery_windows, cur_del_data); + log_debug("Save MAM request of %s for later", win->barejid); + return; } _iq_mam_request(win, startdate, enddate); @@ -2742,7 +2758,7 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) buffer_remove_entry(window->layout->buffer, 0); - char* start_str = NULL; + auto_char char* start_str = NULL; if (data->start_datestr) { start_str = strdup(data->start_datestr); // Convert to iso8601 @@ -2757,24 +2773,10 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) if (is_complete || !data->fetch_next) { chatwin_db_history(data->win, is_complete ? NULL : start_str, end_str, TRUE); - // TODO free memory - if (start_str) { - free(start_str); - free(data->start_datestr); - } - - if (end_str) { - free(data->end_datestr); - } - - free(data->barejid); - free(data); return 0; } chatwin_db_history(data->win, start_str, end_str, TRUE); - if (start_str) - free(start_str); xmpp_stanza_t* set = xmpp_stanza_get_child_by_name_and_ns(fin, STANZA_TYPE_SET, STANZA_NS_RSM); if (set) { @@ -2787,14 +2789,22 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata) // 4.3.2. send same stanza with set,max stanza xmpp_ctx_t* const ctx = connection_get_ctx(); - if (end_str) { + if (data->end_datestr) { free(data->end_datestr); + data->end_datestr = NULL; } - data->end_datestr = NULL; - xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, data->barejid, data->start_datestr, data->end_datestr, firstid, NULL); + xmpp_stanza_t* iq = stanza_create_mam_iq(ctx, data->barejid, data->start_datestr, NULL, firstid, NULL); free(firstid); - iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, NULL, data); + MamRsmUserdata* ndata = malloc(sizeof(*ndata)); + *ndata = *data; + if (data->end_datestr) + ndata->end_datestr = strdup(data->end_datestr); + if (data->start_datestr) + ndata->start_datestr = strdup(data->start_datestr); + if (data->barejid) + ndata->barejid = strdup(data->barejid); + iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, (ProfIqFreeCallback)_mam_userdata_free, ndata); iq_send_stanza(iq); xmpp_stanza_release(iq); diff --git a/src/xmpp/jid.c b/src/xmpp/jid.c index e9aa595e..51c710f1 100644 --- a/src/xmpp/jid.c +++ b/src/xmpp/jid.c @@ -90,10 +90,9 @@ jid_create(const gchar* const str) if (slashp) { result->resourcepart = g_strdup(slashp + 1); result->domainpart = g_utf8_substring(domain_start, 0, g_utf8_pointer_to_offset(domain_start, slashp)); - char* barejidraw = g_utf8_substring(trimmed, 0, g_utf8_pointer_to_offset(trimmed, slashp)); + auto_gchar gchar* barejidraw = g_utf8_substring(trimmed, 0, g_utf8_pointer_to_offset(trimmed, slashp)); result->barejid = g_utf8_strdown(barejidraw, -1); result->fulljid = g_strdup(trimmed); - g_free(barejidraw); } else { result->domainpart = g_strdup(domain_start); result->barejid = g_utf8_strdown(trimmed, -1); @@ -189,15 +188,13 @@ create_fulljid(const char* const barejid, const char* const resource) char* get_nick_from_full_jid(const char* const full_room_jid) { - char** tokens = g_strsplit(full_room_jid, "/", 0); + auto_gcharv gchar** tokens = g_strsplit(full_room_jid, "/", 0); char* nick_part = NULL; if (tokens) { if (tokens[0] && tokens[1]) { nick_part = strdup(tokens[1]); } - - g_strfreev(tokens); } return nick_part; diff --git a/src/xmpp/message.c b/src/xmpp/message.c index 28997474..a6372c4a 100644 --- a/src/xmpp/message.c +++ b/src/xmpp/message.c @@ -638,10 +638,9 @@ message_send_chat_omemo(const char* const jid, uint32_t sid, GList* keys, xmpp_stanza_t* header = xmpp_stanza_new(ctx); xmpp_stanza_set_name(header, "header"); - char* sid_text = g_strdup_printf("%d", sid); + auto_gchar gchar* sid_text = g_strdup_printf("%d", sid); log_debug("[OMEMO] Sending from device sid %s", sid_text); xmpp_stanza_set_attribute(header, "sid", sid_text); - g_free(sid_text); GList* key_iter; for (key_iter = keys; key_iter != NULL; key_iter = key_iter->next) { @@ -649,10 +648,9 @@ message_send_chat_omemo(const char* const jid, uint32_t sid, GList* keys, xmpp_stanza_t* key_stanza = xmpp_stanza_new(ctx); xmpp_stanza_set_name(key_stanza, "key"); - char* rid = g_strdup_printf("%d", key->device_id); + auto_gchar gchar* rid = g_strdup_printf("%d", key->device_id); log_debug("[OMEMO] Sending to device rid %s", STR_MAYBE_NULL(rid)); xmpp_stanza_set_attribute(key_stanza, "rid", rid); - g_free(rid); if (key->prekey) { xmpp_stanza_set_attribute(key_stanza, "prekey", "true"); } @@ -1625,19 +1623,16 @@ message_is_sent_by_us(const ProfMessage* const message, bool checkOID) // our client sents at CON_RAND_ID_LEN + identifier if (tmp_len > CON_RAND_ID_LEN) { - char* uuid = g_strndup(tmp_id, CON_RAND_ID_LEN); + auto_gchar gchar* uuid = g_strndup(tmp_id, CON_RAND_ID_LEN); const char* prof_identifier = connection_get_profanity_identifier(); - gchar* hmac = g_compute_hmac_for_string(G_CHECKSUM_SHA1, - (guchar*)prof_identifier, strlen(prof_identifier), - uuid, strlen(uuid)); + auto_gchar gchar* hmac = g_compute_hmac_for_string(G_CHECKSUM_SHA1, + (guchar*)prof_identifier, strlen(prof_identifier), + uuid, strlen(uuid)); if (g_strcmp0(&tmp_id[CON_RAND_ID_LEN], hmac) == 0) { ret = TRUE; } - - g_free(uuid); - g_free(hmac); } } } diff --git a/src/xmpp/omemo.c b/src/xmpp/omemo.c index e1bdbc3e..23c3d375 100644 --- a/src/xmpp/omemo.c +++ b/src/xmpp/omemo.c @@ -669,11 +669,10 @@ _omemo_bundle_publish_result(xmpp_stanza_t* const stanza, void* const userdata) xmpp_ctx_t* const ctx = connection_get_ctx(); Jid* jid = jid_create(connection_get_fulljid()); char* id = connection_create_stanza_id(); - char* node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, omemo_device_id()); + auto_gchar gchar* node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, omemo_device_id()); log_debug("[OMEMO] node: %s", node); xmpp_stanza_t* iq = stanza_create_pubsub_configure_request(ctx, id, jid->barejid, node); - g_free(node); iq_id_handler_add(id, _omemo_bundle_publish_configure, NULL, userdata); @@ -712,9 +711,8 @@ _omemo_bundle_publish_configure(xmpp_stanza_t* const stanza, void* const userdat xmpp_ctx_t* const ctx = connection_get_ctx(); Jid* jid = jid_create(connection_get_fulljid()); char* id = connection_create_stanza_id(); - char* node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, omemo_device_id()); + auto_gchar gchar* node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, omemo_device_id()); xmpp_stanza_t* iq = stanza_create_pubsub_configure_submit(ctx, id, jid->barejid, node, form); - g_free(node); iq_id_handler_add(id, _omemo_bundle_publish_configure_result, NULL, userdata); diff --git a/src/xmpp/session.h b/src/xmpp/session.h index e6facb93..d8565fa4 100644 --- a/src/xmpp/session.h +++ b/src/xmpp/session.h @@ -47,6 +47,5 @@ void session_init_activity(void); void session_check_autoaway(void); void session_reconnect(gchar* altdomain, unsigned short altport); -void session_reconnect_now(void); #endif diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 0fe3966c..bbc15c13 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -2329,9 +2329,8 @@ stanza_create_omemo_devicelist_publish(xmpp_ctx_t* ctx, GList* const ids) for (GList* i = ids; i != NULL; i = i->next) { xmpp_stanza_t* device = xmpp_stanza_new(ctx); xmpp_stanza_set_name(device, "device"); - char* id = g_strdup_printf("%d", GPOINTER_TO_INT(i->data)); + auto_gchar gchar* id = g_strdup_printf("%d", GPOINTER_TO_INT(i->data)); xmpp_stanza_set_attribute(device, "id", id); - g_free(id); xmpp_stanza_add_child(list, device); xmpp_stanza_release(device); @@ -2366,9 +2365,8 @@ stanza_create_omemo_bundle_publish(xmpp_ctx_t* ctx, const char* const id, xmpp_stanza_t* publish = xmpp_stanza_new(ctx); xmpp_stanza_set_name(publish, STANZA_NAME_PUBLISH); - char* node = g_strdup_printf("%s:%d", "eu.siacs.conversations.axolotl.bundles", device_id); + auto_gchar gchar* node = g_strdup_printf("%s:%d", "eu.siacs.conversations.axolotl.bundles", device_id); xmpp_stanza_set_attribute(publish, STANZA_ATTR_NODE, node); - g_free(node); xmpp_stanza_t* item = xmpp_stanza_new(ctx); xmpp_stanza_set_name(item, STANZA_NAME_ITEM); @@ -2416,9 +2414,8 @@ stanza_create_omemo_bundle_publish(xmpp_ctx_t* ctx, const char* const id, for (p = prekeys, i = prekeys_id, l = prekeys_length; p != NULL; p = p->next, i = i->next, l = l->next) { xmpp_stanza_t* prekey = xmpp_stanza_new(ctx); xmpp_stanza_set_name(prekey, "preKeyPublic"); - char* id = g_strdup_printf("%d", GPOINTER_TO_INT(i->data)); + auto_gchar gchar* id = g_strdup_printf("%d", GPOINTER_TO_INT(i->data)); xmpp_stanza_set_attribute(prekey, "preKeyId", id); - g_free(id); xmpp_stanza_t* prekey_text = xmpp_stanza_new(ctx); char* prekey_b64 = g_base64_encode(p->data, GPOINTER_TO_INT(l->data)); @@ -2464,9 +2461,8 @@ stanza_create_omemo_bundle_request(xmpp_ctx_t* ctx, const char* const id, const xmpp_stanza_t* items = xmpp_stanza_new(ctx); xmpp_stanza_set_name(items, "items"); - char* node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, device_id); + auto_gchar gchar* node = g_strdup_printf("%s:%d", STANZA_NS_OMEMO_BUNDLES, device_id); xmpp_stanza_set_attribute(items, STANZA_ATTR_NODE, node); - g_free(node); xmpp_stanza_add_child(pubsub, items); xmpp_stanza_add_child(iq, pubsub); @@ -2577,9 +2573,8 @@ stanza_create_avatar_retrieve_data_request(xmpp_ctx_t* ctx, const char* stanza_i xmpp_stanza_t* items = xmpp_stanza_new(ctx); xmpp_stanza_set_name(items, "items"); - char* node = g_strdup_printf("%s", STANZA_NS_USER_AVATAR_DATA); + auto_gchar gchar* node = g_strdup_printf("%s", STANZA_NS_USER_AVATAR_DATA); xmpp_stanza_set_attribute(items, STANZA_ATTR_NODE, node); - g_free(node); xmpp_stanza_t* item = xmpp_stanza_new(ctx); xmpp_stanza_set_name(item, STANZA_NAME_ITEM); @@ -2671,16 +2666,13 @@ stanza_create_avatar_metadata_publish_iq(xmpp_ctx_t* ctx, const char* img_data, xmpp_stanza_set_name(info, STANZA_NAME_INFO); xmpp_stanza_set_attribute(info, "id", sha1); xmpp_free(ctx, sha1); - char* bytes = g_strdup_printf("%" G_GSIZE_FORMAT, len); - char* h = g_strdup_printf("%d", height); - char* w = g_strdup_printf("%d", width); + auto_gchar gchar* bytes = g_strdup_printf("%" G_GSIZE_FORMAT, len); + auto_gchar gchar* h = g_strdup_printf("%d", height); + auto_gchar gchar* w = g_strdup_printf("%d", width); xmpp_stanza_set_attribute(info, "bytes", bytes); xmpp_stanza_set_attribute(info, "type", "img/png"); xmpp_stanza_set_attribute(info, "height", h); xmpp_stanza_set_attribute(info, "width", w); - g_free(bytes); - g_free(h); - g_free(w); xmpp_stanza_add_child(metadata, info); xmpp_stanza_add_child(item, metadata); @@ -2765,6 +2757,19 @@ stanza_attach_correction(xmpp_ctx_t* ctx, xmpp_stanza_t* stanza, const char* con return stanza; } +static xmpp_stanza_t* +_text_stanza(xmpp_ctx_t* ctx, const char* name, const char* text) +{ + xmpp_stanza_t* res = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(res, name); + + xmpp_stanza_t* t = xmpp_stanza_new(ctx); + xmpp_stanza_set_text(t, text); + xmpp_stanza_add_child_ex(res, t, 0); + + return res; +} + xmpp_stanza_t* stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const startdate, const char* const enddate, const char* const firstid, const char* const lastid) { @@ -2788,146 +2793,67 @@ stanza_create_mam_iq(xmpp_ctx_t* ctx, const char* const jid, const char* const s xmpp_stanza_set_attribute(field_form_type, STANZA_ATTR_VAR, "FORM_TYPE"); xmpp_stanza_set_type(field_form_type, "hidden"); - xmpp_stanza_t* value_mam = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(value_mam, STANZA_NAME_VALUE); - - xmpp_stanza_t* mam_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(mam_text, STANZA_NS_MAM2); - xmpp_stanza_add_child(value_mam, mam_text); + xmpp_stanza_t* value_mam = _text_stanza(ctx, STANZA_NAME_VALUE, STANZA_NS_MAM2); - xmpp_stanza_add_child(field_form_type, value_mam); + xmpp_stanza_add_child_ex(field_form_type, value_mam, 0); // field 'with' xmpp_stanza_t* field_with = xmpp_stanza_new(ctx); xmpp_stanza_set_name(field_with, STANZA_NAME_FIELD); xmpp_stanza_set_attribute(field_with, STANZA_ATTR_VAR, "with"); - xmpp_stanza_t* value_with = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(value_with, STANZA_NAME_VALUE); - - xmpp_stanza_t* with_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(with_text, jid); - xmpp_stanza_add_child(value_with, with_text); - - xmpp_stanza_add_child(field_with, value_with); - - // field 'start' - xmpp_stanza_t *field_start, *value_start, *start_date_text; - if (startdate) { - field_start = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(field_start, STANZA_NAME_FIELD); - xmpp_stanza_set_attribute(field_start, STANZA_ATTR_VAR, "start"); - - value_start = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(value_start, STANZA_NAME_VALUE); - - start_date_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(start_date_text, startdate); - xmpp_stanza_add_child(value_start, start_date_text); - - xmpp_stanza_add_child(field_start, value_start); - } - - xmpp_stanza_t *field_end, *value_end, *end_date_text; - if (enddate) { - field_end = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(field_end, STANZA_NAME_FIELD); - xmpp_stanza_set_attribute(field_end, STANZA_ATTR_VAR, "end"); - - value_end = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(value_end, STANZA_NAME_VALUE); - - end_date_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(end_date_text, enddate); - xmpp_stanza_add_child(value_end, end_date_text); + xmpp_stanza_t* value_with = _text_stanza(ctx, STANZA_NAME_VALUE, jid); - xmpp_stanza_add_child(field_end, value_end); - } + xmpp_stanza_add_child_ex(field_with, value_with, 0); // 4.3.2 set/rsm - xmpp_stanza_t *set, *max, *max_text; - set = xmpp_stanza_new(ctx); + xmpp_stanza_t* set = xmpp_stanza_new(ctx); xmpp_stanza_set_name(set, STANZA_TYPE_SET); xmpp_stanza_set_ns(set, STANZA_NS_RSM); - max = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(max, STANZA_NAME_MAX); - - max_text = xmpp_stanza_new(ctx); - char* txt = g_strdup_printf("%d", MESSAGES_TO_RETRIEVE); - xmpp_stanza_set_text(max_text, txt); - g_free(txt); - - xmpp_stanza_add_child(max, max_text); - xmpp_stanza_add_child(set, max); + xmpp_stanza_t* max = _text_stanza(ctx, STANZA_NAME_MAX, PROF_STRINGIFY(MESSAGES_TO_RETRIEVE)); + xmpp_stanza_add_child_ex(set, max, 0); - xmpp_stanza_t *after, *after_text; if (lastid) { - after = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(after, STANZA_NAME_AFTER); - - after_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(after_text, lastid); - - xmpp_stanza_add_child(after, after_text); - xmpp_stanza_add_child(set, after); + xmpp_stanza_t* after = _text_stanza(ctx, STANZA_NAME_AFTER, lastid); + xmpp_stanza_add_child_ex(set, after, 0); } - xmpp_stanza_t *before, *before_text; if (firstid) { - before = xmpp_stanza_new(ctx); - xmpp_stanza_set_name(before, STANZA_NAME_BEFORE); - - before_text = xmpp_stanza_new(ctx); - xmpp_stanza_set_text(before_text, firstid); - - xmpp_stanza_add_child(before, before_text); - xmpp_stanza_add_child(set, before); + xmpp_stanza_t* before = _text_stanza(ctx, STANZA_NAME_BEFORE, firstid); + xmpp_stanza_add_child_ex(set, before, 0); } // add and release - xmpp_stanza_add_child(iq, query); - xmpp_stanza_add_child(query, x); - xmpp_stanza_add_child(x, field_form_type); - xmpp_stanza_add_child(x, field_with); + xmpp_stanza_add_child_ex(iq, query, 0); + xmpp_stanza_add_child_ex(query, x, 0); + xmpp_stanza_add_child_ex(x, field_form_type, 0); + xmpp_stanza_add_child_ex(x, field_with, 0); + // field 'start' if (startdate) { - xmpp_stanza_add_child(x, field_start); - xmpp_stanza_release(field_start); - xmpp_stanza_release(value_start); - xmpp_stanza_release(start_date_text); - } + xmpp_stanza_t* field_start = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(field_start, STANZA_NAME_FIELD); + xmpp_stanza_set_attribute(field_start, STANZA_ATTR_VAR, "start"); - if (enddate) { - xmpp_stanza_add_child(x, field_end); - xmpp_stanza_release(field_end); - xmpp_stanza_release(value_end); - xmpp_stanza_release(end_date_text); + xmpp_stanza_t* value_start = _text_stanza(ctx, STANZA_NAME_VALUE, startdate); + + xmpp_stanza_add_child_ex(field_start, value_start, 0); + xmpp_stanza_add_child_ex(x, field_start, 0); } - xmpp_stanza_add_child(query, set); - xmpp_stanza_release(set); - xmpp_stanza_release(max_text); - xmpp_stanza_release(max); + if (enddate) { + xmpp_stanza_t* field_end = xmpp_stanza_new(ctx); + xmpp_stanza_set_name(field_end, STANZA_NAME_FIELD); + xmpp_stanza_set_attribute(field_end, STANZA_ATTR_VAR, "end"); - if (lastid) { - xmpp_stanza_release(after_text); - xmpp_stanza_release(after); - } + xmpp_stanza_t* value_end = _text_stanza(ctx, STANZA_NAME_VALUE, enddate); - if (firstid) { - xmpp_stanza_release(before_text); - xmpp_stanza_release(before); + xmpp_stanza_add_child_ex(field_end, value_end, 0); + xmpp_stanza_add_child_ex(x, field_end, 0); } - xmpp_stanza_release(mam_text); - xmpp_stanza_release(with_text); - xmpp_stanza_release(value_mam); - xmpp_stanza_release(value_with); - xmpp_stanza_release(field_form_type); - xmpp_stanza_release(field_with); - xmpp_stanza_release(x); - xmpp_stanza_release(query); + xmpp_stanza_add_child_ex(query, set, 0); return iq; } diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 539126cd..2babe536 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -186,7 +186,9 @@ void session_disconnect(void); void session_shutdown(void); void session_process_events(void); char* session_get_account_name(void); +void session_reconnect_now(void); +void connection_disconnect(void); jabber_conn_status_t connection_get_status(void); char* connection_get_presence_msg(void); void connection_set_presence_msg(const char* const message); |