about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2014-10-06 22:59:25 +0100
committerJames Booth <boothj5@gmail.com>2014-10-06 22:59:25 +0100
commit78a1556f1205d0d2ad2f9a5e7a29c4515defa128 (patch)
tree8105789e3ec5b6b55b49ea7ec5002f39818a4c70 /src
parent965f048b18f7f7456bcb59dca841784aad3bfa11 (diff)
downloadprofani-tty-78a1556f1205d0d2ad2f9a5e7a29c4515defa128.tar.gz
Added jid autocomplete for affiliation commands
Diffstat (limited to 'src')
-rw-r--r--src/command/command.c21
-rw-r--r--src/muc.c55
-rw-r--r--src/muc.h4
-rw-r--r--src/server_events.c15
-rw-r--r--src/server_events.h3
-rw-r--r--src/ui/core.c52
-rw-r--r--src/ui/ui.h3
-rw-r--r--src/xmpp/presence.c22
-rw-r--r--src/xmpp/stanza.c4
-rw-r--r--src/xmpp/stanza.h4
10 files changed, 171 insertions, 12 deletions
diff --git a/src/command/command.c b/src/command/command.c
index daa86d76..9c4fd746 100644
--- a/src/command/command.c
+++ b/src/command/command.c
@@ -1423,6 +1423,7 @@ cmd_reset_autocomplete()
     if (ui_current_win_type() == WIN_MUC) {
         char *recipient = ui_current_recipient();
         muc_autocomplete_reset(recipient);
+        muc_jid_autocomplete_reset(recipient);
     }
 
     autocomplete_reset(who_room_ac);
@@ -2281,14 +2282,13 @@ _room_autocomplete(char *input, int *size)
 
     char *recipient = ui_current_recipient();
     Autocomplete nick_ac = muc_roster_ac(recipient);
+    Autocomplete jid_ac = muc_roster_jid_ac(recipient);
 
     input[*size] = '\0';
     gchar **args = parse_args(input, 4, 4, &parse_result);
 
-    if ((strncmp(input, "/room", 5) == 0) && (parse_result == TRUE)) {
-        GString *beginning = g_string_new("/room ");
-        g_string_append(beginning, args[0]);
-        g_string_append(beginning, " ");
+    if ((strncmp(input, "/room role", 10) == 0) && (parse_result == TRUE)) {
+        GString *beginning = g_string_new("/room role ");
         g_string_append(beginning, args[1]);
         g_string_append(beginning, " ");
         g_string_append(beginning, args[2]);
@@ -2300,6 +2300,19 @@ _room_autocomplete(char *input, int *size)
         }
     }
 
+    if ((strncmp(input, "/room affiliation", 17) == 0) && (parse_result == TRUE)) {
+        GString *beginning = g_string_new("/room affiliation ");
+        g_string_append(beginning, args[1]);
+        g_string_append(beginning, " ");
+        g_string_append(beginning, args[2]);
+
+        result = autocomplete_param_with_ac(input, size, beginning->str, jid_ac, TRUE);
+        g_string_free(beginning, TRUE);
+        if (result != NULL) {
+            return result;
+        }
+    }
+
     result = autocomplete_param_with_ac(input, size, "/room role set", room_role_ac, TRUE);
     if (result != NULL) {
         return result;
diff --git a/src/muc.c b/src/muc.c
index aa8148b1..2ee59ae5 100644
--- a/src/muc.c
+++ b/src/muc.c
@@ -58,6 +58,7 @@ typedef struct _muc_room_t {
     gboolean pending_nick_change;
     GHashTable *roster;
     Autocomplete nick_ac;
+    Autocomplete jid_ac;
     GHashTable *nick_changes;
     gboolean roster_received;
 } ChatRoom;
@@ -170,6 +171,7 @@ muc_join(const char * const room, const char * const nick,
     new_room->pending_config = FALSE;
     new_room->roster = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)_occupant_free);
     new_room->nick_ac = autocomplete_new();
+    new_room->jid_ac = autocomplete_new();
     new_room->nick_changes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
     new_room->roster_received = FALSE;
     new_room->pending_nick_change = FALSE;
