diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-02-15 00:58:36 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-02-15 00:58:36 +0100 |
commit | 2384a357f41a92421e1e68fdd3a1afda7922a8ea (patch) | |
tree | e4abb48e26d98c44252f583cdd42a58d0a52c7e2 /networking/wget.c | |
parent | 57b4909db92ab403cc955e6cef4ea2b8318586b6 (diff) | |
download | busybox-w32-2384a357f41a92421e1e68fdd3a1afda7922a8ea.tar.gz busybox-w32-2384a357f41a92421e1e68fdd3a1afda7922a8ea.tar.bz2 busybox-w32-2384a357f41a92421e1e68fdd3a1afda7922a8ea.zip |
wget: make "wget -O FILE URL1 URL2" concatenate output
Also fixes a few cases where URL1's data (like start pos)
was leaking into URL2
function old new delta
wget_main 2303 2321 +18
progress_meter 140 152 +12
retrieve_file_data 397 396 -1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 30/-1) Total: 29 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/wget.c')
-rw-r--r-- | networking/wget.c | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/networking/wget.c b/networking/wget.c index cb169aba3..6c9a51211 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -44,6 +44,8 @@ struct globals { | |||
44 | #if ENABLE_FEATURE_WGET_TIMEOUT | 44 | #if ENABLE_FEATURE_WGET_TIMEOUT |
45 | unsigned timeout_seconds; | 45 | unsigned timeout_seconds; |
46 | #endif | 46 | #endif |
47 | int output_fd; | ||
48 | int o_flags; | ||
47 | smallint chunked; /* chunked transfer encoding */ | 49 | smallint chunked; /* chunked transfer encoding */ |
48 | smallint got_clen; /* got content-length: from server */ | 50 | smallint got_clen; /* got content-length: from server */ |
49 | /* Local downloads do benefit from big buffer. | 51 | /* Local downloads do benefit from big buffer. |
@@ -90,8 +92,11 @@ static void progress_meter(int flag) | |||
90 | if (flag == PROGRESS_START) | 92 | if (flag == PROGRESS_START) |
91 | bb_progress_init(&G.pmt, G.curfile); | 93 | bb_progress_init(&G.pmt, G.curfile); |
92 | 94 | ||
93 | bb_progress_update(&G.pmt, G.beg_range, G.transferred, | 95 | bb_progress_update(&G.pmt, |
94 | G.chunked ? 0 : G.beg_range + G.transferred + G.content_len); | 96 | G.beg_range, |
97 | G.transferred, | ||
98 | (G.chunked || !G.got_clen) ? 0 : G.beg_range + G.transferred + G.content_len | ||
99 | ); | ||
95 | 100 | ||
96 | if (flag == PROGRESS_END) { | 101 | if (flag == PROGRESS_END) { |
97 | bb_progress_free(&G.pmt); | 102 | bb_progress_free(&G.pmt); |
@@ -430,7 +435,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ | |||
430 | return sfp; | 435 | return sfp; |
431 | } | 436 | } |
432 | 437 | ||
433 | static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) | 438 | static void NOINLINE retrieve_file_data(FILE *dfp) |
434 | { | 439 | { |
435 | #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT | 440 | #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT |
436 | # if ENABLE_FEATURE_WGET_TIMEOUT | 441 | # if ENABLE_FEATURE_WGET_TIMEOUT |
@@ -516,7 +521,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) | |||
516 | break; /* EOF, not error */ | 521 | break; /* EOF, not error */ |
517 | } | 522 | } |
518 | 523 | ||
519 | xwrite(output_fd, G.wget_buf, n); | 524 | xwrite(G.output_fd, G.wget_buf, n); |
520 | 525 | ||
521 | #if ENABLE_FEATURE_WGET_STATUSBAR | 526 | #if ENABLE_FEATURE_WGET_STATUSBAR |
522 | G.transferred += n; | 527 | G.transferred += n; |
@@ -546,7 +551,8 @@ static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) | |||
546 | } | 551 | } |
547 | 552 | ||
548 | /* Draw full bar and free its resources */ | 553 | /* Draw full bar and free its resources */ |
549 | G.chunked = 0; /* makes it show 100% even for chunked download */ | 554 | G.chunked = 0; /* makes it show 100% even for chunked download */ |
555 | G.got_clen = 1; /* makes it show 100% even for download of (formerly) unknown size */ | ||
550 | progress_meter(PROGRESS_END); | 556 | progress_meter(PROGRESS_END); |
551 | } | 557 | } |
552 | 558 | ||
@@ -554,7 +560,6 @@ static int download_one_url(const char *url) | |||
554 | { | 560 | { |
555 | bool use_proxy; /* Use proxies if env vars are set */ | 561 | bool use_proxy; /* Use proxies if env vars are set */ |
556 | int redir_limit; | 562 | int redir_limit; |
557 | int output_fd; | ||
558 | len_and_sockaddr *lsa; | 563 | len_and_sockaddr *lsa; |
559 | FILE *sfp; /* socket to web/ftp server */ | 564 | FILE *sfp; /* socket to web/ftp server */ |
560 | FILE *dfp; /* socket to ftp server (data) */ | 565 | FILE *dfp; /* socket to ftp server (data) */ |
@@ -574,11 +579,9 @@ static int download_one_url(const char *url) | |||
574 | use_proxy = (strcmp(G.proxy_flag, "off") != 0); | 579 | use_proxy = (strcmp(G.proxy_flag, "off") != 0); |
575 | if (use_proxy) { | 580 | if (use_proxy) { |
576 | proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy"); | 581 | proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy"); |
577 | if (proxy && proxy[0]) { | 582 | use_proxy = (proxy && proxy[0]); |
583 | if (use_proxy) | ||
578 | parse_url(proxy, &server); | 584 | parse_url(proxy, &server); |
579 | } else { | ||
580 | use_proxy = 0; | ||
581 | } | ||
582 | } | 585 | } |
583 | if (!use_proxy) { | 586 | if (!use_proxy) { |
584 | server.port = target.port; | 587 | server.port = target.port; |
@@ -594,7 +597,6 @@ static int download_one_url(const char *url) | |||
594 | strip_ipv6_scope_id(target.host); | 597 | strip_ipv6_scope_id(target.host); |
595 | 598 | ||
596 | /* If there was no -O FILE, guess output filename */ | 599 | /* If there was no -O FILE, guess output filename */ |
597 | output_fd = -1; | ||
598 | fname_out_alloc = NULL; | 600 | fname_out_alloc = NULL; |
599 | if (!(option_mask32 & WGET_OPT_OUTNAME)) { | 601 | if (!(option_mask32 & WGET_OPT_OUTNAME)) { |
600 | G.fname_out = bb_get_last_path_component_nostrip(target.path); | 602 | G.fname_out = bb_get_last_path_component_nostrip(target.path); |
@@ -604,22 +606,17 @@ static int download_one_url(const char *url) | |||
604 | /* -P DIR is considered only if there was no -O FILE */ | 606 | /* -P DIR is considered only if there was no -O FILE */ |
605 | if (G.dir_prefix) | 607 | if (G.dir_prefix) |
606 | G.fname_out = fname_out_alloc = concat_path_file(G.dir_prefix, G.fname_out); | 608 | G.fname_out = fname_out_alloc = concat_path_file(G.dir_prefix, G.fname_out); |
607 | } else { | ||
608 | if (LONE_DASH(G.fname_out)) { | ||
609 | /* -O - */ | ||
610 | output_fd = 1; | ||
611 | option_mask32 &= ~WGET_OPT_CONTINUE; | ||
612 | } | ||
613 | } | 609 | } |
614 | #if ENABLE_FEATURE_WGET_STATUSBAR | 610 | #if ENABLE_FEATURE_WGET_STATUSBAR |
615 | G.curfile = bb_get_last_path_component_nostrip(G.fname_out); | 611 | G.curfile = bb_get_last_path_component_nostrip(G.fname_out); |
616 | #endif | 612 | #endif |
617 | 613 | ||
618 | /* Determine where to start transfer */ | 614 | /* Determine where to start transfer */ |
615 | G.beg_range = 0; | ||
619 | if (option_mask32 & WGET_OPT_CONTINUE) { | 616 | if (option_mask32 & WGET_OPT_CONTINUE) { |
620 | output_fd = open(G.fname_out, O_WRONLY); | 617 | G.output_fd = open(G.fname_out, O_WRONLY); |
621 | if (output_fd >= 0) { | 618 | if (G.output_fd >= 0) { |
622 | G.beg_range = xlseek(output_fd, 0, SEEK_END); | 619 | G.beg_range = xlseek(G.output_fd, 0, SEEK_END); |
623 | } | 620 | } |
624 | /* File doesn't exist. We do not create file here yet. | 621 | /* File doesn't exist. We do not create file here yet. |
625 | * We are not sure it exists on remote side */ | 622 | * We are not sure it exists on remote side */ |
@@ -634,7 +631,9 @@ static int download_one_url(const char *url) | |||
634 | free(s); | 631 | free(s); |
635 | } | 632 | } |
636 | establish_session: | 633 | establish_session: |
637 | G.chunked = G.got_clen = 0; | 634 | /*G.content_len = 0; - redundant, got_clen = 0 is enough */ |
635 | G.got_clen = 0; | ||
636 | G.chunked = 0; | ||
638 | if (use_proxy || !target.is_ftp) { | 637 | if (use_proxy || !target.is_ftp) { |
639 | /* | 638 | /* |
640 | * HTTP session | 639 | * HTTP session |
@@ -833,15 +832,13 @@ However, in real world it was observed that some web servers | |||
833 | free(lsa); | 832 | free(lsa); |
834 | 833 | ||
835 | if (!(option_mask32 & WGET_OPT_SPIDER)) { | 834 | if (!(option_mask32 & WGET_OPT_SPIDER)) { |
836 | if (output_fd < 0) { | 835 | if (G.output_fd < 0) |
837 | int o_flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL; | 836 | G.output_fd = xopen(G.fname_out, G.o_flags); |
838 | /* compat with wget: -O FILE can overwrite */ | 837 | retrieve_file_data(dfp); |
839 | if (option_mask32 & WGET_OPT_OUTNAME) | 838 | if (!(option_mask32 & WGET_OPT_OUTNAME)) { |
840 | o_flags = O_WRONLY | O_CREAT | O_TRUNC; | 839 | xclose(G.output_fd); |
841 | output_fd = xopen(G.fname_out, o_flags); | 840 | G.output_fd = -1; |
842 | } | 841 | } |
843 | retrieve_file_data(dfp, output_fd); | ||
844 | xclose(output_fd); | ||
845 | } | 842 | } |
846 | 843 | ||
847 | if (dfp != sfp) { | 844 | if (dfp != sfp) { |
@@ -929,6 +926,17 @@ int wget_main(int argc UNUSED_PARAM, char **argv) | |||
929 | } | 926 | } |
930 | #endif | 927 | #endif |
931 | 928 | ||
929 | G.output_fd = -1; | ||
930 | G.o_flags = O_WRONLY | O_CREAT | O_TRUNC | O_EXCL; | ||
931 | if (G.fname_out) { /* -O FILE ? */ | ||
932 | if (LONE_DASH(G.fname_out)) { /* -O - ? */ | ||
933 | G.output_fd = 1; | ||
934 | option_mask32 &= ~WGET_OPT_CONTINUE; | ||
935 | } | ||
936 | /* compat with wget: -O FILE can overwrite */ | ||
937 | G.o_flags = O_WRONLY | O_CREAT | O_TRUNC; | ||
938 | } | ||
939 | |||
932 | exitcode = 0; | 940 | exitcode = 0; |
933 | while (*argv) | 941 | while (*argv) |
934 | exitcode |= download_one_url(*argv++); | 942 | exitcode |= download_one_url(*argv++); |