about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/command/cmd_ac.c33
-rw-r--r--src/command/cmd_defs.c10
-rw-r--r--src/command/cmd_funcs.c86
-rw-r--r--src/config/preferences.c2
-rw-r--r--src/event/client_events.c16
-rw-r--r--src/event/client_events.h1
-rw-r--r--src/event/server_events.c2
-rw-r--r--src/xmpp/connection.c2
-rw-r--r--src/xmpp/connection.h1
-rw-r--r--src/xmpp/iq.c41
-rw-r--r--src/xmpp/session.h1
-rw-r--r--src/xmpp/xmpp.h2
-rw-r--r--tests/unittests/xmpp/stub_xmpp.c4
13 files changed, 111 insertions, 90 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c
index 765ef448..48d712e4 100644
--- a/src/command/cmd_ac.c
+++ b/src/command/cmd_ac.c
@@ -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);
@@ -4379,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 c6e886a5..9828ab1a 100644
--- a/src/command/cmd_defs.c
+++ b/src/command/cmd_defs.c
@@ -2437,7 +2437,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",
@@ -2534,23 +2534,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(
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index 83c594f5..bb6cc49d 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -6575,7 +6575,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) {
@@ -9309,9 +9310,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);
         }
@@ -9620,15 +9618,7 @@ out:
 }
 
 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) {
@@ -9638,14 +9628,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);
@@ -9655,62 +9648,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);
-        auto_gchar gchar* cmd = prefs_get_string(PREF_VCARD_PHOTO_CMD);
-        cons_show("`vcard photo open` command set to invoke '%s' (default)", 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/config/preferences.c b/src/config/preferences.c
index 23709747..c10f4d83 100644
--- a/src/config/preferences.c
+++ b/src/config/preferences.c
@@ -2297,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/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 01002a1e..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);
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..4f6eea40 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);
@@ -2651,6 +2652,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 +2707,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);
@@ -2742,13 +2755,13 @@ _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
                 start_str[strlen(start_str) - 3] = '\0';
             }
-            char* end_str = NULL;
+            auto_char char* end_str = NULL;
             if (data->end_datestr) {
                 end_str = strdup(data->end_datestr);
                 // Convert to iso8601
@@ -2757,24 +2770,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 +2786,14 @@ _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);
+                iq_id_handler_add(xmpp_stanza_get_id(iq), _mam_rsm_id_handler, (ProfIqFreeCallback)_mam_userdata_free, data);
 
                 iq_send_stanza(iq);
                 xmpp_stanza_release(iq);
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/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);
diff --git a/tests/unittests/xmpp/stub_xmpp.c b/tests/unittests/xmpp/stub_xmpp.c
index a7dc9ebf..ffa7565d 100644
--- a/tests/unittests/xmpp/stub_xmpp.c
+++ b/tests/unittests/xmpp/stub_xmpp.c
@@ -54,6 +54,10 @@ void
 session_process_events(void)
 {
 }
+void
+connection_disconnect(void)
+{
+}
 const char*
 connection_get_fulljid(void)
 {