src/protocols/jabber/presence.c

changeset 10189
bc7691fee058
parent 10116
054b064145a1
child 10216
37091349650c
equal deleted inserted replaced
10188:e900c432d1ce 10189:bc7691fee058
30 #include "buddy.h" 30 #include "buddy.h"
31 #include "chat.h" 31 #include "chat.h"
32 #include "presence.h" 32 #include "presence.h"
33 #include "iq.h" 33 #include "iq.h"
34 #include "jutil.h" 34 #include "jutil.h"
35 #include "sha.h"
35 #include "xmlnode.h" 36 #include "xmlnode.h"
36 37
37 38
38 static void chats_send_presence_foreach(gpointer key, gpointer val, 39 static void chats_send_presence_foreach(gpointer key, gpointer val,
39 gpointer user_data) 40 gpointer user_data)
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
306 357
307 jabber_chat_destroy(chat); 358 jabber_chat_destroy(chat);
308 jabber_id_free(jid); 359 jabber_id_free(jid);
309 g_free(status); 360 g_free(status);
310 g_free(room_jid); 361 g_free(room_jid);
362 if(avatar_hash)
363 g_free(avatar_hash);
311 return; 364 return;
312 } 365 }
313 366
314 367
315 if(type && !strcmp(type, "unavailable")) { 368 if(type && !strcmp(type, "unavailable")) {
321 if(!strcmp(jid->resource, chat->handle)) 374 if(!strcmp(jid->resource, chat->handle))
322 jabber_chat_destroy(chat); 375 jabber_chat_destroy(chat);
323 jabber_id_free(jid); 376 jabber_id_free(jid);
324 g_free(status); 377 g_free(status);
325 g_free(room_jid); 378 g_free(room_jid);
379 if(avatar_hash)
380 g_free(avatar_hash);
326 return; 381 return;
327 } 382 }
328 383
329 jabber_buddy_remove_resource(jb, jid->resource); 384 jabber_buddy_remove_resource(jb, jid->resource);
330 if(chat->muc) { 385 if(chat->muc) {
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")))) {
439 } 514 }
440 g_free(buddy_name); 515 g_free(buddy_name);
441 } 516 }
442 g_free(status); 517 g_free(status);
443 jabber_id_free(jid); 518 jabber_id_free(jid);
519 if(avatar_hash)
520 g_free(avatar_hash);
444 } 521 }
445 522
446 void jabber_presence_subscription_set(JabberStream *js, const char *who, const char *type) 523 void jabber_presence_subscription_set(JabberStream *js, const char *who, const char *type)
447 { 524 {
448 xmlnode *presence = xmlnode_new("presence"); 525 xmlnode *presence = xmlnode_new("presence");

mercurial