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