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