| 82 |
83 |
| 83 |
84 |
| 84 void jabber_presence_send(GaimConnection *gc, GaimStatus *status) |
85 void jabber_presence_send(GaimConnection *gc, GaimStatus *status) |
| 85 { |
86 { |
| 86 JabberStream *js = gc->proto_data; |
87 JabberStream *js = gc->proto_data; |
| 87 xmlnode *presence; |
88 xmlnode *presence, *x, *photo; |
| 88 char *stripped = NULL; |
89 char *stripped = NULL; |
| 89 const char *msg; |
90 const char *msg; |
| 90 JabberBuddyState state; |
91 JabberBuddyState state; |
| 91 int priority; |
92 int priority; |
| 92 |
93 |
| 97 |
98 |
| 98 presence = jabber_presence_create(state, stripped, priority); |
99 presence = jabber_presence_create(state, stripped, priority); |
| 99 g_free(stripped); |
100 g_free(stripped); |
| 100 |
101 |
| 101 jabber_send(js, presence); |
102 jabber_send(js, presence); |
| |
103 |
| |
104 if(js->avatar_hash) { |
| |
105 x = xmlnode_new_child(presence, "x"); |
| |
106 xmlnode_set_attrib(x, "xmlns", "vcard-temp:x:update"); |
| |
107 photo = xmlnode_new_child(x, "photo"); |
| |
108 xmlnode_insert_data(photo, js->avatar_hash, -1); |
| |
109 } |
| |
110 |
| 102 g_hash_table_foreach(js->chats, chats_send_presence_foreach, presence); |
111 g_hash_table_foreach(js->chats, chats_send_presence_foreach, presence); |
| 103 xmlnode_free(presence); |
112 xmlnode_free(presence); |
| 104 |
113 |
| 105 jabber_presence_fake_to_self(js, status); |
114 jabber_presence_fake_to_self(js, status); |
| 106 |
115 |
| 161 "unsubscribed"); |
170 "unsubscribed"); |
| 162 } |
171 } |
| 163 |
172 |
| 164 g_free(jap->who); |
173 g_free(jap->who); |
| 165 g_free(jap); |
174 g_free(jap); |
| |
175 } |
| |
176 |
| |
177 static void jabber_vcard_parse_avatar(JabberStream *js, xmlnode *packet, gpointer blah) |
| |
178 { |
| |
179 GaimBuddy *b = NULL; |
| |
180 xmlnode *vcard, *photo; |
| |
181 char *text, *data; |
| |
182 int size; |
| |
183 const char *from = xmlnode_get_attrib(packet, "from"); |
| |
184 |
| |
185 if(!from) |
| |
186 return; |
| |
187 |
| |
188 if((vcard = xmlnode_get_child(packet, "vCard")) || |
| |
189 (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) { |
| |
190 if((photo = xmlnode_get_child(vcard, "PHOTO"))) { |
| |
191 if((text = xmlnode_get_data(photo))) { |
| |
192 gaim_base64_decode(text, &data, &size); |
| |
193 |
| |
194 gaim_buddy_icons_set_for_user(js->gc->account, from, data, size); |
| |
195 if((b = gaim_find_buddy(js->gc->account, from))) { |
| |
196 unsigned char hashval[20]; |
| |
197 char hash[41], *p; |
| |
198 int i; |
| |
199 |
| |
200 shaBlock((unsigned char *)data, size, hashval); |
| |
201 p = hash; |
| |
202 for(i=0; i<20; i++, p+=2) |
| |
203 snprintf(p, 3, "%02x", hashval[i]); |
| |
204 gaim_blist_node_set_string((GaimBlistNode*)b, "avatar_hash", hash); |
| |
205 } |
| |
206 } |
| |
207 } |
| |
208 } |
| 166 } |
209 } |
| 167 |
210 |
| 168 void jabber_presence_parse(JabberStream *js, xmlnode *packet) |
211 void jabber_presence_parse(JabberStream *js, xmlnode *packet) |
| 169 { |
212 { |
| 170 const char *from = xmlnode_get_attrib(packet, "from"); |
213 const char *from = xmlnode_get_attrib(packet, "from"); |
| 178 JabberChat *chat; |
221 JabberChat *chat; |
| 179 JabberBuddy *jb; |
222 JabberBuddy *jb; |
| 180 JabberBuddyResource *jbr = NULL, *found_jbr = NULL; |
223 JabberBuddyResource *jbr = NULL, *found_jbr = NULL; |
| 181 GaimConvChatBuddyFlags flags = GAIM_CBFLAGS_NONE; |
224 GaimConvChatBuddyFlags flags = GAIM_CBFLAGS_NONE; |
| 182 gboolean delayed = FALSE; |
225 gboolean delayed = FALSE; |
| 183 GaimBuddy *b; |
226 GaimBuddy *b = NULL; |
| 184 char *buddy_name; |
227 char *buddy_name; |
| 185 JabberBuddyState state = JABBER_BUDDY_STATE_UNKNOWN; |
228 JabberBuddyState state = JABBER_BUDDY_STATE_UNKNOWN; |
| 186 xmlnode *y; |
229 xmlnode *y; |
| 187 gboolean muc = FALSE; |
230 gboolean muc = FALSE; |
| |
231 char *avatar_hash = NULL; |
| 188 |
232 |
| 189 |
233 |
| 190 if(!(jb = jabber_buddy_find(js, from, TRUE))) |
234 if(!(jb = jabber_buddy_find(js, from, TRUE))) |
| 191 return; |
235 return; |
| 192 |
236 |
| 207 struct _jabber_add_permit *jap = g_new0(struct _jabber_add_permit, 1); |
251 struct _jabber_add_permit *jap = g_new0(struct _jabber_add_permit, 1); |
| 208 char *msg = g_strdup_printf(_("The user %s wants to add you to their buddy list."), from); |
252 char *msg = g_strdup_printf(_("The user %s wants to add you to their buddy list."), from); |
| 209 jap->gc = js->gc; |
253 jap->gc = js->gc; |
| 210 jap->who = g_strdup(from); |
254 jap->who = g_strdup(from); |
| 211 |
255 |
| 212 gaim_request_action(js->gc, NULL, msg, NULL, GAIM_DEFAULT_ACTION_NONE, |
256 gaim_request_action(js->gc, NULL, msg, NULL, GAIM_DEFAULT_ACTION_NONE, |
| 213 jap, 2, |
257 jap, 2, |
| 214 _("Authorize"), G_CALLBACK(authorize_add_cb), |
258 _("Authorize"), G_CALLBACK(authorize_add_cb), |
| 215 _("Deny"), G_CALLBACK(deny_add_cb)); |
259 _("Deny"), G_CALLBACK(deny_add_cb)); |
| 216 g_free(msg); |
260 g_free(msg); |
| 217 jabber_id_free(jid); |
261 jabber_id_free(jid); |
| 280 flags |= GAIM_CBFLAGS_OP; |
324 flags |= GAIM_CBFLAGS_OP; |
| 281 else if (!strcmp(role, "participant")) |
325 else if (!strcmp(role, "participant")) |
| 282 flags |= GAIM_CBFLAGS_VOICE; |
326 flags |= GAIM_CBFLAGS_VOICE; |
| 283 } |
327 } |
| 284 } |
328 } |
| |
329 } else if(xmlns && !strcmp(xmlns, "vcard-temp:x:update")) { |
| |
330 xmlnode *photo = xmlnode_get_child(y, "photo"); |
| |
331 if(photo) { |
| |
332 if(avatar_hash) |
| |
333 g_free(avatar_hash); |
| |
334 avatar_hash = xmlnode_get_data(photo); |
| |
335 } |
| 285 } |
336 } |
| 286 } |
337 } |
| 287 } |
338 } |
| 288 |
339 |
| 289 |
340 |
| 402 if(state != JABBER_BUDDY_STATE_ERROR && !(jb->subscription & JABBER_SUB_TO)) { |
457 if(state != JABBER_BUDDY_STATE_ERROR && !(jb->subscription & JABBER_SUB_TO)) { |
| 403 gaim_debug(GAIM_DEBUG_INFO, "jabber", |
458 gaim_debug(GAIM_DEBUG_INFO, "jabber", |
| 404 "got unexpected presence from %s, ignoring\n", from); |
459 "got unexpected presence from %s, ignoring\n", from); |
| 405 jabber_id_free(jid); |
460 jabber_id_free(jid); |
| 406 g_free(status); |
461 g_free(status); |
| |
462 if(avatar_hash) |
| |
463 g_free(avatar_hash); |
| 407 return; |
464 return; |
| 408 } |
465 } |
| 409 |
466 |
| 410 buddy_name = g_strdup_printf("%s%s%s", jid->node ? jid->node : "", |
467 buddy_name = g_strdup_printf("%s%s%s", jid->node ? jid->node : "", |
| 411 jid->node ? "@" : "", jid->domain); |
468 jid->node ? "@" : "", jid->domain); |
| 412 if((b = gaim_find_buddy(js->gc->account, buddy_name)) == NULL) { |
469 if((b = gaim_find_buddy(js->gc->account, buddy_name)) == NULL) { |
| 413 jabber_id_free(jid); |
470 jabber_id_free(jid); |
| |
471 if(avatar_hash) |
| |
472 g_free(avatar_hash); |
| 414 g_free(buddy_name); |
473 g_free(buddy_name); |
| 415 g_free(status); |
474 g_free(status); |
| 416 return; |
475 return; |
| |
476 } |
| |
477 |
| |
478 if(avatar_hash) { |
| |
479 const char *avatar_hash2 = gaim_blist_node_get_string((GaimBlistNode*)b, "avatar_hash"); |
| |
480 if(!avatar_hash2 || strcmp(avatar_hash, avatar_hash2)) { |
| |
481 JabberIq *iq; |
| |
482 xmlnode *vcard; |
| |
483 |
| |
484 iq = jabber_iq_new(js, JABBER_IQ_GET); |
| |
485 xmlnode_set_attrib(iq->node, "to", buddy_name); |
| |
486 vcard = xmlnode_new_child(iq->node, "vCard"); |
| |
487 xmlnode_set_attrib(vcard, "xmlns", "vcard-temp"); |
| |
488 |
| |
489 jabber_iq_set_callback(iq, jabber_vcard_parse_avatar, NULL); |
| |
490 jabber_iq_send(iq); |
| |
491 } |
| 417 } |
492 } |
| 418 |
493 |
| 419 if(state == JABBER_BUDDY_STATE_ERROR || |
494 if(state == JABBER_BUDDY_STATE_ERROR || |
| 420 (type && (!strcmp(type, "unavailable") || |
495 (type && (!strcmp(type, "unavailable") || |
| 421 !strcmp(type, "unsubscribed")))) { |
496 !strcmp(type, "unsubscribed")))) { |