about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2014-04-21 00:37:04 +0100
committerJames Booth <boothj5@gmail.com>2014-04-21 00:37:04 +0100
commit2c15aba92a8288e41bea6e12933a14ffe390e1f4 (patch)
tree6e0efc0358f712a2e991259a0fbf2bf0c941cb61 /src
parent9a55d8ad193e79c38d59c9448330132f1c874bca (diff)
downloadprofani-tty-2c15aba92a8288e41bea6e12933a14ffe390e1f4.tar.gz
Chat room windows now created only after successful join
Diffstat (limited to 'src')
-rw-r--r--src/command/commands.c5
-rw-r--r--src/muc.c23
-rw-r--r--src/muc.h4
-rw-r--r--src/server_events.c36
-rw-r--r--src/server_events.h2
-rw-r--r--src/ui/core.c12
-rw-r--r--src/ui/ui.h3
-rw-r--r--src/xmpp/bookmark.c2
-rw-r--r--src/xmpp/presence.c22
-rw-r--r--src/xmpp/stanza.h1
10 files changed, 79 insertions, 31 deletions
diff --git a/src/command/commands.c b/src/command/commands.c
index 8e026b50..0a96d318 100644
--- a/src/command/commands.c
+++ b/src/command/commands.c
@@ -1591,9 +1591,10 @@ cmd_join(gchar **args, struct cmd_help_t help)
 
     if (!muc_room_is_active(room)) {
         presence_join_room(room, nick, passwd);
+        muc_join_room(room, nick, passwd, FALSE);
+    } else if (muc_get_roster_received(room)) {
+        ui_room_join(room, TRUE);
     }
-    ui_room_join(room, TRUE);
-    muc_remove_invite(room);
 
     jid_destroy(room_arg);
     g_string_free(room_str, TRUE);
diff --git a/src/muc.c b/src/muc.c
index 11a707a4..4ba88191 100644
--- a/src/muc.c
+++ b/src/muc.c
@@ -34,6 +34,7 @@ typedef struct _muc_room_t {
     char *nick; // e.g. Some User
     char *password;
     char *subject;
+    gboolean autojoin;
     gboolean pending_nick_change;
     GHashTable *roster;
     Autocomplete nick_ac;
@@ -126,7 +127,8 @@ muc_clear_invites(void)
  * Join the chat room with the specified nickname
  */
 void
-muc_join_room(const char * const room, const char * const nick, const char * const password)
+muc_join_room(const char * const room, const char * const nick,
+    const char * const password, gboolean autojoin)
 {
     if (rooms == NULL) {
         rooms = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
@@ -149,6 +151,7 @@ muc_join_room(const char * const room, const char * const nick, const char * con
         g_free, g_free);
     new_room->roster_received = FALSE;
     new_room->pending_nick_change = FALSE;
+    new_room->autojoin = autojoin;
 
     g_hash_table_insert(rooms, strdup(room), new_room);
 }
@@ -183,6 +186,22 @@ muc_room_is_active(const char * const room)
     }
 }
 
+gboolean
+muc_room_is_autojoin(const char * const room)
+{
+    if (rooms != NULL) {
+        ChatRoom *chat_room = g_hash_table_lookup(rooms, room);
+
+        if (chat_room != NULL) {
+            return chat_room->autojoin;
+        } else {
+            return FALSE;
+        }
+    } else {
+        return FALSE;
+    }
+}
+
 char *
 muc_get_old_nick(const char * const room, const char * const new_nick)
 {
@@ -504,4 +523,4 @@ gint _compare_participants(PContact a, PContact b)
     g_free(key_b);
 
     return result;
-}
+}
\ No newline at end of file
diff --git a/src/muc.h b/src/muc.h
index fc8c4668..34058bfe 100644
--- a/src/muc.h
+++ b/src/muc.h
@@ -31,9 +31,11 @@
 
 void muc_init(void);
 void muc_close(void);
-void muc_join_room(const char * const room, const char * const nick, const char * const password);
+void muc_join_room(const char * const room, const char * const nick,
+    const char * const password, gboolean autojoin);
 void muc_leave_room(const char * const room);
 gboolean muc_room_is_active(const char * const room);
+gboolean muc_room_is_autojoin(const char * const room);
 GList* muc_get_active_room_list(void);
 char * muc_get_room_nick(const char * const room);
 
diff --git a/src/server_events.c b/src/server_events.c
index afb29bcd..79cc0e26 100644
--- a/src/server_events.c
+++ b/src/server_events.c
@@ -36,23 +36,22 @@
 
 #include "ui/ui.h"
 
