]> sjero.net Git - wget/blob - src/progress.c
Fix some compiler warnings.
[wget] / src / progress.c
1 /* Download progress.
2    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
3    2010, 2011 Free Software Foundation, Inc.
4
5 This file is part of GNU Wget.
6
7 GNU Wget is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 GNU Wget is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Wget.  If not, see <http://www.gnu.org/licenses/>.
19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a
24 modified version of that library), containing parts covered by the
25 terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
26 grants you additional permission to convey the resulting work.
27 Corresponding Source for a non-source form of such a combination
28 shall include the source code for the parts of OpenSSL used as well
29 as that of the covered work.  */
30
31 #include "wget.h"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <assert.h>
37 #include <unistd.h>
38 #include <signal.h>
39 #ifdef HAVE_WCHAR_H
40 # include <wchar.h>
41 #endif
42
43 #include "progress.h"
44 #include "utils.h"
45 #include "retr.h"
46
47 struct progress_implementation {
48   const char *name;
49   bool interactive;
50   void *(*create) (wgint, wgint);
51   void (*update) (void *, wgint, double);
52   void (*finish) (void *, double);
53   void (*set_params) (const char *);
54 };
55
56 /* Necessary forward declarations. */
57
58 static void *dot_create (wgint, wgint);
59 static void dot_update (void *, wgint, double);
60 static void dot_finish (void *, double);
61 static void dot_set_params (const char *);
62
63 static void *bar_create (wgint, wgint);
64 static void bar_update (void *, wgint, double);
65 static void bar_finish (void *, double);
66 static void bar_set_params (const char *);
67
68 static struct progress_implementation implementations[] = {
69   { "dot", 0, dot_create, dot_update, dot_finish, dot_set_params },
70   { "bar", 1, bar_create, bar_update, bar_finish, bar_set_params }
71 };
72 static struct progress_implementation *current_impl;
73 static int current_impl_locked;
74
75 /* Progress implementation used by default.  Can be overriden in
76    wgetrc or by the fallback one.  */
77
78 #define DEFAULT_PROGRESS_IMPLEMENTATION "bar"
79
80 /* Fallback progress implementation should be something that works
81    under all display types.  If you put something other than "dot"
82    here, remember that bar_set_params tries to switch to this if we're
83    not running on a TTY.  So changing this to "bar" could cause
84    infloop.  */
85
86 #define FALLBACK_PROGRESS_IMPLEMENTATION "dot"
87
88 /* Return true if NAME names a valid progress bar implementation.  The
89    characters after the first : will be ignored.  */
90
91 bool
92 valid_progress_implementation_p (const char *name)
93 {
94   size_t i;
95   struct progress_implementation *pi = implementations;
96   char *colon = strchr (name, ':');
97   size_t namelen = colon ? (size_t) (colon - name) : strlen (name);
98
99   for (i = 0; i < countof (implementations); i++, pi++)
100     if (!strncmp (pi->name, name, namelen))
101       return true;
102   return false;
103 }
104
105 /* Set the progress implementation to NAME.  */
106
107 void
108 set_progress_implementation (const char *name)
109 {
110   size_t i, namelen;
111   struct progress_implementation *pi = implementations;
112   const char *colon;
113
114   if (!name)
115     name = DEFAULT_PROGRESS_IMPLEMENTATION;
116
117   colon = strchr (name, ':');
118   namelen = colon ? (size_t) (colon - name) : strlen (name);
119
120   for (i = 0; i < countof (implementations); i++, pi++)
121     if (!strncmp (pi->name, name, namelen))
122       {
123         current_impl = pi;
124         current_impl_locked = 0;
125
126         if (colon)
127           /* We call pi->set_params even if colon is NULL because we
128              want to give the implementation a chance to set up some
129              things it needs to run.  */
130           ++colon;
131
132         if (pi->set_params)
133           pi->set_params (colon);
134         return;
135       }
136   abort ();
137 }
138
139 static int output_redirected;
140
141 void
142 progress_schedule_redirect (void)
143 {
144   output_redirected = 1;
145 }
146
147 /* Create a progress gauge.  INITIAL is the number of bytes the
148    download starts from (zero if the download starts from scratch).
149    TOTAL is the expected total number of bytes in this download.  If
150    TOTAL is zero, it means that the download size is not known in
151    advance.  */
152
153 void *
154 progress_create (wgint initial, wgint total)
155 {
156   /* Check if the log status has changed under our feet. */
157   if (output_redirected)
158     {
159       if (!current_impl_locked)
160         set_progress_implementation (FALLBACK_PROGRESS_IMPLEMENTATION);
161       output_redirected = 0;
162     }
163
164   return current_impl->create (initial, total);
165 }
166
167 /* Return true if the progress gauge is "interactive", i.e. if it can
168    profit from being called regularly even in absence of data.  The
169    progress bar is interactive because it regularly updates the ETA
170    and current update.  */
171
172 bool
173 progress_interactive_p (void *progress)
174 {
175   return current_impl->interactive;
176 }
177
178 /* Inform the progress gauge of newly received bytes.  DLTIME is the
179    time since the beginning of the download.  */
180
181 void
182 progress_update (void *progress, wgint howmuch, double dltime)
183 {
184   current_impl->update (progress, howmuch, dltime);
185 }
186
187 /* Tell the progress gauge to clean up.  Calling this will free the
188    PROGRESS object, the further use of which is not allowed.  */
189
190 void
191 progress_finish (void *progress, double dltime)
192 {
193   current_impl->finish (progress, dltime);
194 }
195 \f
196 /* Dot-printing. */
197
198 struct dot_progress {
199   wgint initial_length;         /* how many bytes have been downloaded
200                                    previously. */
201   wgint total_length;           /* expected total byte count when the
202                                    download finishes */
203
204   int accumulated;              /* number of bytes accumulated after
205                                    the last printed dot */
206
207   int rows;                     /* number of rows printed so far */
208   int dots;                     /* number of dots printed in this row */
209
210   double last_timer_value;
211 };
212
213 /* Dot-progress backend for progress_create. */
214
215 static void *
216 dot_create (wgint initial, wgint total)
217 {
218   struct dot_progress *dp = xnew0 (struct dot_progress);
219   dp->initial_length = initial;
220   dp->total_length   = total;
221
222   if (dp->initial_length)
223     {
224       int dot_bytes = opt.dot_bytes;
225       const wgint ROW_BYTES = opt.dot_bytes * opt.dots_in_line;
226
227       int remainder = dp->initial_length % ROW_BYTES;
228       wgint skipped = dp->initial_length - remainder;
229
230       if (skipped)
231         {
232           wgint skipped_k = skipped / 1024; /* skipped amount in K */
233           int skipped_k_len = numdigit (skipped_k);
234           if (skipped_k_len < 6)
235             skipped_k_len = 6;
236
237           /* Align the [ skipping ... ] line with the dots.  To do
238              that, insert the number of spaces equal to the number of
239              digits in the skipped amount in K.  */
240           logprintf (LOG_VERBOSE, _("\n%*s[ skipping %sK ]"),
241                      2 + skipped_k_len, "",
242                      number_to_static_string (skipped_k));
243         }
244
245       logprintf (LOG_VERBOSE, "\n%6sK",
246                  number_to_static_string (skipped / 1024));
247       for (; remainder >= dot_bytes; remainder -= dot_bytes)
248         {
249           if (dp->dots % opt.dot_spacing == 0)
250             logputs (LOG_VERBOSE, " ");
251           logputs (LOG_VERBOSE, ",");
252           ++dp->dots;
253         }
254       assert (dp->dots < opt.dots_in_line);
255
256       dp->accumulated = remainder;
257       dp->rows = skipped / ROW_BYTES;
258     }
259
260   return dp;
261 }
262
263 static const char *eta_to_human_short (int, bool);
264
265 /* Prints the stats (percentage of completion, speed, ETA) for current
266    row.  DLTIME is the time spent downloading the data in current
267    row.
268
269    #### This function is somewhat uglified by the fact that current
270    row and last row have somewhat different stats requirements.  It
271    might be worthwhile to split it to two different functions.  */
272
273 static void
274 print_row_stats (struct dot_progress *dp, double dltime, bool last)
275 {
276   const wgint ROW_BYTES = opt.dot_bytes * opt.dots_in_line;
277
278   /* bytes_displayed is the number of bytes indicated to the user by
279      dots printed so far, includes the initially "skipped" amount */
280   wgint bytes_displayed = dp->rows * ROW_BYTES + dp->dots * opt.dot_bytes;
281
282   if (last)
283     /* For last row also count bytes accumulated after last dot */
284     bytes_displayed += dp->accumulated;
285
286   if (dp->total_length)
287     {
288       /* Round to floor value to provide gauge how much data *has*
289          been retrieved.  12.8% will round to 12% because the 13% mark
290          has not yet been reached.  100% is only shown when done.  */
291       int percentage = 100.0 * bytes_displayed / dp->total_length;
292       logprintf (LOG_VERBOSE, "%3d%%", percentage);
293     }
294
295   {
296     static char names[] = {' ', 'K', 'M', 'G'};
297     int units;
298     double rate;
299     wgint bytes_this_row;
300     if (!last)
301       bytes_this_row = ROW_BYTES;
302     else
303       /* For last row also include bytes accumulated after last dot.  */
304       bytes_this_row = dp->dots * opt.dot_bytes + dp->accumulated;
305     /* Don't count the portion of the row belonging to initial_length */
306     if (dp->rows == dp->initial_length / ROW_BYTES)
307       bytes_this_row -= dp->initial_length % ROW_BYTES;
308     rate = calc_rate (bytes_this_row, dltime - dp->last_timer_value, &units);
309     logprintf (LOG_VERBOSE, " %4.*f%c",
310                rate >= 99.95 ? 0 : rate >= 9.995 ? 1 : 2,
311                rate, names[units]);
312     dp->last_timer_value = dltime;
313   }
314
315   if (!last)
316     {
317       /* Display ETA based on average speed.  Inspired by Vladi
318          Belperchinov-Shabanski's "wget-new-percentage" patch.  */
319       if (dp->total_length)
320         {
321           wgint bytes_remaining = dp->total_length - bytes_displayed;
322           /* The quantity downloaded in this download run. */
323           wgint bytes_sofar = bytes_displayed - dp->initial_length;
324           double eta = dltime * bytes_remaining / bytes_sofar;
325           if (eta < INT_MAX - 1)
326             logprintf (LOG_VERBOSE, " %s",
327                        eta_to_human_short ((int) (eta + 0.5), true));
328         }
329     }
330   else
331     {
332       /* When done, print the total download time */
333       if (dltime >= 10)
334         logprintf (LOG_VERBOSE, "=%s",
335                    eta_to_human_short ((int) (dltime + 0.5), true));
336       else
337         logprintf (LOG_VERBOSE, "=%ss", print_decimal (dltime));
338     }
339 }
340
341 /* Dot-progress backend for progress_update. */
342
343 static void
344 dot_update (void *progress, wgint howmuch, double dltime)
345 {
346   struct dot_progress *dp = progress;
347   int dot_bytes = opt.dot_bytes;
348   wgint ROW_BYTES = opt.dot_bytes * opt.dots_in_line;
349
350   log_set_flush (false);
351
352   dp->accumulated += howmuch;
353   for (; dp->accumulated >= dot_bytes; dp->accumulated -= dot_bytes)
354     {
355       if (dp->dots == 0)
356         logprintf (LOG_VERBOSE, "\n%6sK",
357                    number_to_static_string (dp->rows * ROW_BYTES / 1024));
358
359       if (dp->dots % opt.dot_spacing == 0)
360         logputs (LOG_VERBOSE, " ");
361       logputs (LOG_VERBOSE, ".");
362
363       ++dp->dots;
364       if (dp->dots >= opt.dots_in_line)
365         {
366           ++dp->rows;
367           dp->dots = 0;
368
369           print_row_stats (dp, dltime, false);
370         }
371     }
372
373   log_set_flush (true);
374 }
375
376 /* Dot-progress backend for progress_finish. */
377
378 static void
379 dot_finish (void *progress, double dltime)
380 {
381   struct dot_progress *dp = progress;
382   wgint ROW_BYTES = opt.dot_bytes * opt.dots_in_line;
383   int i;
384
385   log_set_flush (false);
386
387   if (dp->dots == 0)
388     logprintf (LOG_VERBOSE, "\n%6sK",
389                number_to_static_string (dp->rows * ROW_BYTES / 1024));
390   for (i = dp->dots; i < opt.dots_in_line; i++)
391     {
392       if (i % opt.dot_spacing == 0)
393         logputs (LOG_VERBOSE, " ");
394       logputs (LOG_VERBOSE, " ");
395     }
396
397   print_row_stats (dp, dltime, true);
398   logputs (LOG_VERBOSE, "\n\n");
399   log_set_flush (false);
400
401   xfree (dp);
402 }
403
404 /* This function interprets the progress "parameters".  For example,
405    if Wget is invoked with --progress=dot:mega, it will set the
406    "dot-style" to "mega".  Valid styles are default, binary, mega, and
407    giga.  */
408
409 static void
410 dot_set_params (const char *params)
411 {
412   if (!params || !*params)
413     params = opt.dot_style;
414
415   if (!params)
416     return;
417
418   /* We use this to set the retrieval style.  */
419   if (!strcasecmp (params, "default"))
420     {
421       /* Default style: 1K dots, 10 dots in a cluster, 50 dots in a
422          line.  */
423       opt.dot_bytes = 1024;
424       opt.dot_spacing = 10;
425       opt.dots_in_line = 50;
426     }
427   else if (!strcasecmp (params, "binary"))
428     {
429       /* "Binary" retrieval: 8K dots, 16 dots in a cluster, 48 dots
430          (384K) in a line.  */
431       opt.dot_bytes = 8192;
432       opt.dot_spacing = 16;
433       opt.dots_in_line = 48;
434     }
435   else if (!strcasecmp (params, "mega"))
436     {
437       /* "Mega" retrieval, for retrieving very long files; each dot is
438          64K, 8 dots in a cluster, 6 clusters (3M) in a line.  */
439       opt.dot_bytes = 65536L;
440       opt.dot_spacing = 8;
441       opt.dots_in_line = 48;
442     }
443   else if (!strcasecmp (params, "giga"))
444     {
445       /* "Giga" retrieval, for retrieving very very *very* long files;
446          each dot is 1M, 8 dots in a cluster, 4 clusters (32M) in a
447          line.  */
448       opt.dot_bytes = (1L << 20);
449       opt.dot_spacing = 8;
450       opt.dots_in_line = 32;
451     }
452   else
453     fprintf (stderr,
454              _("Invalid dot style specification %s; leaving unchanged.\n"),
455              quote (params));
456 }
457 \f
458 /* "Thermometer" (bar) progress. */
459
460 /* Assumed screen width if we can't find the real value.  */
461 #define DEFAULT_SCREEN_WIDTH 80
462
463 /* Minimum screen width we'll try to work with.  If this is too small,
464    create_image will overflow the buffer.  */
465 #define MINIMUM_SCREEN_WIDTH 45
466
467 /* The last known screen width.  This can be updated by the code that
468    detects that SIGWINCH was received (but it's never updated from the
469    signal handler).  */
470 static int screen_width;
471
472 /* A flag that, when set, means SIGWINCH was received.  */
473 static volatile sig_atomic_t received_sigwinch;
474
475 /* Size of the download speed history ring. */
476 #define DLSPEED_HISTORY_SIZE 20
477
478 /* The minimum time length of a history sample.  By default, each
479    sample is at least 150ms long, which means that, over the course of
480    20 samples, "current" download speed spans at least 3s into the
481    past.  */
482 #define DLSPEED_SAMPLE_MIN 0.15
483
484 /* The time after which the download starts to be considered
485    "stalled", i.e. the current bandwidth is not printed and the recent
486    download speeds are scratched.  */
487 #define STALL_START_TIME 5
488
489 /* Time between screen refreshes will not be shorter than this, so
490    that Wget doesn't swamp the TTY with output.  */
491 #define REFRESH_INTERVAL 0.2
492
493 /* Don't refresh the ETA too often to avoid jerkiness in predictions.
494    This allows ETA to change approximately once per second.  */
495 #define ETA_REFRESH_INTERVAL 0.99
496
497 struct bar_progress {
498   wgint initial_length;         /* how many bytes have been downloaded
499                                    previously. */
500   wgint total_length;           /* expected total byte count when the
501                                    download finishes */
502   wgint count;                  /* bytes downloaded so far */
503
504   double last_screen_update;    /* time of the last screen update,
505                                    measured since the beginning of
506                                    download. */
507
508   int width;                    /* screen width we're using at the
509                                    time the progress gauge was
510                                    created.  this is different from
511                                    the screen_width global variable in
512                                    that the latter can be changed by a
513                                    signal. */
514   char *buffer;                 /* buffer where the bar "image" is
515                                    stored. */
516   int tick;                     /* counter used for drawing the
517                                    progress bar where the total size
518                                    is not known. */
519
520   /* The following variables (kept in a struct for namespace reasons)
521      keep track of recent download speeds.  See bar_update() for
522      details.  */
523   struct bar_progress_hist {
524     int pos;
525     double times[DLSPEED_HISTORY_SIZE];
526     wgint bytes[DLSPEED_HISTORY_SIZE];
527
528     /* The sum of times and bytes respectively, maintained for
529        efficiency. */
530     double total_time;
531     wgint total_bytes;
532   } hist;
533
534   double recent_start;          /* timestamp of beginning of current
535                                    position. */
536   wgint recent_bytes;           /* bytes downloaded so far. */
537
538   bool stalled;                 /* set when no data arrives for longer
539                                    than STALL_START_TIME, then reset
540                                    when new data arrives. */
541
542   /* create_image() uses these to make sure that ETA information
543      doesn't flicker. */
544   double last_eta_time;         /* time of the last update to download
545                                    speed and ETA, measured since the
546                                    beginning of download. */
547   int last_eta_value;
548 };
549
550 static void create_image (struct bar_progress *, double, bool);
551 static void display_image (char *);
552
553 static void *
554 bar_create (wgint initial, wgint total)
555 {
556   struct bar_progress *bp = xnew0 (struct bar_progress);
557
558   /* In theory, our callers should take care of this pathological
559      case, but it can sometimes happen. */
560   if (initial > total)
561     total = initial;
562
563   bp->initial_length = initial;
564   bp->total_length   = total;
565
566   /* Initialize screen_width if this hasn't been done or if it might
567      have changed, as indicated by receiving SIGWINCH.  */
568   if (!screen_width || received_sigwinch)
569     {
570       screen_width = determine_screen_width ();
571       if (!screen_width)
572         screen_width = DEFAULT_SCREEN_WIDTH;
573       else if (screen_width < MINIMUM_SCREEN_WIDTH)
574         screen_width = MINIMUM_SCREEN_WIDTH;
575       received_sigwinch = 0;
576     }
577
578   /* - 1 because we don't want to use the last screen column. */
579   bp->width = screen_width - 1;
580   /* + enough space for the terminating zero, and hopefully enough room
581    * for multibyte characters. */
582   bp->buffer = xmalloc (bp->width + 100);
583
584   logputs (LOG_VERBOSE, "\n");
585
586   create_image (bp, 0, false);
587   display_image (bp->buffer);
588
589   return bp;
590 }
591
592 static void update_speed_ring (struct bar_progress *, wgint, double);
593
594 static void
595 bar_update (void *progress, wgint howmuch, double dltime)
596 {
597   struct bar_progress *bp = progress;
598   bool force_screen_update = false;
599
600   bp->count += howmuch;
601   if (bp->total_length > 0
602       && bp->count + bp->initial_length > bp->total_length)
603     /* We could be downloading more than total_length, e.g. when the
604        server sends an incorrect Content-Length header.  In that case,
605        adjust bp->total_length to the new reality, so that the code in
606        create_image() that depends on total size being smaller or
607        equal to the expected size doesn't abort.  */
608     bp->total_length = bp->initial_length + bp->count;
609
610   update_speed_ring (bp, howmuch, dltime);
611
612   /* If SIGWINCH (the window size change signal) been received,
613      determine the new screen size and update the screen.  */
614   if (received_sigwinch)
615     {
616       int old_width = screen_width;
617       screen_width = determine_screen_width ();
618       if (!screen_width)
619         screen_width = DEFAULT_SCREEN_WIDTH;
620       else if (screen_width < MINIMUM_SCREEN_WIDTH)
621         screen_width = MINIMUM_SCREEN_WIDTH;
622       if (screen_width != old_width)
623         {
624           bp->width = screen_width - 1;
625           bp->buffer = xrealloc (bp->buffer, bp->width + 100);
626           force_screen_update = true;
627         }
628       received_sigwinch = 0;
629     }
630
631   if (dltime - bp->last_screen_update < REFRESH_INTERVAL && !force_screen_update)
632     /* Don't update more often than five times per second. */
633     return;
634
635   create_image (bp, dltime, false);
636   display_image (bp->buffer);
637   bp->last_screen_update = dltime;
638 }
639
640 static void
641 bar_finish (void *progress, double dltime)
642 {
643   struct bar_progress *bp = progress;
644
645   if (bp->total_length > 0
646       && bp->count + bp->initial_length > bp->total_length)
647     /* See bar_update() for explanation. */
648     bp->total_length = bp->initial_length + bp->count;
649
650   create_image (bp, dltime, true);
651   display_image (bp->buffer);
652
653   logputs (LOG_VERBOSE, "\n\n");
654
655   xfree (bp->buffer);
656   xfree (bp);
657 }
658
659 /* This code attempts to maintain the notion of a "current" download
660    speed, over the course of no less than 3s.  (Shorter intervals
661    produce very erratic results.)
662
663    To do so, it samples the speed in 150ms intervals and stores the
664    recorded samples in a FIFO history ring.  The ring stores no more
665    than 20 intervals, hence the history covers the period of at least
666    three seconds and at most 20 reads into the past.  This method
667    should produce reasonable results for downloads ranging from very
668    slow to very fast.
669
670    The idea is that for fast downloads, we get the speed over exactly
671    the last three seconds.  For slow downloads (where a network read
672    takes more than 150ms to complete), we get the speed over a larger
673    time period, as large as it takes to complete thirty reads.  This
674    is good because slow downloads tend to fluctuate more and a
675    3-second average would be too erratic.  */
676
677 static void
678 update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
679 {
680   struct bar_progress_hist *hist = &bp->hist;
681   double recent_age = dltime - bp->recent_start;
682
683   /* Update the download count. */
684   bp->recent_bytes += howmuch;
685
686   /* For very small time intervals, we return after having updated the
687      "recent" download count.  When its age reaches or exceeds minimum
688      sample time, it will be recorded in the history ring.  */
689   if (recent_age < DLSPEED_SAMPLE_MIN)
690     return;
691
692   if (howmuch == 0)
693     {
694       /* If we're not downloading anything, we might be stalling,
695          i.e. not downloading anything for an extended period of time.
696          Since 0-reads do not enter the history ring, recent_age
697          effectively measures the time since last read.  */
698       if (recent_age >= STALL_START_TIME)
699         {
700           /* If we're stalling, reset the ring contents because it's
701              stale and because it will make bar_update stop printing
702              the (bogus) current bandwidth.  */
703           bp->stalled = true;
704           xzero (*hist);
705           bp->recent_bytes = 0;
706         }
707       return;
708     }
709
710   /* We now have a non-zero amount of to store to the speed ring.  */
711
712   /* If the stall status was acquired, reset it. */
713   if (bp->stalled)
714     {
715       bp->stalled = false;
716       /* "recent_age" includes the entired stalled period, which
717          could be very long.  Don't update the speed ring with that
718          value because the current bandwidth would start too small.
719          Start with an arbitrary (but more reasonable) time value and
720          let it level out.  */
721       recent_age = 1;
722     }
723
724   /* Store "recent" bytes and download time to history ring at the
725      position POS.  */
726
727   /* To correctly maintain the totals, first invalidate existing data
728      (least recent in time) at this position. */
729   hist->total_time  -= hist->times[hist->pos];
730   hist->total_bytes -= hist->bytes[hist->pos];
731
732   /* Now store the new data and update the totals. */
733   hist->times[hist->pos] = recent_age;
734   hist->bytes[hist->pos] = bp->recent_bytes;
735   hist->total_time  += recent_age;
736   hist->total_bytes += bp->recent_bytes;
737
738   /* Start a new "recent" period. */
739   bp->recent_start = dltime;
740   bp->recent_bytes = 0;
741
742   /* Advance the current ring position. */
743   if (++hist->pos == DLSPEED_HISTORY_SIZE)
744     hist->pos = 0;
745
746 #if 0
747   /* Sledgehammer check to verify that the totals are accurate. */
748   {
749     int i;
750     double sumt = 0, sumb = 0;
751     for (i = 0; i < DLSPEED_HISTORY_SIZE; i++)
752       {
753         sumt += hist->times[i];
754         sumb += hist->bytes[i];
755       }
756     assert (sumb == hist->total_bytes);
757     /* We can't use assert(sumt==hist->total_time) because some
758        precision is lost by adding and subtracting floating-point
759        numbers.  But during a download this precision should not be
760        detectable, i.e. no larger than 1ns.  */
761     double diff = sumt - hist->total_time;
762     if (diff < 0) diff = -diff;
763     assert (diff < 1e-9);
764   }
765 #endif
766 }
767
768 #if USE_NLS_PROGRESS_BAR
769 static int
770 count_cols (const char *mbs)
771 {
772   wchar_t wc;
773   int     bytes;
774   int     remaining = strlen(mbs);
775   int     cols = 0;
776   int     wccols;
777
778   while (*mbs != '\0')
779     {
780       bytes = mbtowc (&wc, mbs, remaining);
781       assert (bytes != 0);  /* Only happens when *mbs == '\0' */
782       if (bytes == -1)
783         {
784           /* Invalid sequence. We'll just have to fudge it. */
785           return cols + remaining;
786         }
787       mbs += bytes;
788       remaining -= bytes;
789       wccols = wcwidth(wc);
790       cols += (wccols == -1? 1 : wccols);
791     }
792   return cols;
793 }
794 #else
795 # define count_cols(mbs) ((int)(strlen(mbs)))
796 #endif
797
798 static const char *
799 get_eta (int *bcd)
800 {
801   /* TRANSLATORS: "ETA" is English-centric, but this must
802      be short, ideally 3 chars.  Abbreviate if necessary.  */
803   static const char eta_str[] = N_("  eta %s");
804   static const char *eta_trans;
805   static int bytes_cols_diff;
806   if (eta_trans == NULL)
807     {
808       int nbytes;
809       int ncols;
810
811 #if USE_NLS_PROGRESS_BAR
812       eta_trans = _(eta_str);
813 #else
814       eta_trans = eta_str;
815 #endif
816
817       /* Determine the number of bytes used in the translated string,
818        * versus the number of columns used. This is to figure out how
819        * many spaces to add at the end to pad to the full line width.
820        *
821        * We'll store the difference between the number of bytes and
822        * number of columns, so that removing this from the string length
823        * will reveal the total number of columns in the progress bar. */
824       nbytes = strlen (eta_trans);
825       ncols = count_cols (eta_trans);
826       bytes_cols_diff = nbytes - ncols;
827     }
828
829   if (bcd != NULL)
830     *bcd = bytes_cols_diff;
831
832   return eta_trans;
833 }
834
835 #define APPEND_LITERAL(s) do {                  \
836   memcpy (p, s, sizeof (s) - 1);                \
837   p += sizeof (s) - 1;                          \
838 } while (0)
839
840 /* Use move_to_end (s) to get S to point the end of the string (the
841    terminating \0).  This is faster than s+=strlen(s), but some people
842    are confused when they see strchr (s, '\0') in the code.  */
843 #define move_to_end(s) s = strchr (s, '\0');
844
845 #ifndef MAX
846 # define MAX(a, b) ((a) >= (b) ? (a) : (b))
847 #endif
848
849 static void
850 create_image (struct bar_progress *bp, double dl_total_time, bool done)
851 {
852   char *p = bp->buffer;
853   wgint size = bp->initial_length + bp->count;
854
855   const char *size_grouped = with_thousand_seps (size);
856   int size_grouped_len = count_cols (size_grouped);
857   /* Difference between num cols and num bytes: */
858   int size_grouped_diff = strlen (size_grouped) - size_grouped_len;
859   int size_grouped_pad; /* Used to pad the field width for size_grouped. */
860
861   struct bar_progress_hist *hist = &bp->hist;
862
863   /* The progress bar should look like this:
864      xx% [=======>             ] nn,nnn 12.34KB/s  eta 36m 51s
865
866      Calculate the geometry.  The idea is to assign as much room as
867      possible to the progress bar.  The other idea is to never let
868      things "jitter", i.e. pad elements that vary in size so that
869      their variance does not affect the placement of other elements.
870      It would be especially bad for the progress bar to be resized
871      randomly.
872
873      "xx% " or "100%"  - percentage               - 4 chars
874      "[]"              - progress bar decorations - 2 chars
875      " nnn,nnn,nnn"    - downloaded bytes         - 12 chars or very rarely more
876      " 12.5KB/s"        - download rate           - 9 chars
877      "  eta 36m 51s"   - ETA                      - 14 chars
878
879      "=====>..."       - progress bar             - the rest
880   */
881   int dlbytes_size = 1 + MAX (size_grouped_len, 11);
882   int progress_size = bp->width - (4 + 2 + dlbytes_size + 8 + 14);
883
884   /* The difference between the number of bytes used,
885      and the number of columns used. */
886   int bytes_cols_diff = 0;
887
888   if (progress_size < 5)
889     progress_size = 0;
890
891   /* "xx% " */
892   if (bp->total_length > 0)
893     {
894       int percentage = 100.0 * size / bp->total_length;
895       assert (percentage <= 100);
896
897       if (percentage < 100)
898         sprintf (p, "%2d%% ", percentage);
899       else
900         strcpy (p, "100%");
901       p += 4;
902     }
903   else
904     APPEND_LITERAL ("    ");
905
906   /* The progress bar: "[====>      ]" or "[++==>      ]". */
907   if (progress_size && bp->total_length > 0)
908     {
909       /* Size of the initial portion. */
910       int insz = (double)bp->initial_length / bp->total_length * progress_size;
911
912       /* Size of the downloaded portion. */
913       int dlsz = (double)size / bp->total_length * progress_size;
914
915       char *begin;
916       int i;
917
918       assert (dlsz <= progress_size);
919       assert (insz <= dlsz);
920
921       *p++ = '[';
922       begin = p;
923
924       /* Print the initial portion of the download with '+' chars, the
925          rest with '=' and one '>'.  */
926       for (i = 0; i < insz; i++)
927         *p++ = '+';
928       dlsz -= insz;
929       if (dlsz > 0)
930         {
931           for (i = 0; i < dlsz - 1; i++)
932             *p++ = '=';
933           *p++ = '>';
934         }
935
936       while (p - begin < progress_size)
937         *p++ = ' ';
938       *p++ = ']';
939     }
940   else if (progress_size)
941     {
942       /* If we can't draw a real progress bar, then at least show
943          *something* to the user.  */
944       int ind = bp->tick % (progress_size * 2 - 6);
945       int i, pos;
946
947       /* Make the star move in two directions. */
948       if (ind < progress_size - 2)
949         pos = ind + 1;
950       else
951         pos = progress_size - (ind - progress_size + 5);
952
953       *p++ = '[';
954       for (i = 0; i < progress_size; i++)
955         {
956           if      (i == pos - 1) *p++ = '<';
957           else if (i == pos    ) *p++ = '=';
958           else if (i == pos + 1) *p++ = '>';
959           else
960             *p++ = ' ';
961         }
962       *p++ = ']';
963
964       ++bp->tick;
965     }
966
967   /* " 234,567,890" */
968   sprintf (p, " %s", size_grouped);
969   move_to_end (p);
970   /* Pad with spaces to 11 chars for the size_grouped field;
971    * couldn't use the field width specifier in sprintf, because
972    * it counts in bytes, not characters. */
973   for (size_grouped_pad = 11 - size_grouped_len;
974        size_grouped_pad > 0;
975        --size_grouped_pad)
976     {
977       *p++ = ' ';
978     }
979
980   /* " 12.52Kb/s or 12.52KB/s" */
981   if (hist->total_time > 0 && hist->total_bytes)
982     {
983       static const char *short_units[] = { "B/s", "KB/s", "MB/s", "GB/s" };
984       static const char *short_units_bits[] = { "b/s", "Kb/s", "Mb/s", "Gb/s" };
985       int units = 0;
986       /* Calculate the download speed using the history ring and
987          recent data that hasn't made it to the ring yet.  */
988       wgint dlquant = hist->total_bytes + bp->recent_bytes;
989       double dltime = hist->total_time + (dl_total_time - bp->recent_start);
990       double dlspeed = calc_rate (dlquant, dltime, &units);
991       sprintf (p, " %4.*f%s", dlspeed >= 99.95 ? 0 : dlspeed >= 9.995 ? 1 : 2,
992                dlspeed,  !opt.bits_fmt?short_units[units]:short_units_bits[units]);
993       move_to_end (p);
994     }
995   else
996     APPEND_LITERAL (" --.-K/s");
997
998   if (!done)
999     {
1000       /* "  eta ..m ..s"; wait for three seconds before displaying the ETA.
1001          That's because the ETA value needs a while to become
1002          reliable.  */
1003       if (bp->total_length > 0 && bp->count > 0 && dl_total_time > 3)
1004         {
1005           int eta;
1006
1007           /* Don't change the value of ETA more than approximately once
1008              per second; doing so would cause flashing without providing
1009              any value to the user. */
1010           if (bp->total_length != size
1011               && bp->last_eta_value != 0
1012               && dl_total_time - bp->last_eta_time < ETA_REFRESH_INTERVAL)
1013             eta = bp->last_eta_value;
1014           else
1015             {
1016               /* Calculate ETA using the average download speed to predict
1017                  the future speed.  If you want to use a speed averaged
1018                  over a more recent period, replace dl_total_time with
1019                  hist->total_time and bp->count with hist->total_bytes.
1020                  I found that doing that results in a very jerky and
1021                  ultimately unreliable ETA.  */
1022               wgint bytes_remaining = bp->total_length - size;
1023               double eta_ = dl_total_time * bytes_remaining / bp->count;
1024               if (eta_ >= INT_MAX - 1)
1025                 goto skip_eta;
1026               eta = (int) (eta_ + 0.5);
1027               bp->last_eta_value = eta;
1028               bp->last_eta_time = dl_total_time;
1029             }
1030
1031           sprintf (p, get_eta(&bytes_cols_diff),
1032                    eta_to_human_short (eta, false));
1033           move_to_end (p);
1034         }
1035       else if (bp->total_length > 0)
1036         {
1037         skip_eta:
1038           APPEND_LITERAL ("             ");
1039         }
1040     }
1041   else
1042     {
1043       /* When the download is done, print the elapsed time.  */
1044       int nbytes;
1045       int ncols;
1046
1047       /* Note to translators: this should not take up more room than
1048          available here.  Abbreviate if necessary.  */
1049       strcpy (p, _("   in "));
1050       nbytes = strlen (p);
1051       ncols  = count_cols (p);
1052       bytes_cols_diff = nbytes - ncols;
1053       p += nbytes;
1054       if (dl_total_time >= 10)
1055         strcpy (p, eta_to_human_short ((int) (dl_total_time + 0.5), false));
1056       else
1057         sprintf (p, "%ss", print_decimal (dl_total_time));
1058       move_to_end (p);
1059     }
1060
1061   while (p - bp->buffer - bytes_cols_diff - size_grouped_diff < bp->width)
1062     *p++ = ' ';
1063   *p = '\0';
1064 }
1065
1066 /* Print the contents of the buffer as a one-line ASCII "image" so
1067    that it can be overwritten next time.  */
1068
1069 static void
1070 display_image (char *buf)
1071 {
1072   bool old = log_set_save_context (false);
1073   logputs (LOG_VERBOSE, "\r");
1074   logputs (LOG_VERBOSE, buf);
1075   log_set_save_context (old);
1076 }
1077
1078 static void
1079 bar_set_params (const char *params)
1080 {
1081   char *term = getenv ("TERM");
1082
1083   if (params
1084       && 0 == strcmp (params, "force"))
1085     current_impl_locked = 1;
1086
1087   if ((opt.lfilename
1088 #ifdef HAVE_ISATTY
1089        /* The progress bar doesn't make sense if the output is not a
1090           TTY -- when logging to file, it is better to review the
1091           dots.  */
1092        || !isatty (fileno (stderr))
1093 #endif
1094        /* Normally we don't depend on terminal type because the
1095           progress bar only uses ^M to move the cursor to the
1096           beginning of line, which works even on dumb terminals.  But
1097           Jamie Zawinski reports that ^M and ^H tricks don't work in
1098           Emacs shell buffers, and only make a mess.  */
1099        || (term && 0 == strcmp (term, "emacs"))
1100        )
1101       && !current_impl_locked)
1102     {
1103       /* We're not printing to a TTY, so revert to the fallback
1104          display.  #### We're recursively calling
1105          set_progress_implementation here, which is slightly kludgy.
1106          It would be nicer if we provided that function a return value
1107          indicating a failure of some sort.  */
1108       set_progress_implementation (FALLBACK_PROGRESS_IMPLEMENTATION);
1109       return;
1110     }
1111 }
1112
1113 #ifdef SIGWINCH
1114 void
1115 progress_handle_sigwinch (int sig)
1116 {
1117   received_sigwinch = 1;
1118   signal (SIGWINCH, progress_handle_sigwinch);
1119 }
1120 #endif
1121
1122 /* Provide a short human-readable rendition of the ETA.  This is like
1123    secs_to_human_time in main.c, except the output doesn't include
1124    fractions (which would look silly in by nature imprecise ETA) and
1125    takes less room.  If the time is measured in hours, hours and
1126    minutes (but not seconds) are shown; if measured in days, then days
1127    and hours are shown.  This ensures brevity while still displaying
1128    as much as possible.
1129
1130    If CONDENSED is true, the separator between minutes and seconds
1131    (and hours and minutes, etc.) is not included, shortening the
1132    display by one additional character.  This is used for dot
1133    progress.
1134
1135    The display never occupies more than 7 characters of screen
1136    space.  */
1137
1138 static const char *
1139 eta_to_human_short (int secs, bool condensed)
1140 {
1141   static char buf[10];          /* 8 should be enough, but just in case */
1142   static int last = -1;
1143   const char *space = condensed ? "" : " ";
1144
1145   /* Trivial optimization.  create_image can call us every 200 msecs
1146      (see bar_update) for fast downloads, but ETA will only change
1147      once per 900 msecs.  */
1148   if (secs == last)
1149     return buf;
1150   last = secs;
1151
1152   if (secs < 100)
1153     sprintf (buf, "%ds", secs);
1154   else if (secs < 100 * 60)
1155     sprintf (buf, "%dm%s%ds", secs / 60, space, secs % 60);
1156   else if (secs < 48 * 3600)
1157     sprintf (buf, "%dh%s%dm", secs / 3600, space, (secs / 60) % 60);
1158   else if (secs < 100 * 86400)
1159     sprintf (buf, "%dd%s%dh", secs / 86400, space, (secs / 3600) % 24);
1160   else
1161     /* even (2^31-1)/86400 doesn't overflow BUF. */
1162     sprintf (buf, "%dd", secs / 86400);
1163
1164   return buf;
1165 }