Mercurial > pidgin
annotate src/protocols/msn/slplink.c @ 10284:f776e117c17b
[gaim-migrate @ 11454]
Several MSN memory leaks identified and fixed by Miah Gregory and Felipe
Contreras, plus my own fix for bug 1075347.
As normal, thank them for fixes, blame me for breakages.
Did I mention the new MSN icon? It rocks!
committer: Tailor Script <tailor@pidgin.im>
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Wed, 01 Dec 2004 02:30:47 +0000 |
parents | ecf3ce2e2ab1 |
children | a7b2fd5efcf2 |
rev | line source |
---|---|
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
1 /** |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
2 * @file slplink.c MSNSLP Link support |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
3 * |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
4 * gaim |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
5 * |
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. |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
9 * |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
10 * This program is free software; you can redistribute it and/or modify |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
11 * it under the terms of the GNU General Public License as published by |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
12 * the Free Software Foundation; either version 2 of the License, or |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
13 * (at your option) any later version. |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
14 * |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
15 * This program is distributed in the hope that it will be useful, |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
18 * GNU General Public License for more details. |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
19 * |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
20 * You should have received a copy of the GNU General Public License |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
21 * along with this program; if not, write to the Free Software |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
23 */ |
9193 | 24 #include "msn.h" |
25 #include "slplink.h" | |
26 | |
27 #include "switchboard.h" | |
28 #include "slp.h" | |
29 | |
30 void msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg); | |
31 | |
32 #ifdef DEBUG_SLP_FILES | |
33 static int m_sc = 0; | |
34 static int m_rc = 0; | |
35 | |
36 static void | |
37 debug_msg_to_file(MsnMessage *msg, gboolean send) | |
38 { | |
39 char *tmp; | |
40 char *dir; | |
41 char *pload; | |
42 FILE *tf; | |
43 int c; | |
44 gsize pload_size; | |
45 | |
46 dir = send ? "send" : "recv"; | |
47 c = send ? m_sc++ : m_rc++; | |
48 tmp = g_strdup_printf("%s/msntest/%s/%03d", g_get_home_dir(), dir, c); | |
9219 | 49 tf = fopen(tmp, "wb"); |
9193 | 50 pload = msn_message_gen_payload(msg, &pload_size); |
51 fwrite(pload, 1, pload_size, tf); | |
52 fclose(tf); | |
53 g_free(tmp); | |
54 } | |
55 #endif | |
56 | |
57 MsnSlpLink * | |
58 msn_slplink_new(MsnSession *session, const char *username) | |
59 { | |
60 MsnSlpLink *slplink; | |
61 | |
62 slplink = g_new0(MsnSlpLink, 1); | |
63 | |
64 slplink->session = session; | |
65 slplink->slp_seq_id = rand() % 0xFFFFFF00 + 4; | |
66 | |
67 slplink->local_user = g_strdup(msn_user_get_passport(session->user)); | |
68 slplink->remote_user = g_strdup(username); | |
69 | |
70 slplink->slp_msg_queue = g_queue_new(); | |
71 | |
72 session->slplinks = | |
73 g_list_append(session->slplinks, slplink); | |
74 | |
75 return slplink; | |
76 } | |
77 | |
78 void | |
79 msn_slplink_destroy(MsnSlpLink *slplink) | |
80 { | |
81 MsnSession *session; | |
82 | |
83 session = slplink->session; | |
84 | |
85 if (slplink->local_user != NULL) | |
86 g_free(slplink->local_user); | |
87 | |
88 if (slplink->remote_user != NULL) | |
89 g_free(slplink->remote_user); | |
90 | |
91 if (slplink->directconn != NULL) | |
92 msn_directconn_destroy(slplink->directconn); | |
93 | |
94 session->slplinks = | |
95 g_list_remove(session->slplinks, slplink); | |
96 | |
97 g_free(slplink); | |
98 } | |
99 | |
100 MsnSlpLink * | |
101 msn_session_find_slplink(MsnSession *session, const char *who) | |
102 { | |
103 GList *l; | |
104 | |
105 for (l = session->slplinks; l != NULL; l = l->next) | |
106 { | |
10225 | 107 MsnSlpLink *slplink; |
108 | |
9193 | 109 slplink = l->data; |
110 | |
111 if (!strcmp(slplink->remote_user, who)) | |
112 return slplink; | |
113 } | |
114 | |
115 return NULL; | |
116 } | |
117 | |
118 MsnSlpLink * | |
119 msn_session_get_slplink(MsnSession *session, const char *username) | |
120 { | |
121 MsnSlpLink *slplink; | |
122 | |
123 slplink = msn_session_find_slplink(session, username); | |
124 | |
125 if (slplink == NULL) | |
126 slplink = msn_slplink_new(session, username); | |
127 | |
128 return slplink; | |
129 } | |
130 | |
131 MsnSlpSession * | |
132 msn_slplink_find_slp_session(MsnSlpLink *slplink, long session_id) | |
133 { | |
134 GList *l; | |
135 MsnSlpSession *slpsession; | |
136 | |
137 for (l = slplink->slp_sessions; l != NULL; l = l->next) | |
138 { | |
139 slpsession = l->data; | |
140 | |
141 if (slpsession->id == session_id) | |
142 return slpsession; | |
143 } | |
144 | |
145 return NULL; | |
146 } | |
147 | |
148 MsnSlpCall * | |
149 msn_slplink_find_slp_call(MsnSlpLink *slplink, const char *id) | |
150 { | |
151 GList *l; | |
152 MsnSlpCall *slpcall; | |
153 | |
10107
65e7df286076
[gaim-migrate @ 11139]
Luke Schierer <lschiere@pidgin.im>
parents:
10092
diff
changeset
|
154 if (!id) |
65e7df286076
[gaim-migrate @ 11139]
Luke Schierer <lschiere@pidgin.im>
parents:
10092
diff
changeset
|
155 return NULL; |
65e7df286076
[gaim-migrate @ 11139]
Luke Schierer <lschiere@pidgin.im>
parents:
10092
diff
changeset
|
156 |
9193 | 157 for (l = slplink->slp_calls; l != NULL; l = l->next) |
158 { | |
159 slpcall = l->data; | |
160 | |
10107
65e7df286076
[gaim-migrate @ 11139]
Luke Schierer <lschiere@pidgin.im>
parents:
10092
diff
changeset
|
161 if (slpcall->id && !strcmp(slpcall->id, id)) |
9193 | 162 return slpcall; |
163 } | |
164 | |
165 return NULL; | |
166 } | |
167 | |
168 MsnSlpCall * | |
169 msn_slplink_find_slp_call_with_session_id(MsnSlpLink *slplink, long id) | |
170 { | |
171 GList *l; | |
172 MsnSlpCall *slpcall; | |
173 | |
174 for (l = slplink->slp_calls; l != NULL; l = l->next) | |
175 { | |
176 slpcall = l->data; | |
177 | |
178 if (slpcall->session_id == id) | |
179 return slpcall; | |
180 } | |
181 | |
182 return NULL; | |
183 } | |
184 | |
185 void | |
186 msn_slplink_send_msg(MsnSlpLink *slplink, MsnMessage *msg) | |
187 { | |
188 if (slplink->directconn != NULL) | |
189 { | |
190 msn_directconn_send_msg(slplink->directconn, msg); | |
191 } | |
192 else | |
193 { | |
194 MsnSwitchBoard *swboard; | |
195 | |
10225 | 196 swboard = msn_session_get_swboard(slplink->session, |
197 slplink->remote_user); | |
9193 | 198 |
199 if (swboard == NULL) | |
200 return; | |
201 | |
202 if (!g_queue_is_empty(swboard->im_queue) || | |
203 !swboard->user_joined) | |
204 { | |
205 msn_switchboard_queue_msg(swboard, msg); | |
206 } | |
207 else | |
208 { | |
209 msn_switchboard_send_msg(swboard, msg); | |
210 } | |
211 } | |
212 } | |
213 | |
10225 | 214 /* We have received the message receive ack */ |
9571 | 215 static void |
10225 | 216 msg_ack(void *data) |
9193 | 217 { |
218 MsnSlpMessage *slpmsg; | |
219 long long real_size; | |
220 | |
10225 | 221 slpmsg = data; |
9193 | 222 |
223 real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size; | |
224 | |
225 if (slpmsg->offset < real_size) | |
226 { | |
227 msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); | |
228 } | |
229 else | |
230 { | |
231 /* The whole message has been sent */ | |
232 | |
9246
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
233 if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) |
9193 | 234 { |
9246
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
235 if ((slpmsg->slpcall != NULL) && |
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
236 (slpmsg->slpcall->cb != NULL)) |
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
237 { |
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
238 slpmsg->slpcall->cb(slpmsg->slpcall, NULL, 0); |
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
239 } |
9193 | 240 } |
241 | |
242 msn_slpmsg_destroy(slpmsg); | |
243 } | |
244 } | |
245 | |
246 void | |
247 msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) | |
248 { | |
249 MsnMessage *msg; | |
250 long long real_size; | |
251 size_t len = 0; | |
252 | |
253 msg = slpmsg->msg; | |
254 | |
255 real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size; | |
256 | |
257 if (slpmsg->offset < real_size) | |
258 { | |
259 if (slpmsg->fp) | |
260 { | |
261 char data[1202]; | |
262 len = fread(data, 1, sizeof(data), slpmsg->fp); | |
263 msn_message_set_bin_data(msg, data, len); | |
264 } | |
265 else | |
266 { | |
267 len = slpmsg->size - slpmsg->offset; | |
268 | |
269 if (len > 1202) | |
270 len = 1202; | |
271 | |
272 msn_message_set_bin_data(msg, slpmsg->buffer + slpmsg->offset, len); | |
273 } | |
274 | |
275 msg->msnslp_header.offset = slpmsg->offset; | |
276 msg->msnslp_header.length = len; | |
277 } | |
278 | |
279 #ifdef DEBUG_SLP | |
280 msn_message_show_readable(msg, slpmsg->info, slpmsg->text_body); | |
281 #endif | |
282 | |
283 #ifdef DEBUG_SLP_FILES | |
284 debug_msg_to_file(msg, TRUE); | |
285 #endif | |
286 | |
287 msn_slplink_send_msg(slplink, msg); | |
288 | |
10225 | 289 if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) && (slpmsg->slpcall != NULL)) |
9193 | 290 { |
10225 | 291 if (slpmsg->slpcall->timer) |
292 { | |
293 gaim_timeout_remove(slpmsg->slpcall->timer); | |
294 slpmsg->slpcall->timer = gaim_timeout_add(MSN_SLPCALL_TIMEOUT, | |
295 msn_slp_call_timeout, slpmsg->slpcall); | |
296 } | |
297 | |
298 if (slpmsg->slpcall->progress_cb != NULL) | |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
299 { |
9231
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
300 slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size, |
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
301 len, slpmsg->offset); |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
302 } |
9193 | 303 } |
304 | |
305 slpmsg->offset += len; | |
306 } | |
307 | |
308 void | |
309 msn_slplink_release_msg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) | |
310 { | |
311 MsnMessage *msg; | |
312 | |
313 slpmsg->msg = msg = msn_message_new_msnslp(); | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
314 |
9193 | 315 if (slpmsg->flags == 0x0) |
316 { | |
317 msg->msnslp_header.session_id = slpmsg->session_id; | |
318 msg->msnslp_header.ack_id = rand() % 0xFFFFFF00; | |
319 } | |
320 else if (slpmsg->flags == 0x2) | |
321 { | |
322 msg->msnslp_header.session_id = slpmsg->session_id; | |
323 msg->msnslp_header.ack_id = slpmsg->ack_id; | |
324 msg->msnslp_header.ack_size = slpmsg->ack_size; | |
325 } | |
326 else if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) | |
327 { | |
328 MsnSlpSession *slpsession; | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
329 slpsession = slpmsg->slpsession; |
9193 | 330 |
331 g_return_if_fail(slpsession != NULL); | |
332 msg->msnslp_header.session_id = slpsession->id; | |
333 msg->msnslp_footer.value = slpsession->app_id; | |
334 msg->msnslp_header.ack_id = rand() % 0xFFFFFF00; | |
335 } | |
336 else if (slpmsg->flags == 0x100) | |
337 { | |
338 msg->msnslp_header.ack_id = slpmsg->ack_id; | |
339 msg->msnslp_header.ack_sub_id = slpmsg->ack_sub_id; | |
340 msg->msnslp_header.ack_size = slpmsg->ack_size; | |
341 } | |
342 | |
343 msg->msnslp_header.id = slpmsg->id; | |
344 msg->msnslp_header.flags = slpmsg->flags; | |
345 | |
346 msg->msnslp_header.total_size = slpmsg->size; | |
347 | |
348 msn_message_set_attr(msg, "P2P-Dest", slplink->remote_user); | |
349 | |
10225 | 350 msg->ack_cb = msg_ack; |
9193 | 351 msg->ack_data = slpmsg; |
352 | |
353 msn_slplink_send_msgpart(slplink, slpmsg); | |
10284 | 354 |
355 msn_message_destroy(msg); | |
9193 | 356 } |
357 | |
358 void | |
359 msn_slplink_queue_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) | |
360 { | |
361 slpmsg->id = slplink->slp_seq_id++; | |
362 | |
363 g_queue_push_head(slplink->slp_msg_queue, slpmsg); | |
364 } | |
365 | |
366 void | |
367 msn_slplink_send_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) | |
368 { | |
369 slpmsg->id = slplink->slp_seq_id++; | |
370 | |
371 msn_slplink_release_msg(slplink, slpmsg); | |
372 } | |
373 | |
374 void | |
375 msn_slplink_unleash(MsnSlpLink *slplink) | |
376 { | |
377 MsnSlpMessage *slpmsg; | |
378 | |
379 /* Send the queued msgs in the order they came. */ | |
380 | |
381 while ((slpmsg = g_queue_pop_tail(slplink->slp_msg_queue)) != NULL) | |
382 msn_slplink_release_msg(slplink, slpmsg); | |
383 } | |
384 | |
385 void | |
386 msn_slplink_send_ack(MsnSlpLink *slplink, MsnMessage *msg) | |
387 { | |
388 MsnSlpMessage *slpmsg; | |
389 | |
390 slpmsg = msn_slpmsg_new(slplink); | |
391 | |
392 slpmsg->session_id = msg->msnslp_header.session_id; | |
393 slpmsg->size = msg->msnslp_header.total_size; | |
394 slpmsg->flags = 0x02; | |
395 slpmsg->ack_id = msg->msnslp_header.id; | |
396 slpmsg->ack_sub_id = msg->msnslp_header.ack_id; | |
397 slpmsg->ack_size = msg->msnslp_header.total_size; | |
398 | |
399 #ifdef DEBUG_SLP | |
400 slpmsg->info = "SLP ACK"; | |
401 #endif | |
402 | |
403 msn_slplink_send_slpmsg(slplink, slpmsg); | |
404 } | |
405 | |
9571 | 406 static void |
407 send_file_cb(MsnSlpSession *slpsession) | |
9193 | 408 { |
409 MsnSlpCall *slpcall; | |
410 MsnSlpMessage *slpmsg; | |
411 | |
412 slpcall = slpsession->slpcall; | |
413 slpmsg = msn_slpmsg_new(slpcall->slplink); | |
414 slpmsg->flags = 0x1000030; | |
415 slpmsg->slpsession = slpsession; | |
416 #ifdef DEBUG_SLP | |
417 slpmsg->info = "SLP FILE"; | |
418 #endif | |
419 slpmsg->slpcall = slpcall; | |
420 msn_slpmsg_open_file(slpmsg, gaim_xfer_get_local_filename(slpcall->xfer)); | |
421 | |
422 msn_slplink_send_slpmsg(slpcall->slplink, slpmsg); | |
423 } | |
424 | |
425 void | |
426 msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg) | |
427 { | |
428 MsnSlpMessage *slpmsg; | |
429 const char *data; | |
430 gsize offset; | |
431 gsize len; | |
432 | |
433 #ifdef DEBUG_SLP | |
434 msn_slpmsg_show(msg); | |
435 #endif | |
436 | |
437 #ifdef DEBUG_SLP_FILES | |
438 debug_msg_to_file(msg, FALSE); | |
439 #endif | |
440 | |
441 if (msg->msnslp_header.total_size < msg->msnslp_header.length) | |
442 { | |
443 gaim_debug_error("msn", "This can't be good\n"); | |
444 g_return_if_reached(); | |
445 } | |
446 | |
447 slpmsg = NULL; | |
448 data = msn_message_get_bin_data(msg, &len); | |
449 | |
450 /* | |
451 OVERHEAD! | |
452 if (msg->msnslp_header.length < msg->msnslp_header.total_size) | |
453 */ | |
454 | |
455 offset = msg->msnslp_header.offset; | |
456 | |
457 if (offset == 0) | |
458 { | |
459 slpmsg = msn_slpmsg_new(slplink); | |
460 slpmsg->id = msg->msnslp_header.id; | |
461 slpmsg->session_id = msg->msnslp_header.session_id; | |
462 slpmsg->size = msg->msnslp_header.total_size; | |
463 slpmsg->flags = msg->msnslp_header.flags; | |
464 | |
465 if (slpmsg->session_id) | |
466 { | |
467 if (slpmsg->slpcall == NULL) | |
468 slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id); | |
469 | |
470 if (slpmsg->slpcall != NULL) | |
471 { | |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
472 if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
473 { |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
474 GaimXfer *xfer; |
9193 | 475 |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
476 xfer = slpmsg->slpcall->xfer; |
9193 | 477 |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
478 if (xfer != NULL) |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
479 { |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
480 slpmsg->fp = |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
481 fopen(gaim_xfer_get_local_filename(slpmsg->slpcall->xfer), |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
482 "wb"); |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
483 } |
9193 | 484 } |
485 } | |
486 } | |
10225 | 487 if (!slpmsg->fp && slpmsg->size) |
10092 | 488 { |
489 slpmsg->buffer = g_try_malloc(slpmsg->size); | |
490 if (slpmsg->buffer == NULL) | |
491 { | |
492 gaim_debug_error("msn", "Failed to allocate buffer for slpmsg\n"); | |
493 return; | |
494 } | |
495 } | |
9193 | 496 } |
497 else | |
498 { | |
10092 | 499 slpmsg = msn_slplink_message_find(slplink, msg->msnslp_header.session_id, msg->msnslp_header.id); |
9193 | 500 } |
501 | |
502 if (slpmsg != NULL) | |
503 { | |
504 if (slpmsg->fp) | |
505 { | |
506 /* fseek(slpmsg->fp, offset, SEEK_SET); */ | |
507 len = fwrite(data, 1, len, slpmsg->fp); | |
508 } | |
10225 | 509 else if (slpmsg->size) |
9193 | 510 { |
10092 | 511 if ((offset + len) > slpmsg->size) |
512 { | |
513 gaim_debug_error("msn", "Oversized slpmsg\n"); | |
514 g_return_if_reached(); | |
515 } | |
516 else | |
517 memcpy(slpmsg->buffer + offset, data, len); | |
9193 | 518 } |
519 } | |
520 else | |
521 { | |
522 gaim_debug_error("msn", "Couldn't find slpmsg\n"); | |
523 g_return_if_reached(); | |
524 } | |
525 | |
10225 | 526 if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) && (slpmsg->slpcall != NULL)) |
9193 | 527 { |
10225 | 528 if (slpmsg->slpcall->timer) |
529 { | |
530 gaim_timeout_remove(slpmsg->slpcall->timer); | |
531 slpmsg->slpcall->timer = gaim_timeout_add(MSN_SLPCALL_TIMEOUT, | |
532 msn_slp_call_timeout, slpmsg->slpcall); | |
533 } | |
534 | |
535 if (slpmsg->slpcall->progress_cb != NULL) | |
9231
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
536 { |
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
537 slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size, |
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
538 len, offset); |
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
539 } |
9193 | 540 } |
541 | |
542 #if 0 | |
543 if (slpmsg->buffer == NULL) | |
544 return; | |
545 #endif | |
546 | |
547 if (msg->msnslp_header.offset + msg->msnslp_header.length | |
548 >= msg->msnslp_header.total_size) | |
549 { | |
550 /* All the pieces of the slpmsg have been received */ | |
551 MsnSlpCall *slpcall; | |
552 | |
553 slpcall = msn_slp_process_msg(slplink, slpmsg); | |
554 | |
555 if (slpmsg->flags == 0x100) | |
556 { | |
557 MsnDirectConn *directconn; | |
558 | |
559 directconn = slplink->directconn; | |
560 | |
561 if (!directconn->acked) | |
562 msn_directconn_send_handshake(directconn); | |
563 } | |
564 else if (slpmsg->flags == 0x0 || slpmsg->flags == 0x20 || | |
565 slpmsg->flags == 0x1000030) | |
566 { | |
567 /* Release all the messages and send the ACK */ | |
568 | |
569 msn_slplink_send_ack(slplink, msg); | |
570 msn_slplink_unleash(slplink); | |
571 } | |
572 | |
573 msn_slpmsg_destroy(slpmsg); | |
574 | |
575 if (slpcall != NULL && slpcall->wasted) | |
576 msn_slp_call_destroy(slpcall); | |
577 } | |
578 } | |
579 | |
580 MsnSlpMessage * | |
10092 | 581 msn_slplink_message_find(MsnSlpLink *slplink, long session_id, long id) |
9193 | 582 { |
583 GList *e; | |
584 | |
585 for (e = slplink->slp_msgs; e != NULL; e = e->next) | |
586 { | |
587 MsnSlpMessage *slpmsg = e->data; | |
588 | |
10092 | 589 if ((slpmsg->session_id == session_id) && (slpmsg->id == id)) |
9193 | 590 return slpmsg; |
591 } | |
592 | |
593 return NULL; | |
594 } | |
595 | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
596 typedef struct |
9193 | 597 { |
598 guint32 length; | |
599 guint32 unk1; | |
600 guint32 file_size; | |
601 guint32 unk2; | |
602 guint32 unk3; | |
603 } MsnContextHeader; | |
604 | |
605 #define MAX_FILE_NAME_LEN 0x226 | |
606 | |
9571 | 607 static char * |
10047 | 608 gen_context(const char *file_name, const char *file_path) |
9193 | 609 { |
610 struct stat st; | |
611 gsize size = 0; | |
612 MsnContextHeader header; | |
10047 | 613 gchar *u8 = NULL; |
9193 | 614 gchar *base, *n; |
10047 | 615 gunichar2 *uni = NULL; |
616 glong currentChar = 0; | |
617 glong uni_len = 0; | |
9193 | 618 gsize len; |
619 | |
10088 | 620 if (stat(file_path, &st) == 0) |
9193 | 621 size = st.st_size; |
622 | |
10047 | 623 if(!file_name) { |
624 u8 = gaim_utf8_try_convert(g_basename(file_path)); | |
625 file_name = u8; | |
626 } | |
627 | |
628 uni = g_utf8_to_utf16(file_name, -1, NULL, &uni_len, NULL); | |
629 | |
630 if(u8) { | |
631 g_free(u8); | |
632 file_name = NULL; | |
633 u8 = NULL; | |
634 } | |
9193 | 635 |
636 len = sizeof(MsnContextHeader) + MAX_FILE_NAME_LEN + 4; | |
637 | |
638 header.length = GUINT32_TO_LE(len); | |
639 header.unk1 = GUINT32_TO_LE(2); | |
640 header.file_size = GUINT32_TO_LE(size); | |
641 header.unk2 = GUINT32_TO_LE(0); | |
642 header.unk3 = GUINT32_TO_LE(0); | |
10225 | 643 |
10047 | 644 base = g_malloc(len + 1); |
645 n = base; | |
9193 | 646 |
647 memcpy(n, &header, sizeof(MsnContextHeader)); | |
648 n += sizeof(MsnContextHeader); | |
649 | |
650 memset(n, 0x00, MAX_FILE_NAME_LEN); | |
10047 | 651 for(currentChar = 0; currentChar < uni_len; currentChar++) { |
652 *((gunichar2 *)n + currentChar) = GUINT16_TO_LE(uni[currentChar]); | |
653 } | |
9193 | 654 n += MAX_FILE_NAME_LEN; |
655 | |
656 memset(n, 0xFF, 4); | |
657 n += 4; | |
10225 | 658 |
9193 | 659 g_free(uni); |
660 return gaim_base64_encode(base, len); | |
661 } | |
662 | |
663 void | |
664 msn_slplink_request_ft(MsnSlpLink *slplink, GaimXfer *xfer) | |
665 { | |
666 MsnSlpCall *slpcall; | |
667 char *context; | |
668 const char *fn; | |
10047 | 669 const char *fp; |
9193 | 670 |
10047 | 671 fn = gaim_xfer_get_filename(xfer); |
672 fp = gaim_xfer_get_local_filename(xfer); | |
9193 | 673 |
674 g_return_if_fail(slplink != NULL); | |
10047 | 675 g_return_if_fail(fp != NULL); |
9193 | 676 |
677 slpcall = msn_slp_call_new(slplink); | |
678 msn_slp_call_init(slpcall, MSN_SLPCALL_DC); | |
679 | |
9571 | 680 slpcall->session_init_cb = send_file_cb; |
9715
b030f83693da
[gaim-migrate @ 10576]
Christian Hammond <chipx86@chipx86.com>
parents:
9571
diff
changeset
|
681 slpcall->end_cb = msn_xfer_end_cb; |
9193 | 682 slpcall->progress_cb = msn_xfer_progress_cb; |
9259
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9246
diff
changeset
|
683 slpcall->cb = msn_xfer_completed_cb; |
9193 | 684 slpcall->xfer = xfer; |
685 | |
686 gaim_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel); | |
687 | |
688 xfer->data = slpcall; | |
689 | |
10047 | 690 context = gen_context(fn, fp); |
9193 | 691 |
692 msn_slp_call_invite(slpcall, "5D3E02AB-6190-11D3-BBBB-00C04F795683", 2, | |
693 context); | |
694 | |
695 g_free(context); | |
696 } | |
697 | |
698 void | |
699 msn_slplink_request_object(MsnSlpLink *slplink, | |
700 const char *info, | |
701 MsnSlpCb cb, | |
10225 | 702 MsnSlpEndCb end_cb, |
9193 | 703 const MsnObject *obj) |
704 { | |
705 MsnSlpCall *slpcall; | |
706 char *msnobj_data; | |
707 char *msnobj_base64; | |
708 | |
709 g_return_if_fail(slplink != NULL); | |
9861 | 710 g_return_if_fail(obj != NULL); |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
711 |
9193 | 712 msnobj_data = msn_object_to_string(obj); |
713 msnobj_base64 = gaim_base64_encode(msnobj_data, strlen(msnobj_data)); | |
714 g_free(msnobj_data); | |
715 | |
716 slpcall = msn_slp_call_new(slplink); | |
717 msn_slp_call_init(slpcall, MSN_SLPCALL_ANY); | |
718 | |
719 slpcall->data_info = g_strdup(info); | |
720 slpcall->cb = cb; | |
10225 | 721 slpcall->end_cb = end_cb; |
9193 | 722 |
723 msn_slp_call_invite(slpcall, "A4268EEC-FEC5-49E5-95C3-F126696BDBF6", 1, | |
724 msnobj_base64); | |
725 | |
726 g_free(msnobj_base64); | |
727 } |