+void
+handle_room_join_error(const char * const room, const char * const err)
+{
+    if (muc_room_is_active(room)) {
+        muc_leave_room(room);
+    }
+    ui_handle_room_join_error(room, err);
+}
+
 // handle presence stanza errors
 void
 handle_presence_error(const char *from, const char * const type,
     const char *err_msg)
 {
-    // handle nickname conflict on entering room
-    if ((from != NULL) && g_strcmp0(err_msg, "conflict") == 0) {
-        // remove the room from muc
-        Jid *room_jid = jid_create(from);
-        if (!muc_get_roster_received(room_jid->barejid)) {
-            muc_leave_room(room_jid->barejid);
-            ui_handle_recipient_error(room_jid->barejid, err_msg);
-        }
-        jid_destroy(room_jid);
-
-    // handle any other error from recipient
-    } else if (from != NULL) {
+    // handle error from recipient
+    if (from != NULL) {
         ui_handle_recipient_error(from, err_msg);
 
     // handle errors from no recipient
@@ -404,6 +403,12 @@ handle_room_nick_change(const char * const room,
 void
 handle_room_roster_complete(const char * const room)
 {
+    if (muc_room_is_autojoin(room)) {
+        ui_room_join(room, FALSE);
+    } else {
+        ui_room_join(room, TRUE);
+    }
+    muc_remove_invite(room);
     muc_set_roster_received(room);
     GList *roster = muc_get_roster(room);
     ui_room_roster(room, roster, NULL);
@@ -500,13 +505,6 @@ handle_autoping_cancel(void)
 }
 
 void
-handle_bookmark_autojoin(char *jid)
-{
-    ui_room_join(jid, FALSE);
-    muc_remove_invite(jid);
-}
-
-void
 handle_xmpp_stanza(const char * const msg)
 {
     ui_handle_stanza(msg);
diff --git a/src/server_events.h b/src/server_events.h
index ea49e1f1..98e00731 100644
--- a/src/server_events.h
+++ b/src/server_events.h
@@ -43,6 +43,7 @@ void handle_room_history(const char * const room_jid, const char * const nick,
     GTimeVal tv_stamp, const char * const message);
 void handle_room_message(const char * const room_jid, const char * const nick,
     const char * const message);
+void handle_room_join_error(const char * const room, const char * const err);
 void handle_duck_result(const char * const result);
 void handle_incoming_message(char *from, char *message, gboolean priv);
 void handle_delayed_message(char *from, char *message, GTimeVal tv_stamp,
@@ -78,7 +79,6 @@ void handle_message_error(const char * const from, const char * const type,
     const char * const err_msg);
 void handle_presence_error(const char *from, const char * const type,
     const char *err_msg);
-void handle_bookmark_autojoin(char *jid);
 void handle_xmpp_stanza(const char * const msg);
 
 #endif
diff --git a/src/ui/core.c b/src/ui/core.c
index a84d5856..8f385cf2 100644
--- a/src/ui/core.c
+++ b/src/ui/core.c
@@ -1272,7 +1272,7 @@ _ui_outgoing_msg(const char * const from, const char * const to,
 }
 
 static void
-_ui_room_join(char *room, gboolean focus)
+_ui_room_join(const char * const room, gboolean focus)
 {
     ProfWin *window = wins_get_by_recipient(room);
     int num = 0;
@@ -1289,7 +1289,8 @@ _ui_room_join(char *room, gboolean focus)
     } else {
         status_bar_active(num);
         ProfWin *console = wins_get_console();
-        win_vprint_line(console, '!', COLOUR_ONLINE, "-> Autojoined %s (%d).", room, num);
+        char *nick = muc_get_room_nick(room);
+        win_vprint_line(console, '!', COLOUR_TYPING, "-> Autojoined %s as %s (%d).", room, nick, num);
         win_update_virtual(console);
     }
 }
@@ -1350,6 +1351,12 @@ _ui_room_roster(const char * const room, GList *roster, const char * const prese
 }
 
 static void
+_ui_handle_room_join_error(const char * const room, const char * const err)
+{
+    cons_show_error("Error joining room %s, reason: %s", room, err);
+}
+
+static void
 _ui_room_member_offline(const char * const room, const char * const nick)
 {
     ProfWin *window = wins_get_by_recipient(room);
@@ -1979,4 +1986,5 @@ ui_init_module(void)
     ui_handle_stanza = _ui_handle_stanza;
     ui_create_xmlconsole_win = _ui_create_xmlconsole_win;
     ui_xmlconsole_exists = _ui_xmlconsole_exists;
+    ui_handle_room_join_error = _ui_handle_room_join_error;
 }
diff --git a/src/ui/ui.h b/src/ui/ui.h
index a93cc3d0..14f7137c 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -102,7 +102,7 @@ void (*ui_disconnected)(void);
 void (*ui_recipient_gone)(const char * const barejid);
 void (*ui_outgoing_msg)(const char * const from, const char * const to,
     const char * const message);
-void (*ui_room_join)(char *room, gboolean focus);
+void (*ui_room_join)(const char * const room, gboolean focus);
 void (*ui_room_roster)(const char * const room, GList *roster, const char * const presence);
 void (*ui_room_history)(const char * const room_jid, const char * const nick,
     GTimeVal tv_stamp, const char * const message);
@@ -132,6 +132,7 @@ void (*ui_handle_recipient_not_found)(const char * const recipient, const char *
 void (*ui_handle_recipient_error)(const char * const recipient, const char * const err_msg);
 void (*ui_handle_error)(const char * const err_msg);
 void (*ui_clear_win_title)(void);
+void (*ui_handle_room_join_error)(const char * const room, const char * const err);
 
 // contact status functions
 void (*ui_status_room)(const char * const contact);
diff --git a/src/xmpp/bookmark.c b/src/xmpp/bookmark.c
index 2e4f70db..c73f3db3 100644
--- a/src/xmpp/bookmark.c
+++ b/src/xmpp/bookmark.c
@@ -260,7 +260,7 @@ _bookmark_handle_result(xmpp_conn_t * const conn,
                 room_jid = jid_create_from_bare_and_resource(jid, name);
                 if (!muc_room_is_active(room_jid->barejid)) {
                     presence_join_room(jid, name, NULL);
-                    handle_bookmark_autojoin(jid);
+                    muc_join_room(jid, name, NULL, TRUE);
                 }
                 jid_destroy(room_jid);
             } else {
diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c
index 433c05f3..1cb86645 100644
--- a/src/xmpp/presence.c
+++ b/src/xmpp/presence.c
@@ -283,7 +283,6 @@ _presence_join_room(char *room, char *nick, char * passwd)
     xmpp_send(conn, presence);
     xmpp_stanza_release(presence);
 
-    muc_join_room(jid->barejid, jid->resourcepart, passwd);
     jid_destroy(jid);
 }
 
@@ -342,11 +341,31 @@ _presence_error_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
     char *id = xmpp_stanza_get_id(stanza);
     char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
     xmpp_stanza_t *error_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_ERROR);
+    xmpp_stanza_t *x = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_X);
+    char *xmlns = xmpp_stanza_get_ns(x);
     char *type = NULL;
     if (error_stanza != NULL) {
         type = xmpp_stanza_get_attribute(error_stanza, STANZA_ATTR_TYPE);
     }
 
+    // handle MUC join errors
+    if (g_strcmp0(xmlns, STANZA_NS_MUC) == 0) {
+        Jid *fulljid = jid_create(from);
+
+        char *error_cond = NULL;
+        xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_ns(error_stanza, STANZA_NS_STANZAS);
+        if (reason_st != NULL) {
+            error_cond = xmpp_stanza_get_name(reason_st);
+        }
+        if (error_cond == NULL) {
+            error_cond = "unknown";
+        }
+
+        log_info("Error joining room: %s, reason: %s", fulljid->barejid, error_cond);
+        handle_room_join_error(fulljid->barejid, error_cond);
+        return 1;
+    }
+
     // stanza_get_error never returns NULL
     char *err_msg = stanza_get_error_message(stanza);
 
@@ -676,7 +695,6 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
         // handle roster complete
         } else if (!muc_get_roster_received(room)) {
             handle_room_roster_complete(room);
-
         }
 
     // handle presence from room members
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index d71d3ea1..486421a2 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -124,6 +124,7 @@
 #define STANZA_TEXT_XA "xa"
 #define STANZA_TEXT_ONLINE "online"
 
+#define STANZA_NS_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas"
 #define STANZA_NS_CHATSTATES "http://jabber.org/protocol/chatstates"
 #define STANZA_NS_MUC "http://jabber.org/protocol/muc"
 #define STANZA_NS_MUC_USER "http://jabber.org/protocol/muc#user"