| 506 if (!purple_xfer_is_completed(conn->xfer)) |
506 if (!purple_xfer_is_completed(conn->xfer)) |
| 507 purple_xfer_set_completed(conn->xfer, TRUE); |
507 purple_xfer_set_completed(conn->xfer, TRUE); |
| 508 |
508 |
| 509 purple_input_remove(conn->watcher_incoming); |
509 purple_input_remove(conn->watcher_incoming); |
| 510 conn->watcher_incoming = 0; |
510 conn->watcher_incoming = 0; |
| 511 conn->xfer->fd = conn->fd; |
511 purple_xfer_set_fd(conn->xfer, conn->fd); |
| 512 conn->fd = -1; |
512 conn->fd = -1; |
| 513 conn->disconnect_reason = OSCAR_DISCONNECT_DONE; |
513 conn->disconnect_reason = OSCAR_DISCONNECT_DONE; |
| 514 peer_connection_schedule_destroy(conn, conn->disconnect_reason, NULL); |
514 peer_connection_schedule_destroy(conn, conn->disconnect_reason, NULL); |
| 515 } |
515 } |
| 516 |
516 |
| 587 void |
587 void |
| 588 peer_oft_recvcb_init(PurpleXfer *xfer) |
588 peer_oft_recvcb_init(PurpleXfer *xfer) |
| 589 { |
589 { |
| 590 PeerConnection *conn; |
590 PeerConnection *conn; |
| 591 |
591 |
| 592 conn = xfer->data; |
592 conn = purple_xfer_get_protocol_data(xfer); |
| 593 conn->flags |= PEER_CONNECTION_FLAG_APPROVED; |
593 conn->flags |= PEER_CONNECTION_FLAG_APPROVED; |
| 594 peer_connection_trynext(conn); |
594 peer_connection_trynext(conn); |
| 595 } |
595 } |
| 596 |
596 |
| 597 void |
597 void |
| 598 peer_oft_recvcb_end(PurpleXfer *xfer) |
598 peer_oft_recvcb_end(PurpleXfer *xfer) |
| 599 { |
599 { |
| 600 PeerConnection *conn; |
600 PeerConnection *conn; |
| 601 |
601 |
| 602 conn = xfer->data; |
602 conn = purple_xfer_get_protocol_data(xfer); |
| 603 |
603 |
| 604 /* Tell the other person that we've received everything */ |
604 /* Tell the other person that we've received everything */ |
| 605 conn->fd = conn->xfer->fd; |
605 conn->fd = purple_xfer_get_fd(conn->xfer); |
| 606 conn->xfer->fd = -1; |
606 purple_xfer_set_fd(conn->xfer, -1); |
| 607 peer_oft_send_done(conn); |
607 peer_oft_send_done(conn); |
| 608 |
608 |
| 609 conn->disconnect_reason = OSCAR_DISCONNECT_DONE; |
609 conn->disconnect_reason = OSCAR_DISCONNECT_DONE; |
| 610 conn->sending_data_timer = purple_timeout_add(100, |
610 conn->sending_data_timer = purple_timeout_add(100, |
| 611 destroy_connection_when_done_sending_data, conn); |
611 destroy_connection_when_done_sending_data, conn); |
| 615 peer_oft_recvcb_ack_recv(PurpleXfer *xfer, const guchar *buffer, size_t size) |
615 peer_oft_recvcb_ack_recv(PurpleXfer *xfer, const guchar *buffer, size_t size) |
| 616 { |
616 { |
| 617 PeerConnection *conn; |
617 PeerConnection *conn; |
| 618 |
618 |
| 619 /* Update our rolling checksum. Like Walmart, yo. */ |
619 /* Update our rolling checksum. Like Walmart, yo. */ |
| 620 conn = xfer->data; |
620 conn = purple_xfer_get_protocol_data(xfer); |
| 621 conn->xferdata.recvcsum = peer_oft_checksum_chunk(buffer, |
621 conn->xferdata.recvcsum = peer_oft_checksum_chunk(buffer, |
| 622 size, conn->xferdata.recvcsum, purple_xfer_get_bytes_sent(xfer) & 1); |
622 size, conn->xferdata.recvcsum, purple_xfer_get_bytes_sent(xfer) & 1); |
| 623 } |
623 } |
| 624 |
624 |
| 625 /*******************************************************************/ |
625 /*******************************************************************/ |
| 649 |
649 |
| 650 void |
650 void |
| 651 peer_oft_sendcb_init(PurpleXfer *xfer) |
651 peer_oft_sendcb_init(PurpleXfer *xfer) |
| 652 { |
652 { |
| 653 PeerConnection *conn; |
653 PeerConnection *conn; |
| 654 size_t size; |
654 goffset size; |
| 655 |
655 |
| 656 conn = xfer->data; |
656 conn = purple_xfer_get_protocol_data(xfer); |
| 657 conn->flags |= PEER_CONNECTION_FLAG_APPROVED; |
657 conn->flags |= PEER_CONNECTION_FLAG_APPROVED; |
| 658 |
658 |
| 659 /* Make sure the file size can be represented in 32 bits */ |
659 /* Make sure the file size can be represented in 32 bits */ |
| 660 size = purple_xfer_get_size(xfer); |
660 size = purple_xfer_get_size(xfer); |
| 661 if (size > G_MAXUINT32) |
661 if (size > G_MAXUINT32) |
| 663 gchar *tmp, *size1, *size2; |
663 gchar *tmp, *size1, *size2; |
| 664 size1 = purple_str_size_to_units(size); |
664 size1 = purple_str_size_to_units(size); |
| 665 size2 = purple_str_size_to_units(G_MAXUINT32); |
665 size2 = purple_str_size_to_units(G_MAXUINT32); |
| 666 tmp = g_strdup_printf(_("File %s is %s, which is larger than " |
666 tmp = g_strdup_printf(_("File %s is %s, which is larger than " |
| 667 "the maximum size of %s."), |
667 "the maximum size of %s."), |
| 668 xfer->local_filename, size1, size2); |
668 purple_xfer_get_local_filename(xfer), size1, size2); |
| 669 purple_xfer_error(purple_xfer_get_type(xfer), |
669 purple_xfer_error(purple_xfer_get_type(xfer), |
| 670 purple_xfer_get_account(xfer), xfer->who, tmp); |
670 purple_xfer_get_account(xfer), purple_xfer_get_remote_user(xfer), tmp); |
| 671 g_free(size1); |
671 g_free(size1); |
| 672 g_free(size2); |
672 g_free(size2); |
| 673 g_free(tmp); |
673 g_free(tmp); |
| 674 peer_connection_destroy(conn, OSCAR_DISCONNECT_LOCAL_CLOSED, NULL); |
674 peer_connection_destroy(conn, OSCAR_DISCONNECT_LOCAL_CLOSED, NULL); |
| 675 return; |
675 return; |
| 687 conn->xferdata.rfcsum = 0xffff0000; |
687 conn->xferdata.rfcsum = 0xffff0000; |
| 688 conn->xferdata.recvcsum = 0xffff0000; |
688 conn->xferdata.recvcsum = 0xffff0000; |
| 689 strncpy((gchar *)conn->xferdata.idstring, "Cool FileXfer", 31); |
689 strncpy((gchar *)conn->xferdata.idstring, "Cool FileXfer", 31); |
| 690 conn->xferdata.modtime = 0; |
690 conn->xferdata.modtime = 0; |
| 691 conn->xferdata.cretime = 0; |
691 conn->xferdata.cretime = 0; |
| 692 xfer->filename = g_path_get_basename(xfer->local_filename); |
692 purple_xfer_set_filename(xfer, g_path_get_basename(purple_xfer_get_local_filename(xfer))); |
| 693 conn->xferdata.name_length = MAX(64, strlen(xfer->filename) + 1); |
693 conn->xferdata.name_length = MAX(64, strlen(purple_xfer_get_filename(xfer)) + 1); |
| 694 conn->xferdata.name = (guchar *)g_strndup(xfer->filename, conn->xferdata.name_length - 1); |
694 conn->xferdata.name = (guchar *)g_strndup(purple_xfer_get_filename(xfer), conn->xferdata.name_length - 1); |
| 695 |
695 |
| 696 peer_oft_checksum_file(conn, xfer, |
696 peer_oft_checksum_file(conn, xfer, |
| 697 peer_oft_checksum_calculated_cb, G_MAXUINT32); |
697 peer_oft_checksum_calculated_cb, G_MAXUINT32); |
| 698 } |
698 } |
| 699 |
699 |
| 711 void |
711 void |
| 712 peer_oft_sendcb_ack(PurpleXfer *xfer, const guchar *buffer, size_t size) |
712 peer_oft_sendcb_ack(PurpleXfer *xfer, const guchar *buffer, size_t size) |
| 713 { |
713 { |
| 714 PeerConnection *conn; |
714 PeerConnection *conn; |
| 715 |
715 |
| 716 conn = xfer->data; |
716 conn = purple_xfer_get_protocol_data(xfer); |
| 717 |
717 |
| 718 /* |
718 /* |
| 719 * If we're done sending, intercept the socket from the core ft code |
719 * If we're done sending, intercept the socket from the core ft code |
| 720 * and wait for the other guy to send the "done" OFT packet. |
720 * and wait for the other guy to send the "done" OFT packet. |
| 721 */ |
721 */ |
| 722 if (purple_xfer_get_bytes_remaining(xfer) <= 0) |
722 if (purple_xfer_get_bytes_remaining(xfer) <= 0) |
| 723 { |
723 { |
| 724 purple_input_remove(xfer->watcher); |
724 purple_input_remove(purple_xfer_get_watcher(xfer)); |
| 725 conn->fd = xfer->fd; |
725 conn->fd = purple_xfer_get_fd(xfer); |
| 726 xfer->fd = -1; |
726 purple_xfer_set_fd(xfer, -1); |
| 727 conn->watcher_incoming = purple_input_add(conn->fd, |
727 conn->watcher_incoming = purple_input_add(conn->fd, |
| 728 PURPLE_INPUT_READ, peer_connection_recv_cb, conn); |
728 PURPLE_INPUT_READ, peer_connection_recv_cb, conn); |
| 729 } |
729 } |
| 730 } |
730 } |
| 731 |
731 |