diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-12-11 12:36:10 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-12-11 12:36:10 +0100 |
commit | a3aa3e309506ea96fa8f7546f6b22fa85263a934 (patch) | |
tree | cd6d4adeafec55e230e2d56499df8f0c3cbf47e1 /networking/wget.c | |
parent | 4662de0511487b4da965c4b2158bae318f3d80a8 (diff) | |
download | busybox-w32-a3aa3e309506ea96fa8f7546f6b22fa85263a934.tar.gz busybox-w32-a3aa3e309506ea96fa8f7546f6b22fa85263a934.tar.bz2 busybox-w32-a3aa3e309506ea96fa8f7546f6b22fa85263a934.zip |
wget: check for close success; fix chunked; do not bother to send QUIT to ftp
Also, random fixes to use %u for unsigned quantities. -14 bytes in wget.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/wget.c')
-rw-r--r-- | networking/wget.c | 62 |
1 files changed, 33 insertions, 29 deletions
diff --git a/networking/wget.c b/networking/wget.c index 8ca6def67..64553d49a 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -35,10 +35,6 @@ struct globals { | |||
35 | struct BUG_G_too_big { | 35 | struct BUG_G_too_big { |
36 | char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; | 36 | char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; |
37 | }; | 37 | }; |
38 | #define content_len (G.content_len ) | ||
39 | #define beg_range (G.beg_range ) | ||
40 | #define transferred (G.transferred ) | ||
41 | #define curfile (G.curfile ) | ||
42 | #define INIT_G() do { } while (0) | 38 | #define INIT_G() do { } while (0) |
43 | 39 | ||
44 | 40 | ||
@@ -53,14 +49,14 @@ static void progress_meter(int flag) | |||
53 | bb_progress_init(&G.pmt); | 49 | bb_progress_init(&G.pmt); |
54 | } | 50 | } |
55 | 51 | ||
56 | bb_progress_update(&G.pmt, curfile, beg_range, transferred, | 52 | bb_progress_update(&G.pmt, G.curfile, G.beg_range, G.transferred, |
57 | G.chunked ? 0 : content_len + beg_range); | 53 | G.chunked ? 0 : G.content_len + G.beg_range); |
58 | 54 | ||
59 | if (flag == 0) { | 55 | if (flag == 0) { |
60 | /* last call to progress_meter */ | 56 | /* last call to progress_meter */ |
61 | alarm(0); | 57 | alarm(0); |
62 | fputc('\n', stderr); | 58 | fputc('\n', stderr); |
63 | transferred = 0; | 59 | G.transferred = 0; |
64 | } else { | 60 | } else { |
65 | if (flag == -1) { /* first call to progress_meter */ | 61 | if (flag == -1) { /* first call to progress_meter */ |
66 | signal_SA_RESTART_empty_mask(SIGALRM, progress_meter); | 62 | signal_SA_RESTART_empty_mask(SIGALRM, progress_meter); |
@@ -390,8 +386,8 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ | |||
390 | * Querying file size | 386 | * Querying file size |
391 | */ | 387 | */ |
392 | if (ftpcmd("SIZE ", target->path, sfp, buf) == 213) { | 388 | if (ftpcmd("SIZE ", target->path, sfp, buf) == 213) { |
393 | content_len = BB_STRTOOFF(buf+4, NULL, 10); | 389 | G.content_len = BB_STRTOOFF(buf+4, NULL, 10); |
394 | if (errno || content_len < 0) { | 390 | if (G.content_len < 0 || errno) { |
395 | bb_error_msg_and_die("SIZE value is garbage"); | 391 | bb_error_msg_and_die("SIZE value is garbage"); |
396 | } | 392 | } |
397 | G.got_clen = 1; | 393 | G.got_clen = 1; |
@@ -420,10 +416,10 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ | |||
420 | 416 | ||
421 | *dfpp = open_socket(lsa); | 417 | *dfpp = open_socket(lsa); |
422 | 418 | ||
423 | if (beg_range) { | 419 | if (G.beg_range) { |
424 | sprintf(buf, "REST %"OFF_FMT"d", beg_range); | 420 | sprintf(buf, "REST %"OFF_FMT"u", G.beg_range); |
425 | if (ftpcmd(buf, NULL, sfp, buf) == 350) | 421 | if (ftpcmd(buf, NULL, sfp, buf) == 350) |
426 | content_len -= beg_range; | 422 | G.content_len -= G.beg_range; |
427 | } | 423 | } |
428 | 424 | ||
429 | if (ftpcmd("RETR ", target->path, sfp, buf) > 150) | 425 | if (ftpcmd("RETR ", target->path, sfp, buf) > 150) |
@@ -460,12 +456,18 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) | |||
460 | 456 | ||
461 | /* Loops only if chunked */ | 457 | /* Loops only if chunked */ |
462 | while (1) { | 458 | while (1) { |
463 | while (content_len > 0 || !G.got_clen) { | 459 | while (1) { |
464 | int n; | 460 | int n; |
465 | unsigned rdsz = sizeof(buf); | 461 | unsigned rdsz; |
466 | 462 | ||
467 | if (content_len < sizeof(buf) && (G.chunked || G.got_clen)) | 463 | rdsz = sizeof(buf); |
468 | rdsz = (unsigned)content_len; | 464 | if (G.got_clen) { |
465 | if (G.content_len < sizeof(buf)) { | ||
466 | if ((int)G.content_len <= 0) | ||
467 | break; | ||
468 | rdsz = (unsigned)G.content_len; | ||
469 | } | ||
470 | } | ||
469 | n = safe_fread(buf, rdsz, dfp); | 471 | n = safe_fread(buf, rdsz, dfp); |
470 | if (n <= 0) { | 472 | if (n <= 0) { |
471 | if (ferror(dfp)) { | 473 | if (ferror(dfp)) { |
@@ -476,10 +478,10 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) | |||
476 | } | 478 | } |
477 | xwrite(output_fd, buf, n); | 479 | xwrite(output_fd, buf, n); |
478 | #if ENABLE_FEATURE_WGET_STATUSBAR | 480 | #if ENABLE_FEATURE_WGET_STATUSBAR |
479 | transferred += n; | 481 | G.transferred += n; |
480 | #endif | 482 | #endif |
481 | if (G.got_clen) | 483 | if (G.got_clen) |
482 | content_len -= n; | 484 | G.content_len -= n; |
483 | } | 485 | } |
484 | 486 | ||
485 | if (!G.chunked) | 487 | if (!G.chunked) |
@@ -488,10 +490,11 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) | |||
488 | safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */ | 490 | safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */ |
489 | get_clen: | 491 | get_clen: |
490 | safe_fgets(buf, sizeof(buf), dfp); | 492 | safe_fgets(buf, sizeof(buf), dfp); |
491 | content_len = STRTOOFF(buf, NULL, 16); | 493 | G.content_len = STRTOOFF(buf, NULL, 16); |
492 | /* FIXME: error check? */ | 494 | /* FIXME: error check? */ |
493 | if (content_len == 0) | 495 | if (G.content_len == 0) |
494 | break; /* all done! */ | 496 | break; /* all done! */ |
497 | G.got_clen = 1; | ||
495 | } | 498 | } |
496 | 499 | ||
497 | if (!(option_mask32 & WGET_OPT_QUIET)) | 500 | if (!(option_mask32 & WGET_OPT_QUIET)) |
@@ -621,7 +624,7 @@ int wget_main(int argc UNUSED_PARAM, char **argv) | |||
621 | } | 624 | } |
622 | } | 625 | } |
623 | #if ENABLE_FEATURE_WGET_STATUSBAR | 626 | #if ENABLE_FEATURE_WGET_STATUSBAR |
624 | curfile = bb_get_last_path_component_nostrip(fname_out); | 627 | G.curfile = bb_get_last_path_component_nostrip(fname_out); |
625 | #endif | 628 | #endif |
626 | 629 | ||
627 | /* Impossible? | 630 | /* Impossible? |
@@ -633,7 +636,7 @@ int wget_main(int argc UNUSED_PARAM, char **argv) | |||
633 | if (opt & WGET_OPT_CONTINUE) { | 636 | if (opt & WGET_OPT_CONTINUE) { |
634 | output_fd = open(fname_out, O_WRONLY); | 637 | output_fd = open(fname_out, O_WRONLY); |
635 | if (output_fd >= 0) { | 638 | if (output_fd >= 0) { |
636 | beg_range = xlseek(output_fd, 0, SEEK_END); | 639 | G.beg_range = xlseek(output_fd, 0, SEEK_END); |
637 | } | 640 | } |
638 | /* File doesn't exist. We do not create file here yet. | 641 | /* File doesn't exist. We do not create file here yet. |
639 | * We are not sure it exists on remove side */ | 642 | * We are not sure it exists on remove side */ |
@@ -684,8 +687,8 @@ int wget_main(int argc UNUSED_PARAM, char **argv) | |||
684 | } | 687 | } |
685 | #endif | 688 | #endif |
686 | 689 | ||
687 | if (beg_range) | 690 | if (G.beg_range) |
688 | fprintf(sfp, "Range: bytes=%"OFF_FMT"d-\r\n", beg_range); | 691 | fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range); |
689 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS | 692 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS |
690 | if (extra_headers) | 693 | if (extra_headers) |
691 | fputs(extra_headers, sfp); | 694 | fputs(extra_headers, sfp); |
@@ -756,7 +759,7 @@ However, in real world it was observed that some web servers | |||
756 | case 303: | 759 | case 303: |
757 | break; | 760 | break; |
758 | case 206: | 761 | case 206: |
759 | if (beg_range) | 762 | if (G.beg_range) |
760 | break; | 763 | break; |
761 | /* fall through */ | 764 | /* fall through */ |
762 | default: | 765 | default: |
@@ -777,8 +780,8 @@ However, in real world it was observed that some web servers | |||
777 | } | 780 | } |
778 | key = index_in_strings(keywords, buf) + 1; | 781 | key = index_in_strings(keywords, buf) + 1; |
779 | if (key == KEY_content_length) { | 782 | if (key == KEY_content_length) { |
780 | content_len = BB_STRTOOFF(str, NULL, 10); | 783 | G.content_len = BB_STRTOOFF(str, NULL, 10); |
781 | if (errno || content_len < 0) { | 784 | if (G.content_len < 0 || errno) { |
782 | bb_error_msg_and_die("content-length %s is garbage", sanitize_string(str)); | 785 | bb_error_msg_and_die("content-length %s is garbage", sanitize_string(str)); |
783 | } | 786 | } |
784 | G.got_clen = 1; | 787 | G.got_clen = 1; |
@@ -841,13 +844,14 @@ However, in real world it was observed that some web servers | |||
841 | } | 844 | } |
842 | 845 | ||
843 | retrieve_file_data(dfp, output_fd); | 846 | retrieve_file_data(dfp, output_fd); |
847 | xclose(output_fd); | ||
844 | 848 | ||
845 | if (dfp != sfp) { | 849 | if (dfp != sfp) { |
846 | /* It's ftp. Close it properly */ | 850 | /* It's ftp. Close it properly */ |
847 | fclose(dfp); | 851 | fclose(dfp); |
848 | if (ftpcmd(NULL, NULL, sfp, buf) != 226) | 852 | if (ftpcmd(NULL, NULL, sfp, buf) != 226) |
849 | bb_error_msg_and_die("ftp error: %s", sanitize_string(buf+4)); | 853 | bb_error_msg_and_die("ftp error: %s", sanitize_string(buf+4)); |
850 | ftpcmd("QUIT", NULL, sfp, buf); | 854 | /* ftpcmd("QUIT", NULL, sfp, buf); - why bother? */ |
851 | } | 855 | } |
852 | 856 | ||
853 | return EXIT_SUCCESS; | 857 | return EXIT_SUCCESS; |