コード例 #1
0
ファイル: presence.c プロジェクト: anossov/profanity
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);
    }
}
コード例 #2
0
ファイル: presence.c プロジェクト: dotoole/profanity
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;
}