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); }
/* * 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; }
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); }
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); }
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); }
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); }
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(); }
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(); }
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(); }
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; }
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; }