about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server_events.c6
-rw-r--r--src/server_events.h1
-rw-r--r--src/ui/core.c23
-rw-r--r--src/ui/ui.h1
-rw-r--r--src/xmpp/presence.c5
-rw-r--r--src/xmpp/stanza.c46
-rw-r--r--src/xmpp/stanza.h1
7 files changed, 83 insertions, 0 deletions
diff --git a/src/server_events.c b/src/server_events.c
index d48cfb23..4c14d079 100644
--- a/src/server_events.c
+++ b/src/server_events.c
@@ -450,6 +450,12 @@ handle_room_nick_change(const char * const room,
 }
 
 void
+handle_room_requires_config(const char * const room)
+{
+    ui_room_requires_config(room);
+}
+
+void
 handle_room_roster_complete(const char * const room)
 {
     if (muc_room_is_autojoin(room)) {
diff --git a/src/server_events.h b/src/server_events.h
index 1347aa8c..e9946ee6 100644
--- a/src/server_events.h
+++ b/src/server_events.h
@@ -69,6 +69,7 @@ void handle_contact_online(char *contact, Resource *resource,
 void handle_leave_room(const char * const room);
 void handle_room_nick_change(const char * const room,
     const char * const nick);
+void handle_room_requires_config(const char * const room);
 void handle_room_roster_complete(const char * const room);
 void handle_room_member_presence(const char * const room,
     const char * const nick, const char * const show,
diff --git a/src/ui/core.c b/src/ui/core.c
index 6d6a4092..a447031b 100644
--- a/src/ui/core.c
+++ b/src/ui/core.c
@@ -1589,6 +1589,28 @@ _ui_room_message(const char * const room_jid, const char * const nick,
 }
 
 static void
+_ui_room_requires_config(const char * const room_jid)
+{
+    ProfWin *window = wins_get_by_recipient(room_jid);
+    if (window == NULL) {
+        log_error("Received room config request, but no window open for %s.", room_jid);
+    } else {
+        int num = wins_get_num(window);
+
+        win_save_vprint(window, '!', NULL, 0, COLOUR_ROOMINFO, "", "Room requires configuration, use '/room config accept' or '/room config cancel'");
+
+        // currently in groupchat window
+        if (wins_is_current(window)) {
+            status_bar_active(num);
+
+        // not currenlty on groupchat window
+        } else {
+            status_bar_new(num);
+        }
+    }
+}
+
+static void
 _ui_room_subject(const char * const room_jid, const char * const subject)
 {
     ProfWin *window = wins_get_by_recipient(room_jid);
@@ -2063,4 +2085,5 @@ ui_init_module(void)
     ui_handle_room_join_error = _ui_handle_room_join_error;
     ui_swap_wins = _ui_swap_wins;
     ui_update = _ui_update;
+    ui_room_requires_config = _ui_room_requires_config;
 }
diff --git a/src/ui/ui.h b/src/ui/ui.h
index 7787a101..350561e5 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -135,6 +135,7 @@ void (*ui_room_message)(const char * const room_jid, const char * const nick,
     const char * const message);
 void (*ui_room_subject)(const char * const room_jid,
     const char * const subject);
+void (*ui_room_requires_config)(const char * const room_jid);
 void (*ui_room_broadcast)(const char * const room_jid,
     const char * const message);
 void (*ui_room_member_offline)(const char * const room, const char * const nick);
diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c
index 652b12f1..d2f87273 100644
--- a/src/xmpp/presence.c
+++ b/src/xmpp/presence.c
@@ -708,6 +708,11 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
         // handle roster complete
         } else if (!muc_get_roster_received(from_room)) {
             handle_room_roster_complete(from_room);
+
+            // room configuration required
+            if (stanza_muc_requires_config(stanza)) {
+                handle_room_requires_config(from_room);
+            }
         }
 
     // handle presence from room members
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index 72ebb2f6..6d3dcc54 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -650,6 +650,52 @@ stanza_is_muc_presence(xmpp_stanza_t * const stanza)
 }
 
 gboolean
+stanza_muc_requires_config(xmpp_stanza_t * const stanza)
+{
+    // no stanza, or not presence stanza
+    if ((stanza == NULL) || (g_strcmp0(xmpp_stanza_get_name(stanza), STANZA_NAME_PRESENCE) != 0)) {
+        return FALSE;
+    }
+
+    // muc user namespaced x element
+    xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
+    if (x != NULL) {
+
+        // check for item element with owner affiliation
+        xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, "item");
+        if (item == NULL) {
+            return FALSE;
+        }
+        char *affiliation = xmpp_stanza_get_attribute(item, "affiliation");
+        if (g_strcmp0(affiliation, "owner") != 0) {
+            return FALSE;
+        }
+
+        // check for status code 110 and 201
+        gboolean has110 = FALSE;
+        gboolean has201 = FALSE;
+        xmpp_stanza_t *x_children = xmpp_stanza_get_children(x);
+        while (x_children != NULL) {
+            if (g_strcmp0(xmpp_stanza_get_name(x_children), STANZA_NAME_STATUS) == 0) {
+                char *code = xmpp_stanza_get_attribute(x_children, STANZA_ATTR_CODE);
+                if (g_strcmp0(code, "110") == 0) {
+                    has110 = TRUE;
+                }
+                if (g_strcmp0(code, "201") == 0) {
+                    has201 = TRUE;
+                }
+            }
+            x_children = xmpp_stanza_get_next(x_children);
+        }
+
+        if (has110 && has201) {
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+gboolean
 stanza_is_muc_self_presence(xmpp_stanza_t * const stanza,
     const char * const self_jid)
 {
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index 5cdaee03..93b584f5 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -198,6 +198,7 @@ gboolean stanza_is_muc_presence(xmpp_stanza_t * const stanza);
 gboolean stanza_is_muc_self_presence(xmpp_stanza_t * const stanza,
     const char * const self_jid);
 gboolean stanza_is_room_nick_change(xmpp_stanza_t * const stanza);
+gboolean stanza_muc_requires_config(xmpp_stanza_t * const stanza);
 
 char * stanza_get_new_nick(xmpp_stanza_t * const stanza);