src/ft.c

changeset 8231
347c8992c445
parent 8208
fc5adf1d373c
child 8262
fa907a654af9
equal deleted inserted replaced
8230:0241cfde5c03 8231:347c8992c445
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * 23 *
24 */ 24 */
25 #include "internal.h" 25 #include "internal.h"
26 #include "ft.h" 26 #include "ft.h"
27 #include "network.h"
27 #include "notify.h" 28 #include "notify.h"
28 #include "prefs.h" 29 #include "prefs.h"
29 #include "proxy.h" 30 #include "proxy.h"
30 31
31 static GaimXferUiOps *xfer_ui_ops = NULL; 32 static GaimXferUiOps *xfer_ui_ops = NULL;
46 xfer->type = type; 47 xfer->type = type;
47 xfer->account = account; 48 xfer->account = account;
48 xfer->who = g_strdup(who); 49 xfer->who = g_strdup(who);
49 xfer->ui_ops = gaim_xfers_get_ui_ops(); 50 xfer->ui_ops = gaim_xfers_get_ui_ops();
50 51
51 xfer->local_ip = g_strdup(gaim_xfers_get_ip_for_account(account));
52
53 ui_ops = gaim_xfer_get_ui_ops(xfer); 52 ui_ops = gaim_xfer_get_ui_ops(xfer);
54 53
55 if (ui_ops != NULL && ui_ops->new_xfer != NULL) 54 if (ui_ops != NULL && ui_ops->new_xfer != NULL)
56 ui_ops->new_xfer(xfer); 55 ui_ops->new_xfer(xfer);
57 56
75 74
76 g_free(xfer->who); 75 g_free(xfer->who);
77 g_free(xfer->filename); 76 g_free(xfer->filename);
78 77
79 if (xfer->remote_ip != NULL) g_free(xfer->remote_ip); 78 if (xfer->remote_ip != NULL) g_free(xfer->remote_ip);
80 if (xfer->local_ip != NULL) g_free(xfer->local_ip);
81 79
82 if (xfer->local_filename != NULL) 80 if (xfer->local_filename != NULL)
83 g_free(xfer->local_filename); 81 g_free(xfer->local_filename);
84 82
85 g_free(xfer); 83 g_free(xfer);
278 276
279 return ((double)gaim_xfer_get_bytes_sent(xfer) / 277 return ((double)gaim_xfer_get_bytes_sent(xfer) /
280 (double)gaim_xfer_get_size(xfer)); 278 (double)gaim_xfer_get_size(xfer));
281 } 279 }
282 280
283 const char *
284 gaim_xfer_get_local_ip(const GaimXfer *xfer)
285 {
286 g_return_val_if_fail(xfer != NULL, NULL);
287
288 return xfer->local_ip;
289 }
290
291 unsigned int 281 unsigned int
292 gaim_xfer_get_local_port(const GaimXfer *xfer) 282 gaim_xfer_get_local_port(const GaimXfer *xfer)
293 { 283 {
294 g_return_val_if_fail(xfer != NULL, -1); 284 g_return_val_if_fail(xfer != NULL, -1);
295 285
392 382
393 xfer->ops.request_denied = fnc; 383 xfer->ops.request_denied = fnc;
394 } 384 }
395 385
396 void 386 void
397 gaim_xfer_set_read_fnc(GaimXfer *xfer, size_t (*fnc)(char **, GaimXfer *)) 387 gaim_xfer_set_read_fnc(GaimXfer *xfer, ssize_t (*fnc)(char **, GaimXfer *))
398 { 388 {
399 g_return_if_fail(xfer != NULL); 389 g_return_if_fail(xfer != NULL);
400 390
401 xfer->ops.read = fnc; 391 xfer->ops.read = fnc;
402 } 392 }
403 393
404 void 394 void
405 gaim_xfer_set_write_fnc(GaimXfer *xfer, 395 gaim_xfer_set_write_fnc(GaimXfer *xfer,
406 size_t (*fnc)(const char *, size_t, GaimXfer *)) 396 ssize_t (*fnc)(const char *, size_t, GaimXfer *))
407 { 397 {
408 g_return_if_fail(xfer != NULL); 398 g_return_if_fail(xfer != NULL);
409 399
410 xfer->ops.write = fnc; 400 xfer->ops.write = fnc;
411 } 401 }
449 g_return_if_fail(xfer != NULL); 439 g_return_if_fail(xfer != NULL);
450 440
451 xfer->ops.cancel_recv = fnc; 441 xfer->ops.cancel_recv = fnc;
452 } 442 }
453 443
454 size_t 444 ssize_t
455 gaim_xfer_read(GaimXfer *xfer, char **buffer) 445 gaim_xfer_read(GaimXfer *xfer, char **buffer)
456 { 446 {
457 size_t s, r; 447 ssize_t s, r;
458 448
459 g_return_val_if_fail(xfer != NULL, 0); 449 g_return_val_if_fail(xfer != NULL, 0);
460 g_return_val_if_fail(buffer != NULL, 0); 450 g_return_val_if_fail(buffer != NULL, 0);
461 451
462 if (gaim_xfer_get_size(xfer) == 0) 452 if (gaim_xfer_get_size(xfer) == 0)
476 } 466 }
477 467
478 return r; 468 return r;
479 } 469 }
480 470
481 size_t 471 ssize_t
482 gaim_xfer_write(GaimXfer *xfer, const char *buffer, size_t size) 472 gaim_xfer_write(GaimXfer *xfer, const char *buffer, size_t size)
483 { 473 {
484 size_t r, s; 474 ssize_t r, s;
485 475
486 g_return_val_if_fail(xfer != NULL, 0); 476 g_return_val_if_fail(xfer != NULL, 0);
487 g_return_val_if_fail(buffer != NULL, 0); 477 g_return_val_if_fail(buffer != NULL, 0);
488 g_return_val_if_fail(size != 0, 0); 478 g_return_val_if_fail(size != 0, 0);
489 479
490 s = MIN(gaim_xfer_get_bytes_remaining(xfer), size); 480 s = MIN(gaim_xfer_get_bytes_remaining(xfer), size);
491 481
492 if (xfer->ops.write != NULL) 482 if (xfer->ops.write != NULL) {
493 r = (xfer->ops.write)(buffer, s, xfer); 483 r = (xfer->ops.write)(buffer, s, xfer);
494 else 484 } else {
495 r = write(xfer->fd, buffer, s); 485 r = write(xfer->fd, buffer, s);
486 if ((gaim_xfer_get_bytes_sent(xfer)+r) >= gaim_xfer_get_size(xfer))
487 gaim_xfer_set_completed(xfer, TRUE);
488 }
496 489
497 return r; 490 return r;
498 } 491 }
499 492
500 static void 493 static void
505 char *buffer = NULL; 498 char *buffer = NULL;
506 size_t r; 499 size_t r;
507 500
508 if (condition & GAIM_INPUT_READ) { 501 if (condition & GAIM_INPUT_READ) {
509 r = gaim_xfer_read(xfer, &buffer); 502 r = gaim_xfer_read(xfer, &buffer);
510 if (r > 0) 503 if (r > 0) {
511 fwrite(buffer, 1, r, xfer->dest_fp); 504 fwrite(buffer, 1, r, xfer->dest_fp);
505 } else {
506 gaim_xfer_cancel_remote(xfer);
507 return;
508 }
512 } 509 }
513 else { 510 else {
514 size_t s = MIN(gaim_xfer_get_bytes_remaining(xfer), 4096); 511 size_t s = MIN(gaim_xfer_get_bytes_remaining(xfer), 4096);
515 512
516 buffer = g_malloc0(s); 513 buffer = g_malloc0(s);
518 fread(buffer, 1, s, xfer->dest_fp); 515 fread(buffer, 1, s, xfer->dest_fp);
519 516
520 /* Write as much as we're allowed to. */ 517 /* Write as much as we're allowed to. */
521 r = gaim_xfer_write(xfer, buffer, s); 518 r = gaim_xfer_write(xfer, buffer, s);
522 519
523 if (r < s) { 520 if (r == -1) {
521 gaim_xfer_cancel_remote(xfer);
522 g_free(buffer);
523 return;
524 } else if (r < s) {
524 /* We have to seek back in the file now. */ 525 /* We have to seek back in the file now. */
525 fseek(xfer->dest_fp, r - s, SEEK_CUR); 526 fseek(xfer->dest_fp, r - s, SEEK_CUR);
526 } 527 }
527 } 528 }
528 529
763 } 764 }
764 765
765 /************************************************************************** 766 /**************************************************************************
766 * File Transfer Subsystem API 767 * File Transfer Subsystem API
767 **************************************************************************/ 768 **************************************************************************/
768 void
769 gaim_xfers_set_local_ip(const char *ip)
770 {
771 g_return_if_fail(ip != NULL);
772
773 gaim_prefs_set_string("/core/ft/public_ip", ip);
774 }
775
776 const char *
777 gaim_xfers_get_local_ip(void)
778 {
779 const char *ip;
780
781 ip = gaim_prefs_get_string("/core/ft/public_ip");
782
783 if (ip == NULL || *ip == '\0')
784 return NULL;
785
786 return ip;
787 }
788
789 const char *
790 gaim_xfers_get_local_system_ip(void)
791 {
792 struct hostent *host;
793 char localhost[129];
794 long unsigned add;
795 static char ip[46];
796
797 if (gethostname(localhost, 128) < 0)
798 return NULL;
799
800 if ((host = gethostbyname(localhost)) == NULL)
801 return NULL;
802
803 memcpy(&add, host->h_addr_list[0], 4);
804 add = htonl(add);
805
806 g_snprintf(ip, 16, "%lu.%lu.%lu.%lu",
807 ((add >> 24) & 255),
808 ((add >> 16) & 255),
809 ((add >> 8) & 255),
810 add & 255);
811
812 return ip;
813 }
814
815 const char *
816 gaim_xfers_get_ip_for_account(const GaimAccount *account)
817 {
818 g_return_val_if_fail(account != NULL, NULL);
819
820 if (gaim_account_get_public_ip(account) != NULL)
821 return gaim_account_get_public_ip(account);
822 else if (gaim_xfers_get_local_ip() != NULL)
823 return gaim_xfers_get_local_ip();
824 else
825 return gaim_xfers_get_local_system_ip();
826 }
827
828 void
829 gaim_xfers_init(void)
830 {
831 gaim_prefs_add_none("/core/ft");
832 gaim_prefs_add_string("/core/ft/public_ip", "");
833 }
834 769
835 void 770 void
836 gaim_xfers_set_ui_ops(GaimXferUiOps *ops) 771 gaim_xfers_set_ui_ops(GaimXferUiOps *ops)
837 { 772 {
838 xfer_ui_ops = ops; 773 xfer_ui_ops = ops;

mercurial