about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/command/cmd_ac.c1
-rw-r--r--src/command/cmd_defs.c8
-rw-r--r--src/command/cmd_funcs.c49
-rw-r--r--src/config/account.c57
-rw-r--r--src/config/accounts.c96
-rw-r--r--src/config/accounts.h1
-rw-r--r--src/xmpp/connection.c4
-rw-r--r--src/xmpp/connection.h1
-rw-r--r--src/xmpp/xmpp.h2
-rw-r--r--tests/functionaltests/functionaltests.c1
-rw-r--r--tests/functionaltests/test_muc.c15
-rw-r--r--tests/functionaltests/test_muc.h1
-rw-r--r--tests/functionaltests/test_rooms.c2
-rw-r--r--tests/unittests/config/stub_accounts.c1
14 files changed, 130 insertions, 109 deletions
diff --git a/src/command/cmd_ac.c b/src/command/cmd_ac.c
index 2d3209d5..be198e2a 100644
--- a/src/command/cmd_ac.c
+++ b/src/command/cmd_ac.c
@@ -360,6 +360,7 @@ cmd_ac_init(void)
     autocomplete_add(account_clear_ac, "pgpkeyid");
     autocomplete_add(account_clear_ac, "startscript");
     autocomplete_add(account_clear_ac, "theme");
+    autocomplete_add(account_clear_ac, "muc");
 
     account_default_ac = autocomplete_new();
     autocomplete_add(account_default_ac, "set");
diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c
index 34400ae3..3c2be4db 100644
--- a/src/command/cmd_defs.c
+++ b/src/command/cmd_defs.c
@@ -1989,7 +1989,8 @@ static struct cmd_t command_defs[] =
             "/account clear <account> port",
             "/account clear <account> otr",
             "/account clear <account> pgpkeyid",
-            "/account clear <account> startscript")
+            "/account clear <account> startscript",
+            "/account clean <account> muc")
         CMD_DESC(
             "Commands for creating and managing accounts. "
             "Calling with no arguments will display information for the current account.")
@@ -2012,7 +2013,7 @@ static struct cmd_t command_defs[] =
             { "set <account> resource <resource>",      "The resource to be used for this account, defaults to 'profanity'." },
             { "set <account> password <password>",      "Password for the account, note this is currently stored in plaintext if set." },
             { "set <account> eval_password <command>",  "Shell command evaluated to retrieve password for the account. Can be used to retrieve password from keyring." },
-            { "set <account> muc <service>",            "The default MUC chat service to use, defaults to 'conference.<domainpart>' where the domain part is from the account JID." },
+            { "set <account> muc <service>",            "The default MUC chat service to use, defaults to the servers disco info response." },
             { "set <account> nick <nick>",              "The default nickname to use when joining chat rooms." },
             { "set <account> otr <policy>",             "Override global OTR policy for this account, see /otr." },
             { "set <account> pgpkeyid <pgpkeyid>",      "Set the ID of the PGP key for this account, see /pgp." },
@@ -2028,7 +2029,8 @@ static struct cmd_t command_defs[] =
             { "clear <account> otr",                    "Remove the OTR policy setting for this account." },
             { "clear <account> pgpkeyid",               "Remove pgpkeyid associated with this account." },
             { "clear <account> startscript",            "Remove startscript associated with this account." },
