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 | ||