void jabber_presence_fake_to_self(JabberStream *js, PurpleStatus *status) { PurpleAccount *account; PurplePresence *presence; JabberBuddy *jb; JabberBuddyResource *jbr; const char *username; JabberBuddyState state; char *msg; int priority; g_return_if_fail(js->user != NULL); account = purple_connection_get_account(js->gc); username = purple_connection_get_display_name(js->gc); presence = purple_account_get_presence(account); if (status == NULL) status = purple_presence_get_active_status(presence); purple_status_to_jabber(status, &state, &msg, &priority); jb = js->user_jb; if (state == JABBER_BUDDY_STATE_UNAVAILABLE || state == JABBER_BUDDY_STATE_UNKNOWN) { jabber_buddy_remove_resource(jb, js->user->resource); } else { jbr = jabber_buddy_track_resource(jb, js->user->resource, priority, state, msg); jbr->idle = purple_presence_is_idle(presence) ? purple_presence_get_idle_time(presence) : 0; } /* * While we need to track the status of this resource, the core * only cares if we're on our own buddy list. */ if (purple_find_buddy(account, username)) { jbr = jabber_buddy_find_resource(jb, NULL); if (jbr) { purple_prpl_got_user_status(account, username, jabber_buddy_state_get_status_id(jbr->state), "priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL); purple_prpl_got_user_idle(account, username, jbr->idle, jbr->idle); } else { purple_prpl_got_user_status(account, username, "offline", msg ? "message" : NULL, msg, NULL); } } g_free(msg); }
void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { JabberStream *js = gc->proto_data; char *who; JabberBuddy *jb; JabberBuddyResource *jbr; char *my_bare_jid; if(!js->roster_parsed) return; if(!(who = jabber_get_bare_jid(buddy->name))) return; jb = jabber_buddy_find(js, buddy->name, FALSE); jabber_roster_update(js, who, NULL); my_bare_jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain); if(!strcmp(who, my_bare_jid)) { PurplePresence *gpresence; PurpleStatus *status; gpresence = purple_account_get_presence(js->gc->account); status = purple_presence_get_active_status(gpresence); jabber_presence_fake_to_self(js, status); } else if(!jb || !(jb->subscription & JABBER_SUB_TO)) { jabber_presence_subscription_set(js, who, "subscribe"); } else if((jbr =jabber_buddy_find_resource(jb, NULL))) { purple_prpl_got_user_status(gc->account, who, jabber_buddy_state_get_status_id(jbr->state), "priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL); } g_free(my_bare_jid); g_free(who); }
void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) { JabberStream *js = gc->proto_data; char *who; JabberID *jid; JabberBuddy *jb; JabberBuddyResource *jbr; const char *name; /* If we haven't received the roster yet, ignore any adds */ if (js->state != JABBER_STREAM_CONNECTED) return; name = purple_buddy_get_name(buddy); jid = jabber_id_new(name); if (jid == NULL) { /* TODO: Remove the buddy from the list? */ return; } /* Adding a chat room or a chat buddy to the roster is *not* supported. */ if (jid->node && jabber_chat_find(js, jid->node, jid->domain) != NULL) { /* * This is the same thing Bonjour does. If it causes problems, move * it to an idle callback. */ purple_debug_warning("jabber", "Cowardly refusing to add a MUC user " "to your buddy list and removing the buddy. " "Buddies can only be added by real (non-MUC) " "JID\n"); purple_blist_remove_buddy(buddy); jabber_id_free(jid); return; } who = jabber_id_get_bare_jid(jid); if (jid->resource != NULL) { /* * If the buddy name added contains a resource, strip that off and * rename the buddy. */ purple_blist_rename_buddy(buddy, who); } jb = jabber_buddy_find(js, who, FALSE); purple_debug_info("jabber", "jabber_roster_add_buddy(): Adding %s\n", who); jabber_roster_update(js, who, NULL); if (jb == js->user_jb) { jabber_presence_fake_to_self(js, NULL); } else if(!jb || !(jb->subscription & JABBER_SUB_TO)) { jabber_presence_subscription_set(js, who, "subscribe"); } else if((jbr =jabber_buddy_find_resource(jb, NULL))) { purple_prpl_got_user_status(gc->account, who, jabber_buddy_state_get_status_id(jbr->state), "priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL); } g_free(who); }
static gboolean handle_presence_contact(JabberStream *js, JabberPresence *presence) { JabberBuddyResource *jbr; PurpleAccount *account; PurpleBuddy *b; char *buddy_name; PurpleConversation *conv; buddy_name = jabber_id_get_bare_jid(presence->jid_from); account = purple_connection_get_account(js->gc); b = purple_find_buddy(account, buddy_name); /* * Unbind/unlock from sending messages to a specific resource on * presence changes. This is locked to a specific resource when * receiving a message (in message.c). */ conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, buddy_name, account); if (conv) { purple_debug_info("jabber", "Changed conversation binding from %s to %s\n", purple_conversation_get_name(conv), buddy_name); purple_conversation_set_name(conv, buddy_name); } if (b == NULL) { if (presence->jb != js->user_jb) { purple_debug_warning("jabber", "Got presence for unknown buddy %s on account %s (%p)\n", buddy_name, purple_account_get_username(account), account); g_free(buddy_name); return FALSE; } else { /* this is a different resource of our own account. Resume even when this account isn't on our blist */ } } if (b && presence->vcard_avatar_hash) { const char *ah = presence->vcard_avatar_hash[0] != '\0' ? presence->vcard_avatar_hash : NULL; const char *ah2 = purple_buddy_icons_get_checksum_for_user(b); if (!purple_strequal(ah, ah2)) { /* XXX this is a crappy way of trying to prevent * someone from spamming us with presence packets * and causing us to DoS ourselves...what we really * need is a queue system that can throttle itself, * but i'm too tired to write that right now */ if(!g_slist_find(js->pending_avatar_requests, presence->jb)) { JabberIq *iq; xmlnode *vcard; js->pending_avatar_requests = g_slist_prepend(js->pending_avatar_requests, presence->jb); iq = jabber_iq_new(js, JABBER_IQ_GET); xmlnode_set_attrib(iq->node, "to", buddy_name); vcard = xmlnode_new_child(iq->node, "vCard"); xmlnode_set_namespace(vcard, "vcard-temp"); jabber_iq_set_callback(iq, jabber_vcard_parse_avatar, NULL); jabber_iq_send(iq); } } } if (presence->state == JABBER_BUDDY_STATE_ERROR || presence->type == JABBER_PRESENCE_UNAVAILABLE || presence->type == JABBER_PRESENCE_UNSUBSCRIBED) { jabber_buddy_remove_resource(presence->jb, presence->jid_from->resource); } else { jbr = jabber_buddy_track_resource(presence->jb, presence->jid_from->resource, presence->priority, presence->state, presence->status); jbr->idle = presence->idle ? time(NULL) - presence->idle : 0; } jbr = jabber_buddy_find_resource(presence->jb, NULL); if (jbr) { jabber_google_presence_incoming(js, buddy_name, jbr); purple_prpl_got_user_status(account, buddy_name, jabber_buddy_state_get_status_id(jbr->state), "priority", jbr->priority, "message", jbr->status, NULL); purple_prpl_got_user_idle(account, buddy_name, jbr->idle, jbr->idle); if (presence->nickname) serv_got_alias(js->gc, buddy_name, presence->nickname); } else { purple_prpl_got_user_status(account, buddy_name, jabber_buddy_state_get_status_id(JABBER_BUDDY_STATE_UNAVAILABLE), presence->status ? "message" : NULL, presence->status, NULL); } g_free(buddy_name); return TRUE; }