summaryrefslogtreecommitdiff
path: root/networking/wget.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-10-01 10:58:54 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-10-01 10:58:54 +0000
commitf8aa109a9f7c67b291f240fb3ed91da90f26359b (patch)
treeef77baf65e9c8a58383bf6fe4250db3b34d5a21a /networking/wget.c
parentaecabffb8bf47ee8bf02c1fa1011ca97fc0b97d4 (diff)
downloadbusybox-w32-f8aa109a9f7c67b291f240fb3ed91da90f26359b.tar.gz
busybox-w32-f8aa109a9f7c67b291f240fb3ed91da90f26359b.tar.bz2
busybox-w32-f8aa109a9f7c67b291f240fb3ed91da90f26359b.zip
wget: make progress bar and ETA work correctly with -c
Diffstat (limited to 'networking/wget.c')
-rw-r--r--networking/wget.c72
1 files changed, 37 insertions, 35 deletions
diff --git a/networking/wget.c b/networking/wget.c
index 654973996..bbe1bba9a 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -43,16 +43,16 @@ static char *gethdr(char *buf, size_t bufsiz, FILE *fp, int *istrunc);
43static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf); 43static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf);
44 44
45/* Globals (can be accessed from signal handlers */ 45/* Globals (can be accessed from signal handlers */
46static FILEOFF_TYPE filesize; /* content-length of the file */ 46static FILEOFF_TYPE content_len; /* Content-length of the file */
47static FILEOFF_TYPE beg_range; /* Range at which continue begins */
48static FILEOFF_TYPE transferred; /* Number of bytes transferred so far */
47static int chunked; /* chunked transfer encoding */ 49static int chunked; /* chunked transfer encoding */
48#ifdef CONFIG_FEATURE_WGET_STATUSBAR 50#ifdef CONFIG_FEATURE_WGET_STATUSBAR
49static void progressmeter(int flag); 51static void progressmeter(int flag);
50static char *curfile; /* Name of current file being transferred. */ 52static char *curfile; /* Name of current file being transferred */
51static struct timeval start; /* Time a transfer started. */ 53static struct timeval start; /* Time a transfer started */
52static FILEOFF_TYPE transferred; /* Number of bytes transferred so far. */
53/* For progressmeter() -- number of seconds before xfer considered "stalled" */
54enum { 54enum {
55 STALLTIME = 5 55 STALLTIME = 5 /* Seconds when xfer considered "stalled" */
56}; 56};
57#else 57#else
58static void progressmeter(int flag) {} 58static void progressmeter(int flag) {}
@@ -139,7 +139,6 @@ int wget_main(int argc, char **argv)
139 FILE *sfp = NULL; /* socket to web/ftp server */ 139 FILE *sfp = NULL; /* socket to web/ftp server */
140 FILE *dfp = NULL; /* socket to ftp server (data) */ 140 FILE *dfp = NULL; /* socket to ftp server (data) */
141 char *fname_out = NULL; /* where to direct output (-O) */ 141 char *fname_out = NULL; /* where to direct output (-O) */
142 FILEOFF_TYPE beg_range = 0; /* range at which continue begins */
143 int got_clen = 0; /* got content-length: from server */ 142 int got_clen = 0; /* got content-length: from server */
144 int output_fd = -1; 143 int output_fd = -1;
145 int use_proxy = 1; /* Use proxies if env vars are set */ 144 int use_proxy = 1; /* Use proxies if env vars are set */
@@ -232,7 +231,7 @@ int wget_main(int argc, char **argv)
232 if (output_fd >= 0) { 231 if (output_fd >= 0) {
233 beg_range = LSEEK(output_fd, 0, SEEK_END); 232 beg_range = LSEEK(output_fd, 0, SEEK_END);
234 if (beg_range == (FILEOFF_TYPE)-1) 233 if (beg_range == (FILEOFF_TYPE)-1)
235 bb_perror_msg_and_die("lseek64"); 234 bb_perror_msg_and_die("lseek");
236 } 235 }
237 /* File doesn't exist. We do not create file here yet. 236 /* File doesn't exist. We do not create file here yet.
238 We are not sure it exists on remove side */ 237 We are not sure it exists on remove side */
@@ -337,7 +336,7 @@ read_response:
337 */ 336 */
338 while ((s = gethdr(buf, sizeof(buf), sfp, &n)) != NULL) { 337 while ((s = gethdr(buf, sizeof(buf), sfp, &n)) != NULL) {
339 if (strcasecmp(buf, "content-length") == 0) { 338 if (strcasecmp(buf, "content-length") == 0) {
340 if (SAFE_STRTOOFF(s, &filesize) || filesize < 0) { 339 if (SAFE_STRTOOFF(s, &content_len) || content_len < 0) {
341 bb_error_msg_and_die("content-length %s is garbage", s); 340 bb_error_msg_and_die("content-length %s is garbage", s);
342 } 341 }
343 got_clen = 1; 342 got_clen = 1;
@@ -405,7 +404,7 @@ read_response:
405 * Querying file size 404 * Querying file size
406 */ 405 */
407 if (ftpcmd("SIZE ", target.path, sfp, buf) == 213) { 406 if (ftpcmd("SIZE ", target.path, sfp, buf) == 213) {
408 if (SAFE_STRTOOFF(buf+4, &filesize) || filesize < 0) { 407 if (SAFE_STRTOOFF(buf+4, &content_len) || content_len < 0) {
409 bb_error_msg_and_die("SIZE value is garbage"); 408 bb_error_msg_and_die("SIZE value is garbage");
410 } 409 }
411 got_clen = 1; 410 got_clen = 1;
@@ -427,7 +426,7 @@ read_response:
427 if (beg_range) { 426 if (beg_range) {
428 sprintf(buf, "REST "FILEOFF_FMT, beg_range); 427 sprintf(buf, "REST "FILEOFF_FMT, beg_range);
429 if (ftpcmd(buf, NULL, sfp, buf) == 350) 428 if (ftpcmd(buf, NULL, sfp, buf) == 350)
430 filesize -= beg_range; 429 content_len -= beg_range;
431 } 430 }
432 431
433 if (ftpcmd("RETR ", target.path, sfp, buf) > 150) 432 if (ftpcmd("RETR ", target.path, sfp, buf) > 150)
@@ -440,23 +439,26 @@ read_response:
440 */ 439 */
441 if (chunked) { 440 if (chunked) {
442 fgets(buf, sizeof(buf), dfp); 441 fgets(buf, sizeof(buf), dfp);
443 filesize = STRTOOFF(buf, (char **) NULL, 16); 442 content_len = STRTOOFF(buf, (char **) NULL, 16);
444 /* FIXME: error check?? */ 443 /* FIXME: error check?? */
445 } 444 }
446 445
446 /* Do it before progressmeter (want to have nice error message) */
447 if (output_fd < 0)
448 output_fd = xopen3(fname_out,
449 O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_LARGEFILE, 0666);
450
447 if (!(opt & WGET_OPT_QUIET)) 451 if (!(opt & WGET_OPT_QUIET))
448 progressmeter(-1); 452 progressmeter(-1);
449 453
450 do { 454 do {
451 while (filesize > 0 || !got_clen) { 455 while (content_len > 0 || !got_clen) {
452 unsigned rdsz = sizeof(buf); 456 unsigned rdsz = sizeof(buf);
453 if (filesize < sizeof(buf) && (chunked || got_clen)) 457 if (content_len < sizeof(buf) && (chunked || got_clen))
454 rdsz = (unsigned)filesize; 458 rdsz = (unsigned)content_len;
455 n = safe_fread(buf, 1, rdsz, dfp); 459 n = safe_fread(buf, 1, rdsz, dfp);
456 if (n <= 0) 460 if (n <= 0)
457 break; 461 break;
458 if (output_fd < 0)
459 output_fd = xopen3(fname_out, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_LARGEFILE, 0666);
460 if (full_write(output_fd, buf, n) != n) { 462 if (full_write(output_fd, buf, n) != n) {
461 bb_perror_msg_and_die(bb_msg_write_error); 463 bb_perror_msg_and_die(bb_msg_write_error);
462 } 464 }
@@ -464,16 +466,16 @@ read_response:
464 transferred += n; 466 transferred += n;
465#endif 467#endif
466 if (got_clen) { 468 if (got_clen) {
467 filesize -= n; 469 content_len -= n;
468 } 470 }
469 } 471 }
470 472
471 if (chunked) { 473 if (chunked) {
472 safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */ 474 safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */
473 safe_fgets(buf, sizeof(buf), dfp); 475 safe_fgets(buf, sizeof(buf), dfp);
474 filesize = STRTOOFF(buf, (char **) NULL, 16); 476 content_len = STRTOOFF(buf, (char **) NULL, 16);
475 /* FIXME: error check? */ 477 /* FIXME: error check? */
476 if (filesize == 0) { 478 if (content_len == 0) {
477 chunked = 0; /* all done! */ 479 chunked = 0; /* all done! */
478 } 480 }
479 } 481 }
@@ -636,10 +638,7 @@ static int ftpcmd(char *s1, char *s2, FILE *fp, char *buf)
636#ifdef CONFIG_FEATURE_WGET_STATUSBAR 638#ifdef CONFIG_FEATURE_WGET_STATUSBAR
637/* Stuff below is from BSD rcp util.c, as added to openshh. 639/* Stuff below is from BSD rcp util.c, as added to openshh.
638 * Original copyright notice is retained at the end of this file. 640 * Original copyright notice is retained at the end of this file.
639 *
640 */ 641 */
641
642
643static int 642static int
644getttywidth(void) 643getttywidth(void)
645{ 644{
@@ -679,17 +678,17 @@ progressmeter(int flag)
679 int elapsed, ratio, barlength, i; 678 int elapsed, ratio, barlength, i;
680 char buf[256]; 679 char buf[256];
681 680
682 if (flag == -1) { 681 if (flag == -1) { /* first call to progressmeter */
683 (void) gettimeofday(&start, (struct timezone *) 0); 682 (void) gettimeofday(&start, (struct timezone *) 0);
684 lastupdate = start; 683 lastupdate = start;
685 lastsize = 0; 684 lastsize = 0;
686 totalsize = filesize; /* as filesize changes.. */ 685 totalsize = content_len + beg_range; /* as content_len changes.. */
687 } 686 }
688 687
689 (void) gettimeofday(&now, (struct timezone *) 0); 688 (void) gettimeofday(&now, (struct timezone *) 0);
690 ratio = 100; 689 ratio = 100;
691 if (totalsize != 0 && !chunked) { 690 if (totalsize != 0 && !chunked) {
692 ratio = (int) (100 * transferred / totalsize); 691 ratio = (int) (100 * (transferred+beg_range) / totalsize);
693 ratio = MIN(ratio, 100); 692 ratio = MIN(ratio, 100);
694 } 693 }
695 694
@@ -704,7 +703,7 @@ progressmeter(int flag)
704 fprintf(stderr, "|%s|", buf); 703 fprintf(stderr, "|%s|", buf);
705 } 704 }
706 i = 0; 705 i = 0;
707 abbrevsize = transferred; 706 abbrevsize = transferred + beg_range;
708 while (abbrevsize >= 100000) { 707 while (abbrevsize >= 100000) {
709 i++; 708 i++;
710 abbrevsize >>= 10; 709 abbrevsize >>= 10;
@@ -725,23 +724,26 @@ progressmeter(int flag)
725 724
726 if (tvwait.tv_sec >= STALLTIME) { 725 if (tvwait.tv_sec >= STALLTIME) {
727 fprintf(stderr, " - stalled -"); 726 fprintf(stderr, " - stalled -");
728 } else if (transferred <= 0 || elapsed <= 0 || transferred > totalsize || chunked) {
729 fprintf(stderr, "--:--:-- ETA");
730 } else { 727 } else {
731 /* totalsize / (transferred/elapsed) - elapsed: */ 728 FILEOFF_TYPE to_download = totalsize - beg_range;
732 int eta = (int) (totalsize*elapsed/transferred - elapsed); 729 if (transferred <= 0 || elapsed <= 0 || transferred > to_download || chunked) {
733 i = eta % 3600; 730 fprintf(stderr, "--:--:-- ETA");
734 fprintf(stderr, "%02d:%02d:%02d ETA", eta / 3600, i / 60, i % 60); 731 } else {
732 /* to_download / (transferred/elapsed) - elapsed: */
733 int eta = (int) (to_download*elapsed/transferred - elapsed);
734 i = eta % 3600;
735 fprintf(stderr, "%02d:%02d:%02d ETA", eta / 3600, i / 60, i % 60);
736 }
735 } 737 }
736 738
737 if (flag == -1) { 739 if (flag == -1) { /* first call to progressmeter */
738 struct sigaction sa; 740 struct sigaction sa;
739 sa.sa_handler = updateprogressmeter; 741 sa.sa_handler = updateprogressmeter;
740 sigemptyset(&sa.sa_mask); 742 sigemptyset(&sa.sa_mask);
741 sa.sa_flags = SA_RESTART; 743 sa.sa_flags = SA_RESTART;
742 sigaction(SIGALRM, &sa, NULL); 744 sigaction(SIGALRM, &sa, NULL);
743 alarmtimer(1); 745 alarmtimer(1);
744 } else if (flag == 1) { 746 } else if (flag == 1) { /* last call to progressmeter */
745 alarmtimer(0); 747 alarmtimer(0);
746 transferred = 0; 748 transferred = 0;
747 putc('\n', stderr); 749 putc('\n', stderr);