Mercurial > pidgin
annotate src/protocols/jabber/presence.c @ 10684:72a5babfa8b4
[gaim-migrate @ 12231]
the cipher api that grim has been working on for ages is finally done!! big
congrats and thanks to him!!
lots of modified files in this commit. it builds here.
moved the md5 files to src/protocols/oscar so that it continues to depend
on nothing in gaim. everything else uses the new centralized cipher api.
I'm not sure if src/md5.* needs to be removed or not, so I left it there.
someone let me know or do it directly.
someone check if these need to be added to potfiles.in
and let there be much rejoicing!
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Fri, 11 Mar 2005 13:05:31 +0000 |
parents | 6a618db0a404 |
children | b256ce6b85b8 |
rev | line source |
---|---|
7014 | 1 /* |
2 * gaim - Jabber Protocol Plugin | |
3 * | |
4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 #include "internal.h" | |
22 | |
10684
72a5babfa8b4
[gaim-migrate @ 12231]
Luke Schierer <lschiere@pidgin.im>
parents:
10646
diff
changeset
|
23 #include "cipher.h" |
7014 | 24 #include "debug.h" |
25 #include "notify.h" | |
26 #include "request.h" | |
27 #include "server.h" | |
9954 | 28 #include "status.h" |
7095
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7015
diff
changeset
|
29 #include "util.h" |
7014 | 30 |
31 #include "buddy.h" | |
32 #include "chat.h" | |
33 #include "presence.h" | |
34 #include "iq.h" | |
35 #include "jutil.h" | |
36 #include "xmlnode.h" | |
37 | |
38 | |
39 static void chats_send_presence_foreach(gpointer key, gpointer val, | |
40 gpointer user_data) | |
41 { | |
42 JabberChat *chat = val; | |
43 xmlnode *presence = user_data; | |
8577 | 44 char *chat_full_jid; |
45 | |
46 if(!chat->conv) | |
47 return; | |
48 | |
49 chat_full_jid = g_strdup_printf("%s@%s/%s", chat->room, chat->server, | |
8401 | 50 chat->handle); |
7014 | 51 |
8401 | 52 xmlnode_set_attrib(presence, "to", chat_full_jid); |
7014 | 53 jabber_send(chat->js, presence); |
8401 | 54 g_free(chat_full_jid); |
7014 | 55 } |
56 | |
9954 | 57 void jabber_presence_fake_to_self(JabberStream *js, const GaimStatus *gstatus) { |
10286 | 58 char *my_base_jid; |
59 | |
60 if(!js->user) | |
61 return; | |
62 | |
63 my_base_jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain); | |
8185 | 64 if(gaim_find_buddy(js->gc->account, my_base_jid)) { |
65 JabberBuddy *jb; | |
66 JabberBuddyResource *jbr; | |
67 if((jb = jabber_buddy_find(js, my_base_jid, TRUE))) { | |
9954 | 68 JabberBuddyState state; |
69 const char *msg; | |
70 int priority; | |
71 | |
72 gaim_status_to_jabber(gstatus, &state, &msg, &priority); | |
73 | |
10490 | 74 if (state == JABBER_BUDDY_STATE_UNAVAILABLE || state == JABBER_BUDDY_STATE_UNKNOWN) { |
9744 | 75 jabber_buddy_remove_resource(jb, js->user->resource); |
76 } else { | |
9954 | 77 jabber_buddy_track_resource(jb, js->user->resource, priority, state, msg); |
9744 | 78 } |
9954 | 79 if((jbr = jabber_buddy_find_resource(jb, NULL))) { |
9990 | 80 gaim_prpl_got_user_status(js->gc->account, my_base_jid, jabber_buddy_state_get_status_id(jbr->state), "priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL); |
9954 | 81 } else { |
9990 | 82 gaim_prpl_got_user_status(js->gc->account, my_base_jid, "offline", msg ? "message" : NULL, msg, NULL); |
9954 | 83 } |
8185 | 84 } |
85 } | |
86 g_free(my_base_jid); | |
87 } | |
88 | |
7014 | 89 |
10216 | 90 void jabber_presence_send(GaimAccount *account, GaimStatus *status) |
7014 | 91 { |
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10286
diff
changeset
|
92 GaimConnection *gc = NULL; |
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10286
diff
changeset
|
93 JabberStream *js = NULL; |
10189 | 94 xmlnode *presence, *x, *photo; |
7014 | 95 char *stripped = NULL; |
9954 | 96 const char *msg; |
97 JabberBuddyState state; | |
98 int priority; | |
7014 | 99 |
10486 | 100 if(!gaim_status_is_active(status)) |
101 return; | |
102 | |
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10286
diff
changeset
|
103 if(!account) return ; |
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10286
diff
changeset
|
104 gc = account->gc; |
10646 | 105 |
106 if (!gc && strcmp(gaim_status_get_id(status), "offline")) | |
107 gaim_account_connect(account, status); | |
108 | |
109 if(!gc) return; | |
10382
9f28196ed769
[gaim-migrate @ 11608]
Luke Schierer <lschiere@pidgin.im>
parents:
10286
diff
changeset
|
110 js= gc->proto_data; |
10646 | 111 |
9954 | 112 gaim_status_to_jabber(status, &state, &msg, &priority); |
113 | |
114 if(msg) | |
7095
c8bf2da398e3
[gaim-migrate @ 7660]
Christian Hammond <chipx86@chipx86.com>
parents:
7015
diff
changeset
|
115 gaim_markup_html_to_xhtml(msg, NULL, &stripped); |
7014 | 116 |
9954 | 117 presence = jabber_presence_create(state, stripped, priority); |
118 g_free(stripped); | |
7014 | 119 |
120 jabber_send(js, presence); | |
10189 | 121 |
122 if(js->avatar_hash) { | |
123 x = xmlnode_new_child(presence, "x"); | |
124 xmlnode_set_attrib(x, "xmlns", "vcard-temp:x:update"); | |
125 photo = xmlnode_new_child(x, "photo"); | |
126 xmlnode_insert_data(photo, js->avatar_hash, -1); | |
127 } | |
128 | |
7014 | 129 g_hash_table_foreach(js->chats, chats_send_presence_foreach, presence); |
130 xmlnode_free(presence); | |
8185 | 131 |
9954 | 132 jabber_presence_fake_to_self(js, status); |
133 | |
7014 | 134 } |
135 | |
9954 | 136 xmlnode *jabber_presence_create(JabberBuddyState state, const char *msg, int priority) |
7014 | 137 { |
138 xmlnode *show, *status, *presence; | |
9954 | 139 const char *show_string = NULL; |
7014 | 140 |
141 | |
142 presence = xmlnode_new("presence"); | |
143 | |
144 | |
9954 | 145 if(state == JABBER_BUDDY_STATE_UNAVAILABLE) |
146 xmlnode_set_attrib(presence, "type", "unavailable"); | |
147 else if(state != JABBER_BUDDY_STATE_ONLINE && | |
148 state != JABBER_BUDDY_STATE_UNKNOWN && | |
149 state != JABBER_BUDDY_STATE_ERROR) | |
150 show_string = jabber_buddy_state_get_status_id(state); | |
151 | |
152 if(show_string) { | |
153 show = xmlnode_new_child(presence, "show"); | |
154 xmlnode_insert_data(show, show_string, -1); | |
7014 | 155 } |
156 | |
9954 | 157 if(msg) { |
7014 | 158 status = xmlnode_new_child(presence, "status"); |
159 xmlnode_insert_data(status, msg, -1); | |
160 } | |
161 | |
162 return presence; | |
163 } | |
164 | |
165 struct _jabber_add_permit { | |
166 GaimConnection *gc; | |
167 char *who; | |
168 }; | |
169 | |
170 static void authorize_add_cb(struct _jabber_add_permit *jap) | |
171 { | |
172 if(g_list_find(gaim_connections_get_all(), jap->gc)) { | |
173 jabber_presence_subscription_set(jap->gc->proto_data, jap->who, | |
174 "subscribed"); | |
175 | |
176 if(!gaim_find_buddy(jap->gc->account, jap->who)) | |
7015
dece74f05509
[gaim-migrate @ 7578]
Christian Hammond <chipx86@chipx86.com>
parents:
7014
diff
changeset
|
177 gaim_account_notify_added(jap->gc->account, NULL, jap->who, NULL, NULL); |
7014 | 178 } |
179 | |
180 g_free(jap->who); | |
181 g_free(jap); | |
182 } | |
183 | |
184 static void deny_add_cb(struct _jabber_add_permit *jap) | |
185 { | |
186 if(g_list_find(gaim_connections_get_all(), jap->gc)) { | |
187 jabber_presence_subscription_set(jap->gc->proto_data, jap->who, | |
188 "unsubscribed"); | |
189 } | |
190 | |
191 g_free(jap->who); | |
192 g_free(jap); | |
193 } | |
194 | |
10189 | 195 static void jabber_vcard_parse_avatar(JabberStream *js, xmlnode *packet, gpointer blah) |
196 { | |
197 GaimBuddy *b = NULL; | |
198 xmlnode *vcard, *photo; | |
199 char *text, *data; | |
200 int size; | |
201 const char *from = xmlnode_get_attrib(packet, "from"); | |
202 | |
203 if(!from) | |
204 return; | |
205 | |
206 if((vcard = xmlnode_get_child(packet, "vCard")) || | |
207 (vcard = xmlnode_get_child_with_namespace(packet, "query", "vcard-temp"))) { | |
208 if((photo = xmlnode_get_child(vcard, "PHOTO"))) { | |
209 if((text = xmlnode_get_data(photo))) { | |
210 gaim_base64_decode(text, &data, &size); | |
211 | |
212 gaim_buddy_icons_set_for_user(js->gc->account, from, data, size); | |
213 if((b = gaim_find_buddy(js->gc->account, from))) { | |
214 unsigned char hashval[20]; | |
215 char hash[41], *p; | |
216 int i; | |
217 | |
10684
72a5babfa8b4
[gaim-migrate @ 12231]
Luke Schierer <lschiere@pidgin.im>
parents:
10646
diff
changeset
|
218 gaim_cipher_digest_region("sha1", (guint8 *)data, size, |
72a5babfa8b4
[gaim-migrate @ 12231]
Luke Schierer <lschiere@pidgin.im>
parents:
10646
diff
changeset
|
219 hashval, NULL); |
10189 | 220 p = hash; |
221 for(i=0; i<20; i++, p+=2) | |
222 snprintf(p, 3, "%02x", hashval[i]); | |
223 gaim_blist_node_set_string((GaimBlistNode*)b, "avatar_hash", hash); | |
224 } | |
225 } | |
226 } | |
227 } | |
228 } | |
229 | |
7014 | 230 void jabber_presence_parse(JabberStream *js, xmlnode *packet) |
231 { | |
232 const char *from = xmlnode_get_attrib(packet, "from"); | |
233 const char *type = xmlnode_get_attrib(packet, "type"); | |
7944 | 234 const char *real_jid = NULL; |
9152 | 235 const char *affiliation = NULL; |
236 const char *role = NULL; | |
7014 | 237 char *status = NULL; |
238 int priority = 0; | |
239 JabberID *jid; | |
240 JabberChat *chat; | |
241 JabberBuddy *jb; | |
9954 | 242 JabberBuddyResource *jbr = NULL, *found_jbr = NULL; |
9554 | 243 GaimConvChatBuddyFlags flags = GAIM_CBFLAGS_NONE; |
9846 | 244 gboolean delayed = FALSE; |
10189 | 245 GaimBuddy *b = NULL; |
7014 | 246 char *buddy_name; |
9954 | 247 JabberBuddyState state = JABBER_BUDDY_STATE_UNKNOWN; |
7014 | 248 xmlnode *y; |
249 gboolean muc = FALSE; | |
10189 | 250 char *avatar_hash = NULL; |
7014 | 251 |
252 | |
8043 | 253 if(!(jb = jabber_buddy_find(js, from, TRUE))) |
254 return; | |
255 | |
256 if(!(jid = jabber_id_new(from))) | |
7280 | 257 return; |
258 | |
7014 | 259 if(jb->error_msg) { |
260 g_free(jb->error_msg); | |
261 jb->error_msg = NULL; | |
262 } | |
263 | |
7813 | 264 if(type && !strcmp(type, "error")) { |
8401 | 265 char *msg = jabber_parse_error(js, packet); |
7644 | 266 |
9954 | 267 state = JABBER_BUDDY_STATE_ERROR; |
8401 | 268 jb->error_msg = msg ? msg : g_strdup(_("Unknown Error in presence")); |
7813 | 269 } else if(type && !strcmp(type, "subscribe")) { |
7014 | 270 struct _jabber_add_permit *jap = g_new0(struct _jabber_add_permit, 1); |
271 char *msg = g_strdup_printf(_("The user %s wants to add you to their buddy list."), from); | |
272 jap->gc = js->gc; | |
273 jap->who = g_strdup(from); | |
274 | |
10189 | 275 gaim_request_action(js->gc, NULL, msg, NULL, GAIM_DEFAULT_ACTION_NONE, |
10116 | 276 jap, 2, |
7014 | 277 _("Authorize"), G_CALLBACK(authorize_add_cb), |
278 _("Deny"), G_CALLBACK(deny_add_cb)); | |
279 g_free(msg); | |
8043 | 280 jabber_id_free(jid); |
7145 | 281 return; |
7813 | 282 } else if(type && !strcmp(type, "subscribed")) { |
7014 | 283 /* we've been allowed to see their presence, but we don't care */ |
8043 | 284 jabber_id_free(jid); |
7014 | 285 return; |
286 } else { | |
287 if((y = xmlnode_get_child(packet, "show"))) { | |
288 char *show = xmlnode_get_data(y); | |
9954 | 289 state = jabber_buddy_status_id_get_state(show); |
7014 | 290 g_free(show); |
291 } else { | |
9954 | 292 state = JABBER_BUDDY_STATE_ONLINE; |
7014 | 293 } |
294 } | |
295 | |
7310 | 296 |
7014 | 297 for(y = packet->child; y; y = y->next) { |
8135 | 298 if(y->type != XMLNODE_TYPE_TAG) |
7014 | 299 continue; |
300 | |
301 if(!strcmp(y->name, "status")) { | |
7615 | 302 g_free(status); |
7014 | 303 status = xmlnode_get_data(y); |
304 } else if(!strcmp(y->name, "priority")) { | |
305 char *p = xmlnode_get_data(y); | |
306 if(p) { | |
307 priority = atoi(p); | |
308 g_free(p); | |
309 } | |
310 } else if(!strcmp(y->name, "x")) { | |
311 const char *xmlns = xmlnode_get_attrib(y, "xmlns"); | |
9846 | 312 if(xmlns && !strcmp(xmlns, "jabber:x:delay")) { |
9847 | 313 /* XXX: compare the time. jabber:x:delay can happen on presence packets that aren't really and truly delayed */ |
9846 | 314 delayed = TRUE; |
315 } else if(xmlns && !strcmp(xmlns, "http://jabber.org/protocol/muc#user")) { | |
7629 | 316 xmlnode *z; |
317 | |
7014 | 318 muc = TRUE; |
7629 | 319 if((z = xmlnode_get_child(y, "status"))) { |
320 const char *code = xmlnode_get_attrib(z, "code"); | |
321 if(code && !strcmp(code, "201")) { | |
7895 | 322 chat = jabber_chat_find(js, jid->node, jid->domain); |
8396 | 323 chat->config_dialog_type = GAIM_REQUEST_ACTION; |
324 chat->config_dialog_handle = | |
325 gaim_request_action(js->gc, _("Create New Room"), | |
7895 | 326 _("Create New Room"), |
327 _("You are creating a new room. Would you like to " | |
328 "configure it, or accept the default settings?"), | |
329 1, chat, 2, _("Configure Room"), | |
7923 | 330 G_CALLBACK(jabber_chat_request_room_configure), |
7895 | 331 _("Accept Defaults"), |
332 G_CALLBACK(jabber_chat_create_instant_room)); | |
7629 | 333 } |
334 } | |
7944 | 335 if((z = xmlnode_get_child(y, "item"))) { |
336 real_jid = xmlnode_get_attrib(z, "jid"); | |
9152 | 337 affiliation = xmlnode_get_attrib(z, "affiliation"); |
338 role = xmlnode_get_attrib(z, "role"); | |
9931 | 339 if(affiliation != NULL && !strcmp(affiliation, "owner")) |
340 flags |= GAIM_CBFLAGS_FOUNDER; | |
9743 | 341 if (role != NULL) { |
342 if (!strcmp(role, "moderator")) | |
9931 | 343 flags |= GAIM_CBFLAGS_OP; |
9743 | 344 else if (!strcmp(role, "participant")) |
9931 | 345 flags |= GAIM_CBFLAGS_VOICE; |
9743 | 346 } |
7944 | 347 } |
10189 | 348 } else if(xmlns && !strcmp(xmlns, "vcard-temp:x:update")) { |
349 xmlnode *photo = xmlnode_get_child(y, "photo"); | |
350 if(photo) { | |
351 if(avatar_hash) | |
352 g_free(avatar_hash); | |
353 avatar_hash = xmlnode_get_data(photo); | |
354 } | |
7014 | 355 } |
356 } | |
357 } | |
358 | |
359 | |
7322 | 360 if(jid->node && (chat = jabber_chat_find(js, jid->node, jid->domain))) { |
8462 | 361 static int i = 1; |
7014 | 362 char *room_jid = g_strdup_printf("%s@%s", jid->node, jid->domain); |
363 | |
9954 | 364 if(state == JABBER_BUDDY_STATE_ERROR) { |
8401 | 365 char *title, *msg = jabber_parse_error(js, packet); |
7014 | 366 |
7321 | 367 if(chat->conv) { |
8401 | 368 title = g_strdup_printf(_("Error in chat %s"), from); |
7321 | 369 serv_got_chat_left(js->gc, chat->id); |
370 } else { | |
8401 | 371 title = g_strdup_printf(_("Error joining chat %s"), from); |
7321 | 372 } |
8401 | 373 gaim_notify_error(js->gc, title, title, msg); |
374 g_free(title); | |
375 g_free(msg); | |
7014 | 376 |
377 jabber_chat_destroy(chat); | |
7310 | 378 jabber_id_free(jid); |
7615 | 379 g_free(status); |
8182 | 380 g_free(room_jid); |
10189 | 381 if(avatar_hash) |
382 g_free(avatar_hash); | |
7014 | 383 return; |
384 } | |
385 | |
386 | |
7813 | 387 if(type && !strcmp(type, "unavailable")) { |
7972 | 388 gboolean nick_change = FALSE; |
7973 | 389 |
9152 | 390 /* If we haven't joined the chat yet, we don't care that someone |
391 * left, or it was us leaving after we closed the chat */ | |
8182 | 392 if(!chat->conv) { |
10558 | 393 if(jid->resource && chat->handle && !strcmp(jid->resource, chat->handle)) |
9152 | 394 jabber_chat_destroy(chat); |
8182 | 395 jabber_id_free(jid); |
396 g_free(status); | |
397 g_free(room_jid); | |
10189 | 398 if(avatar_hash) |
399 g_free(avatar_hash); | |
8182 | 400 return; |
401 } | |
402 | |
7973 | 403 jabber_buddy_remove_resource(jb, jid->resource); |
7972 | 404 if(chat->muc) { |
405 xmlnode *x; | |
8135 | 406 for(x = xmlnode_get_child(packet, "x"); x; x = xmlnode_get_next_twin(x)) { |
7972 | 407 const char *xmlns, *nick, *code; |
408 xmlnode *stat, *item; | |
409 if(!(xmlns = xmlnode_get_attrib(x, "xmlns")) || | |
410 strcmp(xmlns, "http://jabber.org/protocol/muc#user")) | |
411 continue; | |
412 if(!(stat = xmlnode_get_child(x, "status"))) | |
413 continue; | |
9152 | 414 if(!(code = xmlnode_get_attrib(stat, "code"))) |
7972 | 415 continue; |
9152 | 416 if(!strcmp(code, "301")) { |
417 /* XXX: we got banned */ | |
418 } else if(!strcmp(code, "303")) { | |
419 if(!(item = xmlnode_get_child(x, "item"))) | |
420 continue; | |
421 if(!(nick = xmlnode_get_attrib(item, "nick"))) | |
422 continue; | |
423 nick_change = TRUE; | |
424 if(!strcmp(jid->resource, chat->handle)) { | |
425 g_free(chat->handle); | |
426 chat->handle = g_strdup(nick); | |
427 } | |
428 gaim_conv_chat_rename_user(GAIM_CONV_CHAT(chat->conv), jid->resource, nick); | |
429 jabber_chat_remove_handle(chat, jid->resource); | |
430 break; | |
431 } else if(!strcmp(code, "307")) { | |
432 /* XXX: we got kicked */ | |
433 } else if(!strcmp(code, "321")) { | |
434 /* XXX: removed due to an affiliation change */ | |
435 } else if(!strcmp(code, "322")) { | |
436 /* XXX: removed because room is now members-only */ | |
437 } else if(!strcmp(code, "332")) { | |
438 /* XXX: removed due to system shutdown */ | |
8401 | 439 } |
7972 | 440 } |
441 } | |
442 if(!nick_change) { | |
9152 | 443 if(!g_utf8_collate(jid->resource, chat->handle)) { |
7972 | 444 serv_got_chat_left(js->gc, chat->id); |
445 jabber_chat_destroy(chat); | |
446 } else { | |
447 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(chat->conv), jid->resource, | |
7974 | 448 status); |
9152 | 449 jabber_chat_remove_handle(chat, jid->resource); |
7972 | 450 } |
7014 | 451 } |
452 } else { | |
8182 | 453 if(!chat->conv) { |
454 chat->id = i++; | |
455 chat->muc = muc; | |
456 chat->conv = serv_got_joined_chat(js->gc, chat->id, room_jid); | |
8401 | 457 g_free(chat->handle); |
458 chat->handle = g_strdup(jid->resource); | |
8182 | 459 gaim_conv_chat_set_nick(GAIM_CONV_CHAT(chat->conv), jid->resource); |
10486 | 460 |
461 /* <iq to='room@server' | |
462 type='get'> | |
463 <query xmlns='http://jabber.org/protocol/disco#info' | |
464 node='http://jabber.org/protocol/muc#traffic'/> | |
465 </iq> | |
466 */ | |
467 /* expected response format: | |
468 <iq from='room@server' | |
469 type='get'> | |
470 <query xmlns='http://jabber.org/protocol/disco#info' | |
471 node='http://jabber.org/protocol/muc#traffic'> | |
472 <feature var='http://jabber.org/protocol/xhtml-im'/> | |
473 <feature var='jabber:x:roster/'/> | |
474 </query> | |
475 </iq> | |
476 */ | |
477 /* | |
478 * XXX: i'm not sure if we turn off XHTML unless we get | |
479 * xhtml back in this, or if we turn it off only if we | |
480 * get a response, and it's not there. Ask stpeter to | |
481 * clarify. | |
482 */ | |
8182 | 483 } |
484 | |
7973 | 485 jabber_buddy_track_resource(jb, jid->resource, priority, state, |
486 status); | |
487 | |
9152 | 488 jabber_chat_track_handle(chat, jid->resource, real_jid, affiliation, role); |
489 | |
7014 | 490 if(!jabber_chat_find_buddy(chat->conv, jid->resource)) |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
7095
diff
changeset
|
491 gaim_conv_chat_add_user(GAIM_CONV_CHAT(chat->conv), jid->resource, |
9846 | 492 real_jid, flags, !delayed); |
9554 | 493 else |
494 gaim_conv_chat_user_set_flags(GAIM_CONV_CHAT(chat->conv), jid->resource, | |
495 flags); | |
7014 | 496 } |
497 g_free(room_jid); | |
498 } else { | |
10486 | 499 if(state != JABBER_BUDDY_STATE_ERROR && !(jb->subscription & JABBER_SUB_TO || jb->subscription & JABBER_SUB_PENDING)) { |
7014 | 500 gaim_debug(GAIM_DEBUG_INFO, "jabber", |
501 "got unexpected presence from %s, ignoring\n", from); | |
502 jabber_id_free(jid); | |
7615 | 503 g_free(status); |
10189 | 504 if(avatar_hash) |
505 g_free(avatar_hash); | |
7014 | 506 return; |
507 } | |
508 | |
7322 | 509 buddy_name = g_strdup_printf("%s%s%s", jid->node ? jid->node : "", |
510 jid->node ? "@" : "", jid->domain); | |
7014 | 511 if((b = gaim_find_buddy(js->gc->account, buddy_name)) == NULL) { |
512 jabber_id_free(jid); | |
10189 | 513 if(avatar_hash) |
514 g_free(avatar_hash); | |
7014 | 515 g_free(buddy_name); |
7615 | 516 g_free(status); |
7014 | 517 return; |
518 } | |
519 | |
10189 | 520 if(avatar_hash) { |
521 const char *avatar_hash2 = gaim_blist_node_get_string((GaimBlistNode*)b, "avatar_hash"); | |
522 if(!avatar_hash2 || strcmp(avatar_hash, avatar_hash2)) { | |
523 JabberIq *iq; | |
524 xmlnode *vcard; | |
525 | |
526 iq = jabber_iq_new(js, JABBER_IQ_GET); | |
527 xmlnode_set_attrib(iq->node, "to", buddy_name); | |
528 vcard = xmlnode_new_child(iq->node, "vCard"); | |
529 xmlnode_set_attrib(vcard, "xmlns", "vcard-temp"); | |
530 | |
531 jabber_iq_set_callback(iq, jabber_vcard_parse_avatar, NULL); | |
532 jabber_iq_send(iq); | |
533 } | |
534 } | |
535 | |
9954 | 536 if(state == JABBER_BUDDY_STATE_ERROR || |
7813 | 537 (type && (!strcmp(type, "unavailable") || |
538 !strcmp(type, "unsubscribed")))) { | |
8043 | 539 GaimConversation *conv; |
540 | |
7014 | 541 jabber_buddy_remove_resource(jb, jid->resource); |
8043 | 542 if((conv = jabber_find_unnormalized_conv(from, js->gc->account))) |
543 gaim_conversation_set_name(conv, buddy_name); | |
544 | |
7395 | 545 } else { |
9954 | 546 jbr = jabber_buddy_track_resource(jb, jid->resource, priority, |
547 state, status); | |
7395 | 548 } |
7014 | 549 |
9954 | 550 if((found_jbr = jabber_buddy_find_resource(jb, NULL))) { |
551 if(!jbr || jbr == found_jbr) { | |
9990 | 552 gaim_prpl_got_user_status(js->gc->account, buddy_name, jabber_buddy_state_get_status_id(state), "priority", found_jbr->priority, found_jbr->status ? "message" : NULL, found_jbr->status, NULL); |
9954 | 553 } |
554 } else { | |
9990 | 555 gaim_prpl_got_user_status(js->gc->account, buddy_name, "offline", status ? "message" : NULL, status, NULL); |
9954 | 556 } |
7014 | 557 g_free(buddy_name); |
558 } | |
559 g_free(status); | |
560 jabber_id_free(jid); | |
10189 | 561 if(avatar_hash) |
562 g_free(avatar_hash); | |
7014 | 563 } |
564 | |
565 void jabber_presence_subscription_set(JabberStream *js, const char *who, const char *type) | |
566 { | |
567 xmlnode *presence = xmlnode_new("presence"); | |
568 | |
569 xmlnode_set_attrib(presence, "to", who); | |
570 xmlnode_set_attrib(presence, "type", type); | |
571 | |
572 jabber_send(js, presence); | |
573 xmlnode_free(presence); | |
574 } | |
9954 | 575 |
576 void gaim_status_to_jabber(const GaimStatus *status, JabberBuddyState *state, const char **msg, int *priority) | |
577 { | |
10216 | 578 const char *status_id = NULL; |
579 | |
580 *state = JABBER_BUDDY_STATE_UNKNOWN; | |
581 *msg = NULL; | |
582 *priority = 0; | |
9954 | 583 |
584 if(!status) { | |
10216 | 585 *state = JABBER_BUDDY_STATE_UNAVAILABLE; |
586 } else { | |
587 if(state) { | |
588 status_id = gaim_status_get_id(status); | |
589 *state = jabber_buddy_status_id_get_state(status_id); | |
590 } | |
591 | |
592 if(msg) | |
593 *msg = gaim_status_get_attr_string(status, "message"); | |
594 | |
595 if(priority) | |
596 *priority = gaim_status_get_attr_int(status, "priority"); | |
9954 | 597 } |
598 | |
599 } |