-            { "clear <account> theme",                  "Clear the theme setting for the account, the global theme will be used." })
+            { "clear <account> theme",                  "Clear the theme setting for the account, the global theme will be used." },
+            { "clear <account> muc",                    "Remove the default MUC service setting."})
         CMD_EXAMPLES(
             "/account add me",
             "/account set me jid me@chatty",
diff --git a/src/command/cmd_funcs.c b/src/command/cmd_funcs.c
index 145752ca..08570e96 100644
--- a/src/command/cmd_funcs.c
+++ b/src/command/cmd_funcs.c
@@ -959,6 +959,10 @@ cmd_account_clear(ProfWin *window, const char *const command, gchar **args)
         accounts_clear_theme(account_name);
         cons_show("Removed theme for account %s", account_name);
         cons_show("");
+    } else if (strcmp(property, "muc") == 0) {
+        accounts_clear_muc(account_name);
+        cons_show("Removed MUC service for account %s", account_name);
+        cons_show("");
     } else {
         cons_show("Invalid property: %s", property);
         cons_show("");
@@ -3426,17 +3430,20 @@ cmd_join(ProfWin *window, const char *const command, gchar **args)
     if (args[0] == NULL) {
         char *account_name = session_get_account_name();
         ProfAccount *account = accounts_get_account(account_name);
+        if (account->muc_service) {
+            GString *room_str = g_string_new("");
+            char *uuid = connection_create_uuid();
+            g_string_append_printf(room_str, "private-chat-%s@%s", uuid, account->muc_service);
+            connection_free_uuid(uuid);
 
-        GString *room_str = g_string_new("");
-        char *uuid = connection_create_uuid();
-        g_string_append_printf(room_str, "private-chat-%s@%s", uuid, account->muc_service);
-        connection_free_uuid(uuid);
-
-        presence_join_room(room_str->str, account->muc_nick, NULL);
-        muc_join(room_str->str, account->muc_nick, NULL, FALSE);
+            presence_join_room(room_str->str, account->muc_nick, NULL);
+            muc_join(room_str->str, account->muc_nick, NULL, FALSE);
 
-        g_string_free(room_str, TRUE);
-        account_free(account);
+            g_string_free(room_str, TRUE);
+            account_free(account);
+        } else {
+            cons_show("Account MUC service property not found.");
+        }
 
         return TRUE;
     }
@@ -3451,7 +3458,6 @@ cmd_join(ProfWin *window, const char *const command, gchar **args)
     char *room = NULL;
     char *nick = NULL;
     char *passwd = NULL;
-    GString *room_str = g_string_new("");
     char *account_name = session_get_account_name();
     ProfAccount *account = accounts_get_account(account_name);
 
@@ -3460,11 +3466,18 @@ cmd_join(ProfWin *window, const char *const command, gchar **args)
         room = args[0];
 
     // server not supplied (room), use account preference
-    } else {
+    } else if (account->muc_service) {
+        GString *room_str = g_string_new("");
         g_string_append(room_str, args[0]);
         g_string_append(room_str, "@");
         g_string_append(room_str, account->muc_service);
         room = room_str->str;
+        g_string_free(room_str, FALSE);
+
+    // no account preference
+    } else {
+        cons_show("Account MUC service property not found.");
+        return TRUE;
     }
 
     // Additional args supplied
@@ -3502,7 +3515,6 @@ cmd_join(ProfWin *window, const char *const command, gchar **args)
     }
 
     jid_destroy(room_arg);
-    g_string_free(room_str, TRUE);
     account_free(account);
 
     return TRUE;
@@ -4307,13 +4319,18 @@ cmd_rooms(ProfWin *window, const char *const command, gchar **args)
         return TRUE;
     }
 
-    if (args[0] == NULL) {
-        ProfAccount *account = accounts_get_account(session_get_account_name());
+    if (args[0]) {
+        iq_room_list_request(args[0]);
+        return TRUE;
+    }
+
+    ProfAccount *account = accounts_get_account(session_get_account_name());
+    if (account->muc_service) {
         iq_room_list_request(account->muc_service);
-        account_free(account);
     } else {
-        iq_room_list_request(args[0]);
+        cons_show("Account MUC service property not found.");
     }
+    account_free(account);
 
     return TRUE;
 }
