Mercurial > pidgin.yaz
annotate src/protocols/msn/slp.c @ 10345:2e01c503aa4f
[gaim-migrate @ 11556]
Patch 1078151 from Felipe Contreras to fix some more MSN bugs:
"User Dislpay messages, and other less used, did not set
an slpcall, so the callback that should not be called,
was called (in some very special cases)."
...
"Here it goes the real real one, as far as I can tell.
Cleaning + organizing + documentation + hard bug fix = big
patch." -- Felipe Contreras
I also fixed drag-and-drop to conversation window file transfers (which
I had broken when I fixed some other dnd thing), made the debug output
of the autoreconnect plugin more useful, and stopped the message
notification plugin notifying you for messages sent by ignored users.
committer: Tailor Script <tailor@pidgin.im>
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Sat, 11 Dec 2004 20:01:58 +0000 |
parents | a7b2fd5efcf2 |
children | e5455f1dc9b6 |
rev | line source |
---|---|
9193 | 1 /** |
2 * @file msnslp.c MSNSLP support | |
3 * | |
4 * gaim | |
5 * | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
6 * Gaim is the legal property of its developers, whose names are too numerous |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
7 * to list here. Please refer to the COPYRIGHT file distributed with this |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
8 * source distribution. |
9193 | 9 * |
10 * This program is free software; you can redistribute it and/or modify | |
11 * it under the terms of the GNU General Public License as published by | |
12 * the Free Software Foundation; either version 2 of the License, or | |
13 * (at your option) any later version. | |
14 * | |
15 * This program is distributed in the hope that it will be useful, | |
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 * GNU General Public License for more details. | |
19 * | |
20 * You should have received a copy of the GNU General Public License | |
21 * along with this program; if not, write to the Free Software | |
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
23 */ | |
24 #include "msn.h" | |
25 #include "slp.h" | |
26 #include "slpcall.h" | |
27 #include "slpmsg.h" | |
28 #include "slpsession.h" | |
29 | |
30 #include "object.h" | |
31 #include "user.h" | |
32 #include "switchboard.h" | |
33 | |
34 /* #include "slplink.h" */ | |
35 /* #include "directconn.h" */ | |
36 | |
37 static void send_ok(MsnSlpCall *slpcall, const char *branch, | |
38 const char *type, const char *content); | |
39 | |
40 static void send_decline(MsnSlpCall *slpcall, const char *branch, | |
41 const char *type, const char *content); | |
42 | |
9860 | 43 void msn_request_user_display(MsnUser *user); |
44 | |
9193 | 45 /************************************************************************** |
46 * Util | |
47 **************************************************************************/ | |
48 | |
49 char * | |
50 get_token(const char *str, const char *start, const char *end) | |
51 { | |
52 const char *c, *c2; | |
53 | |
54 if ((c = strstr(str, start)) == NULL) | |
55 return NULL; | |
56 | |
57 c += strlen(start); | |
58 | |
59 if (end != NULL) | |
60 { | |
61 if ((c2 = strstr(c, end)) == NULL) | |
62 return NULL; | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
63 |
9193 | 64 return g_strndup(c, c2 - c); |
65 } | |
66 else | |
67 { | |
68 /* This has to be changed */ | |
69 return g_strdup(c); | |
70 } | |
71 | |
72 } | |
73 | |
74 /************************************************************************** | |
75 * Xfer | |
76 **************************************************************************/ | |
77 | |
78 static void | |
79 msn_xfer_init(GaimXfer *xfer) | |
80 { | |
81 MsnSlpCall *slpcall; | |
82 /* MsnSlpLink *slplink; */ | |
83 char *content; | |
84 | |
85 gaim_debug_info("msn", "xfer_init\n"); | |
86 | |
87 slpcall = xfer->data; | |
88 | |
89 /* Send Ok */ | |
90 content = g_strdup_printf("SessionID: %lu\r\n\r\n", | |
91 slpcall->session_id); | |
92 | |
93 send_ok(slpcall, slpcall->branch, "application/x-msnmsgr-sessionreqbody", | |
94 content); | |
95 | |
96 g_free(content); | |
97 msn_slplink_unleash(slpcall->slplink); | |
98 } | |
99 | |
100 void | |
101 msn_xfer_cancel(GaimXfer *xfer) | |
102 { | |
103 MsnSlpCall *slpcall; | |
104 char *content; | |
105 | |
9788 | 106 g_return_if_fail(xfer != NULL); |
107 g_return_if_fail(xfer->data != NULL); | |
108 | |
9193 | 109 slpcall = xfer->data; |
110 | |
111 if (gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_LOCAL) | |
112 { | |
113 if (slpcall->started) | |
114 { | |
115 msn_slp_call_close(slpcall); | |
116 } | |
117 else | |
118 { | |
119 content = g_strdup_printf("SessionID: %lu\r\n\r\n", | |
120 slpcall->session_id); | |
121 | |
122 send_decline(slpcall, slpcall->branch, "application/x-msnmsgr-sessionreqbody", | |
123 content); | |
124 | |
125 g_free(content); | |
126 msn_slplink_unleash(slpcall->slplink); | |
127 } | |
128 } | |
129 } | |
130 | |
131 void | |
132 msn_xfer_progress_cb(MsnSlpCall *slpcall, gsize total_length, gsize len, gsize offset) | |
133 { | |
134 GaimXfer *xfer; | |
135 | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
136 xfer = slpcall->xfer; |
9193 | 137 |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9198
diff
changeset
|
138 xfer->bytes_sent = (offset + len); |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9198
diff
changeset
|
139 xfer->bytes_remaining = total_length - (offset + len); |
9193 | 140 |
141 gaim_xfer_update_progress(xfer); | |
142 } | |
143 | |
144 void | |
9259
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
145 msn_xfer_end_cb(MsnSlpCall *slpcall) |
9193 | 146 { |
10225 | 147 if ((gaim_xfer_get_status(slpcall->xfer) != GAIM_XFER_STATUS_DONE) && |
148 (gaim_xfer_get_status(slpcall->xfer) != GAIM_XFER_STATUS_CANCEL_REMOTE) && | |
149 (gaim_xfer_get_status(slpcall->xfer) != GAIM_XFER_STATUS_CANCEL_LOCAL)) | |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9198
diff
changeset
|
150 { |
10226 | 151 gaim_xfer_cancel_remote(slpcall->xfer); |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9198
diff
changeset
|
152 } |
9193 | 153 } |
154 | |
9259
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
155 void |
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
156 msn_xfer_completed_cb(MsnSlpCall *slpcall, const char *body, |
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
157 long long size) |
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
158 { |
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
159 gaim_xfer_set_completed(slpcall->xfer, TRUE); |
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
160 } |
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
161 |
9193 | 162 /************************************************************************** |
163 * SLP Control | |
164 **************************************************************************/ | |
165 | |
166 #if 0 | |
167 static void | |
168 got_transresp(MsnSlpCall *slpcall, const char *nonce, | |
169 const char *ips_str, int port) | |
170 { | |
171 MsnDirectConn *directconn; | |
172 char **ip_addrs, **c; | |
173 | |
174 directconn = msn_directconn_new(slpcall->slplink); | |
175 | |
176 directconn->initial_call = slpcall; | |
177 | |
178 /* msn_directconn_parse_nonce(directconn, nonce); */ | |
179 directconn->nonce = g_strdup(nonce); | |
180 | |
181 ip_addrs = g_strsplit(ips_str, " ", -1); | |
182 | |
183 for (c = ip_addrs; *c != NULL; c++) | |
184 { | |
185 gaim_debug_info("msn", "ip_addr = %s\n", *c); | |
186 if (msn_directconn_connect(directconn, *c, port)) | |
187 break; | |
188 } | |
189 | |
190 g_strfreev(ip_addrs); | |
191 } | |
192 #endif | |
193 | |
194 static void | |
195 send_ok(MsnSlpCall *slpcall, const char *branch, | |
196 const char *type, const char *content) | |
197 { | |
198 MsnSlpLink *slplink; | |
199 MsnSlpMessage *slpmsg; | |
200 | |
201 slplink = slpcall->slplink; | |
202 | |
203 /* 200 OK */ | |
204 slpmsg = msn_slpmsg_sip_new(slpcall, 1, | |
205 "MSNSLP/1.0 200 OK", | |
206 branch, type, content); | |
207 | |
10345 | 208 #ifdef MSN_DEBUG_SLP |
9193 | 209 slpmsg->info = "SLP 200 OK"; |
210 slpmsg->text_body = TRUE; | |
211 #endif | |
212 | |
213 msn_slplink_queue_slpmsg(slplink, slpmsg); | |
214 | |
215 msn_slp_call_session_init(slpcall); | |
216 } | |
217 | |
218 static void | |
219 send_decline(MsnSlpCall *slpcall, const char *branch, | |
220 const char *type, const char *content) | |
221 { | |
222 MsnSlpLink *slplink; | |
223 MsnSlpMessage *slpmsg; | |
224 | |
225 slplink = slpcall->slplink; | |
226 | |
227 /* 603 Decline */ | |
228 slpmsg = msn_slpmsg_sip_new(slpcall, 1, | |
229 "MSNSLP/1.0 603 Decline", | |
230 branch, type, content); | |
231 | |
10345 | 232 #ifdef MSN_DEBUG_SLP |
9193 | 233 slpmsg->info = "SLP 603 Decline"; |
234 slpmsg->text_body = TRUE; | |
235 #endif | |
236 | |
237 msn_slplink_queue_slpmsg(slplink, slpmsg); | |
238 } | |
239 | |
10047 | 240 #define MAX_FILE_NAME_LEN 0x226 |
241 | |
9193 | 242 static void |
243 got_sessionreq(MsnSlpCall *slpcall, const char *branch, | |
244 const char *euf_guid, const char *context) | |
245 { | |
246 if (!strcmp(euf_guid, "A4268EEC-FEC5-49E5-95C3-F126696BDBF6")) | |
247 { | |
248 /* Emoticon or UserDisplay */ | |
249 MsnSlpSession *slpsession; | |
250 MsnSlpLink *slplink; | |
251 MsnSlpMessage *slpmsg; | |
252 MsnObject *obj; | |
253 char *msnobj_data; | |
254 const char *sha1c; | |
255 const char *file_name; | |
256 char *content; | |
10112 | 257 int len; |
9193 | 258 int type; |
259 | |
260 /* Send Ok */ | |
261 content = g_strdup_printf("SessionID: %lu\r\n\r\n", | |
262 slpcall->session_id); | |
263 | |
264 send_ok(slpcall, branch, "application/x-msnmsgr-sessionreqbody", | |
265 content); | |
266 | |
267 g_free(content); | |
268 | |
269 slplink = slpcall->slplink; | |
270 | |
271 gaim_base64_decode(context, &msnobj_data, &len); | |
272 obj = msn_object_new_from_string(msnobj_data); | |
273 type = msn_object_get_type(obj); | |
274 sha1c = msn_object_get_sha1c(obj); | |
275 g_free(msnobj_data); | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
276 |
9193 | 277 if (!(type == MSN_OBJECT_USERTILE)) |
278 { | |
279 gaim_debug_error("msn", "Wrong object?\n"); | |
280 msn_object_destroy(obj); | |
281 g_return_if_reached(); | |
282 } | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
283 |
9193 | 284 file_name = msn_object_get_real_location(obj); |
285 | |
9858 | 286 if (file_name == NULL) |
287 { | |
288 gaim_debug_error("msn", "Wrong object.\n"); | |
289 msn_object_destroy(obj); | |
290 g_return_if_reached(); | |
291 } | |
292 | |
9193 | 293 slpsession = msn_slplink_find_slp_session(slplink, |
9861 | 294 slpcall->session_id); |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
295 |
9193 | 296 /* DATA PREP */ |
297 slpmsg = msn_slpmsg_new(slplink); | |
10345 | 298 slpmsg->slpcall = slpcall; |
9193 | 299 slpmsg->slpsession = slpsession; |
300 slpmsg->session_id = slpsession->id; | |
301 msn_slpmsg_set_body(slpmsg, NULL, 4); | |
10345 | 302 #ifdef MSN_DEBUG_SLP |
9193 | 303 slpmsg->info = "SLP DATA PREP"; |
304 #endif | |
305 msn_slplink_queue_slpmsg(slplink, slpmsg); | |
306 | |
307 /* DATA */ | |
308 slpmsg = msn_slpmsg_new(slplink); | |
10345 | 309 slpmsg->slpcall = slpcall; |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
310 slpmsg->slpsession = slpsession; |
9193 | 311 slpmsg->flags = 0x20; |
10345 | 312 #ifdef MSN_DEBUG_SLP |
9193 | 313 slpmsg->info = "SLP DATA"; |
314 #endif | |
315 msn_slpmsg_open_file(slpmsg, file_name); | |
316 msn_slplink_queue_slpmsg(slplink, slpmsg); | |
317 } | |
318 else if (!strcmp(euf_guid, "5D3E02AB-6190-11D3-BBBB-00C04F795683")) | |
319 { | |
320 /* File Transfer */ | |
321 GaimAccount *account; | |
322 GaimXfer *xfer; | |
323 char *bin; | |
10112 | 324 int bin_len; |
9193 | 325 guint32 file_size; |
326 char *file_name; | |
10047 | 327 gunichar2 *uni_name; |
9193 | 328 |
329 account = slpcall->slplink->session->account; | |
330 | |
9259
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
331 slpcall->cb = msn_xfer_completed_cb; |
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
332 slpcall->end_cb = msn_xfer_end_cb; |
9193 | 333 slpcall->progress_cb = msn_xfer_progress_cb; |
334 slpcall->branch = g_strdup(branch); | |
335 | |
10296 | 336 slpcall->pending = TRUE; |
337 | |
9193 | 338 xfer = gaim_xfer_new(account, GAIM_XFER_RECEIVE, |
339 slpcall->slplink->remote_user); | |
340 | |
341 gaim_base64_decode(context, &bin, &bin_len); | |
9263
70153c759016
[gaim-migrate @ 10062]
Christian Hammond <chipx86@chipx86.com>
parents:
9259
diff
changeset
|
342 file_size = GUINT32_FROM_LE(*((gsize *)bin + 2)); |
10225 | 343 |
10047 | 344 uni_name = (gunichar2 *)(bin + 20); |
345 while(*uni_name != 0 && ((char *)uni_name - (bin + 20)) < MAX_FILE_NAME_LEN) { | |
346 *uni_name = GUINT16_FROM_LE(*uni_name); | |
347 uni_name++; | |
348 } | |
10225 | 349 |
9193 | 350 file_name = g_utf16_to_utf8((const gunichar2 *)(bin + 20), -1, |
351 NULL, NULL, NULL); | |
352 | |
353 g_free(bin); | |
354 | |
355 gaim_xfer_set_filename(xfer, file_name); | |
356 gaim_xfer_set_size(xfer, file_size); | |
357 gaim_xfer_set_init_fnc(xfer, msn_xfer_init); | |
358 gaim_xfer_set_request_denied_fnc(xfer, msn_xfer_cancel); | |
359 gaim_xfer_set_cancel_recv_fnc(xfer, msn_xfer_cancel); | |
360 | |
361 slpcall->xfer = xfer; | |
362 xfer->data = slpcall; | |
363 | |
364 gaim_xfer_request(xfer); | |
365 } | |
366 } | |
367 | |
368 void | |
369 send_bye(MsnSlpCall *slpcall, const char *type) | |
370 { | |
371 MsnSlpLink *slplink; | |
372 MsnSlpMessage *slpmsg; | |
373 char *header; | |
374 | |
375 slplink = slpcall->slplink; | |
376 | |
377 g_return_if_fail(slplink != NULL); | |
378 | |
379 header = g_strdup_printf("BYE MSNMSGR:%s MSNSLP/1.0", | |
380 slplink->local_user); | |
381 | |
382 slpmsg = msn_slpmsg_sip_new(slpcall, 0, header, | |
383 "A0D624A6-6C0C-4283-A9E0-BC97B4B46D32", | |
384 type, | |
385 "\r\n"); | |
386 g_free(header); | |
387 | |
10345 | 388 #ifdef MSN_DEBUG_SLP |
9193 | 389 slpmsg->info = "SLP BYE"; |
390 slpmsg->text_body = TRUE; | |
391 #endif | |
392 | |
393 msn_slplink_queue_slpmsg(slplink, slpmsg); | |
394 } | |
395 | |
396 static void | |
397 got_invite(MsnSlpCall *slpcall, | |
398 const char *branch, const char *type, const char *content) | |
399 { | |
400 MsnSlpLink *slplink; | |
401 | |
402 slplink = slpcall->slplink; | |
403 | |
404 if (!strcmp(type, "application/x-msnmsgr-sessionreqbody")) | |
405 { | |
406 char *euf_guid, *context; | |
407 char *temp; | |
408 | |
409 euf_guid = get_token(content, "EUF-GUID: {", "}\r\n"); | |
410 | |
411 temp = get_token(content, "SessionID: ", "\r\n"); | |
412 if (temp != NULL) | |
413 slpcall->session_id = atoi(temp); | |
414 g_free(temp); | |
415 | |
416 temp = get_token(content, "AppID: ", "\r\n"); | |
417 if (temp != NULL) | |
418 slpcall->app_id = atoi(temp); | |
419 g_free(temp); | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
420 |
9193 | 421 context = get_token(content, "Context: ", "\r\n"); |
422 | |
423 got_sessionreq(slpcall, branch, euf_guid, context); | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
424 |
9193 | 425 g_free(context); |
426 g_free(euf_guid); | |
427 } | |
428 else if (!strcmp(type, "application/x-msnmsgr-transreqbody")) | |
429 { | |
430 /* A direct connection? */ | |
431 | |
432 char *listening, *nonce; | |
433 char *content; | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
434 |
9193 | 435 if (FALSE) |
436 { | |
437 #if 0 | |
438 MsnDirectConn *directconn; | |
439 /* const char *ip_addr; */ | |
440 char *ip_port; | |
441 int port; | |
442 | |
443 /* ip_addr = gaim_prefs_get_string("/core/ft/public_ip"); */ | |
444 ip_port = "5190"; | |
445 listening = "true"; | |
446 nonce = rand_guid(); | |
447 | |
448 directconn = msn_directconn_new(slplink); | |
449 | |
450 /* msn_directconn_parse_nonce(directconn, nonce); */ | |
451 directconn->nonce = g_strdup(nonce); | |
452 | |
453 msn_directconn_listen(directconn); | |
454 | |
455 port = directconn->port; | |
456 | |
457 content = g_strdup_printf( | |
458 "Bridge: TCPv1\r\n" | |
459 "Listening: %s\r\n" | |
460 "Nonce: {%s}\r\n" | |
461 "Ipv4Internal-Addrs: 192.168.0.82\r\n" | |
462 "Ipv4Internal-Port: %d\r\n" | |
463 "\r\n", | |
464 listening, | |
465 nonce, | |
466 port); | |
467 #endif | |
468 } | |
469 else | |
470 { | |
471 listening = "false"; | |
472 nonce = g_strdup("00000000-0000-0000-0000-000000000000"); | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
473 |
9193 | 474 content = g_strdup_printf( |
475 "Bridge: TCPv1\r\n" | |
476 "Listening: %s\r\n" | |
477 "Nonce: {%s}\r\n" | |
478 "\r\n", | |
479 listening, | |
480 nonce); | |
481 } | |
482 | |
483 send_ok(slpcall, branch, | |
484 "application/x-msnmsgr-transrespbody", content); | |
485 | |
486 g_free(content); | |
487 g_free(nonce); | |
488 } | |
489 else if (!strcmp(type, "application/x-msnmsgr-transrespbody")) | |
490 { | |
491 #if 0 | |
492 char *ip_addrs; | |
493 char *temp; | |
494 char *nonce; | |
495 int port; | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
496 |
9193 | 497 nonce = get_token(content, "Nonce: {", "}\r\n"); |
498 ip_addrs = get_token(content, "IPv4Internal-Addrs: ", "\r\n"); | |
499 | |
500 temp = get_token(content, "IPv4Internal-Port: ", "\r\n"); | |
501 if (temp != NULL) | |
502 port = atoi(temp); | |
503 else | |
504 port = -1; | |
505 g_free(temp); | |
506 | |
507 if (ip_addrs == NULL) | |
508 return; | |
509 | |
510 if (port > 0) | |
511 got_transresp(slpcall, nonce, ip_addrs, port); | |
512 | |
513 g_free(nonce); | |
514 g_free(ip_addrs); | |
515 #endif | |
516 } | |
517 } | |
518 | |
519 static void | |
520 got_ok(MsnSlpCall *slpcall, | |
521 const char *type, const char *content) | |
522 { | |
523 g_return_if_fail(slpcall != NULL); | |
524 g_return_if_fail(type != NULL); | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
525 |
9193 | 526 if (!strcmp(type, "application/x-msnmsgr-sessionreqbody")) |
527 { | |
528 #if 0 | |
529 if (slpcall->type == MSN_SLPCALL_DC) | |
530 { | |
531 /* First let's try a DirectConnection. */ | |
532 | |
533 MsnSlpLink *slplink; | |
534 MsnSlpMessage *slpmsg; | |
535 char *header; | |
536 char *content; | |
537 char *branch; | |
538 | |
539 slplink = slpcall->slplink; | |
540 | |
541 branch = rand_guid(); | |
542 | |
543 content = g_strdup_printf( | |
544 "Bridges: TRUDPv1 TCPv1\r\n" | |
545 "NetID: 0\r\n" | |
546 "Conn-Type: Direct-Connect\r\n" | |
547 "UPnPNat: false\r\n" | |
548 "ICF: false\r\n" | |
549 ); | |
550 | |
551 header = g_strdup_printf("INVITE MSNMSGR:%s MSNSLP/1.0", | |
552 slplink->remote_user); | |
553 | |
554 slpmsg = msn_slp_sipmsg_new(slpcall, 0, header, branch, | |
555 "application/x-msnmsgr-transreqbody", | |
556 content); | |
557 | |
10345 | 558 #ifdef MSN_DEBUG_SLP |
9193 | 559 slpmsg->info = "SLP INVITE"; |
560 slpmsg->text_body = TRUE; | |
561 #endif | |
562 msn_slplink_send_slpmsg(slplink, slpmsg); | |
563 | |
564 g_free(header); | |
565 g_free(content); | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
566 |
9193 | 567 g_free(branch); |
568 } | |
569 else | |
570 { | |
571 msn_slp_call_session_init(slpcall); | |
572 } | |
573 #else | |
574 msn_slp_call_session_init(slpcall); | |
575 #endif | |
576 } | |
577 else if (!strcmp(type, "application/x-msnmsgr-transreqbody")) | |
578 { | |
579 /* Do we get this? */ | |
580 gaim_debug_info("msn", "OK with transreqbody\n"); | |
581 } | |
582 else if (!strcmp(type, "application/x-msnmsgr-transrespbody")) | |
583 { | |
584 #if 0 | |
585 char *ip_addrs; | |
586 char *temp; | |
587 char *nonce; | |
588 int port; | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
589 |
9193 | 590 nonce = get_token(content, "Nonce: {", "}\r\n"); |
591 ip_addrs = get_token(content, "IPv4Internal-Addrs: ", "\r\n"); | |
592 | |
593 temp = get_token(content, "IPv4Internal-Port: ", "\r\n"); | |
594 if (temp != NULL) | |
595 port = atoi(temp); | |
596 else | |
597 port = -1; | |
598 g_free(temp); | |
599 | |
600 if (ip_addrs == NULL) | |
601 return; | |
602 | |
603 if (port > 0) | |
604 got_transresp(slpcall, nonce, ip_addrs, port); | |
605 | |
606 g_free(nonce); | |
607 g_free(ip_addrs); | |
608 #endif | |
609 } | |
610 } | |
611 | |
612 MsnSlpCall * | |
613 msn_slp_sip_recv(MsnSlpLink *slplink, const char *body, gsize len) | |
614 { | |
615 MsnSlpCall *slpcall; | |
616 | |
617 if (!strncmp(body, "INVITE", strlen("INVITE"))) | |
618 { | |
619 char *branch; | |
620 char *content; | |
621 char *content_type; | |
622 | |
623 slpcall = msn_slp_call_new(slplink); | |
624 | |
625 /* From: <msnmsgr:buddy@hotmail.com> */ | |
626 #if 0 | |
627 slpcall->remote_user = get_token(body, "From: <msnmsgr:", ">\r\n"); | |
628 #endif | |
629 | |
630 branch = get_token(body, ";branch={", "}"); | |
631 | |
632 slpcall->id = get_token(body, "Call-ID: {", "}"); | |
633 | |
634 #if 0 | |
635 long content_len = -1; | |
636 | |
637 temp = get_token(body, "Content-Length: ", "\r\n"); | |
638 if (temp != NULL) | |
639 content_len = atoi(temp); | |
640 g_free(temp); | |
641 #endif | |
642 content_type = get_token(body, "Content-Type: ", "\r\n"); | |
643 | |
644 content = get_token(body, "\r\n\r\n", NULL); | |
645 | |
646 got_invite(slpcall, branch, content_type, content); | |
647 | |
648 g_free(content_type); | |
649 g_free(content); | |
650 } | |
651 else if (!strncmp(body, "MSNSLP/1.0 ", strlen("MSNSLP/1.0 "))) | |
652 { | |
653 char *content; | |
654 char *content_type; | |
655 /* Make sure this is "OK" */ | |
656 const char *status = body + strlen("MSNSLP/1.0 "); | |
657 char *call_id; | |
658 | |
659 call_id = get_token(body, "Call-ID: {", "}"); | |
660 slpcall = msn_slplink_find_slp_call(slplink, call_id); | |
661 g_free(call_id); | |
662 | |
9231
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
663 g_return_val_if_fail(slpcall != NULL, NULL); |
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
664 |
9193 | 665 if (strncmp(status, "200 OK", 6)) |
666 { | |
667 /* It's not valid. Kill this off. */ | |
668 char temp[32]; | |
669 const char *c; | |
670 | |
671 /* Eww */ | |
672 if ((c = strchr(status, '\r')) || (c = strchr(status, '\n')) || | |
673 (c = strchr(status, '\0'))) | |
674 { | |
9739 | 675 size_t offset = c - status; |
676 if (offset >= sizeof(temp)) | |
677 offset = sizeof(temp) - 1; | |
10225 | 678 |
9739 | 679 strncpy(temp, status, offset); |
680 temp[offset] = '\0'; | |
9193 | 681 } |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
682 |
9193 | 683 gaim_debug_error("msn", "Received non-OK result: %s\n", temp); |
684 | |
685 slpcall->wasted = TRUE; | |
686 | |
687 /* msn_slp_call_destroy(slpcall); */ | |
688 return slpcall; | |
689 } | |
690 | |
691 content_type = get_token(body, "Content-Type: ", "\r\n"); | |
692 | |
693 content = get_token(body, "\r\n\r\n", NULL); | |
694 | |
695 got_ok(slpcall, content_type, content); | |
696 | |
697 g_free(content_type); | |
698 g_free(content); | |
699 } | |
700 else if (!strncmp(body, "BYE", strlen("BYE"))) | |
701 { | |
702 char *call_id; | |
703 | |
704 call_id = get_token(body, "Call-ID: {", "}"); | |
705 slpcall = msn_slplink_find_slp_call(slplink, call_id); | |
706 g_free(call_id); | |
707 | |
708 if (slpcall != NULL) | |
709 slpcall->wasted = TRUE; | |
710 | |
711 /* msn_slp_call_destroy(slpcall); */ | |
712 } | |
713 else | |
714 slpcall = NULL; | |
715 | |
716 return slpcall; | |
717 } | |
718 | |
719 /************************************************************************** | |
720 * Msg Callbacks | |
721 **************************************************************************/ | |
722 | |
723 void | |
724 msn_p2p_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
725 { | |
726 MsnSession *session; | |
727 MsnSlpLink *slplink; | |
728 | |
729 session = cmdproc->servconn->session; | |
730 slplink = msn_session_get_slplink(session, msg->remote_user); | |
731 | |
732 msn_slplink_process_msg(slplink, msg); | |
733 } | |
734 | |
735 void | |
736 got_emoticon(MsnSlpCall *slpcall, | |
737 const char *data, long long size) | |
738 { | |
739 gaim_debug_info("msn", "Got smiley: %s\n", slpcall->data_info); | |
740 | |
741 #if 0 | |
742 GaimConversation *conv; | |
743 GaimConnection *gc = slpsession->swboard->servconn->session->account->gc; | |
744 serv_got_smiley(gc, info, data, size); | |
745 #endif | |
746 } | |
747 | |
748 void | |
749 msn_emoticon_msg(MsnCmdProc *cmdproc, MsnMessage *msg) | |
750 { | |
751 MsnSession *session; | |
752 MsnSlpLink *slplink; | |
753 MsnObject *obj; | |
754 char **tokens; | |
755 char *smile; | |
756 const char *who; | |
757 | |
758 session = cmdproc->servconn->session; | |
759 | |
760 tokens = g_strsplit(msg->body, "\t", 2); | |
761 | |
762 smile = tokens[0]; | |
763 obj = msn_object_new_from_string(gaim_url_decode(tokens[1])); | |
764 | |
765 who = msn_object_get_creator(obj); | |
766 | |
767 slplink = msn_session_get_slplink(session, who); | |
768 | |
10225 | 769 msn_slplink_request_object(slplink, smile, got_emoticon, NULL, obj); |
9193 | 770 |
771 g_strfreev(tokens); | |
772 } | |
773 | |
774 static gboolean | |
775 buddy_icon_cached(GaimConnection *gc, MsnObject *obj) | |
776 { | |
777 GaimAccount *account; | |
778 GaimBuddy *buddy; | |
779 GSList *sl; | |
780 const char *old; | |
781 const char *new; | |
782 | |
783 g_return_val_if_fail(obj != NULL, FALSE); | |
784 | |
785 account = gaim_connection_get_account(gc); | |
786 | |
787 sl = gaim_find_buddies(account, msn_object_get_creator(obj)); | |
788 | |
789 if (sl == NULL) | |
790 return FALSE; | |
791 | |
792 buddy = (GaimBuddy *)sl->data; | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
793 |
9193 | 794 old = gaim_blist_node_get_string((GaimBlistNode *)buddy, "icon_checksum"); |
795 new = msn_object_get_sha1c(obj); | |
796 | |
797 if (new == NULL) | |
798 return FALSE; | |
799 | |
800 if (old != NULL && !strcmp(old, new)) | |
801 return TRUE; | |
802 | |
803 return FALSE; | |
804 } | |
805 | |
806 void | |
9860 | 807 msn_release_buddy_icon_request(MsnUserList *userlist) |
9193 | 808 { |
809 MsnUser *user; | |
9860 | 810 |
10225 | 811 g_return_if_fail(userlist != NULL); |
812 | |
813 gaim_debug_info("msn", "Releasing buddy icon request\n"); | |
814 | |
9860 | 815 while (userlist->buddy_icon_window > 0) |
816 { | |
817 GQueue *queue; | |
818 GaimAccount *account; | |
819 const char *username; | |
820 | |
821 queue = userlist->buddy_icon_requests; | |
822 | |
823 if (g_queue_is_empty(userlist->buddy_icon_requests)) | |
824 break; | |
825 | |
826 user = g_queue_pop_head(queue); | |
9193 | 827 |
9860 | 828 account = userlist->session->account; |
829 username = user->passport; | |
9193 | 830 |
9860 | 831 msn_request_user_display(user); |
832 userlist->buddy_icon_window--; | |
10225 | 833 |
834 gaim_debug_info("msn", "buddy_icon_window=%d\n", | |
835 userlist->buddy_icon_window); | |
9860 | 836 } |
837 } | |
9193 | 838 |
9860 | 839 void |
840 msn_queue_buddy_icon_request(MsnUser *user) | |
841 { | |
842 GaimAccount *account; | |
843 MsnObject *obj; | |
844 GQueue *queue; | |
9193 | 845 |
10225 | 846 g_return_if_fail(user != NULL); |
847 | |
9860 | 848 account = user->userlist->session->account; |
9193 | 849 |
850 obj = msn_user_get_object(user); | |
851 | |
852 if (obj == NULL) | |
9860 | 853 { |
9193 | 854 /* It seems the user has not set a msnobject */ |
9860 | 855 GSList *sl; |
856 | |
857 /* TODO: I think we need better buddy icon core functions. */ | |
858 gaim_buddy_icons_set_for_user(account, user->passport, NULL, -1); | |
859 | |
860 sl = gaim_find_buddies(account, user->passport); | |
861 | |
862 for (; sl != NULL; sl = sl->next) | |
863 { | |
864 GaimBuddy *buddy = (GaimBuddy *)sl->data; | |
865 gaim_blist_node_remove_setting((GaimBlistNode*)buddy, "icon_checksum"); | |
866 } | |
867 | |
9193 | 868 return; |
9860 | 869 } |
870 | |
871 if (!buddy_icon_cached(account->gc, obj)) | |
872 { | |
873 MsnUserList *userlist; | |
874 | |
875 userlist = user->userlist; | |
876 queue = userlist->buddy_icon_requests; | |
877 | |
10225 | 878 gaim_debug_info("msn", "Queueing buddy icon request: %s\n", |
879 user->passport); | |
880 | |
9860 | 881 g_queue_push_tail(queue, user); |
882 | |
10225 | 883 gaim_debug_info("msn", "buddy_icon_window=%d\n", |
884 userlist->buddy_icon_window); | |
885 | |
9860 | 886 if (userlist->buddy_icon_window > 0) |
887 msn_release_buddy_icon_request(userlist); | |
888 } | |
889 } | |
890 | |
891 void | |
892 got_user_display(MsnSlpCall *slpcall, | |
893 const char *data, long long size) | |
894 { | |
10225 | 895 MsnUserList *userlist; |
9860 | 896 const char *info; |
897 GaimAccount *account; | |
898 GSList *sl; | |
899 | |
10225 | 900 g_return_if_fail(slpcall != NULL); |
901 | |
9860 | 902 info = slpcall->data_info; |
903 gaim_debug_info("msn", "Got User Display: %s\n", info); | |
904 | |
10225 | 905 userlist = slpcall->slplink->session->userlist; |
9860 | 906 account = slpcall->slplink->session->account; |
907 | |
908 /* TODO: I think we need better buddy icon core functions. */ | |
909 gaim_buddy_icons_set_for_user(account, slpcall->slplink->remote_user, | |
910 (void *)data, size); | |
911 | |
912 sl = gaim_find_buddies(account, slpcall->slplink->remote_user); | |
913 | |
914 for (; sl != NULL; sl = sl->next) | |
915 { | |
916 GaimBuddy *buddy = (GaimBuddy *)sl->data; | |
917 gaim_blist_node_set_string((GaimBlistNode*)buddy, "icon_checksum", info); | |
918 } | |
919 | |
10225 | 920 #if 0 |
921 /* Free one window slot */ | |
922 userlist->buddy_icon_window++; | |
923 | |
924 gaim_debug_info("msn", "buddy_icon_window=%d\n", | |
925 userlist->buddy_icon_window); | |
926 | |
927 msn_release_buddy_icon_request(userlist); | |
928 #endif | |
929 } | |
930 | |
931 void | |
932 end_user_display(MsnSlpCall *slpcall) | |
933 { | |
934 MsnUserList *userlist; | |
935 | |
936 g_return_if_fail(slpcall != NULL); | |
937 | |
938 gaim_debug_info("msn", "End User Display\n"); | |
939 | |
940 userlist = slpcall->slplink->session->userlist; | |
941 | |
10296 | 942 /* If the session is being destroyed we better stop doing anything. */ |
943 if (slpcall->slplink->session->destroying) | |
944 return; | |
945 | |
10225 | 946 /* Free one window slot */ |
947 userlist->buddy_icon_window++; | |
948 | |
949 gaim_debug_info("msn", "buddy_icon_window=%d\n", | |
950 userlist->buddy_icon_window); | |
951 | |
952 msn_release_buddy_icon_request(userlist); | |
9860 | 953 } |
954 | |
955 void | |
956 msn_request_user_display(MsnUser *user) | |
957 { | |
958 GaimAccount *account; | |
959 MsnSession *session; | |
960 MsnSlpLink *slplink; | |
961 MsnObject *obj; | |
962 const char *info; | |
963 | |
964 session = user->userlist->session; | |
965 account = session->account; | |
966 | |
967 slplink = msn_session_get_slplink(session, user->passport); | |
968 | |
969 obj = msn_user_get_object(user); | |
9193 | 970 |
971 info = msn_object_get_sha1c(obj); | |
972 | |
9860 | 973 if (g_ascii_strcasecmp(user->passport, |
974 gaim_account_get_username(account))) | |
975 { | |
10225 | 976 msn_slplink_request_object(slplink, info, got_user_display, |
977 end_user_display, obj); | |
9860 | 978 } |
979 else | |
980 { | |
10072
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
981 MsnObject *my_obj = NULL; |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
982 const char *filename = NULL; |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
983 gchar *data = NULL; |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
984 gsize len = 0; |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
985 const char *my_info = NULL; |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
986 GSList *sl; |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
987 |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
988 gaim_debug_info("msn", "Requesting our own user display\n"); |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
989 |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
990 my_obj = msn_user_get_object(session->user); |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
991 |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
992 if (my_obj != NULL) |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
993 { |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
994 filename = msn_object_get_real_location(my_obj); |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
995 my_info = msn_object_get_sha1c(my_obj); |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
996 } |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
997 |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
998 if (filename != NULL) |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
999 g_file_get_contents(filename, &data, &len, NULL); |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1000 |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1001 /* TODO: I think we need better buddy icon core functions. */ |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1002 gaim_buddy_icons_set_for_user(account, user->passport, (void *)data, len); |
10225 | 1003 |
10072
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1004 sl = gaim_find_buddies(account, user->passport); |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1005 |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1006 for (; sl != NULL; sl = sl->next) |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1007 { |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1008 GaimBuddy *buddy = (GaimBuddy *)sl->data; |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1009 gaim_blist_node_set_string((GaimBlistNode*)buddy, "icon_checksum", info); |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1010 } |
cf3454eadc22
[gaim-migrate @ 11051]
Luke Schierer <lschiere@pidgin.im>
parents:
10047
diff
changeset
|
1011 |
10225 | 1012 /* Free one window slot */ |
9860 | 1013 session->userlist->buddy_icon_window++; |
10225 | 1014 |
1015 gaim_debug_info("msn", "buddy_icon_window=%d\n", | |
1016 session->userlist->buddy_icon_window); | |
1017 | |
9860 | 1018 msn_release_buddy_icon_request(session->userlist); |
1019 } | |
9193 | 1020 } |