diff options
author | James Booth <boothj5@gmail.com> | 2014-10-05 20:52:34 +0100 |
---|---|---|
committer | James Booth <boothj5@gmail.com> | 2014-10-05 20:52:34 +0100 |
commit | d12534c58e5c466d2b9443e196df151205c2b879 (patch) | |
tree | 330aa0b7a7a749552b4a99d11edccc6c3059e9f8 /src/xmpp | |
parent | ac7bc02c63a5aed8decfcbbdc5582e9e5b389030 (diff) | |
download | profani-tty-d12534c58e5c466d2b9443e196df151205c2b879.tar.gz |
Implemented /room kick command
Diffstat (limited to 'src/xmpp')
-rw-r--r-- | src/xmpp/iq.c | 1 | ||||
-rw-r--r-- | src/xmpp/presence.c | 39 | ||||
-rw-r--r-- | src/xmpp/stanza.c | 150 | ||||
-rw-r--r-- | src/xmpp/stanza.h | 9 |
4 files changed, 196 insertions, 3 deletions
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c index 4be3d97f..c24e4ecc 100644 --- a/src/xmpp/iq.c +++ b/src/xmpp/iq.c @@ -960,7 +960,6 @@ _room_kick_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza return 0; } - handle_room_kick(from, nick); free(nick); return 0; diff --git a/src/xmpp/presence.c b/src/xmpp/presence.c index be2d4a01..adc6fc06 100644 --- a/src/xmpp/presence.c +++ b/src/xmpp/presence.c @@ -704,7 +704,30 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, if (new_nick != NULL) { muc_nick_change_start(from_room, new_nick); } else { - handle_leave_room(from_room); + GSList *status_codes = stanza_get_status_codes_by_ns(stanza, STANZA_NS_MUC_USER); + + // room destroyed + if (stanza_room_destroyed(stanza)) { + char *new_jid = stanza_get_muc_destroy_alternative_room(stanza); + char *password = stanza_get_muc_destroy_alternative_password(stanza); + char *reason = stanza_get_muc_destroy_reason(stanza); + handle_room_destroyed(from_room, new_jid, password, reason); + free(password); + free(reason); + + // 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); + handle_room_kicked(from_room, actor, reason); + free(reason); + + // normal exit + } else { + handle_leave_room(from_room); + } + + g_slist_free(status_codes); } // self online @@ -756,7 +779,19 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, free(new_nick); } } else { - handle_room_member_offline(from_room, from_nick, "offline", status_str); + GSList *status_codes = stanza_get_status_codes_by_ns(stanza, STANZA_NS_MUC_USER); + + // 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); + handle_room_occupent_kicked(from_room, from_nick, actor, reason); + free(reason); + + // normal exit + } else { + handle_room_member_offline(from_room, from_nick, "offline", status_str); + } } } else { // send disco info for capabilities, if not cached diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c index eb5f857c..07e96659 100644 --- a/src/xmpp/stanza.c +++ b/src/xmpp/stanza.c @@ -1010,6 +1010,156 @@ stanza_is_muc_self_presence(xmpp_stanza_t * const stanza, return FALSE; } +GSList * +stanza_get_status_codes_by_ns(xmpp_stanza_t * const stanza, char *ns) +{ + GSList *codes = NULL; + xmpp_stanza_t *ns_child = xmpp_stanza_get_child_by_ns(stanza, ns); + if (ns_child) { + xmpp_stanza_t *child = xmpp_stanza_get_children(ns_child); + while (child) { + char *name = xmpp_stanza_get_name(child); + if (g_strcmp0(name, STANZA_NAME_STATUS) == 0) { + char *code = xmpp_stanza_get_attribute(child, STANZA_ATTR_CODE); + if (code) { + codes = g_slist_append(codes, code); + } + } + child = xmpp_stanza_get_next(child); + } + } + return codes; +} + +gboolean +stanza_room_destroyed(xmpp_stanza_t *stanza) +{ + char *stanza_name = xmpp_stanza_get_name(stanza); + if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) { + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); + if (x) { + xmpp_stanza_t *destroy = xmpp_stanza_get_child_by_name(x, STANZA_NAME_DESTROY); + if (destroy) { + return TRUE; + } + } + } + + return FALSE; +} + +char * +stanza_get_muc_destroy_alternative_room(xmpp_stanza_t *stanza) +{ + char *stanza_name = xmpp_stanza_get_name(stanza); + if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) { + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); + if (x) { + xmpp_stanza_t *destroy = xmpp_stanza_get_child_by_name(x, STANZA_NAME_DESTROY); + if (destroy) { + char *jid = xmpp_stanza_get_attribute(destroy, STANZA_ATTR_JID); + if (jid) { + return jid; + } + } + } + } + + return NULL; +} + +char * +stanza_get_muc_destroy_alternative_password(xmpp_stanza_t *stanza) +{ + char *stanza_name = xmpp_stanza_get_name(stanza); + if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) { + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); + if (x) { + xmpp_stanza_t *destroy = xmpp_stanza_get_child_by_name(x, STANZA_NAME_DESTROY); + if (destroy) { + xmpp_stanza_t *password_st = xmpp_stanza_get_child_by_name(destroy, STANZA_NAME_PASSWORD); + if (password_st) { + char *password = xmpp_stanza_get_text(password_st); + if (password) { + return password; + } + } + } + } + } + return NULL; +} + +char * +stanza_get_muc_destroy_reason(xmpp_stanza_t *stanza) +{ + char *stanza_name = xmpp_stanza_get_name(stanza); + if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) { + xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER); + if (x) { + xmpp_stanza_t *destroy = xmpp_stanza_get_child_by_name(x, STANZA_NAME_DESTROY); + if (destroy) { + xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_name(destroy, STANZA_NAME_REASON); + if (reason_st) { + char *reason = xmpp_stanza_get_text(reason_st); + if (reason) { + return reason; + } + } + } + } + } + return NULL; +} + +char * +stanza_get_kick_actor(xmpp_stanza_t *stanza) +{ + char *stanza_name = xmpp_stanza_get_name(stanza); + if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) { + 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) { + xmpp_stanza_t *actor = xmpp_stanza_get_child_by_name(item, STANZA_NAME_ACTOR); + if (actor) { + char *nick = xmpp_stanza_get_attribute(actor, STANZA_ATTR_NICK); + if (nick) { + return nick; + } + char *jid = xmpp_stanza_get_attribute(actor, STANZA_ATTR_JID); + if (jid) { + return jid; + } + } + } + } + } + return NULL; +} + +char * +stanza_get_kick_reason(xmpp_stanza_t *stanza) +{ + char *stanza_name = xmpp_stanza_get_name(stanza); + if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) { + 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) { + xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_name(item, STANZA_NAME_REASON); + if (reason_st) { + char *reason = xmpp_stanza_get_text(reason_st); + if (reason) { + return reason; + } + } + } + } + } + return NULL; +} + gboolean stanza_is_room_nick_change(xmpp_stanza_t * const stanza) { diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h index fefa47b6..ae673848 100644 --- a/src/xmpp/stanza.h +++ b/src/xmpp/stanza.h @@ -76,6 +76,7 @@ #define STANZA_NAME_CONFERENCE "conference" #define STANZA_NAME_VALUE "value" #define STANZA_NAME_DESTROY "destroy" +#define STANZA_NAME_ACTOR "actor" // error conditions #define STANZA_NAME_BAD_REQUEST "bad-request" @@ -248,4 +249,12 @@ xmpp_stanza_t * stanza_create_roster_remove_set(xmpp_ctx_t *ctx, char * stanza_get_error_message(xmpp_stanza_t * const stanza); +GSList* stanza_get_status_codes_by_ns(xmpp_stanza_t * const stanza, char *ns); +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); + #endif |