Example #1
0
struct resource *
fdstream_resource (const char * path, int fd, const char * content_type)
{
	struct fdstream * st;

	if ((st = calloc (1, sizeof(*st))) == NULL)
		return NULL;

	st->path = x_strdup (path);
	if (st->path == NULL) {
		free (st);
		return NULL;
	}

	st->content_type = x_strdup (content_type);
	if (st->content_type == NULL) {
		free (st);
		free ((char *)st->path);
		return NULL;
	}

	st->stream = stream_open (fd);
	if (st->stream == NULL) {
		free (st);
		free ((char *)st->path);
		free ((char *)st->content_type);
		return NULL;
	}

	return resource_new (fdstream_check, fdstream_head, fdstream_body, fdstream_delete, st);
}
Example #2
0
/*
 * Add a new chat room member to the room's roster
 */
gboolean
muc_add_to_roster(const char * const room, const char * const nick,
    const char * const show, const char * const status,
    const char * const caps_str)
{
    ChatRoom *chat_room = g_hash_table_lookup(rooms, room);
    gboolean updated = FALSE;

    if (chat_room != NULL) {
        PContact old = g_hash_table_lookup(chat_room->roster, nick);

        if (old == NULL) {
            updated = TRUE;
            autocomplete_add(chat_room->nick_ac, nick);
        } else if ((g_strcmp0(p_contact_presence(old), show) != 0) ||
                    (g_strcmp0(p_contact_status(old), status) != 0)) {
            updated = TRUE;
        }
        PContact contact = p_contact_new(nick, NULL, NULL, NULL, NULL, FALSE);
        resource_presence_t resource_presence = resource_presence_from_string(show);
        Resource *resource = resource_new(nick, resource_presence, status, 0, caps_str);
        p_contact_set_presence(contact, resource);
        g_hash_table_replace(chat_room->roster, strdup(nick), contact);
    }

    return updated;
}
Example #3
0
void contact_presence_xa_when_same_prioroty(void **state)
{
    PContact contact = p_contact_new("*****@*****.**", "bob", NULL, "both",
        "is offline", FALSE);

    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    const char *presence = p_contact_presence(contact);

    assert_string_equal("xa", presence);

    p_contact_free(contact);
}
Example #4
0
void contact_available_when_highest_priority_chat(void **state)
{
    PContact contact = p_contact_new("*****@*****.**", "bob", NULL, NULL,
        "is offline", FALSE);

    Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10);
    Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 20);
    Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10);
    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10);
    p_contact_set_presence(contact, resource_online);
    p_contact_set_presence(contact, resource_chat);
    p_contact_set_presence(contact, resource_away);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    gboolean result = p_contact_is_available(contact);

    assert_true(result);

    p_contact_free(contact);
}
Example #5
0
void contact_presence_uses_highest_priority(void **state)
{
    PContact contact = p_contact_new("*****@*****.**", "bob", NULL, "both",
        "is offline", FALSE);

    Resource *resource10 = resource_new("resource10", RESOURCE_ONLINE, NULL, 10);
    Resource *resource20 = resource_new("resource20", RESOURCE_CHAT, NULL, 20);
    Resource *resource30 = resource_new("resource30", RESOURCE_AWAY, NULL, 30);
    Resource *resource1 = resource_new("resource1", RESOURCE_XA, NULL, 1);
    Resource *resource2 = resource_new("resource2", RESOURCE_DND, NULL, 2);
    p_contact_set_presence(contact, resource10);
    p_contact_set_presence(contact, resource20);
    p_contact_set_presence(contact, resource30);
    p_contact_set_presence(contact, resource1);
    p_contact_set_presence(contact, resource2);

    const char *presence = p_contact_presence(contact);

    assert_string_equal("away", presence);

    p_contact_free(contact);
}
Example #6
0
void contact_presence_chat_when_same_prioroty(void **state)
{
    PContact contact = p_contact_new("*****@*****.**", "bob", NULL, "both",
        "is offline", FALSE);

    Resource *resource_online = resource_new("resource_online", RESOURCE_ONLINE, NULL, 10, NULL);
    Resource *resource_chat = resource_new("resource_chat", RESOURCE_CHAT, NULL, 10, NULL);
    Resource *resource_away = resource_new("resource_away", RESOURCE_AWAY, NULL, 10, NULL);
    Resource *resource_xa = resource_new("resource_xa", RESOURCE_XA, NULL, 10, NULL);
    Resource *resource_dnd = resource_new("resource_dnd", RESOURCE_DND, NULL, 10, NULL);
    p_contact_set_presence(contact, resource_online);
    p_contact_set_presence(contact, resource_chat);
    p_contact_set_presence(contact, resource_away);
    p_contact_set_presence(contact, resource_xa);
    p_contact_set_presence(contact, resource_dnd);

    const char *presence = p_contact_presence(contact);

    assert_string_equal("chat", presence);

    p_contact_free(contact);
}
Example #7
0
void console_shows_dnd_presence_when_set_all(void **state)
{
    prefs_set_string(PREF_STATUSES_CONSOLE, "all");
    roster_init();
    char *barejid = "test1@server";
    roster_add(barejid, "bob", NULL, "both", FALSE);
    Resource *resource = resource_new("resource", RESOURCE_ONLINE, NULL, 10);

    expect_memory(ui_contact_online, barejid, barejid, sizeof(barejid));
    expect_memory(ui_contact_online, resource, resource, sizeof(resource));
    expect_value(ui_contact_online, last_activity, NULL);

    sv_ev_contact_online(barejid, resource, NULL, NULL);

    roster_clear();
}
Example #8
0
void handle_offline_removes_chat_session(void **state)
{
    chat_sessions_init();
    char *barejid = "*****@*****.**";
    char *resource = "home";
    roster_init();
    roster_add(barejid, "bob", NULL, "both", FALSE);
    Resource *resourcep = resource_new(resource, RESOURCE_ONLINE, NULL, 10);
    roster_update_presence(barejid, resourcep, NULL);
    chat_session_recipient_active(barejid, resource, FALSE);
    sv_ev_contact_offline(barejid, resource, NULL);
    ChatSession *session = chat_session_get(barejid);

    assert_null(session);

    roster_clear();
    chat_sessions_clear();
}
Example #9
0
void handle_offline_removes_chat_session(void **state)
{
    plugins_init();
    roster_create();
    chat_sessions_init();
    char *barejid = "*****@*****.**";
    char *resource = "home";
    roster_add(barejid, "bob", NULL, "both", FALSE);
    Resource *resourcep = resource_new(resource, RESOURCE_ONLINE, NULL, 10);
    roster_update_presence(barejid, resourcep, NULL);
    chat_session_recipient_active(barejid, resource, FALSE);
    ProfConsoleWin *console = malloc(sizeof(ProfConsoleWin));
    will_return(win_create_console, &console->window);
    wins_init();
    sv_ev_contact_offline(barejid, resource, NULL);
    ChatSession *session = chat_session_get(barejid);

    assert_null(session);

    roster_destroy();
    chat_sessions_clear();
    plugins_shutdown();
}
Example #10
0
static int
_available_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;
    }

    // handler still fires if other types
    if ((g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_UNAVAILABLE) == 0) ||
            (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_SUBSCRIBE) == 0) ||
            (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_SUBSCRIBED) == 0) ||
            (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_UNSUBSCRIBED) == 0)) {
        return 1;
    }

    // handler still fires for muc presence
    if (stanza_is_muc_presence(stanza)) {
        return 1;
    }

    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    if (from) {
        log_info("Available presence handler fired for: %s", from);
    } else {
        log_info("Available presence handler fired");
    }

    // exit when no from attribute
    if (!from) {
        log_warning("No from attribute found.");
        return 1;
    }

    // own jid is invalid
    const char *my_jid_str = xmpp_conn_get_jid(conn);
    Jid *my_jid = jid_create(my_jid_str);
    if (!my_jid) {
        if (my_jid_str) {
            log_error("Could not parse account JID: %s", my_jid_str);
        } else {
            log_error("Could not parse account JID: NULL");
        }
        return 1;
    }

    // contact jid invalud
    Jid *from_jid = jid_create(from);
    if (!from_jid) {
        log_warning("Could not parse contact JID: %s", from);
        jid_destroy(my_jid);
        return 1;
    }

    // presence properties
    char *show_str = stanza_get_show(stanza, "online");
    char *status_str = stanza_get_status(stanza, NULL);

    // presence last activity
    int idle_seconds = stanza_get_idle_time(stanza);
    GDateTime *last_activity = NULL;
    if (idle_seconds > 0) {
        GDateTime *now = g_date_time_new_now_local();
        last_activity = g_date_time_add_seconds(now, 0 - idle_seconds);
        g_date_time_unref(now);
    }

    // priority
    int priority = 0;
    xmpp_stanza_t *priority_stanza = xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PRIORITY);
    if (priority_stanza != NULL) {
        char *priority_str = xmpp_stanza_get_text(priority_stanza);
        if (priority_str != NULL) {
            priority = atoi(priority_str);
        }
        free(priority_str);
    }

    // send disco info for capabilities, if not cached
    if ((g_strcmp0(my_jid->fulljid, from_jid->fulljid) != 0) && (stanza_contains_caps(stanza))) {
        log_info("Presence contains capabilities.");
        _handle_caps(stanza);
    }

    // create Resource
    Resource *resource = NULL;
    resource_presence_t presence = resource_presence_from_string(show_str);
    if (from_jid->resourcepart == NULL) { // hack for servers that do not send full jid
        resource = resource_new("__prof_default", presence, status_str, priority);
    } else {
        resource = resource_new(from_jid->resourcepart, presence, status_str, priority);
    }
    free(status_str);
    free(show_str);

    // check for self presence
    if (g_strcmp0(my_jid->barejid, from_jid->barejid) == 0) {
        connection_add_available_resource(resource);

    // contact presence
    } else {
        handle_contact_online(from_jid->barejid, resource, last_activity);
    }

    if (last_activity != NULL) {
        g_date_time_unref(last_activity);
    }

    jid_destroy(my_jid);
    jid_destroy(from_jid);

    return 1;
}
Example #11
0
static int
_available_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;
    }

    // handler still fires if other types
    if ((g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_UNAVAILABLE) == 0) ||
            (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_SUBSCRIBE) == 0) ||
            (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_SUBSCRIBED) == 0) ||
            (g_strcmp0(xmpp_stanza_get_type(stanza), STANZA_TYPE_UNSUBSCRIBED) == 0)) {
        return 1;
    }

    // handler still fires for muc presence
    if (stanza_is_muc_presence(stanza)) {
        return 1;
    }

    const char *jid = xmpp_conn_get_jid(conn);
    char *from = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_FROM);
    log_debug("Available presence handler fired for %s", from);

    Jid *my_jid = jid_create(jid);
    Jid *from_jid = jid_create(from);
    if (my_jid == NULL || from_jid == NULL) {
        jid_destroy(my_jid);
        jid_destroy(from_jid);
        return 1;
    }

    char *show_str = stanza_get_show(stanza, "online");
    char *status_str = stanza_get_status(stanza, NULL);
    int idle_seconds = stanza_get_idle_time(stanza);
    GDateTime *last_activity = NULL;

    char *caps_key = NULL;
    if (stanza_contains_caps(stanza)) {
        caps_key = _get_caps_key(stanza);
    }

    if (idle_seconds > 0) {
        GDateTime *now = g_date_time_new_now_local();
        last_activity = g_date_time_add_seconds(now, 0 - idle_seconds);
        g_date_time_unref(now);
    }

    // get priority
    int priority = 0;
    xmpp_stanza_t *priority_stanza =
        xmpp_stanza_get_child_by_name(stanza, STANZA_NAME_PRIORITY);

    if (priority_stanza != NULL) {
        char *priority_str = xmpp_stanza_get_text(priority_stanza);
        if (priority_str != NULL) {
            priority = atoi(priority_str);
        }
        free(priority_str);
    }

    resource_presence_t presence = resource_presence_from_string(show_str);
    Resource *resource = NULL;

    // hack for servers that do not send fulljid with initial presence
    if (from_jid->resourcepart == NULL) {
        resource = resource_new("__prof_default", presence,
            status_str, priority, caps_key);
    } else {
        resource = resource_new(from_jid->resourcepart, presence,
            status_str, priority, caps_key);
    }

    // self presence
    if (strcmp(my_jid->barejid, from_jid->barejid) == 0) {
        connection_add_available_resource(resource);

    // contact presence
    } else {
        handle_contact_online(from_jid->barejid, resource,
            last_activity);
    }

    free(caps_key);
    free(status_str);
    free(show_str);
    jid_destroy(my_jid);
    jid_destroy(from_jid);

    if (last_activity != NULL) {
        g_date_time_unref(last_activity);
    }

    return 1;
}