]> sjero.net Git - wget/blob - src/progress.c
Updated licensing exception for OpenSSL from the SFLC.
[wget] / src / progress.c
1 /* Download progress.
2    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software
3    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 <config.h>
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <assert.h>
37 #ifdef HAVE_UNISTD_H
38 # include <unistd.h>
39 #endif
40 #include <signal.h>
41
42 #include "wget.h"
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   int i;
95   struct progress_implementation *pi = implementations;
96   char *colon = strchr (name, ':');
97   int namelen = colon ? 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   int 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 ? 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              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   /* + 1 for the terminating zero. */
581   bp->buffer = xmalloc (bp->width + 1);
582
583   logputs (LOG_VERBOSE, "\n");
584
585   create_image (bp, 0, false);
586   display_image (bp->buffer);
587
588   return bp;
589 }
590
591 static void update_speed_ring (struct bar_progress *, wgint, double);
592
593 static void
594 bar_update (void *progress, wgint howmuch, double dltime)
595 {
596   struct bar_progress *bp = progress;
597   bool force_screen_update = false;
598
599   bp->count += howmuch;
600   if (bp->total_length > 0
601       && bp->count + bp->initial_length > bp->total_length)
602     /* We could be downloading more than total_length, e.g. when the
603        server sends an incorrect Content-Length header.  In that case,
604        adjust bp->total_length to the new reality, so that the code in
605        create_image() that depends on total size being smaller or
606        equal to the expected size doesn't abort.  */
607     bp->total_length = bp->initial_length + bp->count;
608
609   update_speed_ring (bp, howmuch, dltime);
610
611   /* If SIGWINCH (the window size change signal) been received,
612      determine the new screen size and update the screen.  */
613   if (received_sigwinch)
614     {
615       int old_width = screen_width;
616       screen_width = determine_screen_width ();
617       if (!screen_width)
618         screen_width = DEFAULT_SCREEN_WIDTH;
619       else if (screen_width < MINIMUM_SCREEN_WIDTH)
620         screen_width = MINIMUM_SCREEN_WIDTH;
621       if (screen_width != old_width)
622         {
623           bp->width = screen_width - 1;
624           bp->buffer = xrealloc (bp->buffer, bp->width + 1);
625           force_screen_update = true;
626         }
627       received_sigwinch = 0;
628     }
629
630   if (dltime - bp->last_screen_update < REFRESH_INTERVAL && !force_screen_update)
631     /* Don't update more often than five times per second. */
632     return;
633
634   create_image (bp, dltime, false);
635   display_image (bp->buffer);
636   bp->last_screen_update = dltime;
637 }
638
639 static void
640 bar_finish (void *progress, double dltime)
641 {
642   struct bar_progress *bp = progress;
643
644   if (bp->total_length > 0
645       && bp->count + bp->initial_length > bp->total_length)
646     /* See bar_update() for explanation. */
647     bp->total_length = bp->initial_length + bp->count;
648
649   create_image (bp, dltime, true);
650   display_image (bp->buffer);
651
652   logputs (LOG_VERBOSE, "\n\n");
653
654   xfree (bp->buffer);
655   xfree (bp);
656 }
657
658 /* This code attempts to maintain the notion of a "current" download
659    speed, over the course of no less than 3s.  (Shorter intervals
660    produce very erratic results.)
661
662    To do so, it samples the speed in 150ms intervals and stores the
663    recorded samples in a FIFO history ring.  The ring stores no more
664    than 20 intervals, hence the history covers the period of at least
665    three seconds and at most 20 reads into the past.  This method
666    should produce reasonable results for downloads ranging from very
667    slow to very fast.
668
669    The idea is that for fast downloads, we get the speed over exactly
670    the last three seconds.  For slow downloads (where a network read
671    takes more than 150ms to complete), we get the speed over a larger
672    time period, as large as it takes to complete thirty reads.  This
673    is good because slow downloads tend to fluctuate more and a
674    3-second average would be too erratic.  */
675
676 static void
677 update_speed_ring (struct bar_progress *bp, wgint howmuch, double dltime)
678 {
679   struct bar_progress_hist *hist = &bp->hist;
680   double recent_age = dltime - bp->recent_start;
681
682   /* Update the download count. */
683   bp->recent_bytes += howmuch;
684
685   /* For very small time intervals, we return after having updated the
686      "recent" download count.  When its age reaches or exceeds minimum
687      sample time, it will be recorded in the history ring.  */
688   if (recent_age < DLSPEED_SAMPLE_MIN)
689     return;
690
691   if (howmuch == 0)
692     {
693       /* If we're not downloading anything, we might be stalling,
694          i.e. not downloading anything for an extended period of time.
695          Since 0-reads do not enter the history ring, recent_age
696          effectively measures the time since last read.  */
697       if (recent_age >= STALL_START_TIME)
698         {
699           /* If we're stalling, reset the ring contents because it's
700              stale and because it will make bar_update stop printing
701              the (bogus) current bandwidth.  */
702           bp->stalled = true;
703           xzero (*hist);
704           bp->recent_bytes = 0;
705         }
706       return;
707     }
708
709   /* We now have a non-zero amount of to store to the speed ring.  */
710
711   /* If the stall status was acquired, reset it. */
712   if (bp->stalled)
713     {
714       bp->stalled = false;
715       /* "recent_age" includes the the entired stalled period, which
716          could be very long.  Don't update the speed ring with that
717          value because the current bandwidth would start too small.
718          Start with an arbitrary (but more reasonable) time value and
719          let it level out.  */
720       recent_age = 1;
721     }
722
723   /* Store "recent" bytes and download time to history ring at the
724      position POS.  */
725
726   /* To correctly maintain the totals, first invalidate existing data
727      (least recent in time) at this position. */
728   hist->total_time  -= hist->times[hist->pos];
729   hist->total_bytes -= hist->bytes[hist->pos];
730
731   /* Now store the new data and update the totals. */
732   hist->times[hist->pos] = recent_age;
733   hist->bytes[hist->pos] = bp->recent_bytes;
734   hist->total_time  += recent_age;
735   hist->total_bytes += bp->recent_bytes;
736
737   /* Start a new "recent" period. */
738   bp->recent_start = dltime;
739   bp->recent_bytes = 0;
740
741   /* Advance the current ring position. */
742   if (++hist->pos == DLSPEED_HISTORY_SIZE)
743     hist->pos = 0;
744
745 #if 0
746   /* Sledgehammer check to verify that the totals are accurate. */
747   {
748     int i;
749     double sumt = 0, sumb = 0;
750     for (i = 0; i < DLSPEED_HISTORY_SIZE; i++)
751       {
752         sumt += hist->times[i];
753         sumb += hist->bytes[i];
754       }
755     assert (sumb == hist->total_bytes);
756     /* We can't use assert(sumt==hist->total_time) because some
757        precision is lost by adding and subtracting floating-point
758        numbers.  But during a download this precision should not be
759        detectable, i.e. no larger than 1ns.  */
760     double diff = sumt - hist->total_time;
761     if (diff < 0) diff = -diff;
762     assert (diff < 1e-9);
763   }
764 #endif
765 }
766
767 #define APPEND_LITERAL(s) do {                  \
768   memcpy (p, s, sizeof (s) - 1);                \
769   p += sizeof (s) - 1;                          \
770 } while (0)
771
772 /* Use move_to_end (s) to get S to point the end of the string (the
773    terminating \0).  This is faster than s+=strlen(s), but some people
774    are confused when they see strchr (s, '\0') in the code.  */
775 #define move_to_end(s) s = strchr (s, '\0');
776
777 #ifndef MAX
778 # define MAX(a, b) ((a) >= (b) ? (a) : (b))
779 #endif
780
781 static void
782 create_image (struct bar_progress *bp, double dl_total_time, bool done)
783 {
784   char *p = bp->buffer;
785   wgint size = bp->initial_length + bp->count;
786
787   const char *size_grouped = with_thousand_seps (size);
788   int size_grouped_len = strlen (size_grouped);
789
790   struct bar_progress_hist *hist = &bp->hist;
791
792   /* The progress bar should look like this:
793      xx% [=======>             ] nn,nnn 12.34K/s  eta 36m 51s
794
795      Calculate the geometry.  The idea is to assign as much room as
796      possible to the progress bar.  The other idea is to never let
797      things "jitter", i.e. pad elements that vary in size so that
798      their variance does not affect the placement of other elements.
799      It would be especially bad for the progress bar to be resized
800      randomly.
801
802      "xx% " or "100%"  - percentage               - 4 chars
803      "[]"              - progress bar decorations - 2 chars
804      " nnn,nnn,nnn"    - downloaded bytes         - 12 chars or very rarely more
805      " 12.5K/s"        - download rate             - 8 chars
806      "  eta 36m 51s"   - ETA                      - 13 chars
807
808      "=====>..."       - progress bar             - the rest
809   */
810   int dlbytes_size = 1 + MAX (size_grouped_len, 11);
811   int progress_size = bp->width - (4 + 2 + dlbytes_size + 8 + 13);
812
813   if (progress_size < 5)
814     progress_size = 0;
815
816   /* "xx% " */
817   if (bp->total_length > 0)
818     {
819       int percentage = 100.0 * size / bp->total_length;
820       assert (percentage <= 100);
821
822       if (percentage < 100)
823         sprintf (p, "%2d%% ", percentage);
824       else
825         strcpy (p, "100%");
826       p += 4;
827     }
828   else
829     APPEND_LITERAL ("    ");
830
831   /* The progress bar: "[====>      ]" or "[++==>      ]". */
832   if (progress_size && bp->total_length > 0)
833     {
834       /* Size of the initial portion. */
835       int insz = (double)bp->initial_length / bp->total_length * progress_size;
836
837       /* Size of the downloaded portion. */
838       int dlsz = (double)size / bp->total_length * progress_size;
839
840       char *begin;
841       int i;
842
843       assert (dlsz <= progress_size);
844       assert (insz <= dlsz);
845
846       *p++ = '[';
847       begin = p;
848
849       /* Print the initial portion of the download with '+' chars, the
850          rest with '=' and one '>'.  */
851       for (i = 0; i < insz; i++)
852         *p++ = '+';
853       dlsz -= insz;
854       if (dlsz > 0)
855         {
856           for (i = 0; i < dlsz - 1; i++)
857             *p++ = '=';
858           *p++ = '>';
859         }
860
861       while (p - begin < progress_size)
862         *p++ = ' ';
863       *p++ = ']';
864     }
865   else if (progress_size)
866     {
867       /* If we can't draw a real progress bar, then at least show
868          *something* to the user.  */
869       int ind = bp->tick % (progress_size * 2 - 6);
870       int i, pos;
871
872       /* Make the star move in two directions. */
873       if (ind < progress_size - 2)
874         pos = ind + 1;
875       else
876         pos = progress_size - (ind - progress_size + 5);
877
878       *p++ = '[';
879       for (i = 0; i < progress_size; i++)
880         {
881           if      (i == pos - 1) *p++ = '<';
882           else if (i == pos    ) *p++ = '=';
883           else if (i == pos + 1) *p++ = '>';
884           else
885             *p++ = ' ';
886         }
887       *p++ = ']';
888
889       ++bp->tick;
890     }
891
892   /* " 234,567,890" */
893   sprintf (p, " %-11s", size_grouped);
894   move_to_end (p);
895
896   /* " 12.52K/s" */
897   if (hist->total_time > 0 && hist->total_bytes)
898     {
899       static const char *short_units[] = { "B/s", "K/s", "M/s", "G/s" };
900       int units = 0;
901       /* Calculate the download speed using the history ring and
902          recent data that hasn't made it to the ring yet.  */
903       wgint dlquant = hist->total_bytes + bp->recent_bytes;
904       double dltime = hist->total_time + (dl_total_time - bp->recent_start);
905       double dlspeed = calc_rate (dlquant, dltime, &units);
906       sprintf (p, " %4.*f%s", dlspeed >= 99.95 ? 0 : dlspeed >= 9.995 ? 1 : 2,
907                dlspeed, short_units[units]);
908       move_to_end (p);
909     }
910   else
911     APPEND_LITERAL (" --.-K/s");
912
913   if (!done)
914     {
915       /* "  eta ..m ..s"; wait for three seconds before displaying the ETA.
916          That's because the ETA value needs a while to become
917          reliable.  */
918       if (bp->total_length > 0 && bp->count > 0 && dl_total_time > 3)
919         {
920           int eta;
921
922           /* Don't change the value of ETA more than approximately once
923              per second; doing so would cause flashing without providing
924              any value to the user. */
925           if (bp->total_length != size
926               && bp->last_eta_value != 0
927               && dl_total_time - bp->last_eta_time < ETA_REFRESH_INTERVAL)
928             eta = bp->last_eta_value;
929           else
930             {
931               /* Calculate ETA using the average download speed to predict
932                  the future speed.  If you want to use a speed averaged
933                  over a more recent period, replace dl_total_time with
934                  hist->total_time and bp->count with hist->total_bytes.
935                  I found that doing that results in a very jerky and
936                  ultimately unreliable ETA.  */
937               wgint bytes_remaining = bp->total_length - size;
938               double eta_ = dl_total_time * bytes_remaining / bp->count;
939               if (eta_ >= INT_MAX - 1)
940                 goto skip_eta;
941               eta = (int) (eta_ + 0.5);
942               bp->last_eta_value = eta;
943               bp->last_eta_time = dl_total_time;
944             }
945
946           /* Translation note: "ETA" is English-centric, but this must
947              be short, ideally 3 chars.  Abbreviate if necessary.  */
948           sprintf (p, _("  eta %s"), eta_to_human_short (eta, false));
949           move_to_end (p);
950         }
951       else if (bp->total_length > 0)
952         {
953         skip_eta:
954           APPEND_LITERAL ("             ");
955         }
956     }
957   else
958     {
959       /* When the download is done, print the elapsed time.  */
960
961       /* Note to translators: this should not take up more room than
962          available here.  Abbreviate if necessary.  */
963       strcpy (p, _("   in "));
964       move_to_end (p);          /* not p+=6, think translations! */
965       if (dl_total_time >= 10)
966         strcpy (p, eta_to_human_short ((int) (dl_total_time + 0.5), false));
967       else
968         sprintf (p, "%ss", print_decimal (dl_total_time));
969       move_to_end (p);
970     }
971
972   assert (p - bp->buffer <= bp->width);
973
974   while (p < bp->buffer + bp->width)
975     *p++ = ' ';
976   *p = '\0';
977 }
978
979 /* Print the contents of the buffer as a one-line ASCII "image" so
980    that it can be overwritten next time.  */
981
982 static void
983 display_image (char *buf)
984 {
985   bool old = log_set_save_context (false);
986   logputs (LOG_VERBOSE, "\r");
987   logputs (LOG_VERBOSE, buf);
988   log_set_save_context (old);
989 }
990
991 static void
992 bar_set_params (const char *params)
993 {
994   char *term = getenv ("TERM");
995
996   if (params
997       && 0 == strcmp (params, "force"))
998     current_impl_locked = 1;
999
1000   if ((opt.lfilename
1001 #ifdef HAVE_ISATTY
1002        /* The progress bar doesn't make sense if the output is not a
1003           TTY -- when logging to file, it is better to review the
1004           dots.  */
1005        || !isatty (fileno (stderr))
1006 #endif
1007        /* Normally we don't depend on terminal type because the
1008           progress bar only uses ^M to move the cursor to the
1009           beginning of line, which works even on dumb terminals.  But
1010           Jamie Zawinski reports that ^M and ^H tricks don't work in
1011           Emacs shell buffers, and only make a mess.  */
1012        || (term && 0 == strcmp (term, "emacs"))
1013        )
1014       && !current_impl_locked)
1015     {
1016       /* We're not printing to a TTY, so revert to the fallback
1017          display.  #### We're recursively calling
1018          set_progress_implementation here, which is slightly kludgy.
1019          It would be nicer if we provided that function a return value
1020          indicating a failure of some sort.  */
1021       set_progress_implementation (FALLBACK_PROGRESS_IMPLEMENTATION);
1022       return;
1023     }
1024 }
1025
1026 #ifdef SIGWINCH
1027 void
1028 progress_handle_sigwinch (int sig)
1029 {
1030   received_sigwinch = 1;
1031   signal (SIGWINCH, progress_handle_sigwinch);
1032 }
1033 #endif
1034
1035 /* Provide a short human-readable rendition of the ETA.  This is like
1036    secs_to_human_time in main.c, except the output doesn't include
1037    fractions (which would look silly in by nature imprecise ETA) and
1038    takes less room.  If the time is measured in hours, hours and
1039    minutes (but not seconds) are shown; if measured in days, then days
1040    and hours are shown.  This ensures brevity while still displaying
1041    as much as possible.
1042
1043    If CONDENSED is true, the separator between minutes and seconds
1044    (and hours and minutes, etc.) is not included, shortening the
1045    display by one additional character.  This is used for dot
1046    progress.
1047
1048    The display never occupies more than 7 characters of screen
1049    space.  */
1050
1051 static const char *
1052 eta_to_human_short (int secs, bool condensed)
1053 {
1054   static char buf[10];          /* 8 should be enough, but just in case */
1055   static int last = -1;
1056   const char *space = condensed ? "" : " ";
1057
1058   /* Trivial optimization.  create_image can call us every 200 msecs
1059      (see bar_update) for fast downloads, but ETA will only change
1060      once per 900 msecs.  */
1061   if (secs == last)
1062     return buf;
1063   last = secs;
1064
1065   if (secs < 100)
1066     sprintf (buf, "%ds", secs);
1067   else if (secs < 100 * 60)
1068     sprintf (buf, "%dm%s%ds", secs / 60, space, secs % 60);
1069   else if (secs < 48 * 3600)
1070     sprintf (buf, "%dh%s%dm", secs / 3600, space, (secs / 60) % 60);
1071   else if (secs < 100 * 86400)
1072     sprintf (buf, "%dd%s%dh", secs / 86400, space, (secs / 3600) % 60);
1073   else
1074     /* even (2^31-1)/86400 doesn't overflow BUF. */
1075     sprintf (buf, "%dd", secs / 86400);
1076
1077   return buf;
1078 }