diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/command/command.c | 8 | ||||
-rw-r--r-- | src/command/commands.c | 10 | ||||
-rw-r--r-- | src/muc.c | 156 | ||||
-rw-r--r-- | src/muc.h | 5 | ||||
-rw-r--r-- | src/server_events.c | 1 | ||||
-rw-r--r-- | src/xmpp/presence.c | 36 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 12 |
7 files changed, 208 insertions, 20 deletions
diff --git a/src/command/command.c b/src/command/command.c index bee26eff..b937aea2 100644 --- a/src/command/command.c +++ b/src/command/command.c @@ -307,12 +307,13 @@ static struct cmd_t command_defs[] = { "/room", cmd_room, parse_args, 1, 1, NULL, - { "/room accept|destroy|config", "Room configuration.", - { "/room accept|destroy|config", - "---------------------------", + { "/room accept|destroy|config|info", "Room configuration.", + { "/room accept|destroy|config|info", + "--------------------------------", "accept - Accept default room configuration.", "destroy - Reject default room configuration.", "config - Edit room configuration.", + "info - Show room details.", NULL } } }, { "/form", @@ -1226,6 +1227,7 @@ cmd_init(void) autocomplete_add(room_ac, "accept"); autocomplete_add(room_ac, "destroy"); autocomplete_add(room_ac, "config"); + autocomplete_add(room_ac, "info"); form_ac = autocomplete_new(); autocomplete_add(form_ac, "submit"); diff --git a/src/command/commands.c b/src/command/commands.c index 045ad00a..1551f58c 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -2083,7 +2083,8 @@ cmd_room(gchar **args, struct cmd_help_t help) if ((g_strcmp0(args[0], "accept") != 0) && (g_strcmp0(args[0], "destroy") != 0) && - (g_strcmp0(args[0], "config") != 0)) { + (g_strcmp0(args[0], "config") != 0) && + (g_strcmp0(args[0], "info") != 0)) { cons_show("Usage: %s", help.usage); return TRUE; } @@ -2097,6 +2098,13 @@ cmd_room(gchar **args, struct cmd_help_t help) ui_index = 0; } + if (g_strcmp0(args[0], "info") == 0) { + char *role = muc_get_role_str(room); + char *affiliation = muc_get_affiliation_str(room); + ui_current_print_line("Affiliation: %s, Role: %s", affiliation, role); + return TRUE; + } + if (g_strcmp0(args[0], "accept") == 0) { gboolean requires_config = muc_requires_config(room); if (!requires_config) { diff --git a/src/muc.c b/src/muc.c index c38064e3..e4df43e4 100644 --- a/src/muc.c +++ b/src/muc.c @@ -43,9 +43,26 @@ #include "tools/autocomplete.h" #include "ui/ui.h" +typedef enum { + MUC_ROLE_NONE, + MUC_ROLE_VISITOR, + MUC_ROLE_PARTICIPANT, + MUC_ROLE_MODERATOR +} muc_role_t; + +typedef enum { + MUC_AFFILIATION_NONE, + MUC_AFFILIATION_OUTCAST, + MUC_AFFILIATION_MEMBER, + MUC_AFFILIATION_ADMIN, + MUC_AFFILIATION_OWNER +} muc_affiliation_t; + typedef struct _muc_room_t { char *room; // e.g. test@conference.server char *nick; // e.g. Some User + muc_role_t role; + muc_affiliation_t affiliation; char *password; char *subject; char *autocomplete_prefix; @@ -64,6 +81,10 @@ Autocomplete invite_ac; static void _free_room(ChatRoom *room); static gint _compare_participants(PContact a, PContact b); +static muc_role_t _role_from_string(const char * const role); +static muc_affiliation_t _affiliation_from_string(const char * const affiliation); +static char* _role_to_string(muc_role_t role); +static char* _affiliation_to_string(muc_affiliation_t affiliation); void muc_init(void) @@ -147,6 +168,8 @@ muc_join_room(const char * const room, const char * const nick, ChatRoom *new_room = malloc(sizeof(ChatRoom)); new_room->room = strdup(room); new_room->nick = strdup(nick); + new_room->role = MUC_ROLE_NONE; + new_room->affiliation = MUC_AFFILIATION_NONE; new_room->autocomplete_prefix = NULL; if (password) { new_room->password = strdup(password); @@ -582,6 +605,46 @@ muc_reset_autocomplete(const char * const room) } } +char * +muc_get_role_str(const char * const room) +{ + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + return _role_to_string(chat_room->role); + } else { + return "none"; + } +} + +void +muc_set_role(const char * const room, const char * const role) +{ + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + chat_room->role = _role_from_string(role); + } +} + +char * +muc_get_affiliation_str(const char * const room) +{ + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + return _affiliation_to_string(chat_room->affiliation); + } else { + return "none"; + } +} + +void +muc_set_affiliation(const char * const room, const char * const affiliation) +{ + ChatRoom *chat_room = g_hash_table_lookup(rooms, room); + if (chat_room) { + chat_room->affiliation = _affiliation_from_string(affiliation); + } +} + static void _free_room(ChatRoom *room) { @@ -621,3 +684,96 @@ gint _compare_participants(PContact a, PContact b) return result; } + +static muc_role_t +_role_from_string(const char * const role) +{ + if (role) { + if (g_strcmp0(role, "visitor") == 0) { + return MUC_ROLE_VISITOR; + } else if (g_strcmp0(role, "participant") == 0) { + return MUC_ROLE_PARTICIPANT; + } else if (g_strcmp0(role, "moderator") == 0) { + return MUC_ROLE_MODERATOR; + } else { + return MUC_ROLE_NONE; + } + } else { + return MUC_ROLE_NONE; + } +} + +static char * +_role_to_string(muc_role_t role) +{ + char *result = NULL; + + switch (role) { + case MUC_ROLE_NONE: + result = "none"; + break; + case MUC_ROLE_VISITOR: + result = "visitor"; + break; + case MUC_ROLE_PARTICIPANT: + result = "participant"; + break; + case MUC_ROLE_MODERATOR: + result = "moderator"; + break; + default: + result = "none"; + break; + } + + return result; +} + +static muc_affiliation_t +_affiliation_from_string(const char * const affiliation) +{ + if (affiliation) { + if (g_strcmp0(affiliation, "outcast") == 0) { + return MUC_AFFILIATION_OUTCAST; + } else if (g_strcmp0(affiliation, "member") == 0) { + return MUC_AFFILIATION_MEMBER; + } else if (g_strcmp0(affiliation, "admin") == 0) { + return MUC_AFFILIATION_ADMIN; + } else if (g_strcmp0(affiliation, "owner") == 0) { + return MUC_AFFILIATION_OWNER; + } else { + return MUC_AFFILIATION_NONE; + } + } else { + return MUC_AFFILIATION_NONE; + } +} + +static char * +_affiliation_to_string(muc_affiliation_t affiliation) +{ + char *result = NULL; + + switch (affiliation) { + case MUC_AFFILIATION_NONE: + result = "none"; + break; + case MUC_AFFILIATION_OUTCAST: + result = "outcast"; + break; + case MUC_AFFILIATION_MEMBER: + result = "member"; + break; + case MUC_AFFILIATION_ADMIN: + result = "admin"; + break; + case MUC_AFFILIATION_OWNER: + result = "owner"; + break; + default: + result = "none"; + break; + } + + return result; +} diff --git a/src/muc.h b/src/muc.h index 722e4a17..debe420e 100644 --- a/src/muc.h +++ b/src/muc.h @@ -93,4 +93,9 @@ void muc_reset_autocomplete(const char * const room); gboolean muc_requires_config(const char * const room); void muc_set_requires_config(const char * const room, gboolean val); +void muc_set_role(const char * const room, const char * const role); +void muc_set_affiliation(const char * const room, const char * const affiliation); +char *muc_get_role_str(const char * const room); +char *muc_get_affiliation_str(const char * const room); + #endif diff --git a/src/server_events.c b/src/server_events.c index f89385c6..f8815870 100644 --- a/src/server_events.c +++ b/src/server_events.c @@ -456,6 +456,7 @@ void handle_room_nick_change(const char * const room, const char * const nick) { + muc_complete_room_nick_change(room, nick); ui_room_nick_change(room, nick); } diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index adbb21fb..f63b3349 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -697,6 +697,7 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE); char *new_nick = stanza_get_new_nick(stanza); + // self unavailable if ((type != NULL) && (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0)) { // leave room if not self nick change @@ -706,18 +707,33 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, handle_leave_room(from_room); } - // handle self nick change - } else if (muc_is_room_pending_nick_change(from_room)) { - muc_complete_room_nick_change(from_room, from_nick); - handle_room_nick_change(from_room, from_nick); + // self online + } else { + + // handle self nick change + if (muc_is_room_pending_nick_change(from_room)) { + handle_room_nick_change(from_room, from_nick); + + // handle roster complete + } else if (!muc_get_roster_received(from_room)) { + handle_room_roster_complete(from_room); - // 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); + } + } - // room configuration required - if (stanza_muc_requires_config(stanza)) { - handle_room_requires_config(from_room); + // set own affiliation and role + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); + if (x) { + xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, STANZA_NAME_ITEM); + if (item) { + char *role = xmpp_stanza_get_attribute(item, "role"); + muc_set_role(from_room, role); + char *affiliation = xmpp_stanza_get_attribute(item, "affiliation"); + muc_set_affiliation(from_room, affiliation); + } } } diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index 2d99c0f0..045fea59 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -822,11 +822,11 @@ stanza_is_muc_self_presence(xmpp_stanza_t * const stanza, // muc user namespaced x element xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); - if (x != NULL) { + if (x) { // check for status child element with 110 code xmpp_stanza_t *x_children = xmpp_stanza_get_children(x); - while (x_children != NULL) { + while (x_children) { 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) { @@ -838,9 +838,9 @@ stanza_is_muc_self_presence(xmpp_stanza_t * const stanza, // check for item child element with jid property xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, STANZA_NAME_ITEM); - if (item != NULL) { + if (item) { char *jid = xmpp_stanza_get_attribute(item, STANZA_ATTR_JID); - if (jid != NULL) { + if (jid) { if (g_str_has_prefix(self_jid, jid)) { return TRUE; } @@ -849,7 +849,7 @@ stanza_is_muc_self_presence(xmpp_stanza_t * const stanza, // check if 'from' attribute identifies this user char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); - if (from != NULL) { + if (from) { Jid *from_jid = jid_create(from); if (muc_room_is_active(from_jid->barejid)) { char *nick = muc_get_room_nick(from_jid->barejid); @@ -861,7 +861,7 @@ stanza_is_muc_self_presence(xmpp_stanza_t * const stanza, // check if a new nickname maps to a pending nick change for this user if (muc_is_room_pending_nick_change(from_jid->barejid)) { char *new_nick = from_jid->resourcepart; - if (new_nick != NULL) { + if (new_nick) { char *nick = muc_get_room_nick(from_jid->barejid); char *old_nick = muc_get_old_nick(from_jid->barejid, new_nick); if (g_strcmp0(old_nick, nick) == 0) { |