aboutsummaryrefslogtreecommitdiff
path: root/patches/tftp_timeout_multicast.diff
diff options
context:
space:
mode:
authorandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2004-03-15 08:29:22 +0000
committerandersen <andersen@69ca8d6d-28ef-0310-b511-8ec308f3f277>2004-03-15 08:29:22 +0000
commitb16674f3c1a961e0b5d6a57745f5f749d95c641e (patch)
tree4c6d2217f4d8306c59cf1096f8664e1cfd167213 /patches/tftp_timeout_multicast.diff
parente7135df4a650f9197b633784472f45602524855b (diff)
downloadbusybox-w32-b16674f3c1a961e0b5d6a57745f5f749d95c641e.tar.gz
busybox-w32-b16674f3c1a961e0b5d6a57745f5f749d95c641e.tar.bz2
busybox-w32-b16674f3c1a961e0b5d6a57745f5f749d95c641e.zip
Remove trailing whitespace. Update copyright to include 2004.
git-svn-id: svn://busybox.net/trunk/busybox@8630 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'patches/tftp_timeout_multicast.diff')
-rw-r--r--patches/tftp_timeout_multicast.diff192
1 files changed, 96 insertions, 96 deletions
diff --git a/patches/tftp_timeout_multicast.diff b/patches/tftp_timeout_multicast.diff
index a76a18c61..0f09d4a04 100644
--- a/patches/tftp_timeout_multicast.diff
+++ b/patches/tftp_timeout_multicast.diff
@@ -6,15 +6,15 @@ diff -u -r1.40 AUTHORS
6--- a/AUTHORS 9 Oct 2003 21:19:21 -0000 1.40 6--- a/AUTHORS 9 Oct 2003 21:19:21 -0000 1.40
7+++ b/AUTHORS 5 Mar 2004 15:45:47 -0000 7+++ b/AUTHORS 5 Mar 2004 15:45:47 -0000
8@@ -92,6 +92,9 @@ 8@@ -92,6 +92,9 @@
9 Original author of BusyBox in 1995, 1996. Some of his code can 9 Original author of BusyBox in 1995, 1996. Some of his code can
10 still be found hiding here and there... 10 still be found hiding here and there...
11 11
12+John Powers <jpp@ti.com> 12+John Powers <jpp@ti.com>
13+ Added multicast option (rfc2090) and timeout option (rfc2349) to tftp. 13+ Added multicast option (rfc2090) and timeout option (rfc2349) to tftp.
14+ 14+
15 Tim Riker <Tim@Rikers.org> 15 Tim Riker <Tim@Rikers.org>
16 bug fixes, member of fan club 16 bug fixes, member of fan club
17 17
18Index: include/usage.h 18Index: include/usage.h
19=================================================================== 19===================================================================
20RCS file: /var/cvs/busybox/include/usage.h,v 20RCS file: /var/cvs/busybox/include/usage.h,v
@@ -41,7 +41,7 @@ diff -u -r1.191 usage.h
41+#else 41+#else
42+ #define USAGE_TFTP_DEBUG(a) 42+ #define USAGE_TFTP_DEBUG(a)
43+#endif 43+#endif
44 44
45 #define tftp_trivial_usage \ 45 #define tftp_trivial_usage \
46 "[OPTION]... HOST [PORT]" 46 "[OPTION]... HOST [PORT]"
47@@ -2508,6 +2523,16 @@ 47@@ -2508,6 +2523,16 @@
@@ -71,7 +71,7 @@ diff -u -r1.27 Config.in
71@@ -522,6 +522,13 @@ 71@@ -522,6 +522,13 @@
72 Add support for the GET command within the TFTP client. This allows 72 Add support for the GET command within the TFTP client. This allows
73 a client to retrieve a file from a TFTP server. 73 a client to retrieve a file from a TFTP server.
74 74
75+config CONFIG_FEATURE_TFTP_MULTICAST 75+config CONFIG_FEATURE_TFTP_MULTICAST
76+ bool " Enable \"multicast\" option" 76+ bool " Enable \"multicast\" option"
77+ default n 77+ default n
@@ -84,7 +84,7 @@ diff -u -r1.27 Config.in
84 default y 84 default y
85@@ -531,12 +538,19 @@ 85@@ -531,12 +538,19 @@
86 a client to transfer a file to a TFTP server. 86 a client to transfer a file to a TFTP server.
87 87
88 config CONFIG_FEATURE_TFTP_BLOCKSIZE 88 config CONFIG_FEATURE_TFTP_BLOCKSIZE
89- bool " Enable \"blocksize\" command" 89- bool " Enable \"blocksize\" command"
90+ bool " Enable \"blksize\" option" 90+ bool " Enable \"blksize\" option"
@@ -92,7 +92,7 @@ diff -u -r1.27 Config.in
92 depends on CONFIG_TFTP 92 depends on CONFIG_TFTP
93 help 93 help
94 Allow the client to specify the desired block size for transfers. 94 Allow the client to specify the desired block size for transfers.
95 95
96+config CONFIG_FEATURE_TFTP_TIMEOUT 96+config CONFIG_FEATURE_TFTP_TIMEOUT
97+ bool " Enable \"timeout\" option" 97+ bool " Enable \"timeout\" option"
98+ default n 98+ default n
@@ -138,15 +138,15 @@ diff -u -r1.25 tftp.c
138 /* */ 138 /* */
139 /* Parts of the code based on: */ 139 /* Parts of the code based on: */
140@@ -46,8 +61,20 @@ 140@@ -46,8 +61,20 @@
141 141
142 #include "busybox.h" 142 #include "busybox.h"
143 143
144+#if defined(CONFIG_FEATURE_TFTP_BLOCKSIZE) || defined(CONFIG_FEATURE_TFTP_MULTICAST) || defined(CONFIG_FEATURE_TFTP_TIMEOUT) 144+#if defined(CONFIG_FEATURE_TFTP_BLOCKSIZE) || defined(CONFIG_FEATURE_TFTP_MULTICAST) || defined(CONFIG_FEATURE_TFTP_TIMEOUT)
145+ #define TFTP_OPTIONS 145+ #define TFTP_OPTIONS
146+#endif 146+#endif
147+ 147+
148 //#define CONFIG_FEATURE_TFTP_DEBUG 148 //#define CONFIG_FEATURE_TFTP_DEBUG
149 149
150+#ifdef CONFIG_FEATURE_TFTP_DEBUG 150+#ifdef CONFIG_FEATURE_TFTP_DEBUG
151+ static void printtime(void); 151+ static void printtime(void);
152+ #define dprintf(fmt...) if (debug) {printtime(); printf(fmt);} 152+ #define dprintf(fmt...) if (debug) {printtime(); printf(fmt);}
@@ -157,7 +157,7 @@ diff -u -r1.25 tftp.c
157+ 157+
158 #define TFTP_BLOCKSIZE_DEFAULT 512 /* according to RFC 1350, don't change */ 158 #define TFTP_BLOCKSIZE_DEFAULT 512 /* according to RFC 1350, don't change */
159 #define TFTP_TIMEOUT 5 /* seconds */ 159 #define TFTP_TIMEOUT 5 /* seconds */
160 160
161@@ -68,12 +95,24 @@ 161@@ -68,12 +95,24 @@
162 "Illegal TFTP operation", 162 "Illegal TFTP operation",
163 "Unknown transfer ID", 163 "Unknown transfer ID",
@@ -168,10 +168,10 @@ diff -u -r1.25 tftp.c
168+ "Unsupported option", 168+ "Unsupported option",
169+#endif 169+#endif
170 }; 170 };
171 171
172 const int tftp_cmd_get = 1; 172 const int tftp_cmd_get = 1;
173 const int tftp_cmd_put = 2; 173 const int tftp_cmd_put = 2;
174 174
175+ 175+
176+struct tftp_option { 176+struct tftp_option {
177+ int multicast; 177+ int multicast;
@@ -182,12 +182,12 @@ diff -u -r1.25 tftp.c
182+ 182+
183+ 183+
184 #ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE 184 #ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
185 185
186 static int tftp_blocksize_check(int blocksize, int bufsize) 186 static int tftp_blocksize_check(int blocksize, int bufsize)
187@@ -93,16 +132,158 @@ 187@@ -93,16 +132,158 @@
188 return blocksize; 188 return blocksize;
189 } 189 }
190 190
191+#endif 191+#endif
192+ 192+
193+#ifdef CONFIG_FEATURE_TFTP_TIMEOUT 193+#ifdef CONFIG_FEATURE_TFTP_TIMEOUT
@@ -332,15 +332,15 @@ diff -u -r1.25 tftp.c
332+ 332+
333+#ifdef TFTP_OPTIONS 333+#ifdef TFTP_OPTIONS
334+ 334+
335 static char *tftp_option_get(char *buf, int len, char *option) 335 static char *tftp_option_get(char *buf, int len, char *option)
336 { 336 {
337- int opt_val = 0; 337- int opt_val = 0;
338+ int opt_val = 0; 338+ int opt_val = 0;
339 int opt_found = 0; 339 int opt_found = 0;
340 int k; 340 int k;
341- 341-
342- while (len > 0) { 342- while (len > 0) {
343 343
344+ while (len > 0) { 344+ while (len > 0) {
345 /* Make sure the options are terminated correctly */ 345 /* Make sure the options are terminated correctly */
346- 346-
@@ -351,7 +351,7 @@ diff -u -r1.25 tftp.c
351 if (strcasecmp(buf, option) == 0) { 351 if (strcasecmp(buf, option) == 0) {
352 opt_found = 1; 352 opt_found = 1;
353 } 353 }
354- } 354- }
355- else { 355- else {
356- if (opt_found) { 356- if (opt_found) {
357+ } else { 357+ } else {
@@ -361,7 +361,7 @@ diff -u -r1.25 tftp.c
361 } 361 }
362@@ -138,7 +318,8 @@ 362@@ -138,7 +318,8 @@
363 #endif 363 #endif
364 364
365 static inline int tftp(const int cmd, const struct hostent *host, 365 static inline int tftp(const int cmd, const struct hostent *host,
366- const char *remotefile, int localfd, const unsigned short port, int tftp_bufsize) 366- const char *remotefile, int localfd, const unsigned short port, int tftp_bufsize)
367+ const char *remotefile, int localfd, const unsigned short port, 367+ const char *remotefile, int localfd, const unsigned short port,
@@ -376,7 +376,7 @@ diff -u -r1.25 tftp.c
376- int timeout = bb_tftp_num_retries; 376- int timeout = bb_tftp_num_retries;
377+ int retry = bb_tftp_num_retries; 377+ int retry = bb_tftp_num_retries;
378 unsigned short block_nr = 1; 378 unsigned short block_nr = 1;
379 379
380-#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE 380-#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
381- int want_option_ack = 0; 381- int want_option_ack = 0;
382+#ifdef CONFIG_FEATURE_TFTP_MULTICAST 382+#ifdef CONFIG_FEATURE_TFTP_MULTICAST
@@ -393,21 +393,21 @@ diff -u -r1.25 tftp.c
393+ #define master_client 1 393+ #define master_client 1
394+ #define ack_oack 0 394+ #define ack_oack 0
395 #endif 395 #endif
396 396
397 /* Can't use RESERVE_CONFIG_BUFFER here since the allocation 397 /* Can't use RESERVE_CONFIG_BUFFER here since the allocation
398 * size varies meaning BUFFERS_GO_ON_STACK would fail */ 398 * size varies meaning BUFFERS_GO_ON_STACK would fail */
399- char *buf=xmalloc(tftp_bufsize + 4); 399- char *buf=xmalloc(tftp_bufsize + 4);
400+ char *buf=xmalloc(option->blksize + 4); 400+ char *buf=xmalloc(option->blksize + 4);
401 401
402- tftp_bufsize += 4; 402- tftp_bufsize += 4;
403+ int tftp_bufsize = option->blksize + 4; 403+ int tftp_bufsize = option->blksize + 4;
404 404
405 if ((socketfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { 405 if ((socketfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
406 bb_perror_msg("socket"); 406 bb_perror_msg("socket");
407@@ -183,15 +375,21 @@ 407@@ -183,15 +375,21 @@
408 memcpy(&sa.sin_addr, (struct in_addr *) host->h_addr, 408 memcpy(&sa.sin_addr, (struct in_addr *) host->h_addr,
409 sizeof(sa.sin_addr)); 409 sizeof(sa.sin_addr));
410 410
411- /* build opcode */ 411- /* build opcode */
412- 412-
413- if (cmd_get) { 413- if (cmd_get) {
@@ -423,48 +423,48 @@ diff -u -r1.25 tftp.c
423+ memset(mcblockmap, 0, bmsize+1); 423+ memset(mcblockmap, 0, bmsize+1);
424 } 424 }
425+#endif 425+#endif
426 426
427- if (cmd_put) { 427- if (cmd_put) {
428- opcode = TFTP_WRQ; 428- opcode = TFTP_WRQ;
429- } 429- }
430+ /* build opcode */ 430+ /* build opcode */
431+ 431+
432+ opcode = cmd_get ? TFTP_RRQ : TFTP_WRQ; 432+ opcode = cmd_get ? TFTP_RRQ : TFTP_WRQ;
433 433
434 while (1) { 434 while (1) {
435 435
436@@ -203,7 +401,7 @@ 436@@ -203,7 +401,7 @@
437 437
438 cp += 2; 438 cp += 2;
439 439
440- /* add filename and mode */ 440- /* add filename and mode */
441+ /* First packet of file transfer includes file name, mode, and options */ 441+ /* First packet of file transfer includes file name, mode, and options */
442 442
443 if ((cmd_get && (opcode == TFTP_RRQ)) || 443 if ((cmd_get && (opcode == TFTP_RRQ)) ||
444 (cmd_put && (opcode == TFTP_WRQ))) { 444 (cmd_put && (opcode == TFTP_WRQ))) {
445@@ -223,7 +421,7 @@ 445@@ -223,7 +421,7 @@
446 } 446 }
447 447
448 if (too_long || ((&buf[tftp_bufsize - 1] - cp) < 6)) { 448 if (too_long || ((&buf[tftp_bufsize - 1] - cp) < 6)) {
449- bb_error_msg("too long remote-filename"); 449- bb_error_msg("too long remote-filename");
450+ bb_error_msg("too long: remote filename"); 450+ bb_error_msg("too long: remote filename");
451 break; 451 break;
452 } 452 }
453 453
454@@ -238,8 +436,8 @@ 454@@ -238,8 +436,8 @@
455 455
456 if (len != TFTP_BLOCKSIZE_DEFAULT) { 456 if (len != TFTP_BLOCKSIZE_DEFAULT) {
457 457
458- if ((&buf[tftp_bufsize - 1] - cp) < 15) { 458- if ((&buf[tftp_bufsize - 1] - cp) < 15) {
459- bb_error_msg("too long remote-filename"); 459- bb_error_msg("too long remote-filename");
460+ if ((&buf[tftp_bufsize - 1] - cp) < 15) { 460+ if ((&buf[tftp_bufsize - 1] - cp) < 15) {
461+ bb_error_msg("buffer too small for blksize option"); 461+ bb_error_msg("buffer too small for blksize option");
462 break; 462 break;
463 } 463 }
464 464
465@@ -249,16 +447,65 @@ 465@@ -249,16 +447,65 @@
466 cp += 8; 466 cp += 8;
467 467
468 cp += snprintf(cp, 6, "%d", len) + 1; 468 cp += snprintf(cp, 6, "%d", len) + 1;
469+ } 469+ }
470+#endif 470+#endif
@@ -480,7 +480,7 @@ diff -u -r1.25 tftp.c
480+ } 480+ }
481+ 481+
482+ /* add "multicast" option */ 482+ /* add "multicast" option */
483 483
484- want_option_ack = 1; 484- want_option_ack = 1;
485+ memcpy(cp, "multicast\0", 11); 485+ memcpy(cp, "multicast\0", 11);
486+ cp += 11; 486+ cp += 11;
@@ -509,9 +509,9 @@ diff -u -r1.25 tftp.c
509+#endif 509+#endif
510+ 510+
511 } 511 }
512 512
513 /* add ack and data */ 513 /* add ack and data */
514 514
515- if ((cmd_get && (opcode == TFTP_ACK)) || 515- if ((cmd_get && (opcode == TFTP_ACK)) ||
516- (cmd_put && (opcode == TFTP_DATA))) { 516- (cmd_put && (opcode == TFTP_DATA))) {
517+#ifdef CONFIG_FEATURE_TFTP_MULTICAST 517+#ifdef CONFIG_FEATURE_TFTP_MULTICAST
@@ -528,33 +528,33 @@ diff -u -r1.25 tftp.c
528+#endif 528+#endif
529+ else if ((cmd_get && opcode == TFTP_ACK) || 529+ else if ((cmd_get && opcode == TFTP_ACK) ||
530+ (cmd_put && opcode == TFTP_DATA)) { 530+ (cmd_put && opcode == TFTP_DATA)) {
531 531
532 *((unsigned short *) cp) = htons(block_nr); 532 *((unsigned short *) cp) = htons(block_nr);
533 533
534@@ -275,7 +522,7 @@ 534@@ -275,7 +522,7 @@
535 } 535 }
536 536
537 if (len != (tftp_bufsize - 4)) { 537 if (len != (tftp_bufsize - 4)) {
538- finished++; 538- finished++;
539+ finished = 1; 539+ finished = 1;
540 } 540 }
541 541
542 cp += len; 542 cp += len;
543@@ -283,82 +530,119 @@ 543@@ -283,82 +530,119 @@
544 } 544 }
545 545
546 546
547- /* send packet */ 547- /* send packet */
548+ /* send packet and receive reply */ 548+ /* send packet and receive reply */
549 549
550 550
551- timeout = bb_tftp_num_retries; /* re-initialize */ 551- timeout = bb_tftp_num_retries; /* re-initialize */
552+ retry = bb_tftp_num_retries; /* re-initialize */ 552+ retry = bb_tftp_num_retries; /* re-initialize */
553 do { 553 do {
554- 554-
555+ int selectrc; 555+ int selectrc;
556 len = cp - buf; 556 len = cp - buf;
557 557
558-#ifdef CONFIG_FEATURE_TFTP_DEBUG 558-#ifdef CONFIG_FEATURE_TFTP_DEBUG
559- fprintf(stderr, "sending %u bytes\n", len); 559- fprintf(stderr, "sending %u bytes\n", len);
560- for (cp = buf; cp < &buf[len]; cp++) 560- for (cp = buf; cp < &buf[len]; cp++)
@@ -570,7 +570,7 @@ diff -u -r1.25 tftp.c
570- 570-
571+ /* send packet */ 571+ /* send packet */
572+ if ((len > 2) && (! option->multicast || master_client || ack_oack)) { 572+ if ((len > 2) && (! option->multicast || master_client || ack_oack)) {
573 573
574- if (finished && (opcode == TFTP_ACK)) { 574- if (finished && (opcode == TFTP_ACK)) {
575- break; 575- break;
576+#ifdef CONFIG_FEATURE_TFTP_DEBUG 576+#ifdef CONFIG_FEATURE_TFTP_DEBUG
@@ -593,17 +593,17 @@ diff -u -r1.25 tftp.c
593+ break; 593+ break;
594+ } 594+ }
595 } 595 }
596 596
597- /* receive packet */ 597- /* receive packet */
598+ /* receive reply packet */ 598+ /* receive reply packet */
599 599
600 memset(&from, 0, sizeof(from)); 600 memset(&from, 0, sizeof(from));
601 fromlen = sizeof(from); 601 fromlen = sizeof(from);
602 602
603- tv.tv_sec = TFTP_TIMEOUT; 603- tv.tv_sec = TFTP_TIMEOUT;
604+ tv.tv_sec = option->client_timeout; 604+ tv.tv_sec = option->client_timeout;
605 tv.tv_usec = 0; 605 tv.tv_usec = 0;
606 606
607 FD_ZERO(&rfds); 607 FD_ZERO(&rfds);
608 FD_SET(socketfd, &rfds); 608 FD_SET(socketfd, &rfds);
609+ dprintf("set to receive from socketfd (%d)\n", socketfd); 609+ dprintf("set to receive from socketfd (%d)\n", socketfd);
@@ -613,7 +613,7 @@ diff -u -r1.25 tftp.c
613+ dprintf("set to receive from mcfd (%d)\n", mcfd); 613+ dprintf("set to receive from mcfd (%d)\n", mcfd);
614+ } 614+ }
615+#endif 615+#endif
616 616
617- switch (select(FD_SETSIZE, &rfds, NULL, NULL, &tv)) { 617- switch (select(FD_SETSIZE, &rfds, NULL, NULL, &tv)) {
618- case 1: 618- case 1:
619- len = recvfrom(socketfd, buf, tftp_bufsize, 0, 619- len = recvfrom(socketfd, buf, tftp_bufsize, 0,
@@ -646,7 +646,7 @@ diff -u -r1.25 tftp.c
646+ } 646+ }
647+ } 647+ }
648 } 648 }
649 649
650- timeout = 0; 650- timeout = 0;
651- 651-
652- if (sa.sin_port == port) { 652- if (sa.sin_port == port) {
@@ -677,13 +677,13 @@ diff -u -r1.25 tftp.c
677- /* discard the packet - treat as timeout */ 677- /* discard the packet - treat as timeout */
678- timeout = bb_tftp_num_retries; 678- timeout = bb_tftp_num_retries;
679+#endif 679+#endif
680 680
681- case 0: 681- case 0:
682+ } else if (selectrc == 0) { 682+ } else if (selectrc == 0) {
683+ /* Time out */ 683+ /* Time out */
684+ dprintf("timeout\n"); 684+ dprintf("timeout\n");
685 bb_error_msg("timeout"); 685 bb_error_msg("timeout");
686 686
687- timeout--; 687- timeout--;
688- if (timeout == 0) { 688- if (timeout == 0) {
689+ retry--; 689+ retry--;
@@ -700,59 +700,59 @@ diff -u -r1.25 tftp.c
700 bb_perror_msg("select"); 700 bb_perror_msg("select");
701 len = -1; 701 len = -1;
702 } 702 }
703 703
704- } while (timeout && (len >= 0)); 704- } while (timeout && (len >= 0));
705+ } while (retry && len >= 0); 705+ } while (retry && len >= 0);
706 706
707 if ((finished) || (len < 0)) { 707 if ((finished) || (len < 0)) {
708 break; 708 break;
709@@ -370,9 +654,8 @@ 709@@ -370,9 +654,8 @@
710 opcode = ntohs(*((unsigned short *) buf)); 710 opcode = ntohs(*((unsigned short *) buf));
711 tmp = ntohs(*((unsigned short *) &buf[2])); 711 tmp = ntohs(*((unsigned short *) &buf[2]));
712 712
713-#ifdef CONFIG_FEATURE_TFTP_DEBUG 713-#ifdef CONFIG_FEATURE_TFTP_DEBUG
714- fprintf(stderr, "received %d bytes: %04x %04x\n", len, opcode, tmp); 714- fprintf(stderr, "received %d bytes: %04x %04x\n", len, opcode, tmp);
715-#endif 715-#endif
716+ dprintf("received %d bytes: %04x %04x\n", len, opcode, tmp); 716+ dprintf("received %d bytes: %04x %04x\n", len, opcode, tmp);
717+ dprintf("master_client=%d\n", master_client); 717+ dprintf("master_client=%d\n", master_client);
718 718
719 if (opcode == TFTP_ERROR) { 719 if (opcode == TFTP_ERROR) {
720 char *msg = NULL; 720 char *msg = NULL;
721@@ -393,55 +676,116 @@ 721@@ -393,55 +676,116 @@
722 break; 722 break;
723 } 723 }
724 724
725-#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE 725-#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
726- if (want_option_ack) { 726- if (want_option_ack) {
727+#ifdef TFTP_OPTIONS 727+#ifdef TFTP_OPTIONS
728 728
729- want_option_ack = 0; 729- want_option_ack = 0;
730+ if (opcode == TFTP_OACK) { 730+ if (opcode == TFTP_OACK) {
731 731
732- if (opcode == TFTP_OACK) { 732- if (opcode == TFTP_OACK) {
733+ /* server seems to support options */ 733+ /* server seems to support options */
734 734
735- /* server seems to support options */ 735- /* server seems to support options */
736+ char *res; 736+ char *res;
737+ 737+
738+ block_nr = 0; /* acknowledge option packet with block number 0 */ 738+ block_nr = 0; /* acknowledge option packet with block number 0 */
739+ opcode = cmd_put ? TFTP_DATA : TFTP_ACK; 739+ opcode = cmd_put ? TFTP_DATA : TFTP_ACK;
740 740
741- char *res; 741- char *res;
742 742
743- res = tftp_option_get(&buf[2], len-2, 743- res = tftp_option_get(&buf[2], len-2,
744- "blksize"); 744- "blksize");
745+#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE 745+#ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
746+ res = tftp_option_get(&buf[2], len-2, "blksize"); 746+ res = tftp_option_get(&buf[2], len-2, "blksize");
747 747
748- if (res) { 748- if (res) {
749- int blksize = atoi(res); 749- int blksize = atoi(res);
750- 750-
751- if (tftp_blocksize_check(blksize, 751- if (tftp_blocksize_check(blksize,
752- tftp_bufsize - 4)) { 752- tftp_bufsize - 4)) {
753+ if (res) { 753+ if (res) {
754+ int blksize = atoi(res); 754+ int blksize = atoi(res);
755 755
756- if (cmd_put) { 756- if (cmd_put) {
757- opcode = TFTP_DATA; 757- opcode = TFTP_DATA;
758- } 758- }
@@ -782,10 +782,10 @@ diff -u -r1.25 tftp.c
782- bb_error_msg("bad server option"); 782- bb_error_msg("bad server option");
783- break; 783- break;
784- } 784- }
785 785
786- bb_error_msg("warning: blksize not supported by server" 786- bb_error_msg("warning: blksize not supported by server"
787- " - reverting to 512"); 787- " - reverting to 512");
788 788
789- tftp_bufsize = TFTP_BLOCKSIZE_DEFAULT + 4; 789- tftp_bufsize = TFTP_BLOCKSIZE_DEFAULT + 4;
790+#ifdef CONFIG_FEATURE_TFTP_MULTICAST 790+#ifdef CONFIG_FEATURE_TFTP_MULTICAST
791+ res = tftp_option_get(&buf[2], len-2, "multicast"); 791+ res = tftp_option_get(&buf[2], len-2, "multicast");
@@ -837,9 +837,9 @@ diff -u -r1.25 tftp.c
837 } 837 }
838+ else 838+ else
839 #endif 839 #endif
840 840
841 if (cmd_get && (opcode == TFTP_DATA)) { 841 if (cmd_get && (opcode == TFTP_DATA)) {
842 842
843+#ifdef CONFIG_FEATURE_TFTP_MULTICAST 843+#ifdef CONFIG_FEATURE_TFTP_MULTICAST
844+ if (option->multicast) { 844+ if (option->multicast) {
845+ int bn = tmp - 1; 845+ int bn = tmp - 1;
@@ -867,35 +867,35 @@ diff -u -r1.25 tftp.c
867+#endif 867+#endif
868+ 868+
869 if (tmp == block_nr) { 869 if (tmp == block_nr) {
870 870
871 len = write(localfd, &buf[4], len - 4); 871 len = write(localfd, &buf[4], len - 4);
872@@ -452,15 +796,14 @@ 872@@ -452,15 +796,14 @@
873 } 873 }
874 874
875 if (len != (tftp_bufsize - 4)) { 875 if (len != (tftp_bufsize - 4)) {
876- finished++; 876- finished++;
877+ finished = 1; 877+ finished = 1;
878 } 878 }
879 879
880 opcode = TFTP_ACK; 880 opcode = TFTP_ACK;
881- continue; 881- continue;
882 } 882 }
883 } 883 }
884 884
885- if (cmd_put && (opcode == TFTP_ACK)) { 885- if (cmd_put && (opcode == TFTP_ACK)) {
886+ else if (cmd_put && opcode == TFTP_ACK) { 886+ else if (cmd_put && opcode == TFTP_ACK) {
887 887
888 if (tmp == (unsigned short)(block_nr - 1)) { 888 if (tmp == (unsigned short)(block_nr - 1)) {
889 if (finished) { 889 if (finished) {
890@@ -468,15 +811,19 @@ 890@@ -468,15 +811,19 @@
891 } 891 }
892 892
893 opcode = TFTP_DATA; 893 opcode = TFTP_DATA;
894- continue; 894- continue;
895 } 895 }
896 } 896 }
897 } 897 }
898 898
899 #ifdef CONFIG_FEATURE_CLEAN_UP 899 #ifdef CONFIG_FEATURE_CLEAN_UP
900 close(socketfd); 900 close(socketfd);
901+ free(buf); 901+ free(buf);
@@ -904,10 +904,10 @@ diff -u -r1.25 tftp.c
904+ if (mcblockmap != NULL) 904+ if (mcblockmap != NULL)
905+ free(mcblockmap); 905+ free(mcblockmap);
906+#endif 906+#endif
907 907
908- free(buf); 908- free(buf);
909 #endif 909 #endif
910 910
911 return finished ? EXIT_SUCCESS : EXIT_FAILURE; 911 return finished ? EXIT_SUCCESS : EXIT_FAILURE;
912@@ -487,13 +834,18 @@ 912@@ -487,13 +834,18 @@
913 struct hostent *host = NULL; 913 struct hostent *host = NULL;
@@ -927,13 +927,13 @@ diff -u -r1.25 tftp.c
927+ .client_timeout = TFTP_TIMEOUT, 927+ .client_timeout = TFTP_TIMEOUT,
928+ .server_timeout = TFTP_TIMEOUT, 928+ .server_timeout = TFTP_TIMEOUT,
929+ }; 929+ };
930 930
931 /* figure out what to pass to getopt */ 931 /* figure out what to pass to getopt */
932 932
933@@ -515,13 +867,45 @@ 933@@ -515,13 +867,45 @@
934 #define PUT 934 #define PUT
935 #endif 935 #endif
936 936
937- while ((opt = getopt(argc, argv, BS GET PUT "l:r:")) != -1) { 937- while ((opt = getopt(argc, argv, BS GET PUT "l:r:")) != -1) {
938+#ifdef CONFIG_FEATURE_TFTP_TIMEOUT 938+#ifdef CONFIG_FEATURE_TFTP_TIMEOUT
939+#define TO "T:t:" 939+#define TO "T:t:"
@@ -994,7 +994,7 @@ diff -u -r1.25 tftp.c
994+ debug = 1; 994+ debug = 1;
995+ break; 995+ break;
996+#endif 996+#endif
997 case 'l': 997 case 'l':
998 localfile = bb_xstrdup(optarg); 998 localfile = bb_xstrdup(optarg);
999 break; 999 break;
1000 case 'r': 1000 case 'r':
@@ -1004,7 +1004,7 @@ diff -u -r1.25 tftp.c
1004+ bb_show_usage(); 1004+ bb_show_usage();
1005 } 1005 }
1006 } 1006 }
1007 1007
1008 if ((cmd == 0) || (optind == argc)) { 1008 if ((cmd == 0) || (optind == argc)) {
1009 bb_show_usage(); 1009 bb_show_usage();
1010 } 1010 }
@@ -1018,7 +1018,7 @@ diff -u -r1.25 tftp.c
1018@@ -566,14 +966,12 @@ 1018@@ -566,14 +966,12 @@
1019 host = xgethostbyname(argv[optind]); 1019 host = xgethostbyname(argv[optind]);
1020 port = bb_lookup_port(argv[optind + 1], "udp", 69); 1020 port = bb_lookup_port(argv[optind + 1], "udp", 69);
1021 1021
1022-#ifdef CONFIG_FEATURE_TFTP_DEBUG 1022-#ifdef CONFIG_FEATURE_TFTP_DEBUG
1023- fprintf(stderr, "using server \"%s\", remotefile \"%s\", " 1023- fprintf(stderr, "using server \"%s\", remotefile \"%s\", "
1024+ dprintf("using server \"%s\", remotefile \"%s\", " 1024+ dprintf("using server \"%s\", remotefile \"%s\", "
@@ -1026,10 +1026,10 @@ diff -u -r1.25 tftp.c
1026 inet_ntoa(*((struct in_addr *) host->h_addr)), 1026 inet_ntoa(*((struct in_addr *) host->h_addr)),
1027 remotefile, localfile); 1027 remotefile, localfile);
1028-#endif 1028-#endif
1029 1029
1030- result = tftp(cmd, host, remotefile, fd, port, blocksize); 1030- result = tftp(cmd, host, remotefile, fd, port, blocksize);
1031+ result = tftp(cmd, host, remotefile, fd, port, &option); 1031+ result = tftp(cmd, host, remotefile, fd, port, &option);
1032 1032
1033 #ifdef CONFIG_FEATURE_CLEAN_UP 1033 #ifdef CONFIG_FEATURE_CLEAN_UP
1034 if (!(fd == fileno(stdout) || fd == fileno(stdin))) { 1034 if (!(fd == fileno(stdout) || fd == fileno(stdin))) {
1035@@ -582,3 +980,18 @@ 1035@@ -582,3 +980,18 @@