Mercurial > pidgin.yaz
comparison src/protocols/msn/slp.c @ 9193:502707ca1836
[gaim-migrate @ 9988]
Patch by Felipe Contreras to add MSN file transfer and buddy icons. Please
test and report any bugs!
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Sun, 06 Jun 2004 02:39:08 +0000 |
parents | |
children | ab6636c5a136 |
comparison
equal
deleted
inserted
replaced
9192:5655dcd94d0f | 9193:502707ca1836 |
---|---|
1 /** | |
2 * @file msnslp.c MSNSLP support | |
3 * | |
4 * gaim | |
5 * | |
6 * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org> | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 */ | |
22 #include "msn.h" | |
23 #include "slp.h" | |
24 #include "slpcall.h" | |
25 #include "slpmsg.h" | |
26 #include "slpsession.h" | |
27 | |
28 #include "object.h" | |
29 #include "user.h" | |
30 #include "switchboard.h" | |
31 | |
32 /* #include "slplink.h" */ | |
33 /* #include "directconn.h" */ | |
34 | |
35 static void send_ok(MsnSlpCall *slpcall, const char *branch, | |
36 const char *type, const char *content); | |
37 | |
38 static void send_decline(MsnSlpCall *slpcall, const char *branch, | |
39 const char *type, const char *content); | |
40 | |
41 /************************************************************************** | |
42 * Util | |
43 **************************************************************************/ | |
44 | |
45 char * | |
46 get_token(const char *str, const char *start, const char *end) | |
47 { | |
48 const char *c, *c2; | |
49 | |
50 if ((c = strstr(str, start)) == NULL) | |
51 return NULL; | |
52 | |
53 c += strlen(start); | |
54 | |
55 if (end != NULL) | |
56 { | |
57 if ((c2 = strstr(c, end)) == NULL) | |
58 return NULL; | |
59 | |
60 return g_strndup(c, c2 - c); | |
61 } | |
62 else | |
63 { | |
64 /* This has to be changed */ | |
65 return g_strdup(c); | |
66 } | |
67 | |
68 } | |
69 | |
70 /************************************************************************** | |
71 * Xfer | |
72 **************************************************************************/ | |
73 | |
74 static void | |
75 msn_xfer_init(GaimXfer *xfer) | |
76 { | |
77 MsnSlpCall *slpcall; | |
78 /* MsnSlpLink *slplink; */ | |
79 char *content; | |
80 | |
81 gaim_debug_info("msn", "xfer_init\n"); | |
82 | |
83 slpcall = xfer->data; | |
84 | |
85 /* Send Ok */ | |
86 content = g_strdup_printf("SessionID: %lu\r\n\r\n", | |
87 slpcall->session_id); | |
88 | |
89 send_ok(slpcall, slpcall->branch, "application/x-msnmsgr-sessionreqbody", | |
90 content); | |
91 | |
92 g_free(content); | |
93 gaim_xfer_add(xfer); | |
94 msn_slplink_unleash(slpcall->slplink); | |
95 } | |
96 | |
97 void | |
98 msn_xfer_cancel(GaimXfer *xfer) | |
99 { | |
100 MsnSlpCall *slpcall; | |
101 char *content; | |
102 | |
103 slpcall = xfer->data; | |
104 | |
105 if (gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_LOCAL) | |
106 { | |
107 if (slpcall->started) | |
108 { | |
109 msn_slp_call_close(slpcall); | |
110 } | |
111 else | |
112 { | |
113 content = g_strdup_printf("SessionID: %lu\r\n\r\n", | |
114 slpcall->session_id); | |
115 | |
116 send_decline(slpcall, slpcall->branch, "application/x-msnmsgr-sessionreqbody", | |
117 content); | |
118 | |
119 g_free(content); | |
120 msn_slplink_unleash(slpcall->slplink); | |
121 } | |
122 } | |
123 } | |
124 | |
125 void | |
126 msn_xfer_progress_cb(MsnSlpCall *slpcall, gsize total_length, gsize len, gsize offset) | |
127 { | |
128 GaimXfer *xfer; | |
129 | |
130 xfer = slpcall->xfer; | |
131 | |
132 xfer->bytes_sent = offset; | |
133 xfer->bytes_remaining = total_length - offset; | |
134 | |
135 gaim_xfer_update_progress(xfer); | |
136 } | |
137 | |
138 void | |
139 msn_xfer_finish_cb(MsnSlpCall *slpcall, | |
140 const char *body, long long size) | |
141 { | |
142 if (size < 0) | |
143 gaim_xfer_cancel_remote(slpcall->xfer); | |
144 else | |
145 gaim_xfer_set_completed(slpcall->xfer, TRUE); | |
146 } | |
147 | |
148 /************************************************************************** | |
149 * SLP Control | |
150 **************************************************************************/ | |
151 | |
152 #if 0 | |
153 static void | |
154 got_transresp(MsnSlpCall *slpcall, const char *nonce, | |
155 const char *ips_str, int port) | |
156 { | |
157 MsnDirectConn *directconn; | |
158 char **ip_addrs, **c; | |
159 | |
160 directconn = msn_directconn_new(slpcall->slplink); | |
161 | |
162 directconn->initial_call = slpcall; | |
163 | |
164 /* msn_directconn_parse_nonce(directconn, nonce); */ | |
165 directconn->nonce = g_strdup(nonce); | |
166 | |
167 ip_addrs = g_strsplit(ips_str, " ", -1); | |
168 | |
169 for (c = ip_addrs; *c != NULL; c++) | |
170 { | |
171 gaim_debug_info("msn", "ip_addr = %s\n", *c); | |
172 if (msn_directconn_connect(directconn, *c, port)) | |
173 break; | |
174 } | |
175 | |
176 g_strfreev(ip_addrs); | |
177 } | |
178 #endif | |
179 | |
180 static void | |
181 send_ok(MsnSlpCall *slpcall, const char *branch, | |
182 const char *type, const char *content) | |
183 { | |
184 MsnSlpLink *slplink; | |
185 MsnSlpMessage *slpmsg; | |
186 | |
187 slplink = slpcall->slplink; | |
188 | |
189 /* 200 OK */ | |
190 slpmsg = msn_slpmsg_sip_new(slpcall, 1, | |
191 "MSNSLP/1.0 200 OK", | |
192 branch, type, content); | |
193 | |
194 #ifdef DEBUG_SLP | |
195 slpmsg->info = "SLP 200 OK"; | |
196 slpmsg->text_body = TRUE; | |
197 #endif | |
198 | |
199 msn_slplink_queue_slpmsg(slplink, slpmsg); | |
200 | |
201 msn_slp_call_session_init(slpcall); | |
202 } | |
203 | |
204 static void | |
205 send_decline(MsnSlpCall *slpcall, const char *branch, | |
206 const char *type, const char *content) | |
207 { | |
208 MsnSlpLink *slplink; | |
209 MsnSlpMessage *slpmsg; | |
210 | |
211 slplink = slpcall->slplink; | |
212 | |
213 /* 603 Decline */ | |
214 slpmsg = msn_slpmsg_sip_new(slpcall, 1, | |
215 "MSNSLP/1.0 603 Decline", | |
216 branch, type, content); | |
217 | |
218 #ifdef DEBUG_SLP | |
219 slpmsg->info = "SLP 603 Decline"; | |
220 slpmsg->text_body = TRUE; | |
221 #endif | |
222 | |
223 msn_slplink_queue_slpmsg(slplink, slpmsg); | |
224 } | |
225 | |
226 static void | |
227 got_sessionreq(MsnSlpCall *slpcall, const char *branch, | |
228 const char *euf_guid, const char *context) | |
229 { | |
230 if (!strcmp(euf_guid, "A4268EEC-FEC5-49E5-95C3-F126696BDBF6")) | |
231 { | |
232 /* Emoticon or UserDisplay */ | |
233 MsnSlpSession *slpsession; | |
234 MsnSlpLink *slplink; | |
235 MsnSlpMessage *slpmsg; | |
236 MsnObject *obj; | |
237 char *msnobj_data; | |
238 const char *sha1c; | |
239 const char *file_name; | |
240 char *content; | |
241 gsize len; | |
242 int type; | |
243 | |
244 /* Send Ok */ | |
245 content = g_strdup_printf("SessionID: %lu\r\n\r\n", | |
246 slpcall->session_id); | |
247 | |
248 send_ok(slpcall, branch, "application/x-msnmsgr-sessionreqbody", | |
249 content); | |
250 | |
251 g_free(content); | |
252 | |
253 slplink = slpcall->slplink; | |
254 | |
255 gaim_base64_decode(context, &msnobj_data, &len); | |
256 obj = msn_object_new_from_string(msnobj_data); | |
257 type = msn_object_get_type(obj); | |
258 sha1c = msn_object_get_sha1c(obj); | |
259 g_free(msnobj_data); | |
260 | |
261 if (!(type == MSN_OBJECT_USERTILE)) | |
262 { | |
263 gaim_debug_error("msn", "Wrong object?\n"); | |
264 msn_object_destroy(obj); | |
265 g_return_if_reached(); | |
266 } | |
267 | |
268 file_name = msn_object_get_real_location(obj); | |
269 | |
270 slpsession = msn_slplink_find_slp_session(slplink, | |
271 slpcall->session_id); | |
272 | |
273 /* DATA PREP */ | |
274 slpmsg = msn_slpmsg_new(slplink); | |
275 slpmsg->slpsession = slpsession; | |
276 slpmsg->session_id = slpsession->id; | |
277 msn_slpmsg_set_body(slpmsg, NULL, 4); | |
278 #ifdef DEBUG_SLP | |
279 slpmsg->info = "SLP DATA PREP"; | |
280 #endif | |
281 msn_slplink_queue_slpmsg(slplink, slpmsg); | |
282 | |
283 /* DATA */ | |
284 slpmsg = msn_slpmsg_new(slplink); | |
285 slpmsg->slpsession = slpsession; | |
286 slpmsg->flags = 0x20; | |
287 #ifdef DEBUG_SLP | |
288 slpmsg->info = "SLP DATA"; | |
289 #endif | |
290 msn_slpmsg_open_file(slpmsg, file_name); | |
291 msn_slplink_queue_slpmsg(slplink, slpmsg); | |
292 } | |
293 else if (!strcmp(euf_guid, "5D3E02AB-6190-11D3-BBBB-00C04F795683")) | |
294 { | |
295 /* File Transfer */ | |
296 GaimAccount *account; | |
297 GaimXfer *xfer; | |
298 char *bin; | |
299 gsize bin_len; | |
300 guint32 file_size; | |
301 char *file_name; | |
302 | |
303 account = slpcall->slplink->session->account; | |
304 | |
305 slpcall->cb = msn_xfer_finish_cb; | |
306 slpcall->progress_cb = msn_xfer_progress_cb; | |
307 slpcall->branch = g_strdup(branch); | |
308 | |
309 xfer = gaim_xfer_new(account, GAIM_XFER_RECEIVE, | |
310 slpcall->slplink->remote_user); | |
311 | |
312 gaim_base64_decode(context, &bin, &bin_len); | |
313 file_size = *((gsize *)bin + 2); | |
314 file_name = g_utf16_to_utf8((const gunichar2 *)(bin + 20), -1, | |
315 NULL, NULL, NULL); | |
316 | |
317 g_free(bin); | |
318 | |
319 gaim_xfer_set_filename(xfer, file_name); | |
320 gaim_xfer_set_size(xfer, file_size); | |
321 gaim_xfer_set_init_fnc(xfer, msn_xfer_init); | |
322 gaim_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel); | |
323 gaim_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel); | |
324 | |
325 slpcall->xfer = xfer; | |
326 xfer->data = slpcall; | |
327 | |
328 gaim_xfer_request(xfer); | |
329 } | |
330 } | |
331 | |
332 void | |
333 send_bye(MsnSlpCall *slpcall, const char *type) | |
334 { | |
335 MsnSlpLink *slplink; | |
336 MsnSlpMessage *slpmsg; | |
337 char *header; | |
338 | |
339 slplink = slpcall->slplink; | |
340 | |
341 g_return_if_fail(slplink != NULL); | |
342 | |
343 header = g_strdup_printf("BYE MSNMSGR:%s MSNSLP/1.0", | |
344 slplink->local_user); | |
345 | |
346 slpmsg = msn_slpmsg_sip_new(slpcall, 0, header, | |
347 "A0D624A6-6C0C-4283-A9E0-BC97B4B46D32", | |
348 type, | |
349 "\r\n"); | |
350 g_free(header); | |
351 | |
352 #ifdef DEBUG_SLP | |
353 slpmsg->info = "SLP BYE"; | |
354 slpmsg->text_body = TRUE; | |
355 #endif | |
356 | |
357 msn_slplink_queue_slpmsg(slplink, slpmsg); | |
358 } | |
359 | |
360 static void | |
361 got_invite(MsnSlpCall *slpcall, | |
362 const char *branch, const char *type, const char *content) | |
363 { | |
364 MsnSlpLink *slplink; | |
365 | |
366 slplink = slpcall->slplink; | |
367 | |
368 if (!strcmp(type, "application/x-msnmsgr-sessionreqbody")) | |
369 { | |
370 char *euf_guid, *context; | |
371 char *temp; | |
372 | |
373 euf_guid = get_token(content, "EUF-GUID: {", "}\r\n"); | |
374 | |
375 temp = get_token(content, "SessionID: ", "\r\n"); | |
376 if (temp != NULL) | |
377 slpcall->session_id = atoi(temp); | |
378 g_free(temp); | |
379 | |
380 temp = get_token(content, "AppID: ", "\r\n"); | |
381 if (temp != NULL) | |
382 slpcall->app_id = atoi(temp); | |
383 g_free(temp); | |
384 | |
385 context = get_token(content, "Context: ", "\r\n"); | |
386 | |
387 got_sessionreq(slpcall, branch, euf_guid, context); | |
388 | |
389 g_free(context); | |
390 g_free(euf_guid); | |
391 } | |
392 else if (!strcmp(type, "application/x-msnmsgr-transreqbody")) | |
393 { | |
394 /* A direct connection? */ | |
395 | |
396 char *listening, *nonce; | |
397 char *content; | |
398 | |
399 if (FALSE) | |
400 { | |
401 #if 0 | |
402 MsnDirectConn *directconn; | |
403 /* const char *ip_addr; */ | |
404 char *ip_port; | |
405 int port; | |
406 | |
407 /* ip_addr = gaim_prefs_get_string("/core/ft/public_ip"); */ | |
408 ip_port = "5190"; | |
409 listening = "true"; | |
410 nonce = rand_guid(); | |
411 | |
412 directconn = msn_directconn_new(slplink); | |
413 | |
414 /* msn_directconn_parse_nonce(directconn, nonce); */ | |
415 directconn->nonce = g_strdup(nonce); | |
416 | |
417 msn_directconn_listen(directconn); | |
418 | |
419 port = directconn->port; | |
420 | |
421 content = g_strdup_printf( | |
422 "Bridge: TCPv1\r\n" | |
423 "Listening: %s\r\n" | |
424 "Nonce: {%s}\r\n" | |
425 "Ipv4Internal-Addrs: 192.168.0.82\r\n" | |
426 "Ipv4Internal-Port: %d\r\n" | |
427 "\r\n", | |
428 listening, | |
429 nonce, | |
430 port); | |
431 #endif | |
432 } | |
433 else | |
434 { | |
435 listening = "false"; | |
436 nonce = g_strdup("00000000-0000-0000-0000-000000000000"); | |
437 | |
438 content = g_strdup_printf( | |
439 "Bridge: TCPv1\r\n" | |
440 "Listening: %s\r\n" | |
441 "Nonce: {%s}\r\n" | |
442 "\r\n", | |
443 listening, | |
444 nonce); | |
445 } | |
446 | |
447 send_ok(slpcall, branch, | |
448 "application/x-msnmsgr-transrespbody", content); | |
449 | |
450 g_free(content); | |
451 g_free(nonce); | |
452 } | |
453 else if (!strcmp(type, "application/x-msnmsgr-transrespbody")) | |
454 { | |
455 #if 0 | |
456 char *ip_addrs; | |
457 char *temp; | |
458 char *nonce; | |
459 int port; | |
460 | |
461 nonce = get_token(content, "Nonce: {", "}\r\n"); | |
462 ip_addrs = get_token(content, "IPv4Internal-Addrs: ", "\r\n"); | |
463 | |
464 temp = get_token(content, "IPv4Internal-Port: ", "\r\n"); | |
465 if (temp != NULL) | |
466 port = atoi(temp); | |
467 else | |
468 port = -1; | |
469 g_free(temp); | |
470 | |
471 if (ip_addrs == NULL) | |
472 return; | |
473 | |
474 if (port > 0) | |
475 got_transresp(slpcall, nonce, ip_addrs, port); | |
476 | |
477 g_free(nonce); | |
478 g_free(ip_addrs); | |
479 #endif | |
480 } | |
481 } | |
482 | |
483 static void | |
484 got_ok(MsnSlpCall *slpcall, | |
485 const char *type, const char *content) | |
486 { | |
487 g_return_if_fail(slpcall != NULL); | |
488 g_return_if_fail(type != NULL); | |
489 | |
490 if (!strcmp(type, "application/x-msnmsgr-sessionreqbody")) | |
491 { | |
492 #if 0 | |
493 if (slpcall->type == MSN_SLPCALL_DC) | |
494 { | |
495 /* First let's try a DirectConnection. */ | |
496 | |
497 MsnSlpLink *slplink; | |
498 MsnSlpMessage *slpmsg; | |
499 char *header; | |
500 char *content; | |
501 char *branch; | |
502 | |
503 slplink = slpcall->slplink; | |
504 | |
505 branch = rand_guid(); | |
506 | |
507 content = g_strdup_printf( | |
508 "Bridges: TRUDPv1 TCPv1\r\n" | |
509 "NetID: 0\r\n" | |
510 "Conn-Type: Direct-Connect\r\n" | |
511 "UPnPNat: false\r\n" | |
512 "ICF: false\r\n" | |
513 ); | |
514 | |
515 header = g_strdup_printf("INVITE MSNMSGR:%s MSNSLP/1.0", | |
516 slplink->remote_user); | |
517 | |
518 slpmsg = msn_slp_sipmsg_new(slpcall, 0, header, branch, | |
519 "application/x-msnmsgr-transreqbody", | |
520 content); | |
521 | |
522 #ifdef DEBUG_SLP | |
523 slpmsg->info = "SLP INVITE"; | |
524 slpmsg->text_body = TRUE; | |
525 #endif | |
526 msn_slplink_send_slpmsg(slplink, slpmsg); | |
527 | |
528 g_free(header); | |
529 g_free(content); | |
530 | |
531 g_free(branch); | |
532 } | |
533 else | |
534 { | |
535 msn_slp_call_session_init(slpcall); | |
536 } | |
537 #else | |
538 msn_slp_call_session_init(slpcall); | |
539 #endif | |
540 } | |
541 else if (!strcmp(type, "application/x-msnmsgr-transreqbody")) | |
542 { | |
543 /* Do we get this? */ | |
544 gaim_debug_info("msn", "OK with transreqbody\n"); | |
545 } | |
546 else if (!strcmp(type, "application/x-msnmsgr-transrespbody")) | |
547 { | |
548 #if 0 | |
549 char *ip_addrs; | |
550 char *temp; | |
551 char *nonce; | |
552 int port; | |
553 | |
554 nonce = get_token(content, "Nonce: {", "}\r\n"); | |
555 ip_addrs = get_token(content, "IPv4Internal-Addrs: ", "\r\n"); | |
556 | |
557 temp = get_token(content, "IPv4Internal-Port: ", "\r\n"); | |
558 if (temp != NULL) | |
559 port = atoi(temp); | |
560 else | |
561 port = -1; | |
562 g_free(temp); | |
563 | |
564 if (ip_addrs == NULL) | |
565 return; | |
566 | |
567 if (port > 0) | |
568 got_transresp(slpcall, nonce, ip_addrs, port); | |
569 | |
570 g_free(nonce); | |
571 g_free(ip_addrs); | |
572 #endif | |
573 } | |
574 } | |
575 | |
576 MsnSlpCall * | |
577 msn_slp_sip_recv(MsnSlpLink *slplink, const char *body, gsize len) | |
578 { | |
579 MsnSlpCall *slpcall; | |
580 | |
581 if (!strncmp(body, "INVITE", strlen("INVITE"))) | |
582 { | |
583 char *branch; | |
584 char *content; | |
585 char *content_type; | |
586 | |
587 slpcall = msn_slp_call_new(slplink); | |
588 | |
589 /* From: <msnmsgr:buddy@hotmail.com> */ | |
590 #if 0 | |
591 slpcall->remote_user = get_token(body, "From: <msnmsgr:", ">\r\n"); | |
592 #endif | |
593 | |
594 branch = get_token(body, ";branch={", "}"); | |
595 | |
596 slpcall->id = get_token(body, "Call-ID: {", "}"); | |
597 | |
598 #if 0 | |
599 long content_len = -1; | |
600 | |
601 temp = get_token(body, "Content-Length: ", "\r\n"); | |
602 if (temp != NULL) | |
603 content_len = atoi(temp); | |
604 g_free(temp); | |
605 #endif | |
606 content_type = get_token(body, "Content-Type: ", "\r\n"); | |
607 | |
608 content = get_token(body, "\r\n\r\n", NULL); | |
609 | |
610 got_invite(slpcall, branch, content_type, content); | |
611 | |
612 g_free(content_type); | |
613 g_free(content); | |
614 } | |
615 else if (!strncmp(body, "MSNSLP/1.0 ", strlen("MSNSLP/1.0 "))) | |
616 { | |
617 char *content; | |
618 char *content_type; | |
619 /* Make sure this is "OK" */ | |
620 const char *status = body + strlen("MSNSLP/1.0 "); | |
621 char *call_id; | |
622 | |
623 call_id = get_token(body, "Call-ID: {", "}"); | |
624 slpcall = msn_slplink_find_slp_call(slplink, call_id); | |
625 g_free(call_id); | |
626 | |
627 if (strncmp(status, "200 OK", 6)) | |
628 { | |
629 /* It's not valid. Kill this off. */ | |
630 char temp[32]; | |
631 const char *c; | |
632 | |
633 /* Eww */ | |
634 if ((c = strchr(status, '\r')) || (c = strchr(status, '\n')) || | |
635 (c = strchr(status, '\0'))) | |
636 { | |
637 strncpy(temp, status, c - status); | |
638 temp[c - status] = '\0'; | |
639 } | |
640 | |
641 gaim_debug_error("msn", "Received non-OK result: %s\n", temp); | |
642 | |
643 slpcall->wasted = TRUE; | |
644 | |
645 /* msn_slp_call_destroy(slpcall); */ | |
646 return slpcall; | |
647 } | |
648 | |
649 content_type = get_token(body, "Content-Type: ", "\r\n"); | |
650 | |
651 content = get_token(body, "\r\n\r\n", NULL); | |
652 | |
653 got_ok(slpcall, content_type, content); | |
654 | |
655 g_free(content_type); | |
656 g_free(content); | |
657 } | |
658 else if (!strncmp(body, "BYE", strlen("BYE"))) | |
659 { | |
660 char *call_id; | |
661 | |
662 call_id = get_token(body, "Call-ID: {", "}"); | |
663 slpcall = msn_slplink_find_slp_call(slplink, call_id); | |
664 g_free(call_id); | |
665 | |
666 if (slpcall != NULL) | |
667 slpcall->wasted = TRUE; | |
668 | |
669 /* msn_slp_call_destroy(slpcall); */ | |
670 } | |
671 else | |
672 slpcall = NULL; | |
673 | |
674 return slpcall; | |
675 } | |
676 | |
677 /************************************************************************** | |
678 * Msg Callbacks | |
679 **************************************************************************/ | |
680 | |
681 void | |
682 msn_p2p_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
683 { | |
684 MsnSession *session; | |
685 MsnSlpLink *slplink; | |
686 | |
687 session = cmdproc->servconn->session; | |
688 slplink = msn_session_get_slplink(session, msg->remote_user); | |
689 | |
690 msn_slplink_process_msg(slplink, msg); | |
691 } | |
692 | |
693 void | |
694 got_emoticon(MsnSlpCall *slpcall, | |
695 const char *data, long long size) | |
696 { | |
697 gaim_debug_info("msn", "Got smiley: %s\n", slpcall->data_info); | |
698 | |
699 #if 0 | |
700 GaimConversation *conv; | |
701 GaimConnection *gc = slpsession->swboard->servconn->session->account->gc; | |
702 serv_got_smiley(gc, info, data, size); | |
703 #endif | |
704 } | |
705 | |
706 void | |
707 msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
708 { | |
709 MsnSession *session; | |
710 MsnSlpLink *slplink; | |
711 MsnObject *obj; | |
712 char **tokens; | |
713 char *smile; | |
714 const char *who; | |
715 | |
716 session = cmdproc->servconn->session; | |
717 | |
718 tokens = g_strsplit(msg->body, "\t", 2); | |
719 | |
720 smile = tokens[0]; | |
721 obj = msn_object_new_from_string(gaim_url_decode(tokens[1])); | |
722 | |
723 who = msn_object_get_creator(obj); | |
724 | |
725 slplink = msn_session_get_slplink(session, who); | |
726 | |
727 msn_slplink_request_object(slplink, smile, got_emoticon, obj); | |
728 | |
729 g_strfreev(tokens); | |
730 } | |
731 | |
732 void | |
733 got_user_display(MsnSlpCall *slpcall, | |
734 const char *data, long long size) | |
735 { | |
736 const char *info; | |
737 GaimAccount *account; | |
738 GSList *sl; | |
739 | |
740 info = slpcall->data_info; | |
741 gaim_debug_info("msn", "Got User Display: %s\n", info); | |
742 | |
743 account = slpcall->slplink->session->account; | |
744 | |
745 /* TODO: I think we need better buddy icon core functions. */ | |
746 gaim_buddy_icons_set_for_user(account, slpcall->slplink->remote_user, | |
747 (void *)data, size); | |
748 | |
749 sl = gaim_find_buddies(account, slpcall->slplink->remote_user); | |
750 | |
751 for (; sl != NULL; sl = sl->next) | |
752 { | |
753 GaimBuddy *buddy = (GaimBuddy *)sl->data; | |
754 gaim_blist_node_set_string((GaimBlistNode*)buddy, "icon_checksum", info); | |
755 gaim_blist_save(); | |
756 } | |
757 } | |
758 | |
759 static gboolean | |
760 buddy_icon_cached(GaimConnection *gc, MsnObject *obj) | |
761 { | |
762 GaimAccount *account; | |
763 GaimBuddy *buddy; | |
764 GSList *sl; | |
765 const char *old; | |
766 const char *new; | |
767 | |
768 g_return_val_if_fail(obj != NULL, FALSE); | |
769 | |
770 account = gaim_connection_get_account(gc); | |
771 | |
772 sl = gaim_find_buddies(account, msn_object_get_creator(obj)); | |
773 | |
774 if (sl == NULL) | |
775 { | |
776 return FALSE; | |
777 } | |
778 | |
779 buddy = (GaimBuddy *)sl->data; | |
780 | |
781 old = gaim_blist_node_get_string((GaimBlistNode *)buddy, "icon_checksum"); | |
782 new = msn_object_get_sha1c(obj); | |
783 | |
784 if (new == NULL) | |
785 { | |
786 return FALSE; | |
787 } | |
788 | |
789 if (old != NULL && !strcmp(old, new)) | |
790 return TRUE; | |
791 | |
792 return FALSE; | |
793 } | |
794 | |
795 void | |
796 msn_request_buddy_icon(GaimConnection *gc, const char *passport) | |
797 { | |
798 MsnSession *session; | |
799 MsnSlpLink *slplink; | |
800 MsnUser *user; | |
801 MsnObject *obj; | |
802 const char *info; | |
803 | |
804 session = gc->proto_data; | |
805 | |
806 g_return_if_fail(session->protocol_ver == 9); | |
807 | |
808 slplink = msn_session_get_slplink(session, passport); | |
809 | |
810 user = msn_userlist_find_user(session->userlist, passport); | |
811 | |
812 obj = msn_user_get_object(user); | |
813 | |
814 if (obj == NULL) | |
815 /* It seems the user has not set a msnobject */ | |
816 return; | |
817 | |
818 info = msn_object_get_sha1c(obj); | |
819 | |
820 if (!buddy_icon_cached(gc, obj)) | |
821 msn_slplink_request_object(slplink, info, got_user_display, obj); | |
822 } |