@@ -410,6 +412,14 @@ muc_roster_add(const char * const room, const char * const nick, const char * co
         muc_affiliation_t affiliation_t = _affiliation_from_string(affiliation);
         Occupant *occupant = _muc_occupant_new(nick, jid, role_t, affiliation_t, presence, status);
         g_hash_table_replace(chat_room->roster, strdup(nick), occupant);
+
+        if (jid) {
+            Jid *jidp = jid_create(jid);
+            if (jidp->barejid) {
+                autocomplete_add(chat_room->jid_ac, jidp->barejid);
+            }
+            jid_destroy(jidp);
+        }
     }
 
     return updated;
@@ -479,6 +489,17 @@ muc_roster_ac(const char * const room)
     }
 }
 
+Autocomplete
+muc_roster_jid_ac(const char * const room)
+{
+    ChatRoom *chat_room = g_hash_table_lookup(rooms, room);
+    if (chat_room) {
+        return chat_room->jid_ac;
+    } else {
+        return NULL;
+    }
+}
+
 /*
  * Set to TRUE when the rooms roster has been fully received
  */
@@ -646,6 +667,39 @@ muc_autocomplete(char *input, int *size)
 }
 
 void
+muc_jid_autocomplete_reset(const char * const room)
+{
+    ChatRoom *chat_room = g_hash_table_lookup(rooms, room);
+    if (chat_room) {
+        if (chat_room->jid_ac) {
+            autocomplete_reset(chat_room->jid_ac);
+        }
+    }
+}
+
+void
+muc_jid_autocomplete_add_all(const char * const room, GSList *jids)
+{
+    ChatRoom *chat_room = g_hash_table_lookup(rooms, room);
+    if (chat_room) {
+        if (chat_room->jid_ac) {
+            GSList *curr_jid = jids;
+            while (curr_jid) {
+                char *jid = curr_jid->data;
+                Jid *jidp = jid_create(jid);
+                if (jidp) {
+                    if (jidp->barejid) {
+                        autocomplete_add(chat_room->jid_ac, jidp->barejid);
+                    }
+                }
+                jid_destroy(jidp);
+                curr_jid = g_slist_next(curr_jid);
+            }
+        }
+    }
+}
+
+void
 muc_autocomplete_reset(const char * const room)
 {
     ChatRoom *chat_room = g_hash_table_lookup(rooms, room);
@@ -714,6 +768,7 @@ _free_room(ChatRoom *room)
             g_hash_table_destroy(room->roster);
         }
         autocomplete_free(room->nick_ac);
+        autocomplete_free(room->jid_ac);
         if (room->nick_changes) {
             g_hash_table_destroy(room->nick_changes);
         }
diff --git a/src/muc.h b/src/muc.h
index 597a462e..96e8c1d0 100644
--- a/src/muc.h
+++ b/src/muc.h
@@ -93,6 +93,10 @@ void muc_roster_remove(const char * const room, const char * const nick);
 void muc_roster_set_complete(const char * const room);
 GList * muc_roster(const char * const room);
 Autocomplete muc_roster_ac(const char * const room);
+Autocomplete muc_roster_jid_ac(const char * const room);
+void muc_jid_autocomplete_reset(const char * const room);
+void muc_jid_autocomplete_add_all(const char * const room, GSList *jids);
+
 Occupant* muc_roster_item(const char * const room, const char * const nick);
 
 gboolean muc_occupant_available(Occupant *occupant);
