static void _muc_user_handler(xmpp_stanza_t *const stanza) { inp_nonblocking(TRUE); const char *type = xmpp_stanza_get_type(stanza); // handler still fires if error if (g_strcmp0(type, STANZA_TYPE_ERROR) == 0) { return; } const char *from = xmpp_stanza_get_from(stanza); if (!from) { log_warning("MUC User stanza received with no from attribute"); return; } Jid *from_jid = jid_create(from); if (from_jid == NULL || from_jid->resourcepart == NULL) { log_warning("MUC User stanza received with invalid from attribute: %s", from); jid_destroy(from_jid); return; } jid_destroy(from_jid); if (stanza_is_muc_self_presence(stanza, connection_get_fulljid())) { _muc_user_self_handler(stanza); } else { _muc_user_occupant_handler(stanza); } }
static int _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza, void * const userdata) { // handler still fires if error if (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_ERROR) == 0) { return 1; } char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM); Jid *from_jid = jid_create(from); if (from_jid == NULL || from_jid->resourcepart == NULL) { return 1; } char *from_room = from_jid->barejid; char *from_nick = from_jid->resourcepart; // handle self presence if (stanza_is_muc_self_presence(stanza, jabber_get_fulljid())) { char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE); char *new_nick = stanza_get_new_nick(stanza); if ((type != NULL) && (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0)) { // leave room if not self nick change if (new_nick != NULL) { muc_set_room_pending_nick_change(from_room, new_nick); } else { 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); // 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 } else { char *type = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_TYPE); char *status_str; log_debug("Room presence received from %s", from_jid->fulljid); status_str = stanza_get_status(stanza, NULL); if ((type != NULL) && (strcmp(type, STANZA_TYPE_UNAVAILABLE) == 0)) { // handle nickname change if (stanza_is_room_nick_change(stanza)) { char *new_nick = stanza_get_new_nick(stanza); if (new_nick != NULL) { muc_set_roster_pending_nick_change(from_room, new_nick, from_nick); free(new_nick); } } else { handle_room_member_offline(from_room, from_nick, "offline", status_str); } } else { // send disco info for capabilities, if not cached if (stanza_contains_caps(stanza)) { log_info("Presence contains capabilities."); _handle_caps(stanza); } char *show_str = stanza_get_show(stanza, "online"); if (!muc_get_roster_received(from_room)) { muc_add_to_roster(from_room, from_nick, show_str, status_str); } else { char *old_nick = muc_complete_roster_nick_change(from_room, from_nick); if (old_nick != NULL) { muc_add_to_roster(from_room, from_nick, show_str, status_str); handle_room_member_nick_change(from_room, old_nick, from_nick); free(old_nick); } else { if (!muc_nick_in_roster(from_room, from_nick)) { handle_room_member_online(from_room, from_nick, show_str, status_str); } else { handle_room_member_presence(from_room, from_nick, show_str, status_str); } } } free(show_str); } free(status_str); } jid_destroy(from_jid); return 1; }