Mercurial > pidgin.yaz
annotate libgaim/ft.c @ 14837:118fd0dc5b6e
[gaim-migrate @ 17606]
Add a "handle" parameter to gaim_proxy_connect(). It seemed like
people thought this was a good idea. You can still cancel
each gaim_proxy_connect() individually, if needed. I passed in
NULL for the handle in most places. It might be better to pass
in the gc in more places, but these changes do no harm, and they
should help some Yahoo! things, and I wanted to get the API change in.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sat, 28 Oct 2006 20:04:03 +0000 |
parents | 2f0b4d0de5bb |
children | dff16b654f14 |
rev | line source |
---|---|
14192 | 1 /** |
2 * @file ft.c File Transfer API | |
3 * | |
4 * gaim | |
5 * | |
6 * Gaim is the legal property of its developers, whose names are too numerous | |
7 * to list here. Please refer to the COPYRIGHT file distributed with this | |
8 * source distribution. | |
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 */ | |
25 #include "internal.h" | |
26 #include "ft.h" | |
27 #include "network.h" | |
28 #include "notify.h" | |
29 #include "prefs.h" | |
30 #include "proxy.h" | |
31 #include "request.h" | |
32 #include "util.h" | |
33 | |
34 static GaimXferUiOps *xfer_ui_ops = NULL; | |
35 | |
36 GaimXfer * | |
37 gaim_xfer_new(GaimAccount *account, GaimXferType type, const char *who) | |
38 { | |
39 GaimXfer *xfer; | |
40 GaimXferUiOps *ui_ops; | |
41 | |
42 g_return_val_if_fail(type != GAIM_XFER_UNKNOWN, NULL); | |
43 g_return_val_if_fail(account != NULL, NULL); | |
44 g_return_val_if_fail(who != NULL, NULL); | |
45 | |
46 xfer = g_new0(GaimXfer, 1); | |
47 | |
48 xfer->ref = 1; | |
49 xfer->type = type; | |
50 xfer->account = account; | |
51 xfer->who = g_strdup(who); | |
52 xfer->ui_ops = gaim_xfers_get_ui_ops(); | |
53 xfer->message = NULL; | |
54 | |
55 ui_ops = gaim_xfer_get_ui_ops(xfer); | |
56 | |
57 if (ui_ops != NULL && ui_ops->new_xfer != NULL) | |
58 ui_ops->new_xfer(xfer); | |
59 | |
60 return xfer; | |
61 } | |
62 | |
63 static void | |
64 gaim_xfer_destroy(GaimXfer *xfer) | |
65 { | |
66 GaimXferUiOps *ui_ops; | |
67 | |
68 g_return_if_fail(xfer != NULL); | |
69 | |
70 /* Close the file browser, if it's open */ | |
71 gaim_request_close_with_handle(xfer); | |
72 | |
73 if (gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_STARTED) | |
74 gaim_xfer_cancel_local(xfer); | |
75 | |
76 ui_ops = gaim_xfer_get_ui_ops(xfer); | |
77 | |
78 if (ui_ops != NULL && ui_ops->destroy != NULL) | |
79 ui_ops->destroy(xfer); | |
80 | |
81 g_free(xfer->who); | |
82 g_free(xfer->filename); | |
83 g_free(xfer->remote_ip); | |
84 g_free(xfer->local_filename); | |
85 | |
86 g_free(xfer); | |
87 } | |
88 | |
89 void | |
90 gaim_xfer_ref(GaimXfer *xfer) | |
91 { | |
92 g_return_if_fail(xfer != NULL); | |
93 | |
94 xfer->ref++; | |
95 } | |
96 | |
97 void | |
98 gaim_xfer_unref(GaimXfer *xfer) | |
99 { | |
100 g_return_if_fail(xfer != NULL); | |
101 g_return_if_fail(xfer->ref > 0); | |
102 | |
103 xfer->ref--; | |
104 | |
105 if (xfer->ref == 0) | |
106 gaim_xfer_destroy(xfer); | |
107 } | |
108 | |
109 static void | |
110 gaim_xfer_set_status(GaimXfer *xfer, GaimXferStatusType status) | |
111 { | |
112 g_return_if_fail(xfer != NULL); | |
113 | |
114 if(xfer->type == GAIM_XFER_SEND) { | |
115 switch(status) { | |
116 case GAIM_XFER_STATUS_ACCEPTED: | |
117 gaim_signal_emit(gaim_xfers_get_handle(), "file-send-accept", xfer); | |
118 break; | |
119 case GAIM_XFER_STATUS_STARTED: | |
120 gaim_signal_emit(gaim_xfers_get_handle(), "file-send-start", xfer); | |
121 break; | |
122 case GAIM_XFER_STATUS_DONE: | |
123 gaim_signal_emit(gaim_xfers_get_handle(), "file-send-complete", xfer); | |
124 break; | |
125 case GAIM_XFER_STATUS_CANCEL_LOCAL: | |
126 case GAIM_XFER_STATUS_CANCEL_REMOTE: | |
127 gaim_signal_emit(gaim_xfers_get_handle(), "file-send-cancel", xfer); | |
128 break; | |
129 default: | |
130 break; | |
131 } | |
132 } else if(xfer->type == GAIM_XFER_RECEIVE) { | |
133 switch(status) { | |
134 case GAIM_XFER_STATUS_ACCEPTED: | |
135 gaim_signal_emit(gaim_xfers_get_handle(), "file-recv-accept", xfer); | |
136 break; | |
137 case GAIM_XFER_STATUS_STARTED: | |
138 gaim_signal_emit(gaim_xfers_get_handle(), "file-recv-start", xfer); | |
139 break; | |
140 case GAIM_XFER_STATUS_DONE: | |
141 gaim_signal_emit(gaim_xfers_get_handle(), "file-recv-complete", xfer); | |
142 break; | |
143 case GAIM_XFER_STATUS_CANCEL_LOCAL: | |
144 case GAIM_XFER_STATUS_CANCEL_REMOTE: | |
145 gaim_signal_emit(gaim_xfers_get_handle(), "file-recv-cancel", xfer); | |
146 break; | |
147 default: | |
148 break; | |
149 } | |
150 } | |
151 | |
152 xfer->status = status; | |
153 } | |
154 | |
155 void gaim_xfer_conversation_write(GaimXfer *xfer, char *message, gboolean is_error) | |
156 { | |
157 GaimConversation *conv = NULL; | |
158 GaimMessageFlags flags = GAIM_MESSAGE_SYSTEM; | |
159 char *escaped; | |
160 | |
161 g_return_if_fail(xfer != NULL); | |
162 g_return_if_fail(message != NULL); | |
163 | |
164 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, xfer->who, | |
165 gaim_xfer_get_account(xfer)); | |
166 | |
167 if (conv == NULL) | |
168 return; | |
169 | |
170 escaped = g_markup_escape_text(message, -1); | |
171 | |
172 if (is_error) | |
173 flags = GAIM_MESSAGE_ERROR; | |
174 | |
175 gaim_conversation_write(conv, NULL, escaped, flags, time(NULL)); | |
176 g_free(escaped); | |
177 } | |
178 | |
179 static void gaim_xfer_show_file_error(GaimXfer *xfer, const char *filename) | |
180 { | |
181 int err = errno; | |
182 gchar *msg = NULL, *utf8; | |
183 GaimXferType xfer_type = gaim_xfer_get_type(xfer); | |
184 GaimAccount *account = gaim_xfer_get_account(xfer); | |
185 | |
186 utf8 = g_filename_to_utf8(filename, -1, NULL, NULL, NULL); | |
187 switch(xfer_type) { | |
188 case GAIM_XFER_SEND: | |
189 msg = g_strdup_printf(_("Error reading %s: \n%s.\n"), | |
190 utf8, strerror(err)); | |
191 break; | |
192 case GAIM_XFER_RECEIVE: | |
193 msg = g_strdup_printf(_("Error writing %s: \n%s.\n"), | |
194 utf8, strerror(err)); | |
195 break; | |
196 default: | |
197 msg = g_strdup_printf(_("Error accessing %s: \n%s.\n"), | |
198 utf8, strerror(err)); | |
199 break; | |
200 } | |
201 g_free(utf8); | |
202 | |
203 gaim_xfer_conversation_write(xfer, msg, TRUE); | |
204 gaim_xfer_error(xfer_type, account, xfer->who, msg); | |
205 g_free(msg); | |
206 } | |
207 | |
208 static void | |
209 gaim_xfer_choose_file_ok_cb(void *user_data, const char *filename) | |
210 { | |
211 GaimXfer *xfer; | |
212 struct stat st; | |
213 | |
214 xfer = (GaimXfer *)user_data; | |
215 | |
216 if (g_stat(filename, &st) != 0) { | |
217 /* File not found. */ | |
218 if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) { | |
219 gaim_xfer_request_accepted(xfer, filename); | |
220 } | |
221 else { | |
222 gaim_xfer_show_file_error(xfer, filename); | |
223 gaim_xfer_request_denied(xfer); | |
224 } | |
225 } | |
226 else if ((gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) && | |
227 (st.st_size == 0)) { | |
228 | |
229 gaim_notify_error(NULL, NULL, | |
230 _("Cannot send a file of 0 bytes."), NULL); | |
231 | |
232 gaim_xfer_request_denied(xfer); | |
233 } | |
234 else if ((gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) && | |
235 S_ISDIR(st.st_mode)) { | |
236 /* | |
237 * XXX - Sending a directory should be valid for some protocols. | |
238 */ | |
239 gaim_notify_error(NULL, NULL, | |
240 _("Cannot send a directory."), NULL); | |
241 | |
242 gaim_xfer_request_denied(xfer); | |
243 } | |
244 else if ((gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) && | |
245 S_ISDIR(st.st_mode)) { | |
246 char *msg, *utf8; | |
247 utf8 = g_filename_to_utf8(filename, -1, NULL, NULL, NULL); | |
248 msg = g_strdup_printf( | |
249 _("%s is not a regular file. Cowardly refusing to overwrite it.\n"), utf8); | |
250 g_free(utf8); | |
251 gaim_notify_error(NULL, NULL, msg, NULL); | |
252 g_free(msg); | |
253 gaim_xfer_request_denied(xfer); | |
254 } | |
255 else { | |
256 gaim_xfer_request_accepted(xfer, filename); | |
257 } | |
258 | |
259 gaim_xfer_unref(xfer); | |
260 } | |
261 | |
262 static void | |
263 gaim_xfer_choose_file_cancel_cb(void *user_data, const char *filename) | |
264 { | |
265 GaimXfer *xfer = (GaimXfer *)user_data; | |
266 | |
267 gaim_xfer_set_status(xfer, GAIM_XFER_STATUS_CANCEL_LOCAL); | |
268 gaim_xfer_request_denied(xfer); | |
269 } | |
270 | |
271 static int | |
272 gaim_xfer_choose_file(GaimXfer *xfer) | |
273 { | |
274 gaim_request_file(xfer, NULL, gaim_xfer_get_filename(xfer), | |
275 (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE), | |
276 G_CALLBACK(gaim_xfer_choose_file_ok_cb), | |
277 G_CALLBACK(gaim_xfer_choose_file_cancel_cb), xfer); | |
278 | |
279 return 0; | |
280 } | |
281 | |
282 static int | |
283 cancel_recv_cb(GaimXfer *xfer) | |
284 { | |
285 gaim_xfer_set_status(xfer, GAIM_XFER_STATUS_CANCEL_LOCAL); | |
286 gaim_xfer_request_denied(xfer); | |
287 gaim_xfer_unref(xfer); | |
288 | |
289 return 0; | |
290 } | |
291 | |
292 static void | |
293 gaim_xfer_ask_recv(GaimXfer *xfer) | |
294 { | |
295 char *buf, *size_buf; | |
296 size_t size; | |
297 | |
298 /* If we have already accepted the request, ask the destination file | |
299 name directly */ | |
300 if (gaim_xfer_get_status(xfer) != GAIM_XFER_STATUS_ACCEPTED) { | |
301 GaimBuddy *buddy = gaim_find_buddy(xfer->account, xfer->who); | |
302 | |
303 if (gaim_xfer_get_filename(xfer) != NULL) | |
304 { | |
305 size = gaim_xfer_get_size(xfer); | |
306 size_buf = gaim_str_size_to_units(size); | |
307 buf = g_strdup_printf(_("%s wants to send you %s (%s)"), | |
308 buddy ? gaim_buddy_get_alias(buddy) : xfer->who, | |
309 gaim_xfer_get_filename(xfer), size_buf); | |
310 g_free(size_buf); | |
311 } | |
312 else | |
313 { | |
314 buf = g_strdup_printf(_("%s wants to send you a file"), | |
315 buddy ? gaim_buddy_get_alias(buddy) : xfer->who); | |
316 } | |
317 | |
318 if (xfer->message != NULL) | |
319 serv_got_im(gaim_account_get_connection(xfer->account), | |
320 xfer->who, xfer->message, 0, time(NULL)); | |
321 | |
322 gaim_request_accept_cancel(xfer, NULL, buf, NULL, | |
323 GAIM_DEFAULT_ACTION_NONE, xfer, | |
324 G_CALLBACK(gaim_xfer_choose_file), | |
325 G_CALLBACK(cancel_recv_cb)); | |
326 | |
327 g_free(buf); | |
328 } else | |
329 gaim_xfer_choose_file(xfer); | |
330 } | |
331 | |
332 static int | |
333 ask_accept_ok(GaimXfer *xfer) | |
334 { | |
335 gaim_xfer_request_accepted(xfer, NULL); | |
336 | |
337 return 0; | |
338 } | |
339 | |
340 static int | |
341 ask_accept_cancel(GaimXfer *xfer) | |
342 { | |
343 gaim_xfer_request_denied(xfer); | |
344 gaim_xfer_unref(xfer); | |
345 | |
346 return 0; | |
347 } | |
348 | |
349 static void | |
350 gaim_xfer_ask_accept(GaimXfer *xfer) | |
351 { | |
352 char *buf, *buf2 = NULL; | |
353 GaimBuddy *buddy = gaim_find_buddy(xfer->account, xfer->who); | |
354 | |
355 buf = g_strdup_printf(_("Accept file transfer request from %s?"), | |
356 buddy ? gaim_buddy_get_alias(buddy) : xfer->who); | |
357 if (gaim_xfer_get_remote_ip(xfer) && | |
358 gaim_xfer_get_remote_port(xfer)) | |
359 buf2 = g_strdup_printf(_("A file is available for download from:\n" | |
360 "Remote host: %s\nRemote port: %d"), | |
361 gaim_xfer_get_remote_ip(xfer), | |
362 gaim_xfer_get_remote_port(xfer)); | |
363 gaim_request_accept_cancel(xfer, NULL, buf, buf2, | |
364 GAIM_DEFAULT_ACTION_NONE, xfer, | |
365 G_CALLBACK(ask_accept_ok), | |
366 G_CALLBACK(ask_accept_cancel)); | |
367 g_free(buf); | |
368 g_free(buf2); | |
369 } | |
370 | |
371 void | |
372 gaim_xfer_request(GaimXfer *xfer) | |
373 { | |
374 g_return_if_fail(xfer != NULL); | |
375 g_return_if_fail(xfer->ops.init != NULL); | |
376 | |
377 gaim_xfer_ref(xfer); | |
378 | |
379 if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) | |
380 { | |
381 gaim_signal_emit(gaim_xfers_get_handle(), "file-recv-request", xfer); | |
382 if (gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_LOCAL) | |
383 { | |
384 /* The file-transfer was cancelled by a plugin */ | |
385 gaim_xfer_cancel_local(xfer); | |
386 } | |
387 else if (gaim_xfer_get_filename(xfer) || | |
388 gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_ACCEPTED) | |
389 { | |
390 gchar* message = NULL; | |
391 GaimBuddy *buddy = gaim_find_buddy(xfer->account, xfer->who); | |
392 message = g_strdup_printf(_("%s is offering to send file %s"), | |
393 buddy ? gaim_buddy_get_alias(buddy) : xfer->who, gaim_xfer_get_filename(xfer)); | |
394 gaim_xfer_conversation_write(xfer, message, FALSE); | |
395 g_free(message); | |
396 /* Ask for a filename to save to if it's not already given by a plugin */ | |
397 if (xfer->local_filename == NULL) | |
398 gaim_xfer_ask_recv(xfer); | |
399 } | |
400 else | |
401 { | |
402 gaim_xfer_ask_accept(xfer); | |
403 } | |
404 } | |
405 else | |
406 { | |
407 gaim_xfer_choose_file(xfer); | |
408 } | |
409 } | |
410 | |
411 void | |
412 gaim_xfer_request_accepted(GaimXfer *xfer, const char *filename) | |
413 { | |
414 GaimXferType type; | |
415 struct stat st; | |
416 char *msg, *utf8; | |
417 GaimAccount *account; | |
418 GaimBuddy *buddy; | |
419 | |
420 if (xfer == NULL) | |
421 return; | |
422 | |
423 type = gaim_xfer_get_type(xfer); | |
424 account = gaim_xfer_get_account(xfer); | |
425 | |
426 if (!filename && type == GAIM_XFER_RECEIVE) { | |
427 xfer->status = GAIM_XFER_STATUS_ACCEPTED; | |
428 xfer->ops.init(xfer); | |
429 return; | |
430 } | |
431 | |
432 buddy = gaim_find_buddy(account, xfer->who); | |
433 | |
434 if (type == GAIM_XFER_SEND) { | |
435 /* Sending a file */ | |
436 /* Check the filename. */ | |
437 #ifdef _WIN32 | |
438 if (g_strrstr(filename, "../") || g_strrstr(filename, "..\\")) { | |
439 #else | |
440 if (g_strrstr(filename, "../")) { | |
441 #endif | |
442 char *utf8 = g_filename_to_utf8(filename, -1, NULL, NULL, NULL); | |
443 | |
444 msg = g_strdup_printf(_("%s is not a valid filename.\n"), utf8); | |
445 gaim_xfer_error(type, account, xfer->who, msg); | |
446 g_free(utf8); | |
447 g_free(msg); | |
448 | |
449 gaim_xfer_unref(xfer); | |
450 return; | |
451 } | |
452 | |
453 if (g_stat(filename, &st) == -1) { | |
454 gaim_xfer_show_file_error(xfer, filename); | |
455 gaim_xfer_unref(xfer); | |
456 return; | |
457 } | |
458 | |
459 gaim_xfer_set_local_filename(xfer, filename); | |
460 gaim_xfer_set_size(xfer, st.st_size); | |
461 | |
462 utf8 = g_filename_to_utf8(g_basename(filename), -1, NULL, NULL, NULL); | |
463 gaim_xfer_set_filename(xfer, utf8); | |
464 | |
465 msg = g_strdup_printf(_("Offering to send %s to %s"), | |
466 utf8, buddy ? gaim_buddy_get_alias(buddy) : xfer->who); | |
467 g_free(utf8); | |
468 | |
469 gaim_xfer_conversation_write(xfer, msg, FALSE); | |
470 g_free(msg); | |
471 } | |
472 else { | |
473 /* Receiving a file */ | |
474 xfer->status = GAIM_XFER_STATUS_ACCEPTED; | |
475 gaim_xfer_set_local_filename(xfer, filename); | |
476 | |
477 msg = g_strdup_printf(_("Starting transfer of %s from %s"), | |
478 xfer->filename, buddy ? gaim_buddy_get_alias(buddy) : xfer->who); | |
479 gaim_xfer_conversation_write(xfer, msg, FALSE); | |
480 g_free(msg); | |
481 } | |
482 | |
483 gaim_xfer_add(xfer); | |
484 xfer->ops.init(xfer); | |
485 | |
486 } | |
487 | |
488 void | |
489 gaim_xfer_request_denied(GaimXfer *xfer) | |
490 { | |
491 g_return_if_fail(xfer != NULL); | |
492 | |
493 if (xfer->ops.request_denied != NULL) | |
494 xfer->ops.request_denied(xfer); | |
495 | |
496 gaim_xfer_unref(xfer); | |
497 } | |
498 | |
499 GaimXferType | |
500 gaim_xfer_get_type(const GaimXfer *xfer) | |
501 { | |
502 g_return_val_if_fail(xfer != NULL, GAIM_XFER_UNKNOWN); | |
503 | |
504 return xfer->type; | |
505 } | |
506 | |
507 GaimAccount * | |
508 gaim_xfer_get_account(const GaimXfer *xfer) | |
509 { | |
510 g_return_val_if_fail(xfer != NULL, NULL); | |
511 | |
512 return xfer->account; | |
513 } | |
514 | |
515 GaimXferStatusType | |
516 gaim_xfer_get_status(const GaimXfer *xfer) | |
517 { | |
518 g_return_val_if_fail(xfer != NULL, GAIM_XFER_STATUS_UNKNOWN); | |
519 | |
520 return xfer->status; | |
521 } | |
522 | |
523 gboolean | |
524 gaim_xfer_is_canceled(const GaimXfer *xfer) | |
525 { | |
526 g_return_val_if_fail(xfer != NULL, TRUE); | |
527 | |
528 if ((gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_LOCAL) || | |
529 (gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_CANCEL_REMOTE)) | |
530 return TRUE; | |
531 else | |
532 return FALSE; | |
533 } | |
534 | |
535 gboolean | |
536 gaim_xfer_is_completed(const GaimXfer *xfer) | |
537 { | |
538 g_return_val_if_fail(xfer != NULL, TRUE); | |
539 | |
540 return (gaim_xfer_get_status(xfer) == GAIM_XFER_STATUS_DONE); | |
541 } | |
542 | |
543 const char * | |
544 gaim_xfer_get_filename(const GaimXfer *xfer) | |
545 { | |
546 g_return_val_if_fail(xfer != NULL, NULL); | |
547 | |
548 return xfer->filename; | |
549 } | |
550 | |
551 const char * | |
552 gaim_xfer_get_local_filename(const GaimXfer *xfer) | |
553 { | |
554 g_return_val_if_fail(xfer != NULL, NULL); | |
555 | |
556 return xfer->local_filename; | |
557 } | |
558 | |
559 size_t | |
560 gaim_xfer_get_bytes_sent(const GaimXfer *xfer) | |
561 { | |
562 g_return_val_if_fail(xfer != NULL, 0); | |
563 | |
564 return xfer->bytes_sent; | |
565 } | |
566 | |
567 size_t | |
568 gaim_xfer_get_bytes_remaining(const GaimXfer *xfer) | |
569 { | |
570 g_return_val_if_fail(xfer != NULL, 0); | |
571 | |
572 return xfer->bytes_remaining; | |
573 } | |
574 | |
575 size_t | |
576 gaim_xfer_get_size(const GaimXfer *xfer) | |
577 { | |
578 g_return_val_if_fail(xfer != NULL, 0); | |
579 | |
580 return xfer->size; | |
581 } | |
582 | |
583 double | |
584 gaim_xfer_get_progress(const GaimXfer *xfer) | |
585 { | |
586 g_return_val_if_fail(xfer != NULL, 0.0); | |
587 | |
588 if (gaim_xfer_get_size(xfer) == 0) | |
589 return 0.0; | |
590 | |
591 return ((double)gaim_xfer_get_bytes_sent(xfer) / | |
592 (double)gaim_xfer_get_size(xfer)); | |
593 } | |
594 | |
595 unsigned int | |
596 gaim_xfer_get_local_port(const GaimXfer *xfer) | |
597 { | |
598 g_return_val_if_fail(xfer != NULL, -1); | |
599 | |
600 return xfer->local_port; | |
601 } | |
602 | |
603 const char * | |
604 gaim_xfer_get_remote_ip(const GaimXfer *xfer) | |
605 { | |
606 g_return_val_if_fail(xfer != NULL, NULL); | |
607 | |
608 return xfer->remote_ip; | |
609 } | |
610 | |
611 unsigned int | |
612 gaim_xfer_get_remote_port(const GaimXfer *xfer) | |
613 { | |
614 g_return_val_if_fail(xfer != NULL, -1); | |
615 | |
616 return xfer->remote_port; | |
617 } | |
618 | |
619 void | |
620 gaim_xfer_set_completed(GaimXfer *xfer, gboolean completed) | |
621 { | |
622 GaimXferUiOps *ui_ops; | |
623 | |
624 g_return_if_fail(xfer != NULL); | |
625 | |
626 if (completed == TRUE) { | |
627 char *msg = NULL; | |
628 gaim_xfer_set_status(xfer, GAIM_XFER_STATUS_DONE); | |
629 | |
630 if (gaim_xfer_get_filename(xfer) != NULL) | |
631 msg = g_strdup_printf(_("Transfer of file %s complete"), | |
632 gaim_xfer_get_filename(xfer)); | |
633 else | |
634 msg = g_strdup_printf(_("File transfer complete")); | |
635 gaim_xfer_conversation_write(xfer, msg, FALSE); | |
636 g_free(msg); | |
637 } | |
638 | |
639 ui_ops = gaim_xfer_get_ui_ops(xfer); | |
640 | |
641 if (ui_ops != NULL && ui_ops->update_progress != NULL) | |
642 ui_ops->update_progress(xfer, gaim_xfer_get_progress(xfer)); | |
643 } | |
644 | |
645 void | |
646 gaim_xfer_set_message(GaimXfer *xfer, const char *message) | |
647 { | |
648 g_return_if_fail(xfer != NULL); | |
649 | |
650 g_free(xfer->message); | |
651 xfer->message = g_strdup(message); | |
652 } | |
653 | |
654 void | |
655 gaim_xfer_set_filename(GaimXfer *xfer, const char *filename) | |
656 { | |
657 g_return_if_fail(xfer != NULL); | |
658 | |
659 g_free(xfer->filename); | |
660 xfer->filename = g_strdup(filename); | |
661 } | |
662 | |
663 void | |
664 gaim_xfer_set_local_filename(GaimXfer *xfer, const char *filename) | |
665 { | |
666 g_return_if_fail(xfer != NULL); | |
667 | |
668 g_free(xfer->local_filename); | |
669 xfer->local_filename = g_strdup(filename); | |
670 } | |
671 | |
672 void | |
673 gaim_xfer_set_size(GaimXfer *xfer, size_t size) | |
674 { | |
675 g_return_if_fail(xfer != NULL); | |
676 | |
677 if (xfer->size == 0) | |
678 xfer->bytes_remaining = size - xfer->bytes_sent; | |
679 | |
680 xfer->size = size; | |
681 } | |
682 | |
683 GaimXferUiOps * | |
684 gaim_xfer_get_ui_ops(const GaimXfer *xfer) | |
685 { | |
686 g_return_val_if_fail(xfer != NULL, NULL); | |
687 | |
688 return xfer->ui_ops; | |
689 } | |
690 | |
691 void | |
692 gaim_xfer_set_init_fnc(GaimXfer *xfer, void (*fnc)(GaimXfer *)) | |
693 { | |
694 g_return_if_fail(xfer != NULL); | |
695 | |
696 xfer->ops.init = fnc; | |
697 } | |
698 | |
699 void gaim_xfer_set_request_denied_fnc(GaimXfer *xfer, void (*fnc)(GaimXfer *)) | |
700 { | |
701 g_return_if_fail(xfer != NULL); | |
702 | |
703 xfer->ops.request_denied = fnc; | |
704 } | |
705 | |
706 void | |
707 gaim_xfer_set_read_fnc(GaimXfer *xfer, gssize (*fnc)(guchar **, GaimXfer *)) | |
708 { | |
709 g_return_if_fail(xfer != NULL); | |
710 | |
711 xfer->ops.read = fnc; | |
712 } | |
713 | |
714 void | |
715 gaim_xfer_set_write_fnc(GaimXfer *xfer, | |
716 gssize (*fnc)(const guchar *, size_t, GaimXfer *)) | |
717 { | |
718 g_return_if_fail(xfer != NULL); | |
719 | |
720 xfer->ops.write = fnc; | |
721 } | |
722 | |
723 void | |
724 gaim_xfer_set_ack_fnc(GaimXfer *xfer, | |
725 void (*fnc)(GaimXfer *, const guchar *, size_t)) | |
726 { | |
727 g_return_if_fail(xfer != NULL); | |
728 | |
729 xfer->ops.ack = fnc; | |
730 } | |
731 | |
732 void | |
733 gaim_xfer_set_start_fnc(GaimXfer *xfer, void (*fnc)(GaimXfer *)) | |
734 { | |
735 g_return_if_fail(xfer != NULL); | |
736 | |
737 xfer->ops.start = fnc; | |
738 } | |
739 | |
740 void | |
741 gaim_xfer_set_end_fnc(GaimXfer *xfer, void (*fnc)(GaimXfer *)) | |
742 { | |
743 g_return_if_fail(xfer != NULL); | |
744 | |
745 xfer->ops.end = fnc; | |
746 } | |
747 | |
748 void | |
749 gaim_xfer_set_cancel_send_fnc(GaimXfer *xfer, void (*fnc)(GaimXfer *)) | |
750 { | |
751 g_return_if_fail(xfer != NULL); | |
752 | |
753 xfer->ops.cancel_send = fnc; | |
754 } | |
755 | |
756 void | |
757 gaim_xfer_set_cancel_recv_fnc(GaimXfer *xfer, void (*fnc)(GaimXfer *)) | |
758 { | |
759 g_return_if_fail(xfer != NULL); | |
760 | |
761 xfer->ops.cancel_recv = fnc; | |
762 } | |
763 | |
764 gssize | |
765 gaim_xfer_read(GaimXfer *xfer, guchar **buffer) | |
766 { | |
767 gssize s, r; | |
768 | |
769 g_return_val_if_fail(xfer != NULL, 0); | |
770 g_return_val_if_fail(buffer != NULL, 0); | |
771 | |
772 if (gaim_xfer_get_size(xfer) == 0) | |
773 s = 4096; | |
774 else | |
775 s = MIN(gaim_xfer_get_bytes_remaining(xfer), 4096); | |
776 | |
777 if (xfer->ops.read != NULL) | |
778 r = (xfer->ops.read)(buffer, xfer); | |
779 else { | |
780 *buffer = g_malloc0(s); | |
781 | |
782 r = read(xfer->fd, *buffer, s); | |
783 if (r < 0 && errno == EAGAIN) | |
784 r = 0; | |
785 else if (r < 0) | |
786 r = -1; | |
787 else if ((gaim_xfer_get_size(xfer) > 0) && | |
788 ((gaim_xfer_get_bytes_sent(xfer)+r) >= gaim_xfer_get_size(xfer))) | |
789 gaim_xfer_set_completed(xfer, TRUE); | |
790 else if (r == 0) | |
791 r = -1; | |
792 } | |
793 | |
794 return r; | |
795 } | |
796 | |
797 gssize | |
798 gaim_xfer_write(GaimXfer *xfer, const guchar *buffer, gsize size) | |
799 { | |
800 gssize r, s; | |
801 | |
802 g_return_val_if_fail(xfer != NULL, 0); | |
803 g_return_val_if_fail(buffer != NULL, 0); | |
804 g_return_val_if_fail(size != 0, 0); | |
805 | |
806 s = MIN(gaim_xfer_get_bytes_remaining(xfer), size); | |
807 | |
808 if (xfer->ops.write != NULL) { | |
809 r = (xfer->ops.write)(buffer, s, xfer); | |
810 } else { | |
811 r = write(xfer->fd, buffer, s); | |
812 if (r < 0 && errno == EAGAIN) | |
813 r = 0; | |
814 if ((gaim_xfer_get_bytes_sent(xfer)+r) >= gaim_xfer_get_size(xfer)) | |
815 gaim_xfer_set_completed(xfer, TRUE); | |
816 } | |
817 | |
818 return r; | |
819 } | |
820 | |
821 static void | |
822 transfer_cb(gpointer data, gint source, GaimInputCondition condition) | |
823 { | |
824 GaimXferUiOps *ui_ops; | |
825 GaimXfer *xfer = (GaimXfer *)data; | |
826 guchar *buffer = NULL; | |
827 gssize r = 0; | |
828 | |
829 if (condition & GAIM_INPUT_READ) { | |
830 r = gaim_xfer_read(xfer, &buffer); | |
831 if (r > 0) { | |
832 fwrite(buffer, 1, r, xfer->dest_fp); | |
833 } else if(r <= 0) { | |
834 gaim_xfer_cancel_remote(xfer); | |
835 return; | |
836 } | |
837 } | |
838 | |
839 if (condition & GAIM_INPUT_WRITE) { | |
840 size_t s = MIN(gaim_xfer_get_bytes_remaining(xfer), 4096); | |
841 | |
842 /* this is so the prpl can keep the connection open | |
843 if it needs to for some odd reason. */ | |
844 if (s == 0) { | |
845 if (xfer->watcher) { | |
846 gaim_input_remove(xfer->watcher); | |
847 xfer->watcher = 0; | |
848 } | |
849 return; | |
850 } | |
851 | |
852 buffer = g_malloc0(s); | |
853 | |
854 fread(buffer, 1, s, xfer->dest_fp); | |
855 | |
856 /* Write as much as we're allowed to. */ | |
857 r = gaim_xfer_write(xfer, buffer, s); | |
858 | |
859 if (r == -1) { | |
860 gaim_xfer_cancel_remote(xfer); | |
861 g_free(buffer); | |
862 return; | |
863 } else if (r < s) { | |
864 /* We have to seek back in the file now. */ | |
865 fseek(xfer->dest_fp, r - s, SEEK_CUR); | |
866 } | |
867 } | |
868 | |
869 if (r > 0) { | |
870 if (gaim_xfer_get_size(xfer) > 0) | |
871 xfer->bytes_remaining -= r; | |
872 | |
873 xfer->bytes_sent += r; | |
874 | |
875 if (xfer->ops.ack != NULL) | |
876 xfer->ops.ack(xfer, buffer, r); | |
877 | |
878 g_free(buffer); | |
879 | |
880 ui_ops = gaim_xfer_get_ui_ops(xfer); | |
881 | |
882 if (ui_ops != NULL && ui_ops->update_progress != NULL) | |
883 ui_ops->update_progress(xfer, | |
884 gaim_xfer_get_progress(xfer)); | |
885 } | |
886 | |
887 if (gaim_xfer_is_completed(xfer)) | |
888 gaim_xfer_end(xfer); | |
889 } | |
890 | |
891 static void | |
892 begin_transfer(GaimXfer *xfer, GaimInputCondition cond) | |
893 { | |
894 GaimXferType type = gaim_xfer_get_type(xfer); | |
895 | |
896 xfer->dest_fp = g_fopen(gaim_xfer_get_local_filename(xfer), | |
897 type == GAIM_XFER_RECEIVE ? "wb" : "rb"); | |
898 | |
899 if (xfer->dest_fp == NULL) { | |
900 gaim_xfer_show_file_error(xfer, gaim_xfer_get_local_filename(xfer)); | |
901 gaim_xfer_cancel_local(xfer); | |
902 return; | |
903 } | |
904 | |
905 xfer->watcher = gaim_input_add(xfer->fd, cond, transfer_cb, xfer); | |
906 | |
907 xfer->start_time = time(NULL); | |
908 | |
909 if (xfer->ops.start != NULL) | |
910 xfer->ops.start(xfer); | |
911 } | |
912 | |
913 static void | |
914 connect_cb(gpointer data, gint source, const gchar *error_message) | |
915 { | |
916 GaimXfer *xfer = (GaimXfer *)data; | |
917 | |
918 xfer->fd = source; | |
919 | |
920 begin_transfer(xfer, GAIM_INPUT_READ); | |
921 } | |
922 | |
923 void | |
924 gaim_xfer_start(GaimXfer *xfer, int fd, const char *ip, | |
925 unsigned int port) | |
926 { | |
927 GaimInputCondition cond; | |
928 GaimXferType type; | |
929 | |
930 g_return_if_fail(xfer != NULL); | |
931 g_return_if_fail(gaim_xfer_get_type(xfer) != GAIM_XFER_UNKNOWN); | |
932 | |
933 type = gaim_xfer_get_type(xfer); | |
934 | |
935 xfer->bytes_remaining = gaim_xfer_get_size(xfer); | |
936 xfer->bytes_sent = 0; | |
937 | |
938 gaim_xfer_set_status(xfer, GAIM_XFER_STATUS_STARTED); | |
939 | |
940 if (type == GAIM_XFER_RECEIVE) { | |
941 cond = GAIM_INPUT_READ; | |
942 | |
943 if (ip != NULL) { | |
944 xfer->remote_ip = g_strdup(ip); | |
945 xfer->remote_port = port; | |
946 | |
947 /* Establish a file descriptor. */ | |
14837 | 948 gaim_proxy_connect(NULL, xfer->account, xfer->remote_ip, |
14192 | 949 xfer->remote_port, connect_cb, xfer); |
950 | |
951 return; | |
952 } | |
953 else { | |
954 xfer->fd = fd; | |
955 } | |
956 } | |
957 else { | |
958 cond = GAIM_INPUT_WRITE; | |
959 | |
960 xfer->fd = fd; | |
961 } | |
962 | |
963 begin_transfer(xfer, cond); | |
964 } | |
965 | |
966 void | |
967 gaim_xfer_end(GaimXfer *xfer) | |
968 { | |
969 g_return_if_fail(xfer != NULL); | |
970 | |
971 /* See if we are actually trying to cancel this. */ | |
972 if (!gaim_xfer_is_completed(xfer)) { | |
973 gaim_xfer_cancel_local(xfer); | |
974 return; | |
975 } | |
976 | |
977 xfer->end_time = time(NULL); | |
978 if (xfer->ops.end != NULL) | |
979 xfer->ops.end(xfer); | |
980 | |
981 if (xfer->watcher != 0) { | |
982 gaim_input_remove(xfer->watcher); | |
983 xfer->watcher = 0; | |
984 } | |
985 | |
986 if (xfer->fd != 0) | |
987 close(xfer->fd); | |
988 | |
989 if (xfer->dest_fp != NULL) { | |
990 fclose(xfer->dest_fp); | |
991 xfer->dest_fp = NULL; | |
992 } | |
993 | |
994 gaim_xfer_unref(xfer); | |
995 } | |
996 | |
997 void | |
998 gaim_xfer_add(GaimXfer *xfer) | |
999 { | |
1000 GaimXferUiOps *ui_ops; | |
1001 | |
1002 g_return_if_fail(xfer != NULL); | |
1003 | |
1004 ui_ops = gaim_xfer_get_ui_ops(xfer); | |
1005 | |
1006 if (ui_ops != NULL && ui_ops->add_xfer != NULL) | |
1007 ui_ops->add_xfer(xfer); | |
1008 } | |
1009 | |
1010 void | |
1011 gaim_xfer_cancel_local(GaimXfer *xfer) | |
1012 { | |
1013 GaimXferUiOps *ui_ops; | |
1014 char *msg = NULL; | |
1015 | |
1016 g_return_if_fail(xfer != NULL); | |
1017 | |
1018 gaim_xfer_set_status(xfer, GAIM_XFER_STATUS_CANCEL_LOCAL); | |
1019 xfer->end_time = time(NULL); | |
1020 | |
1021 if (gaim_xfer_get_filename(xfer) != NULL) | |
1022 { | |
1023 msg = g_strdup_printf(_("You canceled the transfer of %s"), | |
1024 gaim_xfer_get_filename(xfer)); | |
1025 } | |
1026 else | |
1027 { | |
1028 msg = g_strdup_printf(_("File transfer cancelled")); | |
1029 } | |
1030 gaim_xfer_conversation_write(xfer, msg, FALSE); | |
1031 g_free(msg); | |
1032 | |
1033 if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) | |
1034 { | |
1035 if (xfer->ops.cancel_send != NULL) | |
1036 xfer->ops.cancel_send(xfer); | |
1037 } | |
1038 else | |
1039 { | |
1040 if (xfer->ops.cancel_recv != NULL) | |
1041 xfer->ops.cancel_recv(xfer); | |
1042 } | |
1043 | |
1044 if (xfer->watcher != 0) { | |
1045 gaim_input_remove(xfer->watcher); | |
1046 xfer->watcher = 0; | |
1047 } | |
1048 | |
1049 if (xfer->fd != 0) | |
1050 close(xfer->fd); | |
1051 | |
1052 if (xfer->dest_fp != NULL) { | |
1053 fclose(xfer->dest_fp); | |
1054 xfer->dest_fp = NULL; | |
1055 } | |
1056 | |
1057 ui_ops = gaim_xfer_get_ui_ops(xfer); | |
1058 | |
1059 if (ui_ops != NULL && ui_ops->cancel_local != NULL) | |
1060 ui_ops->cancel_local(xfer); | |
1061 | |
1062 xfer->bytes_remaining = 0; | |
1063 | |
1064 gaim_xfer_unref(xfer); | |
1065 } | |
1066 | |
1067 void | |
1068 gaim_xfer_cancel_remote(GaimXfer *xfer) | |
1069 { | |
1070 GaimXferUiOps *ui_ops; | |
1071 gchar *msg; | |
1072 GaimAccount *account; | |
1073 GaimBuddy *buddy; | |
1074 | |
1075 g_return_if_fail(xfer != NULL); | |
1076 | |
1077 gaim_request_close_with_handle(xfer); | |
1078 gaim_xfer_set_status(xfer, GAIM_XFER_STATUS_CANCEL_REMOTE); | |
1079 xfer->end_time = time(NULL); | |
1080 | |
1081 account = gaim_xfer_get_account(xfer); | |
1082 buddy = gaim_find_buddy(account, xfer->who); | |
1083 | |
1084 if (gaim_xfer_get_filename(xfer) != NULL) | |
1085 { | |
1086 msg = g_strdup_printf(_("%s canceled the transfer of %s"), | |
1087 buddy ? gaim_buddy_get_alias(buddy) : xfer->who, gaim_xfer_get_filename(xfer)); | |
1088 } | |
1089 else | |
1090 { | |
1091 msg = g_strdup_printf(_("%s canceled the file transfer"), | |
1092 buddy ? gaim_buddy_get_alias(buddy) : xfer->who); | |
1093 } | |
1094 gaim_xfer_conversation_write(xfer, msg, TRUE); | |
1095 gaim_xfer_error(gaim_xfer_get_type(xfer), account, xfer->who, msg); | |
1096 g_free(msg); | |
1097 | |
1098 if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) | |
1099 { | |
1100 if (xfer->ops.cancel_send != NULL) | |
1101 xfer->ops.cancel_send(xfer); | |
1102 } | |
1103 else | |
1104 { | |
1105 if (xfer->ops.cancel_recv != NULL) | |
1106 xfer->ops.cancel_recv(xfer); | |
1107 } | |
1108 | |
1109 if (xfer->watcher != 0) { | |
1110 gaim_input_remove(xfer->watcher); | |
1111 xfer->watcher = 0; | |
1112 } | |
1113 | |
1114 if (xfer->fd != 0) | |
1115 close(xfer->fd); | |
1116 | |
1117 if (xfer->dest_fp != NULL) { | |
1118 fclose(xfer->dest_fp); | |
1119 xfer->dest_fp = NULL; | |
1120 } | |
1121 | |
1122 ui_ops = gaim_xfer_get_ui_ops(xfer); | |
1123 | |
1124 if (ui_ops != NULL && ui_ops->cancel_remote != NULL) | |
1125 ui_ops->cancel_remote(xfer); | |
1126 | |
1127 xfer->bytes_remaining = 0; | |
1128 | |
1129 gaim_xfer_unref(xfer); | |
1130 } | |
1131 | |
1132 void | |
1133 gaim_xfer_error(GaimXferType type, GaimAccount *account, const char *who, const char *msg) | |
1134 { | |
1135 char *title; | |
1136 | |
1137 g_return_if_fail(msg != NULL); | |
1138 g_return_if_fail(type != GAIM_XFER_UNKNOWN); | |
1139 | |
1140 if (account) { | |
1141 GaimBuddy *buddy; | |
1142 buddy = gaim_find_buddy(account, who); | |
1143 if (buddy) | |
1144 who = gaim_buddy_get_alias(buddy); | |
1145 } | |
1146 | |
1147 if (type == GAIM_XFER_SEND) | |
1148 title = g_strdup_printf(_("File transfer to %s failed."), who); | |
1149 else | |
1150 title = g_strdup_printf(_("File transfer from %s failed."), who); | |
1151 | |
1152 gaim_notify_error(NULL, NULL, title, msg); | |
1153 | |
1154 g_free(title); | |
1155 } | |
1156 | |
1157 void | |
1158 gaim_xfer_update_progress(GaimXfer *xfer) | |
1159 { | |
1160 GaimXferUiOps *ui_ops; | |
1161 | |
1162 g_return_if_fail(xfer != NULL); | |
1163 | |
1164 ui_ops = gaim_xfer_get_ui_ops(xfer); | |
1165 if (ui_ops != NULL && ui_ops->update_progress != NULL) | |
1166 ui_ops->update_progress(xfer, gaim_xfer_get_progress(xfer)); | |
1167 } | |
1168 | |
1169 | |
1170 /************************************************************************** | |
1171 * File Transfer Subsystem API | |
1172 **************************************************************************/ | |
1173 void * | |
1174 gaim_xfers_get_handle(void) { | |
1175 static int handle = 0; | |
1176 | |
1177 return &handle; | |
1178 } | |
1179 | |
1180 void | |
1181 gaim_xfers_init(void) { | |
1182 void *handle = gaim_xfers_get_handle(); | |
1183 | |
1184 /* register signals */ | |
1185 gaim_signal_register(handle, "file-recv-accept", | |
14618
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1186 gaim_marshal_VOID__POINTER, NULL, 1, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1187 gaim_value_new(GAIM_TYPE_SUBTYPE, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1188 GAIM_SUBTYPE_XFER)); |
14192 | 1189 gaim_signal_register(handle, "file-send-accept", |
14618
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1190 gaim_marshal_VOID__POINTER, NULL, 1, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1191 gaim_value_new(GAIM_TYPE_SUBTYPE, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1192 GAIM_SUBTYPE_XFER)); |
14192 | 1193 gaim_signal_register(handle, "file-recv-start", |
14618
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1194 gaim_marshal_VOID__POINTER, NULL, 1, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1195 gaim_value_new(GAIM_TYPE_SUBTYPE, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1196 GAIM_SUBTYPE_XFER)); |
14192 | 1197 gaim_signal_register(handle, "file-send-start", |
14618
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1198 gaim_marshal_VOID__POINTER, NULL, 1, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1199 gaim_value_new(GAIM_TYPE_SUBTYPE, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1200 GAIM_SUBTYPE_XFER)); |
14192 | 1201 gaim_signal_register(handle, "file-send-cancel", |
14618
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1202 gaim_marshal_VOID__POINTER, NULL, 1, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1203 gaim_value_new(GAIM_TYPE_SUBTYPE, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1204 GAIM_SUBTYPE_XFER)); |
14192 | 1205 gaim_signal_register(handle, "file-recv-cancel", |
14618
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1206 gaim_marshal_VOID__POINTER, NULL, 1, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1207 gaim_value_new(GAIM_TYPE_SUBTYPE, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1208 GAIM_SUBTYPE_XFER)); |
14192 | 1209 gaim_signal_register(handle, "file-send-complete", |
14618
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1210 gaim_marshal_VOID__POINTER, NULL, 1, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1211 gaim_value_new(GAIM_TYPE_SUBTYPE, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1212 GAIM_SUBTYPE_XFER)); |
14192 | 1213 gaim_signal_register(handle, "file-recv-complete", |
14618
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1214 gaim_marshal_VOID__POINTER, NULL, 1, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1215 gaim_value_new(GAIM_TYPE_SUBTYPE, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1216 GAIM_SUBTYPE_XFER)); |
14192 | 1217 gaim_signal_register(handle, "file-recv-request", |
14618
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1218 gaim_marshal_VOID__POINTER, NULL, 1, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1219 gaim_value_new(GAIM_TYPE_SUBTYPE, |
2f0b4d0de5bb
[gaim-migrate @ 17346]
Etan Reisner <pidgin@unreliablesource.net>
parents:
14192
diff
changeset
|
1220 GAIM_SUBTYPE_XFER)); |
14192 | 1221 } |
1222 | |
1223 void | |
1224 gaim_xfers_uninit(void) { | |
1225 gaim_signals_disconnect_by_handle(gaim_xfers_get_handle()); | |
1226 } | |
1227 | |
1228 void | |
1229 gaim_xfers_set_ui_ops(GaimXferUiOps *ops) { | |
1230 xfer_ui_ops = ops; | |
1231 } | |
1232 | |
1233 GaimXferUiOps * | |
1234 gaim_xfers_get_ui_ops(void) { | |
1235 return xfer_ui_ops; | |
1236 } |