diff --git a/src/server_events.c b/src/server_events.c
index 3c2620b1..cadb4d96 100644
--- a/src/server_events.c
+++ b/src/server_events.c
@@ -193,6 +193,7 @@ handle_room_affiliation_list_result_error(const char * const room, const char *
 void
 handle_room_affiliation_list(const char * const room, const char * const affiliation, GSList *jids)
 {
+    muc_jid_autocomplete_add_all(room, jids);
     ui_handle_room_affiliation_list(room, affiliation, jids);
 }
 
@@ -558,6 +559,13 @@ handle_room_kicked(const char * const room, const char * const actor, const char
 }
 
 void
+handle_room_banned(const char * const room, const char * const actor, const char * const reason)
+{
+    muc_leave(room);
+    ui_room_banned(room, actor, reason);
+}
+
+void
 handle_room_configure(const char * const room, DataForm *form)
 {
     ui_handle_room_configuration(room, form);
@@ -664,6 +672,13 @@ handle_room_occupent_kicked(const char * const room, const char * const nick, co
     ui_room_member_kicked(room, nick, actor, reason);
 }
 
+void
+handle_room_occupent_banned(const char * const room, const char * const nick, const char * const actor,
+    const char * const reason)
+{
+    muc_roster_remove(room, nick);
+    ui_room_member_banned(room, nick, actor, reason);
+}
 
 void
 handle_room_member_nick_change(const char * const room,
diff --git a/src/server_events.h b/src/server_events.h
index 56b01965..70c6b6bf 100644
--- a/src/server_events.h
+++ b/src/server_events.h
@@ -100,6 +100,9 @@ void handle_room_destroyed(const char * const room, const char * const new_jid,
 void handle_room_kicked(const char * const room, const char * const actor, const char * const reason);
 void handle_room_occupent_kicked(const char * const room, const char * const nick, const char * const actor,
     const char * const reason);
+void handle_room_banned(const char * const room, const char * const actor, const char * const reason);
+void handle_room_occupent_banned(const char * const room, const char * const nick, const char * const actor,
+    const char * const reason);
 void handle_group_add(const char * const contact,
     const char * const group);
 void handle_group_remove(const char * const contact,
diff --git a/src/ui/core.c b/src/ui/core.c
index 5269e96b..cab56169 100644
--- a/src/ui/core.c
+++ b/src/ui/core.c
@@ -1517,6 +1517,29 @@ _ui_room_member_kicked(const char * const room, const char * const nick, const c
     }
 }
 
+static void
+_ui_room_member_banned(const char * const room, const char * const nick, const char * const actor,
+    const char * const reason)
+{
+    ProfWin *window = wins_get_by_recipient(room);
+    if (window == NULL) {
+        log_error("Received ban for room participant %s, but no window open for %s.", nick, room);
+    } else {
+        GString *message = g_string_new(nick);
+        g_string_append(message, " has been banned from the room");
+        if (actor) {
+            g_string_append(message, " by ");
+            g_string_append(message, actor);
+        }
+        if (reason) {
+            g_string_append(message, ", reason: ");
+            g_string_append(message, reason);
+        }
+
+        win_save_vprint(window, '!', NULL, 0, COLOUR_OFFLINE, "", "<- %s", message->str);
+        g_string_free(message, TRUE);
+    }
+}
 
 static void
 _ui_room_member_online(const char * const room, const char * const nick,
@@ -1794,6 +1817,33 @@ _ui_room_kicked(const char * const room, const char * const actor, const char *
 }
 
 static void
+_ui_room_banned(const char * const room, const char * const actor, const char * const reason)
+{
+    ProfWin *window = wins_get_by_recipient(room);
+    if (window == NULL) {
+        log_error("Received ban, but no window open for %s.", room);
+    } else {
+        int num = wins_get_num(window);
+        ui_close_win(num);
+
+        GString *message = g_string_new("Banned from ");
+        g_string_append(message, room);
+        if (actor) {
+            g_string_append(message, " by ");
+            g_string_append(message, actor);
+        }
+        if (reason) {
+            g_string_append(message, ", reason: ");
+            g_string_append(message, reason);
+        }
+
+        ProfWin *console = wins_get_console();
+        win_save_vprint(console, '!', NULL, 0, COLOUR_TYPING, "", "<- %s", message->str);
+        g_string_free(message, TRUE);
+    }
+}
+
+static void
 _ui_room_subject(const char * const room, const char * const nick, const char * const subject)
 {
     ProfWin *window = wins_get_by_recipient(room);
@@ -2925,8 +2975,10 @@ ui_init_module(void)
     ui_handle_room_kick_error = _ui_handle_room_kick_error;
     ui_room_destroyed = _ui_room_destroyed;
     ui_room_kicked = _ui_room_kicked;
+    ui_room_banned = _ui_room_banned;
     ui_leave_room = _ui_leave_room;
     ui_room_member_kicked = _ui_room_member_kicked;
+    ui_room_member_banned = _ui_room_member_banned;
     ui_handle_room_role_set_error = _ui_handle_room_role_set_error;
     ui_handle_room_role_set = _ui_handle_room_role_set;
     ui_handle_room_role_list_error = _ui_handle_room_role_list_error;
diff --git a/src/ui/ui.h b/src/ui/ui.h
index f987bdbb..b7bd7fbd 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -146,6 +146,9 @@ void (*ui_room_destroyed)(const char * const room, const char * const reason, co
 void (*ui_room_kicked)(const char * const room, const char * const actor, const char * const reason);
 void (*ui_room_member_kicked)(const char * const room, const char * const nick, const char * const actor,
     const char * const reason);
+void (*ui_room_banned)(const char * const room, const char * const actor, const char * const reason);
+void (*ui_room_member_banned)(const char * const room, const char * const nick, const char * const actor,
+    const char * const reason);
 void (*ui_leave_room)(const char * const room);
 void (*ui_room_broadcast)(const char * const room_jid,
     const char * const message);
diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c
index adc6fc06..00506175 100644
--- a/src/xmpp/presence.c
+++ b/src/xmpp/presence.c
@@ -717,11 +717,18 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
 
                 // kicked from room
                 } else if (g_slist_find_custom(status_codes, "307", (GCompareFunc)g_strcmp0) != NULL) {
-                    char *actor = stanza_get_kick_actor(stanza);
-                    char *reason = stanza_get_kick_reason(stanza);
+                    char *actor = stanza_get_kickban_actor(stanza);
+                    char *reason = stanza_get_kickban_reason(stanza);
                     handle_room_kicked(from_room, actor, reason);
                     free(reason);
 
+                // banned from room
+                } else if (g_slist_find_custom(status_codes, "301", (GCompareFunc)g_strcmp0) != NULL) {
+                    char *actor = stanza_get_kickban_actor(stanza);
+                    char *reason = stanza_get_kickban_reason(stanza);
+                    handle_room_banned(from_room, actor, reason);
+                    free(reason);
+
                 // normal exit
                 } else {
                     handle_leave_room(from_room);
@@ -783,11 +790,18 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
 
                 // kicked from room
                 if (g_slist_find_custom(status_codes, "307", (GCompareFunc)g_strcmp0) != NULL) {
-                    char *actor = stanza_get_kick_actor(stanza);
-                    char *reason = stanza_get_kick_reason(stanza);
+                    char *actor = stanza_get_kickban_actor(stanza);
+                    char *reason = stanza_get_kickban_reason(stanza);
                     handle_room_occupent_kicked(from_room, from_nick, actor, reason);
                     free(reason);
 
+                // banned from room
+                } else if (g_slist_find_custom(status_codes, "301", (GCompareFunc)g_strcmp0) != NULL) {
+                    char *actor = stanza_get_kickban_actor(stanza);
+                    char *reason = stanza_get_kickban_reason(stanza);
+                    handle_room_occupent_banned(from_room, from_nick, actor, reason);
+                    free(reason);
+
                 // normal exit
                 } else {
                     handle_room_member_offline(from_room, from_nick, "offline", status_str);
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index 03b81bf3..58194124 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -1181,7 +1181,7 @@ stanza_get_muc_destroy_reason(xmpp_stanza_t *stanza)
 }
 
 char *
-stanza_get_kick_actor(xmpp_stanza_t *stanza)
+stanza_get_kickban_actor(xmpp_stanza_t *stanza)
 {
     char *stanza_name = xmpp_stanza_get_name(stanza);
     if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) {
@@ -1207,7 +1207,7 @@ stanza_get_kick_actor(xmpp_stanza_t *stanza)
 }
 
 char *
-stanza_get_kick_reason(xmpp_stanza_t *stanza)
+stanza_get_kickban_reason(xmpp_stanza_t *stanza)
 {
     char *stanza_name = xmpp_stanza_get_name(stanza);
     if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) {
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index 56aea01b..cbb6d23f 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -258,7 +258,7 @@ gboolean stanza_room_destroyed(xmpp_stanza_t *stanza);
 char* stanza_get_muc_destroy_alternative_room(xmpp_stanza_t *stanza);
 char* stanza_get_muc_destroy_alternative_password(xmpp_stanza_t *stanza);
 char* stanza_get_muc_destroy_reason(xmpp_stanza_t *stanza);
-char* stanza_get_kick_actor(xmpp_stanza_t *stanza);
-char* stanza_get_kick_reason(xmpp_stanza_t *stanza);
+char* stanza_get_kickban_actor(xmpp_stanza_t *stanza);
+char* stanza_get_kickban_reason(xmpp_stanza_t *stanza);
 
 #endif