diff options
author | Magnus Damm <magnus.damm@gmail.com> | 2009-11-08 16:34:43 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-11-08 16:34:43 +0100 |
commit | f5914992f316f8a628505067e108e7ba5a9590ba (patch) | |
tree | e7e34807bf4b5fab00303064c0aab5df1bd8b543 /networking/wget.c | |
parent | f5c2f72917e5f75634665f67a6105e1e82ece875 (diff) | |
download | busybox-w32-f5914992f316f8a628505067e108e7ba5a9590ba.tar.gz busybox-w32-f5914992f316f8a628505067e108e7ba5a9590ba.tar.bz2 busybox-w32-f5914992f316f8a628505067e108e7ba5a9590ba.zip |
wget: factor out progress bar code
Signed-off-by: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/wget.c')
-rw-r--r-- | networking/wget.c | 127 |
1 files changed, 6 insertions, 121 deletions
diff --git a/networking/wget.c b/networking/wget.c index 0f99e8d13..11d39cb66 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -24,12 +24,9 @@ struct globals { | |||
24 | off_t content_len; /* Content-length of the file */ | 24 | off_t content_len; /* Content-length of the file */ |
25 | off_t beg_range; /* Range at which continue begins */ | 25 | off_t beg_range; /* Range at which continue begins */ |
26 | #if ENABLE_FEATURE_WGET_STATUSBAR | 26 | #if ENABLE_FEATURE_WGET_STATUSBAR |
27 | off_t lastsize; | ||
28 | off_t totalsize; | ||
29 | off_t transferred; /* Number of bytes transferred so far */ | 27 | off_t transferred; /* Number of bytes transferred so far */ |
30 | const char *curfile; /* Name of current file being transferred */ | 28 | const char *curfile; /* Name of current file being transferred */ |
31 | unsigned lastupdate_sec; | 29 | bb_progress_t pmt; |
32 | unsigned start_sec; | ||
33 | #endif | 30 | #endif |
34 | smallint chunked; /* chunked transfer encoding */ | 31 | smallint chunked; /* chunked transfer encoding */ |
35 | smallint got_clen; /* got content-length: from server */ | 32 | smallint got_clen; /* got content-length: from server */ |
@@ -40,108 +37,30 @@ struct BUG_G_too_big { | |||
40 | }; | 37 | }; |
41 | #define content_len (G.content_len ) | 38 | #define content_len (G.content_len ) |
42 | #define beg_range (G.beg_range ) | 39 | #define beg_range (G.beg_range ) |
43 | #define lastsize (G.lastsize ) | ||
44 | #define totalsize (G.totalsize ) | ||
45 | #define transferred (G.transferred ) | 40 | #define transferred (G.transferred ) |
46 | #define curfile (G.curfile ) | 41 | #define curfile (G.curfile ) |
47 | #define lastupdate_sec (G.lastupdate_sec ) | ||
48 | #define start_sec (G.start_sec ) | ||
49 | #define INIT_G() do { } while (0) | 42 | #define INIT_G() do { } while (0) |
50 | 43 | ||
51 | 44 | ||
52 | #if ENABLE_FEATURE_WGET_STATUSBAR | 45 | #if ENABLE_FEATURE_WGET_STATUSBAR |
53 | enum { | ||
54 | STALLTIME = 5 /* Seconds when xfer considered "stalled" */ | ||
55 | }; | ||
56 | |||
57 | static unsigned int get_tty2_width(void) | ||
58 | { | ||
59 | unsigned width; | ||
60 | get_terminal_width_height(2, &width, NULL); | ||
61 | return width; | ||
62 | } | ||
63 | 46 | ||
64 | static void progress_meter(int flag) | 47 | static void progress_meter(int flag) |
65 | { | 48 | { |
66 | /* We can be called from signal handler */ | 49 | /* We can be called from signal handler */ |
67 | int save_errno = errno; | 50 | int save_errno = errno; |
68 | off_t abbrevsize; | ||
69 | unsigned since_last_update, elapsed; | ||
70 | unsigned ratio; | ||
71 | int barlength, i; | ||
72 | 51 | ||
73 | if (flag == -1) { /* first call to progress_meter */ | 52 | if (flag == -1) { /* first call to progress_meter */ |
74 | start_sec = monotonic_sec(); | 53 | bb_progress_init(&G.pmt); |
75 | lastupdate_sec = start_sec; | ||
76 | lastsize = 0; | ||
77 | totalsize = content_len + beg_range; /* as content_len changes.. */ | ||
78 | } | ||
79 | |||
80 | ratio = 100; | ||
81 | if (totalsize != 0 && !G.chunked) { | ||
82 | /* long long helps to have it working even if !LFS */ | ||
83 | ratio = (unsigned) (100ULL * (transferred+beg_range) / totalsize); | ||
84 | if (ratio > 100) ratio = 100; | ||
85 | } | ||
86 | |||
87 | fprintf(stderr, "\r%-20.20s%4d%% ", curfile, ratio); | ||
88 | |||
89 | barlength = get_tty2_width() - 49; | ||
90 | if (barlength > 0) { | ||
91 | /* god bless gcc for variable arrays :) */ | ||
92 | i = barlength * ratio / 100; | ||
93 | { | ||
94 | char buf[i+1]; | ||
95 | memset(buf, '*', i); | ||
96 | buf[i] = '\0'; | ||
97 | fprintf(stderr, "|%s%*s|", buf, barlength - i, ""); | ||
98 | } | ||
99 | } | ||
100 | i = 0; | ||
101 | abbrevsize = transferred + beg_range; | ||
102 | while (abbrevsize >= 100000) { | ||
103 | i++; | ||
104 | abbrevsize >>= 10; | ||
105 | } | ||
106 | /* see http://en.wikipedia.org/wiki/Tera */ | ||
107 | fprintf(stderr, "%6d%c ", (int)abbrevsize, " kMGTPEZY"[i]); | ||
108 | |||
109 | // Nuts! Ain't it easier to update progress meter ONLY when we transferred++? | ||
110 | |||
111 | elapsed = monotonic_sec(); | ||
112 | since_last_update = elapsed - lastupdate_sec; | ||
113 | if (transferred > lastsize) { | ||
114 | lastupdate_sec = elapsed; | ||
115 | lastsize = transferred; | ||
116 | if (since_last_update >= STALLTIME) { | ||
117 | /* We "cut off" these seconds from elapsed time | ||
118 | * by adjusting start time */ | ||
119 | start_sec += since_last_update; | ||
120 | } | ||
121 | since_last_update = 0; /* we are un-stalled now */ | ||
122 | } | 54 | } |
123 | elapsed -= start_sec; /* now it's "elapsed since start" */ | ||
124 | 55 | ||
125 | if (since_last_update >= STALLTIME) { | 56 | bb_progress_update(&G.pmt, curfile, beg_range, transferred, |
126 | fprintf(stderr, " - stalled -"); | 57 | G.chunked ? 0 : content_len + beg_range); |
127 | } else { | ||
128 | off_t to_download = totalsize - beg_range; | ||
129 | if (transferred <= 0 || (int)elapsed <= 0 || transferred > to_download || G.chunked) { | ||
130 | fprintf(stderr, "--:--:-- ETA"); | ||
131 | } else { | ||
132 | /* to_download / (transferred/elapsed) - elapsed: */ | ||
133 | int eta = (int) ((unsigned long long)to_download*elapsed/transferred - elapsed); | ||
134 | /* (long long helps to have working ETA even if !LFS) */ | ||
135 | i = eta % 3600; | ||
136 | fprintf(stderr, "%02d:%02d:%02d ETA", eta / 3600, i / 60, i % 60); | ||
137 | } | ||
138 | } | ||
139 | 58 | ||
140 | if (flag == 0) { | 59 | if (flag == 0) { |
141 | /* last call to progress_meter */ | 60 | /* last call to progress_meter */ |
142 | alarm(0); | 61 | alarm(0); |
143 | transferred = 0; | ||
144 | fputc('\n', stderr); | 62 | fputc('\n', stderr); |
63 | transferred = 0; | ||
145 | } else { | 64 | } else { |
146 | if (flag == -1) { /* first call to progress_meter */ | 65 | if (flag == -1) { /* first call to progress_meter */ |
147 | signal_SA_RESTART_empty_mask(SIGALRM, progress_meter); | 66 | signal_SA_RESTART_empty_mask(SIGALRM, progress_meter); |
@@ -151,41 +70,7 @@ static void progress_meter(int flag) | |||
151 | 70 | ||
152 | errno = save_errno; | 71 | errno = save_errno; |
153 | } | 72 | } |
154 | /* Original copyright notice which applies to the CONFIG_FEATURE_WGET_STATUSBAR stuff, | 73 | |
155 | * much of which was blatantly stolen from openssh. */ | ||
156 | /*- | ||
157 | * Copyright (c) 1992, 1993 | ||
158 | * The Regents of the University of California. All rights reserved. | ||
159 | * | ||
160 | * Redistribution and use in source and binary forms, with or without | ||
161 | * modification, are permitted provided that the following conditions | ||
162 | * are met: | ||
163 | * 1. Redistributions of source code must retain the above copyright | ||
164 | * notice, this list of conditions and the following disclaimer. | ||
165 | * 2. Redistributions in binary form must reproduce the above copyright | ||
166 | * notice, this list of conditions and the following disclaimer in the | ||
167 | * documentation and/or other materials provided with the distribution. | ||
168 | * | ||
169 | * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change | ||
170 | * ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change> | ||
171 | * | ||
172 | * 4. Neither the name of the University nor the names of its contributors | ||
173 | * may be used to endorse or promote products derived from this software | ||
174 | * without specific prior written permission. | ||
175 | * | ||
176 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | ||
177 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
178 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
179 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
180 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
181 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
182 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
183 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
184 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
185 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
186 | * SUCH DAMAGE. | ||
187 | * | ||
188 | */ | ||
189 | #else /* FEATURE_WGET_STATUSBAR */ | 74 | #else /* FEATURE_WGET_STATUSBAR */ |
190 | 75 | ||
191 | static ALWAYS_INLINE void progress_meter(int flag UNUSED_PARAM) { } | 76 | static ALWAYS_INLINE void progress_meter(int flag UNUSED_PARAM) { } |