/* * 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; }
/* * Add a new chat room member to the room's roster */ gboolean muc_roster_add(const char * const room, const char * const nick, const char * const jid, const char * const role, const char * const affiliation, const char * const show, const char * const status) { ChatRoom *chat_room = g_hash_table_lookup(rooms, room); gboolean updated = FALSE; resource_presence_t new_presence = resource_presence_from_string(show); if (chat_room) { Occupant *old = g_hash_table_lookup(chat_room->roster, nick); if (!old) { updated = TRUE; autocomplete_add(chat_room->nick_ac, nick); } else if (old->presence != new_presence || (g_strcmp0(old->status, status) != 0)) { updated = TRUE; } resource_presence_t presence = resource_presence_from_string(show); muc_role_t role_t = _role_from_string(role); muc_affiliation_t affiliation_t = _affiliation_from_string(affiliation); Occupant *occupant = _muc_occupant_new(nick, jid, role_t, affiliation_t, presence, status); g_hash_table_replace(chat_room->roster, strdup(nick), occupant); if (jid) { Jid *jidp = jid_create(jid); if (jidp->barejid) { autocomplete_add(chat_room->jid_ac, jidp->barejid); } jid_destroy(jidp); } } return updated; }
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; }