Mercurial > pidgin
annotate src/protocols/msn/slplink.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 | bbf738a0ce7b |
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 | |
10345 | 32 #ifdef MSN_DEBUG_SLP_FILES |
9193 | 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 | |
10296 | 62 g_return_val_if_fail(session != NULL, NULL); |
63 | |
9193 | 64 slplink = g_new0(MsnSlpLink, 1); |
65 | |
66 slplink->session = session; | |
67 slplink->slp_seq_id = rand() % 0xFFFFFF00 + 4; | |
68 | |
69 slplink->local_user = g_strdup(msn_user_get_passport(session->user)); | |
70 slplink->remote_user = g_strdup(username); | |
71 | |
72 slplink->slp_msg_queue = g_queue_new(); | |
73 | |
74 session->slplinks = | |
75 g_list_append(session->slplinks, slplink); | |
76 | |
77 return slplink; | |
78 } | |
79 | |
80 void | |
81 msn_slplink_destroy(MsnSlpLink *slplink) | |
82 { | |
83 MsnSession *session; | |
84 | |
10296 | 85 g_return_if_fail(slplink != NULL); |
86 | |
10345 | 87 if (slplink->swboard != NULL) |
88 slplink->swboard->slplink = NULL; | |
89 | |
9193 | 90 session = slplink->session; |
91 | |
92 if (slplink->local_user != NULL) | |
93 g_free(slplink->local_user); | |
94 | |
95 if (slplink->remote_user != NULL) | |
96 g_free(slplink->remote_user); | |
97 | |
98 if (slplink->directconn != NULL) | |
99 msn_directconn_destroy(slplink->directconn); | |
100 | |
10296 | 101 while (slplink->slp_calls != NULL) |
102 msn_slp_call_destroy(slplink->slp_calls->data); | |
103 | |
9193 | 104 session->slplinks = |
105 g_list_remove(session->slplinks, slplink); | |
106 | |
107 g_free(slplink); | |
108 } | |
109 | |
110 MsnSlpLink * | |
111 msn_session_find_slplink(MsnSession *session, const char *who) | |
112 { | |
113 GList *l; | |
114 | |
115 for (l = session->slplinks; l != NULL; l = l->next) | |
116 { | |
10225 | 117 MsnSlpLink *slplink; |
118 | |
9193 | 119 slplink = l->data; |
120 | |
121 if (!strcmp(slplink->remote_user, who)) | |
122 return slplink; | |
123 } | |
124 | |
125 return NULL; | |
126 } | |
127 | |
128 MsnSlpLink * | |
129 msn_session_get_slplink(MsnSession *session, const char *username) | |
130 { | |
131 MsnSlpLink *slplink; | |
132 | |
133 slplink = msn_session_find_slplink(session, username); | |
134 | |
135 if (slplink == NULL) | |
136 slplink = msn_slplink_new(session, username); | |
137 | |
138 return slplink; | |
139 } | |
140 | |
141 MsnSlpSession * | |
142 msn_slplink_find_slp_session(MsnSlpLink *slplink, long session_id) | |
143 { | |
144 GList *l; | |
145 MsnSlpSession *slpsession; | |
146 | |
147 for (l = slplink->slp_sessions; l != NULL; l = l->next) | |
148 { | |
149 slpsession = l->data; | |
150 | |
151 if (slpsession->id == session_id) | |
152 return slpsession; | |
153 } | |
154 | |
155 return NULL; | |
156 } | |
157 | |
158 MsnSlpCall * | |
159 msn_slplink_find_slp_call(MsnSlpLink *slplink, const char *id) | |
160 { | |
161 GList *l; | |
162 MsnSlpCall *slpcall; | |
163 | |
10107
65e7df286076
[gaim-migrate @ 11139]
Luke Schierer <lschiere@pidgin.im>
parents:
10092
diff
changeset
|
164 if (!id) |
65e7df286076
[gaim-migrate @ 11139]
Luke Schierer <lschiere@pidgin.im>
parents:
10092
diff
changeset
|
165 return NULL; |
65e7df286076
[gaim-migrate @ 11139]
Luke Schierer <lschiere@pidgin.im>
parents:
10092
diff
changeset
|
166 |
9193 | 167 for (l = slplink->slp_calls; l != NULL; l = l->next) |
168 { | |
169 slpcall = l->data; | |
170 | |
10107
65e7df286076
[gaim-migrate @ 11139]
Luke Schierer <lschiere@pidgin.im>
parents:
10092
diff
changeset
|
171 if (slpcall->id && !strcmp(slpcall->id, id)) |
9193 | 172 return slpcall; |
173 } | |
174 | |
175 return NULL; | |
176 } | |
177 | |
178 MsnSlpCall * | |
179 msn_slplink_find_slp_call_with_session_id(MsnSlpLink *slplink, long id) | |
180 { | |
181 GList *l; | |
182 MsnSlpCall *slpcall; | |
183 | |
184 for (l = slplink->slp_calls; l != NULL; l = l->next) | |
185 { | |
186 slpcall = l->data; | |
187 | |
188 if (slpcall->session_id == id) | |
189 return slpcall; | |
190 } | |
191 | |
192 return NULL; | |
193 } | |
194 | |
195 void | |
196 msn_slplink_send_msg(MsnSlpLink *slplink, MsnMessage *msg) | |
197 { | |
198 if (slplink->directconn != NULL) | |
199 { | |
200 msn_directconn_send_msg(slplink->directconn, msg); | |
201 } | |
202 else | |
203 { | |
10345 | 204 if (slplink->swboard == NULL) |
205 { | |
206 slplink->swboard = msn_session_get_swboard(slplink->session, | |
207 slplink->remote_user); | |
9193 | 208 |
10345 | 209 if (slplink->swboard == NULL) |
210 return; | |
9193 | 211 |
10345 | 212 /* If swboard is destroyed we will too */ |
213 slplink->swboard->slplink = slplink; | |
214 } | |
9193 | 215 |
10345 | 216 if (!g_queue_is_empty(slplink->swboard->im_queue) || |
217 slplink->swboard->empty) | |
9193 | 218 { |
10345 | 219 msn_switchboard_queue_msg(slplink->swboard, msg); |
9193 | 220 } |
221 else | |
222 { | |
10345 | 223 msn_switchboard_send_msg(slplink->swboard, msg); |
9193 | 224 } |
225 } | |
226 } | |
227 | |
10345 | 228 /* We have received the message ack */ |
9571 | 229 static void |
10345 | 230 msg_ack(MsnMessage *msg, void *data) |
9193 | 231 { |
232 MsnSlpMessage *slpmsg; | |
233 long long real_size; | |
234 | |
10225 | 235 slpmsg = data; |
9193 | 236 |
237 real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size; | |
238 | |
10345 | 239 slpmsg->offset += msg->msnslp_header.length; |
240 | |
9193 | 241 if (slpmsg->offset < real_size) |
242 { | |
243 msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); | |
244 } | |
245 else | |
246 { | |
247 /* The whole message has been sent */ | |
248 | |
9246
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
249 if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) |
9193 | 250 { |
9246
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
251 if ((slpmsg->slpcall != NULL) && |
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
252 (slpmsg->slpcall->cb != NULL)) |
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
253 { |
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
254 slpmsg->slpcall->cb(slpmsg->slpcall, NULL, 0); |
e20af87d8721
[gaim-migrate @ 10045]
Christian Hammond <chipx86@chipx86.com>
parents:
9231
diff
changeset
|
255 } |
9193 | 256 } |
10345 | 257 } |
9193 | 258 |
10345 | 259 slpmsg->msgs = g_list_remove(slpmsg->msgs, msg); |
260 } | |
261 | |
262 /* We have received the message nak. */ | |
263 static void | |
264 msg_nak(MsnMessage *msg, void *data) | |
265 { | |
266 MsnSlpMessage *slpmsg; | |
267 | |
268 slpmsg = data; | |
269 | |
270 msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); | |
271 | |
272 slpmsg->msgs = g_list_remove(slpmsg->msgs, msg); | |
9193 | 273 } |
274 | |
275 void | |
276 msn_slplink_send_msgpart(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) | |
277 { | |
278 MsnMessage *msg; | |
279 long long real_size; | |
280 size_t len = 0; | |
281 | |
10345 | 282 /* Maybe we will want to create a new msg for this slpmsg instead of |
283 * reusing the same one all the time. */ | |
9193 | 284 msg = slpmsg->msg; |
285 | |
286 real_size = (slpmsg->flags == 0x2) ? 0 : slpmsg->size; | |
287 | |
288 if (slpmsg->offset < real_size) | |
289 { | |
290 if (slpmsg->fp) | |
291 { | |
292 char data[1202]; | |
293 len = fread(data, 1, sizeof(data), slpmsg->fp); | |
294 msn_message_set_bin_data(msg, data, len); | |
295 } | |
296 else | |
297 { | |
298 len = slpmsg->size - slpmsg->offset; | |
299 | |
300 if (len > 1202) | |
301 len = 1202; | |
302 | |
303 msn_message_set_bin_data(msg, slpmsg->buffer + slpmsg->offset, len); | |
304 } | |
305 | |
306 msg->msnslp_header.offset = slpmsg->offset; | |
307 msg->msnslp_header.length = len; | |
308 } | |
309 | |
10345 | 310 #ifdef MSN_DEBUG_SLP |
9193 | 311 msn_message_show_readable(msg, slpmsg->info, slpmsg->text_body); |
312 #endif | |
313 | |
10345 | 314 #ifdef MSN_DEBUG_SLP_FILES |
9193 | 315 debug_msg_to_file(msg, TRUE); |
316 #endif | |
317 | |
10345 | 318 slpmsg->msgs = |
319 g_list_append(slpmsg->msgs, msg); | |
9193 | 320 msn_slplink_send_msg(slplink, msg); |
321 | |
10345 | 322 if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) && |
323 (slpmsg->slpcall != NULL)) | |
9193 | 324 { |
10296 | 325 slpmsg->slpcall->progress = TRUE; |
10225 | 326 |
327 if (slpmsg->slpcall->progress_cb != NULL) | |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
328 { |
9231
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
329 slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size, |
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
330 len, slpmsg->offset); |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
331 } |
9193 | 332 } |
333 | |
10345 | 334 /* slpmsg->offset += len; */ |
9193 | 335 } |
336 | |
337 void | |
10345 | 338 msn_slplink_release_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) |
9193 | 339 { |
340 MsnMessage *msg; | |
341 | |
342 slpmsg->msg = msg = msn_message_new_msnslp(); | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
343 |
9193 | 344 if (slpmsg->flags == 0x0) |
345 { | |
346 msg->msnslp_header.session_id = slpmsg->session_id; | |
347 msg->msnslp_header.ack_id = rand() % 0xFFFFFF00; | |
348 } | |
349 else if (slpmsg->flags == 0x2) | |
350 { | |
351 msg->msnslp_header.session_id = slpmsg->session_id; | |
352 msg->msnslp_header.ack_id = slpmsg->ack_id; | |
353 msg->msnslp_header.ack_size = slpmsg->ack_size; | |
354 } | |
355 else if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) | |
356 { | |
357 MsnSlpSession *slpsession; | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
358 slpsession = slpmsg->slpsession; |
9193 | 359 |
360 g_return_if_fail(slpsession != NULL); | |
361 msg->msnslp_header.session_id = slpsession->id; | |
362 msg->msnslp_footer.value = slpsession->app_id; | |
363 msg->msnslp_header.ack_id = rand() % 0xFFFFFF00; | |
364 } | |
365 else if (slpmsg->flags == 0x100) | |
366 { | |
367 msg->msnslp_header.ack_id = slpmsg->ack_id; | |
368 msg->msnslp_header.ack_sub_id = slpmsg->ack_sub_id; | |
369 msg->msnslp_header.ack_size = slpmsg->ack_size; | |
370 } | |
371 | |
372 msg->msnslp_header.id = slpmsg->id; | |
373 msg->msnslp_header.flags = slpmsg->flags; | |
374 | |
375 msg->msnslp_header.total_size = slpmsg->size; | |
376 | |
377 msn_message_set_attr(msg, "P2P-Dest", slplink->remote_user); | |
378 | |
10225 | 379 msg->ack_cb = msg_ack; |
10345 | 380 msg->nak_cb = msg_nak; |
9193 | 381 msg->ack_data = slpmsg; |
382 | |
383 msn_slplink_send_msgpart(slplink, slpmsg); | |
10284 | 384 |
385 msn_message_destroy(msg); | |
9193 | 386 } |
387 | |
388 void | |
389 msn_slplink_queue_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) | |
390 { | |
391 slpmsg->id = slplink->slp_seq_id++; | |
392 | |
393 g_queue_push_head(slplink->slp_msg_queue, slpmsg); | |
394 } | |
395 | |
396 void | |
397 msn_slplink_send_slpmsg(MsnSlpLink *slplink, MsnSlpMessage *slpmsg) | |
398 { | |
399 slpmsg->id = slplink->slp_seq_id++; | |
400 | |
10345 | 401 msn_slplink_release_slpmsg(slplink, slpmsg); |
9193 | 402 } |
403 | |
404 void | |
405 msn_slplink_unleash(MsnSlpLink *slplink) | |
406 { | |
407 MsnSlpMessage *slpmsg; | |
408 | |
409 /* Send the queued msgs in the order they came. */ | |
410 | |
411 while ((slpmsg = g_queue_pop_tail(slplink->slp_msg_queue)) != NULL) | |
10345 | 412 { |
413 msn_slplink_release_slpmsg(slplink, slpmsg); | |
414 } | |
9193 | 415 } |
416 | |
417 void | |
418 msn_slplink_send_ack(MsnSlpLink *slplink, MsnMessage *msg) | |
419 { | |
420 MsnSlpMessage *slpmsg; | |
421 | |
422 slpmsg = msn_slpmsg_new(slplink); | |
423 | |
424 slpmsg->session_id = msg->msnslp_header.session_id; | |
425 slpmsg->size = msg->msnslp_header.total_size; | |
426 slpmsg->flags = 0x02; | |
427 slpmsg->ack_id = msg->msnslp_header.id; | |
428 slpmsg->ack_sub_id = msg->msnslp_header.ack_id; | |
429 slpmsg->ack_size = msg->msnslp_header.total_size; | |
430 | |
10345 | 431 #ifdef MSN_DEBUG_SLP |
9193 | 432 slpmsg->info = "SLP ACK"; |
433 #endif | |
434 | |
435 msn_slplink_send_slpmsg(slplink, slpmsg); | |
436 } | |
437 | |
9571 | 438 static void |
439 send_file_cb(MsnSlpSession *slpsession) | |
9193 | 440 { |
441 MsnSlpCall *slpcall; | |
442 MsnSlpMessage *slpmsg; | |
443 | |
444 slpcall = slpsession->slpcall; | |
445 slpmsg = msn_slpmsg_new(slpcall->slplink); | |
10345 | 446 slpmsg->slpcall = slpcall; |
9193 | 447 slpmsg->flags = 0x1000030; |
448 slpmsg->slpsession = slpsession; | |
10345 | 449 #ifdef MSN_DEBUG_SLP |
9193 | 450 slpmsg->info = "SLP FILE"; |
451 #endif | |
452 msn_slpmsg_open_file(slpmsg, gaim_xfer_get_local_filename(slpcall->xfer)); | |
453 | |
454 msn_slplink_send_slpmsg(slpcall->slplink, slpmsg); | |
455 } | |
456 | |
457 void | |
458 msn_slplink_process_msg(MsnSlpLink *slplink, MsnMessage *msg) | |
459 { | |
460 MsnSlpMessage *slpmsg; | |
461 const char *data; | |
462 gsize offset; | |
463 gsize len; | |
464 | |
10345 | 465 #ifdef MSN_DEBUG_SLP |
9193 | 466 msn_slpmsg_show(msg); |
467 #endif | |
468 | |
10345 | 469 #ifdef MSN_DEBUG_SLP_FILES |
9193 | 470 debug_msg_to_file(msg, FALSE); |
471 #endif | |
472 | |
473 if (msg->msnslp_header.total_size < msg->msnslp_header.length) | |
474 { | |
475 gaim_debug_error("msn", "This can't be good\n"); | |
476 g_return_if_reached(); | |
477 } | |
478 | |
479 slpmsg = NULL; | |
480 data = msn_message_get_bin_data(msg, &len); | |
481 | |
482 /* | |
483 OVERHEAD! | |
484 if (msg->msnslp_header.length < msg->msnslp_header.total_size) | |
485 */ | |
486 | |
487 offset = msg->msnslp_header.offset; | |
488 | |
489 if (offset == 0) | |
490 { | |
491 slpmsg = msn_slpmsg_new(slplink); | |
492 slpmsg->id = msg->msnslp_header.id; | |
493 slpmsg->session_id = msg->msnslp_header.session_id; | |
494 slpmsg->size = msg->msnslp_header.total_size; | |
495 slpmsg->flags = msg->msnslp_header.flags; | |
496 | |
497 if (slpmsg->session_id) | |
498 { | |
499 if (slpmsg->slpcall == NULL) | |
500 slpmsg->slpcall = msn_slplink_find_slp_call_with_session_id(slplink, slpmsg->session_id); | |
501 | |
502 if (slpmsg->slpcall != NULL) | |
503 { | |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
504 if (slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
505 { |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
506 GaimXfer *xfer; |
9193 | 507 |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
508 xfer = slpmsg->slpcall->xfer; |
9193 | 509 |
9226
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
510 if (xfer != NULL) |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
511 { |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
512 slpmsg->fp = |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
513 fopen(gaim_xfer_get_local_filename(slpmsg->slpcall->xfer), |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
514 "wb"); |
7a00289f2ef1
[gaim-migrate @ 10022]
Christian Hammond <chipx86@chipx86.com>
parents:
9219
diff
changeset
|
515 } |
9193 | 516 } |
517 } | |
518 } | |
10225 | 519 if (!slpmsg->fp && slpmsg->size) |
10092 | 520 { |
521 slpmsg->buffer = g_try_malloc(slpmsg->size); | |
522 if (slpmsg->buffer == NULL) | |
523 { | |
524 gaim_debug_error("msn", "Failed to allocate buffer for slpmsg\n"); | |
525 return; | |
526 } | |
527 } | |
9193 | 528 } |
529 else | |
530 { | |
10092 | 531 slpmsg = msn_slplink_message_find(slplink, msg->msnslp_header.session_id, msg->msnslp_header.id); |
9193 | 532 } |
533 | |
10345 | 534 if (slpmsg == NULL) |
9193 | 535 { |
10345 | 536 /* Probably the transfer was canceled */ |
9193 | 537 gaim_debug_error("msn", "Couldn't find slpmsg\n"); |
10345 | 538 return; |
9193 | 539 } |
540 | |
10345 | 541 if (slpmsg->fp) |
542 { | |
543 /* fseek(slpmsg->fp, offset, SEEK_SET); */ | |
544 len = fwrite(data, 1, len, slpmsg->fp); | |
545 } | |
546 else if (slpmsg->size) | |
547 { | |
548 if ((offset + len) > slpmsg->size) | |
549 { | |
550 gaim_debug_error("msn", "Oversized slpmsg\n"); | |
551 g_return_if_reached(); | |
552 } | |
553 else | |
554 memcpy(slpmsg->buffer + offset, data, len); | |
555 } | |
556 | |
557 if ((slpmsg->flags == 0x20 || slpmsg->flags == 0x1000030) && | |
558 (slpmsg->slpcall != NULL)) | |
9193 | 559 { |
10296 | 560 slpmsg->slpcall->progress = TRUE; |
10225 | 561 |
562 if (slpmsg->slpcall->progress_cb != NULL) | |
9231
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
563 { |
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
564 slpmsg->slpcall->progress_cb(slpmsg->slpcall, slpmsg->size, |
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
565 len, offset); |
ac8790437abe
[gaim-migrate @ 10027]
Christian Hammond <chipx86@chipx86.com>
parents:
9226
diff
changeset
|
566 } |
9193 | 567 } |
568 | |
569 #if 0 | |
570 if (slpmsg->buffer == NULL) | |
571 return; | |
572 #endif | |
573 | |
574 if (msg->msnslp_header.offset + msg->msnslp_header.length | |
575 >= msg->msnslp_header.total_size) | |
576 { | |
577 /* All the pieces of the slpmsg have been received */ | |
578 MsnSlpCall *slpcall; | |
579 | |
580 slpcall = msn_slp_process_msg(slplink, slpmsg); | |
581 | |
582 if (slpmsg->flags == 0x100) | |
583 { | |
584 MsnDirectConn *directconn; | |
585 | |
586 directconn = slplink->directconn; | |
587 | |
588 if (!directconn->acked) | |
589 msn_directconn_send_handshake(directconn); | |
590 } | |
591 else if (slpmsg->flags == 0x0 || slpmsg->flags == 0x20 || | |
592 slpmsg->flags == 0x1000030) | |
593 { | |
594 /* Release all the messages and send the ACK */ | |
595 | |
596 msn_slplink_send_ack(slplink, msg); | |
597 msn_slplink_unleash(slplink); | |
598 } | |
599 | |
600 msn_slpmsg_destroy(slpmsg); | |
601 | |
602 if (slpcall != NULL && slpcall->wasted) | |
603 msn_slp_call_destroy(slpcall); | |
604 } | |
605 } | |
606 | |
607 MsnSlpMessage * | |
10092 | 608 msn_slplink_message_find(MsnSlpLink *slplink, long session_id, long id) |
9193 | 609 { |
610 GList *e; | |
611 | |
612 for (e = slplink->slp_msgs; e != NULL; e = e->next) | |
613 { | |
614 MsnSlpMessage *slpmsg = e->data; | |
615 | |
10092 | 616 if ((slpmsg->session_id == session_id) && (slpmsg->id == id)) |
9193 | 617 return slpmsg; |
618 } | |
619 | |
620 return NULL; | |
621 } | |
622 | |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
623 typedef struct |
9193 | 624 { |
625 guint32 length; | |
626 guint32 unk1; | |
627 guint32 file_size; | |
628 guint32 unk2; | |
629 guint32 unk3; | |
630 } MsnContextHeader; | |
631 | |
632 #define MAX_FILE_NAME_LEN 0x226 | |
633 | |
9571 | 634 static char * |
10047 | 635 gen_context(const char *file_name, const char *file_path) |
9193 | 636 { |
637 struct stat st; | |
638 gsize size = 0; | |
639 MsnContextHeader header; | |
10047 | 640 gchar *u8 = NULL; |
9193 | 641 gchar *base, *n; |
10047 | 642 gunichar2 *uni = NULL; |
643 glong currentChar = 0; | |
644 glong uni_len = 0; | |
9193 | 645 gsize len; |
646 | |
10088 | 647 if (stat(file_path, &st) == 0) |
9193 | 648 size = st.st_size; |
649 | |
10047 | 650 if(!file_name) { |
651 u8 = gaim_utf8_try_convert(g_basename(file_path)); | |
652 file_name = u8; | |
653 } | |
654 | |
655 uni = g_utf8_to_utf16(file_name, -1, NULL, &uni_len, NULL); | |
656 | |
657 if(u8) { | |
658 g_free(u8); | |
659 file_name = NULL; | |
660 u8 = NULL; | |
661 } | |
9193 | 662 |
663 len = sizeof(MsnContextHeader) + MAX_FILE_NAME_LEN + 4; | |
664 | |
665 header.length = GUINT32_TO_LE(len); | |
666 header.unk1 = GUINT32_TO_LE(2); | |
667 header.file_size = GUINT32_TO_LE(size); | |
668 header.unk2 = GUINT32_TO_LE(0); | |
669 header.unk3 = GUINT32_TO_LE(0); | |
10225 | 670 |
10047 | 671 base = g_malloc(len + 1); |
672 n = base; | |
9193 | 673 |
674 memcpy(n, &header, sizeof(MsnContextHeader)); | |
675 n += sizeof(MsnContextHeader); | |
676 | |
677 memset(n, 0x00, MAX_FILE_NAME_LEN); | |
10047 | 678 for(currentChar = 0; currentChar < uni_len; currentChar++) { |
679 *((gunichar2 *)n + currentChar) = GUINT16_TO_LE(uni[currentChar]); | |
680 } | |
9193 | 681 n += MAX_FILE_NAME_LEN; |
682 | |
683 memset(n, 0xFF, 4); | |
684 n += 4; | |
10225 | 685 |
9193 | 686 g_free(uni); |
687 return gaim_base64_encode(base, len); | |
688 } | |
689 | |
690 void | |
691 msn_slplink_request_ft(MsnSlpLink *slplink, GaimXfer *xfer) | |
692 { | |
693 MsnSlpCall *slpcall; | |
694 char *context; | |
695 const char *fn; | |
10047 | 696 const char *fp; |
9193 | 697 |
10047 | 698 fn = gaim_xfer_get_filename(xfer); |
699 fp = gaim_xfer_get_local_filename(xfer); | |
9193 | 700 |
701 g_return_if_fail(slplink != NULL); | |
10047 | 702 g_return_if_fail(fp != NULL); |
9193 | 703 |
704 slpcall = msn_slp_call_new(slplink); | |
705 msn_slp_call_init(slpcall, MSN_SLPCALL_DC); | |
706 | |
9571 | 707 slpcall->session_init_cb = send_file_cb; |
9715
b030f83693da
[gaim-migrate @ 10576]
Christian Hammond <chipx86@chipx86.com>
parents:
9571
diff
changeset
|
708 slpcall->end_cb = msn_xfer_end_cb; |
9193 | 709 slpcall->progress_cb = msn_xfer_progress_cb; |
9259
f5f7482678d2
[gaim-migrate @ 10058]
Christian Hammond <chipx86@chipx86.com>
parents:
9246
diff
changeset
|
710 slpcall->cb = msn_xfer_completed_cb; |
9193 | 711 slpcall->xfer = xfer; |
712 | |
10296 | 713 slpcall->pending = TRUE; |
714 | |
9193 | 715 gaim_xfer_set_cancel_send_fnc(xfer, msn_xfer_cancel); |
716 | |
717 xfer->data = slpcall; | |
718 | |
10047 | 719 context = gen_context(fn, fp); |
9193 | 720 |
721 msn_slp_call_invite(slpcall, "5D3E02AB-6190-11D3-BBBB-00C04F795683", 2, | |
722 context); | |
723 | |
724 g_free(context); | |
725 } | |
726 | |
727 void | |
728 msn_slplink_request_object(MsnSlpLink *slplink, | |
729 const char *info, | |
730 MsnSlpCb cb, | |
10225 | 731 MsnSlpEndCb end_cb, |
9193 | 732 const MsnObject *obj) |
733 { | |
734 MsnSlpCall *slpcall; | |
735 char *msnobj_data; | |
736 char *msnobj_base64; | |
737 | |
738 g_return_if_fail(slplink != NULL); | |
9861 | 739 g_return_if_fail(obj != NULL); |
9198
ab6636c5a136
[gaim-migrate @ 9993]
Christian Hammond <chipx86@chipx86.com>
parents:
9193
diff
changeset
|
740 |
9193 | 741 msnobj_data = msn_object_to_string(obj); |
742 msnobj_base64 = gaim_base64_encode(msnobj_data, strlen(msnobj_data)); | |
743 g_free(msnobj_data); | |
744 | |
745 slpcall = msn_slp_call_new(slplink); | |
746 msn_slp_call_init(slpcall, MSN_SLPCALL_ANY); | |
747 | |
748 slpcall->data_info = g_strdup(info); | |
749 slpcall->cb = cb; | |
10225 | 750 slpcall->end_cb = end_cb; |
9193 | 751 |
752 msn_slp_call_invite(slpcall, "A4268EEC-FEC5-49E5-95C3-F126696BDBF6", 1, | |
753 msnobj_base64); | |
754 | |
755 g_free(msnobj_base64); | |
756 } |