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