diff --git a/src/config/account.c b/src/config/account.c
index 3e8c8cf1..40b91224 100644
--- a/src/config/account.c
+++ b/src/config/account.c
@@ -115,17 +115,10 @@ account_new(const gchar *const name, const gchar *const jid,
     new_account->priority_xa = priority_xa;
     new_account->priority_dnd = priority_dnd;
 
-    if (muc_service == NULL) {
-        GString *g_muc_service = g_string_new("conference.");
-        Jid *jidp = jid_create(new_account->jid);
-        g_string_append(g_muc_service, jidp->domainpart);
-
-        new_account->muc_service = g_muc_service->str;
-
-        g_string_free(g_muc_service, FALSE);
-        jid_destroy(jidp);
-    } else {
+    if (muc_service) {
         new_account->muc_service = strdup(muc_service);
+    } else {
+        new_account->muc_service = NULL;
     }
 
     if (muc_nick == NULL) {
@@ -224,25 +217,27 @@ account_eval_password(ProfAccount *account)
 void
 account_free(ProfAccount *account)
 {
-    if (account) {
-        free(account->name);
-        free(account->jid);
-        free(account->password);
-        free(account->eval_password);
-        free(account->resource);
-        free(account->server);
-        free(account->last_presence);
-        free(account->login_presence);
-        free(account->muc_service);
-        free(account->muc_nick);
-        free(account->otr_policy);
-        free(account->pgp_keyid);
-        free(account->startscript);
-        free(account->theme);
-        free(account->tls_policy);
-        g_list_free_full(account->otr_manual, g_free);
-        g_list_free_full(account->otr_opportunistic, g_free);
-        g_list_free_full(account->otr_always, g_free);
-        free(account);
-    }
+    if (account == NULL) {
+        return;
+    }
+
+    free(account->name);
+    free(account->jid);
+    free(account->password);
+    free(account->eval_password);
+    free(account->resource);
+    free(account->server);
+    free(account->last_presence);
+    free(account->login_presence);
+    free(account->muc_service);
+    free(account->muc_nick);
+    free(account->otr_policy);
+    free(account->pgp_keyid);
+    free(account->startscript);
+    free(account->theme);
+    free(account->tls_policy);
+    g_list_free_full(account->otr_manual, g_free);
+    g_list_free_full(account->otr_opportunistic, g_free);
+    g_list_free_full(account->otr_always, g_free);
+    free(account);
 }
diff --git a/src/config/accounts.c b/src/config/accounts.c
index 96168b5b..233a5aa8 100644
--- a/src/config/accounts.c
+++ b/src/config/accounts.c
@@ -133,46 +133,46 @@ accounts_add(const char *account_name, const char *altdomain, const int port, co
         }
     }
 
-    // doesn't yet exist
-    if (!g_key_file_has_group(accounts, account_name)) {
-        g_key_file_set_boolean(accounts, account_name, "enabled", TRUE);
-        g_key_file_set_string(accounts, account_name, "jid", barejid);
-        g_key_file_set_string(accounts, account_name, "resource", resource);
-        if (altdomain) {
-            g_key_file_set_string(accounts, account_name, "server", altdomain);
-        }
-        if (port != 0) {
-            g_key_file_set_integer(accounts, account_name, "port", port);
-        }
-        if (tls_policy) {
-            g_key_file_set_string(accounts, account_name, "tls.policy", tls_policy);
-        }
+    if (g_key_file_has_group(accounts, account_name)) {
+        jid_destroy(jid);
+        return;
+    }
 
-        Jid *jidp = jid_create(barejid);
-        GString *muc_service = g_string_new("conference.");
-        g_string_append(muc_service, jidp->domainpart);
-        g_key_file_set_string(accounts, account_name, "muc.service", muc_service->str);
-        g_string_free(muc_service, TRUE);
-        if (jidp->localpart == NULL) {
-            g_key_file_set_string(accounts, account_name, "muc.nick", jidp->domainpart);
-        } else {
-            g_key_file_set_string(accounts, account_name, "muc.nick", jidp->localpart);
-        }
-        jid_destroy(jidp);
+    g_key_file_set_boolean(accounts, account_name, "enabled", TRUE);
+    g_key_file_set_string(accounts, account_name, "jid", barejid);
+    g_key_file_set_string(accounts, account_name, "resource", resource);
+    if (altdomain) {
+        g_key_file_set_string(accounts, account_name, "server", altdomain);
+    }
+    if (port != 0) {
+        g_key_file_set_integer(accounts, account_name, "port", port);
+    }
+    if (tls_policy) {
+        g_key_file_set_string(accounts, account_name, "tls.policy", tls_policy);
+    }
 
-        g_key_file_set_string(accounts, account_name, "presence.last", "online");
-        g_key_file_set_string(accounts, account_name, "presence.login", "online");
-        g_key_file_set_integer(accounts, account_name, "priority.online", 0);
-        g_key_file_set_integer(accounts, account_name, "priority.chat", 0);
-        g_key_file_set_integer(accounts, account_name, "priority.away", 0);
-        g_key_file_set_integer(accounts, account_name, "priority.xa", 0);
-        g_key_file_set_integer(accounts, account_name, "priority.dnd", 0);
+    Jid *jidp = jid_create(barejid);
 
-        _save_accounts();
-        autocomplete_add(all_ac, account_name);
-        autocomplete_add(enabled_ac, account_name);
+    if (jidp->localpart == NULL) {
+        g_key_file_set_string(accounts, account_name, "muc.nick", jidp->domainpart);
+    } else {
+        g_key_file_set_string(accounts, account_name, "muc.nick", jidp->localpart);
     }
 
+    jid_destroy(jidp);
+
+    g_key_file_set_string(accounts, account_name, "presence.last", "online");
+    g_key_file_set_string(accounts, account_name, "presence.login", "online");
+    g_key_file_set_integer(accounts, account_name, "priority.online", 0);
+    g_key_file_set_integer(accounts, account_name, "priority.chat", 0);
+    g_key_file_set_integer(accounts, account_name, "priority.away", 0);
+    g_key_file_set_integer(accounts, account_name, "priority.xa", 0);
+    g_key_file_set_integer(accounts, account_name, "priority.dnd", 0);
+
+    _save_accounts();
+    autocomplete_add(all_ac, account_name);
+    autocomplete_add(enabled_ac, account_name);
+
     jid_destroy(jid);
 }
 
@@ -223,7 +223,18 @@ accounts_get_account(const char *const name)
         int priority_xa = g_key_file_get_integer(accounts, name, "priority.xa", NULL);
         int priority_dnd = g_key_file_get_integer(accounts, name, "priority.dnd", NULL);
 
-        gchar *muc_service = g_key_file_get_string(accounts, name, "muc.service", NULL);
+        gchar *muc_service = NULL;
+        if (g_key_file_has_key(accounts, name, "muc.service", NULL)) {
+            muc_service = g_key_file_get_string(accounts, name, "muc.service", NULL);
+        } else {
+            jabber_conn_status_t conn_status = connection_get_status();
+            if (conn_status == JABBER_CONNECTED) {
+                char* conf_jid = connection_jid_for_feature(XMPP_FEATURE_MUC);
+                if (conf_jid) {
+                    muc_service = strdup(conf_jid);
+                }
+            }
+        }
         gchar *muc_nick = g_key_file_get_string(accounts, name, "muc.nick", NULL);
 
         gchar *otr_policy = NULL;
@@ -416,10 +427,6 @@ accounts_set_jid(const char *const account_name, const char *const value)
                 g_key_file_set_string(accounts, account_name, "resource", jid->resourcepart);
             }
 
-            GString *muc_service = g_string_new("conference.");
-            g_string_append(muc_service, jid->domainpart);
-            g_key_file_set_string(accounts, account_name, "muc.service", muc_service->str);
-            g_string_free(muc_service, TRUE);
             if (jid->localpart == NULL) {
                 g_key_file_set_string(accounts, account_name, "muc.nick", jid->domainpart);
             } else {
@@ -569,6 +576,15 @@ accounts_clear_theme(const char *const account_name)
 }
 
 void
+accounts_clear_muc(const char *const account_name)
+{
+    if (accounts_account_exists(account_name)) {
+        g_key_file_remove_key(accounts, account_name, "muc.service", NULL);
+        _save_accounts();
+    }
+}
+
+void
 accounts_clear_otr(const char *const account_name)
 {
     if (accounts_account_exists(account_name)) {
diff --git a/src/config/accounts.h b/src/config/accounts.h
index 7524c65e..6c6cb1c9 100644
--- a/src/config/accounts.h
+++ b/src/config/accounts.h
@@ -93,6 +93,7 @@ void accounts_clear_otr(const char *const account_name);
 void accounts_clear_pgp_keyid(const char *const account_name);
 void accounts_clear_script_start(const char *const account_name);
 void accounts_clear_theme(const char *const account_name);
+void accounts_clear_muc(const char *const account_name);
 void accounts_add_otr_policy(const char *const account_name, const char *const contact_jid, const char *const policy);
 
 #endif
diff --git a/src/xmpp/connection.c b/src/xmpp/connection.c
index 304d984d..4e0ca9a8 100644
--- a/src/xmpp/connection.c
+++ b/src/xmpp/connection.c
@@ -290,6 +290,10 @@ connection_supports(const char *const feature)
 char*
 connection_jid_for_feature(const char *const feature)
 {
+    if (conn.features_by_jid == NULL) {
+        return NULL;
+    }
+
     GList *jids = g_hash_table_get_keys(conn.features_by_jid);
 
     GList *curr = jids;
diff --git a/src/xmpp/connection.h b/src/xmpp/connection.h
index ef997a29..b691e90d 100644
--- a/src/xmpp/connection.h
+++ b/src/xmpp/connection.h
@@ -54,7 +54,6 @@ void connection_set_disco_items(GSList *items);
 xmpp_conn_t* connection_get_conn(void);
 xmpp_ctx_t* connection_get_ctx(void);
 char *connection_get_domain(void);
-char* connection_jid_for_feature(const char *const feature);
 GHashTable* connection_get_features(const char *const jid);
 
 void connection_clear_data(void);
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index 8dfe7c0e..7302b279 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -58,6 +58,7 @@
 #define XMPP_FEATURE_BLOCKING "urn:xmpp:blocking"
 #define XMPP_FEATURE_RECEIPTS "urn:xmpp:receipts"
 #define XMPP_FEATURE_LASTACTIVITY "jabber:iq:last"
+#define XMPP_FEATURE_MUC "http://jabber.org/protocol/muc"
 
 typedef enum {
     JABBER_CONNECTING,
@@ -129,6 +130,7 @@ gboolean connection_is_secured(void);
 gboolean connection_send_stanza(const char *const stanza);
 GList* connection_get_available_resources(void);
 gboolean connection_supports(const char *const feature);
+char* connection_jid_for_feature(const char *const feature);
 
 char* message_send_chat(const char *const barejid, const char *const msg, const char *const oob_url,
     gboolean request_receipt);
diff --git a/tests/functionaltests/functionaltests.c b/tests/functionaltests/functionaltests.c
index 617ab838..ef9f0e39 100644
--- a/tests/functionaltests/functionaltests.c
+++ b/tests/functionaltests/functionaltests.c
@@ -89,7 +89,6 @@ int main(int argc, char* argv[]) {
         PROF_FUNC_TEST(display_software_version_result_in_chat),
 
         PROF_FUNC_TEST(sends_room_join),
-        PROF_FUNC_TEST(sends_room_join_with_default_muc_service),
         PROF_FUNC_TEST(sends_room_join_with_nick),
         PROF_FUNC_TEST(sends_room_join_with_password),
         PROF_FUNC_TEST(sends_room_join_with_nick_and_password),
diff --git a/tests/functionaltests/test_muc.c b/tests/functionaltests/test_muc.c
index 5a117045..e7fc8dcb 100644
--- a/tests/functionaltests/test_muc.c
+++ b/tests/functionaltests/test_muc.c
@@ -27,21 +27,6 @@ sends_room_join(void **state)
 }
 
 void
-sends_room_join_with_default_muc_service(void **state)
-{
-    prof_connect();
-
-    prof_input("/join testroom");
-
-    assert_true(stbbr_last_received(
-        "<presence id='*' to='testroom@conference.localhost/stabber'>"
-            "<x xmlns='http://jabber.org/protocol/muc'/>"
-            "<c hash='sha-1' xmlns='http://jabber.org/protocol/caps' ver='*' node='http://www.profanity.im'/>"
-        "</presence>"
-    ));
-}
-
-void
 sends_room_join_with_nick(void **state)
 {
     prof_connect();
diff --git a/tests/functionaltests/test_muc.h b/tests/functionaltests/test_muc.h
index 30a6c2c8..4f3c4f5d 100644
--- a/tests/functionaltests/test_muc.h
+++ b/tests/functionaltests/test_muc.h
@@ -1,5 +1,4 @@
 void sends_room_join(void **state);
-void sends_room_join_with_default_muc_service(void **state);
 void sends_room_join_with_nick(void **state);
 void sends_room_join_with_password(void **state);
 void sends_room_join_with_nick_and_password(void **state);
diff --git a/tests/functionaltests/test_rooms.c b/tests/functionaltests/test_rooms.c
index 9bff2e19..c0103279 100644
--- a/tests/functionaltests/test_rooms.c
+++ b/tests/functionaltests/test_rooms.c
@@ -25,7 +25,7 @@ rooms_query(void **state)
 
     prof_connect();
 
-    prof_input("/rooms");
+    prof_input("/rooms conference.localhost");
 
     assert_true(prof_output_exact("chatroom@conference.localhost, (A chat room)"));
     assert_true(prof_output_exact("hangout@conference.localhost, (Another chat room)"));
diff --git a/tests/unittests/config/stub_accounts.c b/tests/unittests/config/stub_accounts.c
index 4c0449d6..669ceb33 100644
--- a/tests/unittests/config/stub_accounts.c
+++ b/tests/unittests/config/stub_accounts.c
@@ -196,6 +196,7 @@ void accounts_clear_otr(const char * const account_name) {}
 void accounts_clear_pgp_keyid(const char * const account_name) {}
 void accounts_clear_script_start(const char * const account_name) {}
 void accounts_clear_theme(const char * const account_name) {}
+void accounts_clear_muc(const char * const account_name) {}
 void accounts_add_otr_policy(const char * const account_name, const char * const contact_jid, const char * const policy) {}
 char* accounts_get_last_activity(const char *const account_name)
 {