diff options
| author | Magnus Damm <magnus.damm@gmail.com> | 2009-11-08 18:00:59 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-11-08 18:02:53 +0100 |
| commit | bbd423530f58ab695030f3d26cb81089a2f7a945 (patch) | |
| tree | e94fafe270ef440f2ca3d68a29ecc14a588812a4 | |
| parent | f5914992f316f8a628505067e108e7ba5a9590ba (diff) | |
| download | busybox-w32-bbd423530f58ab695030f3d26cb81089a2f7a945.tar.gz busybox-w32-bbd423530f58ab695030f3d26cb81089a2f7a945.tar.bz2 busybox-w32-bbd423530f58ab695030f3d26cb81089a2f7a945.zip | |
tftp: extend tsize support a little
function old new delta
tftp_protocol 1624 1662 +38
tftpd_main 495 513 +18
tftp_main 274 276 +2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 58/0) Total: 58 bytes
Signed-off-by: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
| -rw-r--r-- | networking/tftp.c | 96 |
1 files changed, 57 insertions, 39 deletions
diff --git a/networking/tftp.c b/networking/tftp.c index 9b08c147a..c2d3ccfa8 100644 --- a/networking/tftp.c +++ b/networking/tftp.c | |||
| @@ -110,9 +110,9 @@ static int tftp_blksize_check(const char *blksize_str, int maxsize) | |||
| 110 | bb_error_msg("bad blocksize '%s'", blksize_str); | 110 | bb_error_msg("bad blocksize '%s'", blksize_str); |
| 111 | return -1; | 111 | return -1; |
| 112 | } | 112 | } |
| 113 | #if ENABLE_TFTP_DEBUG | 113 | # if ENABLE_TFTP_DEBUG |
| 114 | bb_error_msg("using blksize %u", blksize); | 114 | bb_error_msg("using blksize %u", blksize); |
| 115 | #endif | 115 | # endif |
| 116 | return blksize; | 116 | return blksize; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| @@ -154,19 +154,18 @@ static char *tftp_get_option(const char *option, char *buf, int len) | |||
| 154 | #endif | 154 | #endif |
| 155 | 155 | ||
| 156 | static int tftp_protocol( | 156 | static int tftp_protocol( |
| 157 | len_and_sockaddr *our_lsa, /* NULL if tftp, !NULL if tftpd */ | 157 | /* NULL if tftp, !NULL if tftpd: */ |
| 158 | len_and_sockaddr *our_lsa, | ||
| 158 | len_and_sockaddr *peer_lsa, | 159 | len_and_sockaddr *peer_lsa, |
| 159 | const char *local_file | 160 | const char *local_file |
| 160 | IF_TFTP(, const char *remote_file) | 161 | IF_TFTP(, const char *remote_file) |
| 161 | IF_FEATURE_TFTP_BLOCKSIZE(IF_TFTPD(, void *tsize)) | ||
| 162 | IF_FEATURE_TFTP_BLOCKSIZE(, int blksize)) | ||
| 163 | { | ||
| 164 | #if !ENABLE_TFTP | 162 | #if !ENABLE_TFTP |
| 165 | # define remote_file NULL | 163 | # define remote_file NULL |
| 166 | #endif | 164 | #endif |
| 167 | #if !(ENABLE_FEATURE_TFTP_BLOCKSIZE && ENABLE_TFTPD) | 165 | /* 1 for tftp; 1/0 for tftpd depending whether client asked about it: */ |
| 168 | # define tsize NULL | 166 | IF_FEATURE_TFTP_BLOCKSIZE(, off_t transfer_size) |
| 169 | #endif | 167 | IF_FEATURE_TFTP_BLOCKSIZE(, int blksize)) |
| 168 | { | ||
| 170 | #if !ENABLE_FEATURE_TFTP_BLOCKSIZE | 169 | #if !ENABLE_FEATURE_TFTP_BLOCKSIZE |
| 171 | enum { blksize = TFTP_BLKSIZE_DEFAULT }; | 170 | enum { blksize = TFTP_BLKSIZE_DEFAULT }; |
| 172 | #endif | 171 | #endif |
| @@ -270,7 +269,7 @@ static int tftp_protocol( | |||
| 270 | } | 269 | } |
| 271 | /* gcc 4.3.1 would NOT optimize it out as it should! */ | 270 | /* gcc 4.3.1 would NOT optimize it out as it should! */ |
| 272 | #if ENABLE_FEATURE_TFTP_BLOCKSIZE | 271 | #if ENABLE_FEATURE_TFTP_BLOCKSIZE |
| 273 | if (blksize != TFTP_BLKSIZE_DEFAULT || tsize) { | 272 | if (blksize != TFTP_BLKSIZE_DEFAULT || transfer_size) { |
| 274 | /* Create and send OACK packet. */ | 273 | /* Create and send OACK packet. */ |
| 275 | /* For the download case, block_nr is still 1 - | 274 | /* For the download case, block_nr is still 1 - |
| 276 | * we expect 1st ACK from peer to be for (block_nr-1), | 275 | * we expect 1st ACK from peer to be for (block_nr-1), |
| @@ -321,41 +320,50 @@ static int tftp_protocol( | |||
| 321 | } | 320 | } |
| 322 | strcpy(cp, remote_file); | 321 | strcpy(cp, remote_file); |
| 323 | cp += len; | 322 | cp += len; |
| 324 | /* add "mode" part of the package */ | 323 | /* add "mode" part of the packet */ |
| 325 | strcpy(cp, "octet"); | 324 | strcpy(cp, "octet"); |
| 326 | cp += sizeof("octet"); | 325 | cp += sizeof("octet"); |
| 327 | 326 | ||
| 328 | #if ENABLE_FEATURE_TFTP_BLOCKSIZE | 327 | # if ENABLE_FEATURE_TFTP_BLOCKSIZE |
| 329 | if (blksize == TFTP_BLKSIZE_DEFAULT) | 328 | if (blksize == TFTP_BLKSIZE_DEFAULT && !transfer_size) |
| 330 | goto send_pkt; | 329 | goto send_pkt; |
| 331 | 330 | ||
| 332 | /* Non-standard blocksize: add option to pkt */ | 331 | /* Need to add option to pkt */ |
| 333 | if ((&xbuf[io_bufsize - 1] - cp) < sizeof("blksize NNNNN")) { | 332 | if ((&xbuf[io_bufsize - 1] - cp) < sizeof("blksize NNNNN tsize ") + sizeof(transfer_size)*3) { |
| 334 | bb_error_msg("remote filename is too long"); | 333 | bb_error_msg("remote filename is too long"); |
| 335 | goto ret; | 334 | goto ret; |
| 336 | } | 335 | } |
| 337 | expect_OACK = 1; | 336 | expect_OACK = 1; |
| 338 | #endif | 337 | # endif |
| 339 | #endif /* ENABLE_TFTP */ | 338 | #endif /* ENABLE_TFTP */ |
| 340 | 339 | ||
| 341 | #if ENABLE_FEATURE_TFTP_BLOCKSIZE | 340 | #if ENABLE_FEATURE_TFTP_BLOCKSIZE |
| 342 | add_blksize_opt: | 341 | add_blksize_opt: |
| 343 | #if ENABLE_TFTPD | ||
| 344 | if (tsize) { | ||
| 345 | struct stat st; | ||
| 346 | /* add "tsize", <nul>, size, <nul> */ | ||
| 347 | strcpy(cp, "tsize"); | ||
| 348 | cp += sizeof("tsize"); | ||
| 349 | fstat(local_fd, &st); | ||
| 350 | cp += snprintf(cp, 10, "%u", (int) st.st_size) + 1; | ||
| 351 | } | ||
| 352 | #endif | ||
| 353 | if (blksize != TFTP_BLKSIZE_DEFAULT) { | 342 | if (blksize != TFTP_BLKSIZE_DEFAULT) { |
| 354 | /* add "blksize", <nul>, blksize, <nul> */ | 343 | /* add "blksize", <nul>, blksize, <nul> */ |
| 355 | strcpy(cp, "blksize"); | 344 | strcpy(cp, "blksize"); |
| 356 | cp += sizeof("blksize"); | 345 | cp += sizeof("blksize"); |
| 357 | cp += snprintf(cp, 6, "%d", blksize) + 1; | 346 | cp += snprintf(cp, 6, "%d", blksize) + 1; |
| 358 | } | 347 | } |
| 348 | if (transfer_size) { | ||
| 349 | /* add "tsize", <nul>, size, <nul> (see RFC2349) */ | ||
| 350 | /* if tftp and downloading, we send "0" (since we opened local_fd with O_TRUNC) | ||
| 351 | * and this makes server to send "tsize" option with the size */ | ||
| 352 | /* if tftp and uploading, we send file size (maybe dont, to not confuse old servers???) */ | ||
| 353 | /* if tftpd and downloading, we are answering to client's request */ | ||
| 354 | /* if tftpd and uploading: transfer_size == 0, this code is not executed */ | ||
| 355 | struct stat st; | ||
| 356 | strcpy(cp, "tsize"); | ||
| 357 | cp += sizeof("tsize"); | ||
| 358 | st.st_size = 0; | ||
| 359 | fstat(local_fd, &st); | ||
| 360 | cp += sprintf(cp, "%"OFF_FMT"u", (off_t)st.st_size) + 1; | ||
| 361 | # if 0 /*ENABLE_FEATURE_TFTP_PROGRESS_BAR*/ | ||
| 362 | /* Save for progress bar. If 0 (tftp downloading), | ||
| 363 | * we look at server's reply later */ | ||
| 364 | transfer_size = st.st_size; | ||
| 365 | # endif | ||
| 366 | } | ||
| 359 | #endif | 367 | #endif |
| 360 | /* First packet is built, so skip packet generation */ | 368 | /* First packet is built, so skip packet generation */ |
| 361 | goto send_pkt; | 369 | goto send_pkt; |
| @@ -497,6 +505,14 @@ static int tftp_protocol( | |||
| 497 | } | 505 | } |
| 498 | io_bufsize = blksize + 4; | 506 | io_bufsize = blksize + 4; |
| 499 | } | 507 | } |
| 508 | # if 0 /*ENABLE_FEATURE_TFTP_PROGRESS_BAR*/ | ||
| 509 | if (transfer_size == 0) { /* if we don't know it yet */ | ||
| 510 | res = tftp_get_option("tsize", &rbuf[2], len - 2); | ||
| 511 | if (res) { | ||
| 512 | transfer_size = bb_strtoull(res, NULL, 10); | ||
| 513 | } | ||
| 514 | } | ||
| 515 | # endif | ||
| 500 | if (CMD_GET(option_mask32)) { | 516 | if (CMD_GET(option_mask32)) { |
| 501 | /* We'll send ACK for OACK, | 517 | /* We'll send ACK for OACK, |
| 502 | * such ACK has "block no" of 0 */ | 518 | * such ACK has "block no" of 0 */ |
| @@ -578,7 +594,6 @@ static int tftp_protocol( | |||
| 578 | &peer_lsa->u.sa, peer_lsa->len); | 594 | &peer_lsa->u.sa, peer_lsa->len); |
| 579 | return EXIT_FAILURE; | 595 | return EXIT_FAILURE; |
| 580 | #undef remote_file | 596 | #undef remote_file |
| 581 | #undef tsize | ||
| 582 | } | 597 | } |
| 583 | 598 | ||
| 584 | #if ENABLE_TFTP | 599 | #if ENABLE_TFTP |
| @@ -589,10 +604,10 @@ int tftp_main(int argc UNUSED_PARAM, char **argv) | |||
| 589 | len_and_sockaddr *peer_lsa; | 604 | len_and_sockaddr *peer_lsa; |
| 590 | const char *local_file = NULL; | 605 | const char *local_file = NULL; |
| 591 | const char *remote_file = NULL; | 606 | const char *remote_file = NULL; |
| 592 | #if ENABLE_FEATURE_TFTP_BLOCKSIZE | 607 | # if ENABLE_FEATURE_TFTP_BLOCKSIZE |
| 593 | const char *blksize_str = TFTP_BLKSIZE_DEFAULT_STR; | 608 | const char *blksize_str = TFTP_BLKSIZE_DEFAULT_STR; |
| 594 | int blksize; | 609 | int blksize; |
| 595 | #endif | 610 | # endif |
| 596 | int result; | 611 | int result; |
| 597 | int port; | 612 | int port; |
| 598 | IF_GETPUT(int opt;) | 613 | IF_GETPUT(int opt;) |
| @@ -610,7 +625,7 @@ int tftp_main(int argc UNUSED_PARAM, char **argv) | |||
| 610 | IF_FEATURE_TFTP_BLOCKSIZE(, &blksize_str)); | 625 | IF_FEATURE_TFTP_BLOCKSIZE(, &blksize_str)); |
| 611 | argv += optind; | 626 | argv += optind; |
| 612 | 627 | ||
| 613 | #if ENABLE_FEATURE_TFTP_BLOCKSIZE | 628 | # if ENABLE_FEATURE_TFTP_BLOCKSIZE |
| 614 | /* Check if the blksize is valid: | 629 | /* Check if the blksize is valid: |
| 615 | * RFC2348 says between 8 and 65464 */ | 630 | * RFC2348 says between 8 and 65464 */ |
| 616 | blksize = tftp_blksize_check(blksize_str, 65564); | 631 | blksize = tftp_blksize_check(blksize_str, 65564); |
| @@ -618,7 +633,7 @@ int tftp_main(int argc UNUSED_PARAM, char **argv) | |||
| 618 | //bb_error_msg("bad block size"); | 633 | //bb_error_msg("bad block size"); |
| 619 | return EXIT_FAILURE; | 634 | return EXIT_FAILURE; |
| 620 | } | 635 | } |
| 621 | #endif | 636 | # endif |
| 622 | 637 | ||
| 623 | if (remote_file) { | 638 | if (remote_file) { |
| 624 | if (!local_file) { | 639 | if (!local_file) { |
| @@ -636,16 +651,16 @@ int tftp_main(int argc UNUSED_PARAM, char **argv) | |||
| 636 | port = bb_lookup_port(argv[1], "udp", 69); | 651 | port = bb_lookup_port(argv[1], "udp", 69); |
| 637 | peer_lsa = xhost2sockaddr(argv[0], port); | 652 | peer_lsa = xhost2sockaddr(argv[0], port); |
| 638 | 653 | ||
| 639 | #if ENABLE_TFTP_DEBUG | 654 | # if ENABLE_TFTP_DEBUG |
| 640 | fprintf(stderr, "using server '%s', remote_file '%s', local_file '%s'\n", | 655 | fprintf(stderr, "using server '%s', remote_file '%s', local_file '%s'\n", |
| 641 | xmalloc_sockaddr2dotted(&peer_lsa->u.sa), | 656 | xmalloc_sockaddr2dotted(&peer_lsa->u.sa), |
| 642 | remote_file, local_file); | 657 | remote_file, local_file); |
| 643 | #endif | 658 | # endif |
| 644 | 659 | ||
| 645 | result = tftp_protocol( | 660 | result = tftp_protocol( |
| 646 | NULL /*our_lsa*/, peer_lsa, | 661 | NULL /*our_lsa*/, peer_lsa, |
| 647 | local_file, remote_file | 662 | local_file, remote_file |
| 648 | IF_FEATURE_TFTP_BLOCKSIZE(IF_TFTPD(, NULL /*tsize*/)) | 663 | IF_FEATURE_TFTP_BLOCKSIZE(, 1 /* transfer_size */) |
| 649 | IF_FEATURE_TFTP_BLOCKSIZE(, blksize) | 664 | IF_FEATURE_TFTP_BLOCKSIZE(, blksize) |
| 650 | ); | 665 | ); |
| 651 | 666 | ||
| @@ -667,7 +682,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) | |||
| 667 | const char *error_msg; | 682 | const char *error_msg; |
| 668 | int opt, result, opcode; | 683 | int opt, result, opcode; |
| 669 | IF_FEATURE_TFTP_BLOCKSIZE(int blksize = TFTP_BLKSIZE_DEFAULT;) | 684 | IF_FEATURE_TFTP_BLOCKSIZE(int blksize = TFTP_BLKSIZE_DEFAULT;) |
| 670 | IF_FEATURE_TFTP_BLOCKSIZE(char *tsize = NULL;) | 685 | IF_FEATURE_TFTP_BLOCKSIZE(off_t transfer_size = 0;) |
| 671 | 686 | ||
| 672 | INIT_G(); | 687 | INIT_G(); |
| 673 | 688 | ||
| @@ -714,7 +729,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) | |||
| 714 | if (mode >= block_buf + result || strcmp(mode, "octet") != 0) { | 729 | if (mode >= block_buf + result || strcmp(mode, "octet") != 0) { |
| 715 | goto err; | 730 | goto err; |
| 716 | } | 731 | } |
| 717 | #if ENABLE_FEATURE_TFTP_BLOCKSIZE | 732 | # if ENABLE_FEATURE_TFTP_BLOCKSIZE |
| 718 | { | 733 | { |
| 719 | char *res; | 734 | char *res; |
| 720 | char *opt_str = mode + sizeof("octet"); | 735 | char *opt_str = mode + sizeof("octet"); |
| @@ -730,10 +745,12 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) | |||
| 730 | } | 745 | } |
| 731 | } | 746 | } |
| 732 | /* did client ask us about file size? */ | 747 | /* did client ask us about file size? */ |
| 733 | tsize = tftp_get_option("tsize", opt_str, opt_len); | 748 | if (tftp_get_option("tsize", opt_str, opt_len)) { |
| 749 | transfer_size = 1; | ||
| 750 | } | ||
| 734 | } | 751 | } |
| 735 | } | 752 | } |
| 736 | #endif | 753 | # endif |
| 737 | 754 | ||
| 738 | if (!ENABLE_FEATURE_TFTP_PUT || opcode == TFTP_WRQ) { | 755 | if (!ENABLE_FEATURE_TFTP_PUT || opcode == TFTP_WRQ) { |
| 739 | if (opt & TFTPD_OPT_r) { | 756 | if (opt & TFTPD_OPT_r) { |
| @@ -743,6 +760,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) | |||
| 743 | goto err; | 760 | goto err; |
| 744 | } | 761 | } |
| 745 | IF_GETPUT(option_mask32 |= TFTP_OPT_GET;) /* will receive file's data */ | 762 | IF_GETPUT(option_mask32 |= TFTP_OPT_GET;) /* will receive file's data */ |
| 763 | transfer_size = 0; /* do not send file size, it's meaningless */ | ||
| 746 | } else { | 764 | } else { |
| 747 | IF_GETPUT(option_mask32 |= TFTP_OPT_PUT;) /* will send file's data */ | 765 | IF_GETPUT(option_mask32 |= TFTP_OPT_PUT;) /* will send file's data */ |
| 748 | } | 766 | } |
| @@ -756,7 +774,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) | |||
| 756 | result = tftp_protocol( | 774 | result = tftp_protocol( |
| 757 | our_lsa, peer_lsa, | 775 | our_lsa, peer_lsa, |
| 758 | local_file IF_TFTP(, NULL /*remote_file*/) | 776 | local_file IF_TFTP(, NULL /*remote_file*/) |
| 759 | IF_FEATURE_TFTP_BLOCKSIZE(, tsize) | 777 | IF_FEATURE_TFTP_BLOCKSIZE(, transfer_size) |
| 760 | IF_FEATURE_TFTP_BLOCKSIZE(, blksize) | 778 | IF_FEATURE_TFTP_BLOCKSIZE(, blksize) |
| 761 | ); | 779 | ); |
| 762 | 780 | ||
