comparison libpurple/protocols/jabber/si.c @ 32827:4a34689eeb33 default tip

merged from im.pidgin.pidgin
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Sat, 19 Nov 2011 14:42:54 +0900
parents 0f94ec89f0bc fb5b5f6cf111
children
comparison
equal deleted inserted replaced
32692:0f94ec89f0bc 32827:4a34689eeb33
393 jsx->rxlen += len; 393 jsx->rxlen += len;
394 394
395 if (jsx->rxlen < jsx->rxmaxlen) 395 if (jsx->rxlen < jsx->rxmaxlen)
396 return; 396 return;
397 397
398 purple_input_remove(xfer->watcher); 398 purple_input_remove(purple_xfer_get_watcher(xfer));
399 xfer->watcher = 0; 399 purple_xfer_set_watcher(xfer, 0);
400 g_free(jsx->rxqueue); 400 g_free(jsx->rxqueue);
401 jsx->rxqueue = NULL; 401 jsx->rxqueue = NULL;
402 402
403 /* Before actually starting sending the file, we need to wait until the 403 /* Before actually starting sending the file, we need to wait until the
404 * recipient sends the IQ result with <streamhost-used/> 404 * recipient sends the IQ result with <streamhost-used/>
462 462
463 /* Have we not read all of DST.ADDR and the following 2-byte port number? */ 463 /* Have we not read all of DST.ADDR and the following 2-byte port number? */
464 if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2) 464 if(jsx->rxlen - 5 < jsx->rxqueue[4] + 2)
465 return; 465 return;
466 466
467 purple_input_remove(xfer->watcher); 467 purple_input_remove(purple_xfer_get_watcher(xfer));
468 xfer->watcher = 0; 468 purple_xfer_set_watcher(xfer, 0);
469 469
470 dstaddr = g_strdup_printf("%s%s@%s/%s%s", jsx->stream_id, 470 dstaddr = g_strdup_printf("%s%s@%s/%s%s", jsx->stream_id,
471 jsx->js->user->node, jsx->js->user->domain, 471 jsx->js->user->node, jsx->js->user->domain,
472 jsx->js->user->resource, purple_xfer_get_remote_user(xfer)); 472 jsx->js->user->resource, purple_xfer_get_remote_user(xfer));
473 473
508 jsx->rxqueue[4] = strlen(host); 508 jsx->rxqueue[4] = strlen(host);
509 memcpy(jsx->rxqueue + 5, host, strlen(host)); 509 memcpy(jsx->rxqueue + 5, host, strlen(host));
510 jsx->rxqueue[5+strlen(host)] = 0x00; 510 jsx->rxqueue[5+strlen(host)] = 0x00;
511 jsx->rxqueue[6+strlen(host)] = 0x00; 511 jsx->rxqueue[6+strlen(host)] = 0x00;
512 512
513 xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE, 513 purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE,
514 jabber_si_xfer_bytestreams_send_read_again_resp_cb, xfer); 514 jabber_si_xfer_bytestreams_send_read_again_resp_cb, xfer));
515 jabber_si_xfer_bytestreams_send_read_again_resp_cb(xfer, source, 515 jabber_si_xfer_bytestreams_send_read_again_resp_cb(xfer, source,
516 PURPLE_INPUT_WRITE); 516 PURPLE_INPUT_WRITE);
517 } 517 }
518 518
519 static void 519 static void
539 if (jsx->rxlen < jsx->rxmaxlen) 539 if (jsx->rxlen < jsx->rxmaxlen)
540 return; 540 return;
541 541
542 /* If we sent a "Success", wait for a response, otherwise give up and cancel */ 542 /* If we sent a "Success", wait for a response, otherwise give up and cancel */
543 if (jsx->rxqueue[1] == 0x00) { 543 if (jsx->rxqueue[1] == 0x00) {
544 purple_input_remove(xfer->watcher); 544 purple_input_remove(purple_xfer_get_watcher(xfer));
545 xfer->watcher = purple_input_add(source, PURPLE_INPUT_READ, 545 purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_READ,
546 jabber_si_xfer_bytestreams_send_read_again_cb, xfer); 546 jabber_si_xfer_bytestreams_send_read_again_cb, xfer));
547 g_free(jsx->rxqueue); 547 g_free(jsx->rxqueue);
548 jsx->rxqueue = NULL; 548 jsx->rxqueue = NULL;
549 jsx->rxlen = 0; 549 jsx->rxlen = 0;
550 } else { 550 } else {
551 close(source); 551 close(source);
563 int len; 563 int len;
564 char buffer[256]; 564 char buffer[256];
565 565
566 purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_cb\n"); 566 purple_debug_info("jabber", "in jabber_si_xfer_bytestreams_send_read_cb\n");
567 567
568 xfer->fd = source; 568 purple_xfer_set_fd(xfer, source);
569 569
570 /** Try to read the SOCKS5 header */ 570 /** Try to read the SOCKS5 header */
571 if(jsx->rxlen < 2) { 571 if(jsx->rxlen < 2) {
572 purple_debug_info("jabber", "reading those first two bytes\n"); 572 purple_debug_info("jabber", "reading those first two bytes\n");
573 len = read(source, buffer, 2 - jsx->rxlen); 573 len = read(source, buffer, 2 - jsx->rxlen);
619 jsx->rxlen = 0; 619 jsx->rxlen = 0;
620 jsx->rxmaxlen = 2; 620 jsx->rxmaxlen = 2;
621 jsx->rxqueue = g_malloc(jsx->rxmaxlen); 621 jsx->rxqueue = g_malloc(jsx->rxmaxlen);
622 jsx->rxqueue[0] = 0x05; 622 jsx->rxqueue[0] = 0x05;
623 jsx->rxqueue[1] = 0x00; 623 jsx->rxqueue[1] = 0x00;
624 purple_input_remove(xfer->watcher); 624 purple_input_remove(purple_xfer_get_watcher(xfer));
625 xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE, 625 purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE,
626 jabber_si_xfer_bytestreams_send_read_response_cb, 626 jabber_si_xfer_bytestreams_send_read_response_cb,
627 xfer); 627 xfer));
628 jabber_si_xfer_bytestreams_send_read_response_cb(xfer, 628 jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
629 source, PURPLE_INPUT_WRITE); 629 source, PURPLE_INPUT_WRITE);
630 jsx->rxqueue = NULL; 630 jsx->rxqueue = NULL;
631 jsx->rxlen = 0; 631 jsx->rxlen = 0;
632 return; 632 return;
637 jsx->rxlen = 0; 637 jsx->rxlen = 0;
638 jsx->rxmaxlen = 2; 638 jsx->rxmaxlen = 2;
639 jsx->rxqueue = g_malloc(jsx->rxmaxlen); 639 jsx->rxqueue = g_malloc(jsx->rxmaxlen);
640 jsx->rxqueue[0] = 0x05; 640 jsx->rxqueue[0] = 0x05;
641 jsx->rxqueue[1] = 0xFF; 641 jsx->rxqueue[1] = 0xFF;
642 purple_input_remove(xfer->watcher); 642 purple_input_remove(purple_xfer_get_watcher(xfer));
643 xfer->watcher = purple_input_add(source, PURPLE_INPUT_WRITE, 643 purple_xfer_set_watcher(xfer, purple_input_add(source, PURPLE_INPUT_WRITE,
644 jabber_si_xfer_bytestreams_send_read_response_cb, xfer); 644 jabber_si_xfer_bytestreams_send_read_response_cb, xfer));
645 jabber_si_xfer_bytestreams_send_read_response_cb(xfer, 645 jabber_si_xfer_bytestreams_send_read_response_cb(xfer,
646 source, PURPLE_INPUT_WRITE); 646 source, PURPLE_INPUT_WRITE);
647 } 647 }
648 648
649 static gint 649 static gint
674 purple_debug_warning("jabber", "accept: %s\n", g_strerror(errno)); 674 purple_debug_warning("jabber", "accept: %s\n", g_strerror(errno));
675 /* Don't cancel the ft - allow it to fall to the next streamhost.*/ 675 /* Don't cancel the ft - allow it to fall to the next streamhost.*/
676 return; 676 return;
677 } 677 }
678 678
679 purple_input_remove(xfer->watcher); 679 purple_input_remove(purple_xfer_get_watcher(xfer));
680 close(source); 680 close(source);
681 jsx->local_streamhost_fd = -1; 681 jsx->local_streamhost_fd = -1;
682 682
683 flags = fcntl(acceptfd, F_GETFL); 683 flags = fcntl(acceptfd, F_GETFL);
684 fcntl(acceptfd, F_SETFL, flags | O_NONBLOCK); 684 fcntl(acceptfd, F_SETFL, flags | O_NONBLOCK);
685 #ifndef _WIN32 685 #ifndef _WIN32
686 fcntl(acceptfd, F_SETFD, FD_CLOEXEC); 686 fcntl(acceptfd, F_SETFD, FD_CLOEXEC);
687 #endif 687 #endif
688 688
689 xfer->watcher = purple_input_add(acceptfd, PURPLE_INPUT_READ, 689 purple_xfer_set_watcher(xfer, purple_input_add(acceptfd, PURPLE_INPUT_READ,
690 jabber_si_xfer_bytestreams_send_read_cb, xfer); 690 jabber_si_xfer_bytestreams_send_read_cb, xfer));
691 } 691 }
692 692
693 static void 693 static void
694 jabber_si_connect_proxy_cb(JabberStream *js, const char *from, 694 jabber_si_connect_proxy_cb(JabberStream *js, const char *from,
695 JabberIqType type, const char *id, 695 JabberIqType type, const char *id,
761 { 761 {
762 gchar *my_jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node, 762 gchar *my_jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
763 jsx->js->user->domain, jsx->js->user->resource); 763 jsx->js->user->domain, jsx->js->user->resource);
764 if (!strcmp(jid, my_jid)) { 764 if (!strcmp(jid, my_jid)) {
765 purple_debug_info("jabber", "Got local SOCKS5 streamhost-used.\n"); 765 purple_debug_info("jabber", "Got local SOCKS5 streamhost-used.\n");
766 purple_xfer_start(xfer, xfer->fd, NULL, -1); 766 purple_xfer_start(xfer, purple_xfer_get_fd(xfer), NULL, -1);
767 } else { 767 } else {
768 /* if available, try to revert to IBB... */ 768 /* if available, try to revert to IBB... */
769 if (jsx->stream_method & STREAM_METHOD_IBB) { 769 if (jsx->stream_method & STREAM_METHOD_IBB) {
770 purple_debug_info("jabber", 770 purple_debug_info("jabber",
771 "jabber_si_connect_proxy_cb: trying to revert to IBB\n"); 771 "jabber_si_connect_proxy_cb: trying to revert to IBB\n");
785 g_free(my_jid); 785 g_free(my_jid);
786 return; 786 return;
787 } 787 }
788 788
789 /* Clean up the local streamhost - it isn't going to be used.*/ 789 /* Clean up the local streamhost - it isn't going to be used.*/
790 if (xfer->watcher > 0) { 790 if (purple_xfer_get_watcher(xfer) > 0) {
791 purple_input_remove(xfer->watcher); 791 purple_input_remove(purple_xfer_get_watcher(xfer));
792 xfer->watcher = 0; 792 purple_xfer_set_watcher(xfer, 0);
793 } 793 }
794 if (jsx->local_streamhost_fd >= 0) { 794 if (jsx->local_streamhost_fd >= 0) {
795 close(jsx->local_streamhost_fd); 795 close(jsx->local_streamhost_fd);
796 jsx->local_streamhost_fd = -1; 796 jsx->local_streamhost_fd = -1;
797 } 797 }
845 845
846 jsx->local_streamhost_fd = sock; 846 jsx->local_streamhost_fd = sock;
847 847
848 jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node, 848 jid = g_strdup_printf("%s@%s/%s", jsx->js->user->node,
849 jsx->js->user->domain, jsx->js->user->resource); 849 jsx->js->user->domain, jsx->js->user->resource);
850 xfer->local_port = purple_network_get_port_from_fd(sock); 850 purple_xfer_set_local_port(xfer, purple_network_get_port_from_fd(sock));
851 g_snprintf(port, sizeof(port), "%hu", purple_xfer_get_local_port(xfer)); 851 g_snprintf(port, sizeof(port), "%hu", purple_xfer_get_local_port(xfer));
852 852
853 public_ip = purple_network_get_my_ip(jsx->js->fd); 853 public_ip = purple_network_get_my_ip(jsx->js->fd);
854 854
855 /* Include the localhost's IPs (for in-network transfers) */ 855 /* Include the localhost's IPs (for in-network transfers) */
876 } 876 }
877 877
878 g_free(jid); 878 g_free(jid);
879 879
880 /* The listener for the local proxy */ 880 /* The listener for the local proxy */
881 xfer->watcher = purple_input_add(sock, PURPLE_INPUT_READ, 881 purple_xfer_set_watcher(xfer, purple_input_add(sock, PURPLE_INPUT_READ,
882 jabber_si_xfer_bytestreams_send_connected_cb, xfer); 882 jabber_si_xfer_bytestreams_send_connected_cb, xfer));
883 } 883 }
884 884
885 for (tmp = jsx->js->bs_proxies; tmp; tmp = tmp->next) { 885 for (tmp = jsx->js->bs_proxies; tmp; tmp = tmp->next) {
886 sh = tmp->data; 886 sh = tmp->data;
887 887
1099 1099
1100 static void 1100 static void
1101 jabber_si_xfer_ibb_sent_cb(JabberIBBSession *sess) 1101 jabber_si_xfer_ibb_sent_cb(JabberIBBSession *sess)
1102 { 1102 {
1103 PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess); 1103 PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
1104 gsize remaining = purple_xfer_get_bytes_remaining(xfer); 1104 goffset remaining = purple_xfer_get_bytes_remaining(xfer);
1105 1105
1106 if (remaining == 0) { 1106 if (remaining == 0) {
1107 /* close the session */ 1107 /* close the session */
1108 jabber_ibb_session_close(sess); 1108 jabber_ibb_session_close(sess);
1109 purple_xfer_set_completed(xfer, TRUE); 1109 purple_xfer_set_completed(xfer, TRUE);
1252 xmlnode_set_attrib(si, "profile", NS_SI_FILE_TRANSFER); 1252 xmlnode_set_attrib(si, "profile", NS_SI_FILE_TRANSFER);
1253 1253
1254 file = xmlnode_new_child(si, "file"); 1254 file = xmlnode_new_child(si, "file");
1255 xmlnode_set_namespace(file, NS_SI_FILE_TRANSFER); 1255 xmlnode_set_namespace(file, NS_SI_FILE_TRANSFER);
1256 xmlnode_set_attrib(file, "name", purple_xfer_get_filename(xfer)); 1256 xmlnode_set_attrib(file, "name", purple_xfer_get_filename(xfer));
1257 g_snprintf(buf, sizeof(buf), "%" G_GSIZE_FORMAT, purple_xfer_get_size(xfer)); 1257 g_snprintf(buf, sizeof(buf), "%" G_GOFFSET_FORMAT, purple_xfer_get_size(xfer));
1258 xmlnode_set_attrib(file, "size", buf); 1258 xmlnode_set_attrib(file, "size", buf);
1259 /* maybe later we'll do hash and date attribs */ 1259 /* maybe later we'll do hash and date attribs */
1260 1260
1261 #if ENABLE_FT_THUMBNAILS 1261 #if ENABLE_FT_THUMBNAILS
1262 /* add thumbnail, if appropriate */ 1262 /* add thumbnail, if appropriate */
1316 purple_network_listen_cancel(jsx->listen_data); 1316 purple_network_listen_cancel(jsx->listen_data);
1317 if (jsx->iq_id != NULL) 1317 if (jsx->iq_id != NULL)
1318 jabber_iq_remove_callback_by_id(js, jsx->iq_id); 1318 jabber_iq_remove_callback_by_id(js, jsx->iq_id);
1319 if (jsx->local_streamhost_fd >= 0) 1319 if (jsx->local_streamhost_fd >= 0)
1320 close(jsx->local_streamhost_fd); 1320 close(jsx->local_streamhost_fd);
1321 if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && xfer->fd >= 0) { 1321 if (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND && purple_xfer_get_fd(xfer) >= 0) {
1322 purple_debug_info("jabber", "remove port mapping\n"); 1322 purple_debug_info("jabber", "remove port mapping\n");
1323 purple_network_remove_port_mapping(xfer->fd); 1323 purple_network_remove_port_mapping(purple_xfer_get_fd(xfer));
1324 } 1324 }
1325 if (jsx->connect_timeout > 0) 1325 if (jsx->connect_timeout > 0)
1326 purple_timeout_remove(jsx->connect_timeout); 1326 purple_timeout_remove(jsx->connect_timeout);
1327 if (jsx->ibb_timeout_handle > 0) 1327 if (jsx->ibb_timeout_handle > 0)
1328 purple_timeout_remove(jsx->ibb_timeout_handle); 1328 purple_timeout_remove(jsx->ibb_timeout_handle);
1573 1573
1574 purple_request_fields_add_group(fields, group); 1574 purple_request_fields_add_group(fields, group);
1575 1575
1576 purple_request_fields(jsx->js->gc, _("Select a Resource"), msg, NULL, fields, 1576 purple_request_fields(jsx->js->gc, _("Select a Resource"), msg, NULL, fields,
1577 _("Send File"), G_CALLBACK(resource_select_ok_cb), _("Cancel"), G_CALLBACK(resource_select_cancel_cb), 1577 _("Send File"), G_CALLBACK(resource_select_ok_cb), _("Cancel"), G_CALLBACK(resource_select_cancel_cb),
1578 jsx->js->gc->account, purple_xfer_get_remote_user(xfer), NULL, xfer); 1578 purple_connection_get_account(jsx->js->gc), purple_xfer_get_remote_user(xfer), NULL, xfer);
1579 1579
1580 g_free(msg); 1580 g_free(msg);
1581 } 1581 }
1582 1582
1583 g_list_free(resources); 1583 g_list_free(resources);
1629 PurpleXfer *xfer; 1629 PurpleXfer *xfer;
1630 JabberSIXfer *jsx; 1630 JabberSIXfer *jsx;
1631 1631
1632 js = purple_connection_get_protocol_data(gc); 1632 js = purple_connection_get_protocol_data(gc);
1633 1633
1634 xfer = purple_xfer_new(gc->account, PURPLE_XFER_SEND, who); 1634 xfer = purple_xfer_new(purple_connection_get_account(gc), PURPLE_XFER_SEND, who);
1635 if (xfer) 1635 if (xfer)
1636 { 1636 {
1637 jsx = g_new0(JabberSIXfer, 1); 1637 jsx = g_new0(JabberSIXfer, 1);
1638 purple_xfer_set_protocol_data(xfer, jsx); 1638 purple_xfer_set_protocol_data(xfer, jsx);
1639 jsx->js = js; 1639 jsx->js = js;
1688 xmlnode *file, *feature, *x, *field, *option, *value; 1688 xmlnode *file, *feature, *x, *field, *option, *value;
1689 #if ENABLE_FT_THUMBNAILS 1689 #if ENABLE_FT_THUMBNAILS
1690 xmlnode *thumbnail; 1690 xmlnode *thumbnail;
1691 #endif 1691 #endif
1692 const char *stream_id, *filename, *filesize_c, *profile; 1692 const char *stream_id, *filename, *filesize_c, *profile;
1693 guint64 filesize_64 = 0; 1693 goffset filesize = 0;
1694 size_t filesize = 0;
1695 1694
1696 if(!(profile = xmlnode_get_attrib(si, "profile")) || 1695 if(!(profile = xmlnode_get_attrib(si, "profile")) ||
1697 strcmp(profile, NS_SI_FILE_TRANSFER)) 1696 strcmp(profile, NS_SI_FILE_TRANSFER))
1698 return; 1697 return;
1699 1698
1705 1704
1706 if(!(filename = xmlnode_get_attrib(file, "name"))) 1705 if(!(filename = xmlnode_get_attrib(file, "name")))
1707 return; 1706 return;
1708 1707
1709 if((filesize_c = xmlnode_get_attrib(file, "size"))) 1708 if((filesize_c = xmlnode_get_attrib(file, "size")))
1710 filesize_64 = g_ascii_strtoull(filesize_c, NULL, 10); 1709 filesize = g_ascii_strtoull(filesize_c, NULL, 10);
1711 /* TODO 3.0.0: When the core uses a guint64, this is redundant.
1712 * See #8477.
1713 */
1714 if (filesize_64 > G_MAXSIZE) {
1715 /* Should this pop up a warning? */
1716 purple_debug_warning("jabber", "Unable to transfer file (too large)"
1717 " -- see #8477 for more details.");
1718 return;
1719 }
1720 filesize = filesize_64;
1721 1710
1722 if(!(feature = xmlnode_get_child(si, "feature"))) 1711 if(!(feature = xmlnode_get_child(si, "feature")))
1723 return; 1712 return;
1724 1713
1725 if(!(x = xmlnode_get_child_with_namespace(feature, "x", "jabber:x:data"))) 1714 if(!(x = xmlnode_get_child_with_namespace(feature, "x", "jabber:x:data")))
1766 1755
1767 jsx->js = js; 1756 jsx->js = js;
1768 jsx->stream_id = g_strdup(stream_id); 1757 jsx->stream_id = g_strdup(stream_id);
1769 jsx->iq_id = g_strdup(id); 1758 jsx->iq_id = g_strdup(id);
1770 1759
1771 xfer = purple_xfer_new(js->gc->account, PURPLE_XFER_RECEIVE, from); 1760 xfer = purple_xfer_new(purple_connection_get_account(js->gc), PURPLE_XFER_RECEIVE, from);
1772 g_return_if_fail(xfer != NULL); 1761 g_return_if_fail(xfer != NULL);
1773 1762
1774 purple_xfer_set_protocol_data(xfer, jsx); 1763 purple_xfer_set_protocol_data(xfer, jsx);
1775 1764
1776 purple_xfer_set_filename(xfer, filename); 1765 purple_xfer_set_filename(xfer, filename);