1 /*
2  * Display functions.
3  */
4 
5 #include "pv-internal.h"
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <string.h>
11 #include <ctype.h>
12 #include <errno.h>
13 #include <time.h>
14 #include <unistd.h>
15 #include <termios.h>
16 #include <sys/ioctl.h>
17 
18 
19 /*
20  * Output an error message.  If we've displayed anything to the terminal
21  * already, then put a newline before our error so we don't write over what
22  * we've written.
23  */
pv_error(pvstate_t state,char * format,...)24 void pv_error(pvstate_t state, char *format, ...)
25 {
26 	va_list ap;
27 	if (state->display_visible)
28 		fprintf(stderr, "\n");
29 	fprintf(stderr, "%s: ", state->program_name);
30 	va_start(ap, format);
31 	(void) vfprintf(stderr, format, ap);
32 	va_end(ap);
33 	fprintf(stderr, "\n");
34 }
35 
36 
37 /*
38  * Return true if we are the foreground process on the terminal, or if we
39  * aren't outputting to a terminal; false otherwise.
40  */
pv_in_foreground(void)41 bool pv_in_foreground(void)
42 {
43 	pid_t our_process_group;
44 	pid_t tty_process_group;
45 
46 	if (0 == isatty(STDERR_FILENO))
47 		return true;
48 
49 	our_process_group = getpgrp();
50 	tty_process_group = tcgetpgrp(STDERR_FILENO);
51 	if (our_process_group == tty_process_group)
52 		return true;
53 
54 	return false;
55 }
56 
57 
58 /*
59  * Fill in *width and *height with the current terminal size,
60  * if possible.
61  */
pv_screensize(unsigned int * width,unsigned int * height)62 void pv_screensize(unsigned int *width, unsigned int *height)
63 {
64 #ifdef TIOCGWINSZ
65 	struct winsize wsz;
66 
67 	if (0 != isatty(STDERR_FILENO)) {
68 		if (0 == ioctl(STDERR_FILENO, TIOCGWINSZ, &wsz)) {
69 			*width = wsz.ws_col;
70 			*height = wsz.ws_row;
71 		}
72 	}
73 #endif
74 }
75 
76 
77 /*
78  * Calculate the percentage transferred so far and return it.
79  */
pv__calc_percentage(long long so_far,const long long total)80 static long pv__calc_percentage(long long so_far, const long long total)
81 {
82 	if (total < 1)
83 		return 0;
84 
85 	so_far *= 100;
86 	so_far /= total;
87 
88 	return (long) so_far;
89 }
90 
91 
92 /*
93  * Given how many bytes have been transferred, the total byte count to
94  * transfer, and how long it's taken so far in seconds, return the estimated
95  * number of seconds until completion.
96  */
pv__calc_eta(const long long so_far,const long long total,const long elapsed)97 static long pv__calc_eta(const long long so_far, const long long total,
98 			 const long elapsed)
99 {
100 	long long amount_left;
101 
102 	if (so_far < 1)
103 		return 0;
104 
105 	amount_left = total - so_far;
106 	amount_left *= (long long) elapsed;
107 	amount_left /= so_far;
108 
109 	return (long) amount_left;
110 }
111 
112 /*
113  * Given a long double value, it is divided or multiplied by the ratio until
114  * a value in the range 1.0 to 999.999... is found.  The string "prefix" to
115  * is updated to the corresponding SI prefix.
116  *
117  * If "is_bytes" is 1, then the second byte of "prefix" is set to "i" to
118  * denote MiB etc (IEEE1541).  Thus "prefix" should be at least 3 bytes long
119  * (to include the terminating null).
120  *
121  * Submitted by Henry Gebhardt <hsggebhardt@googlemail.com> and then
122  * modified.  Further changed after input from Thomas Rachel; changed still
123  * further after Debian bug #706175.
124  */
pv__si_prefix(long double * value,char * prefix,const long double ratio,int is_bytes)125 static void pv__si_prefix(long double *value, char *prefix,
126 			  const long double ratio, int is_bytes)
127 {
128 	static char *pfx_000 = NULL;	 /* kilo, mega, etc */
129 	static char *pfx_024 = NULL;	 /* kibi, mibi, etc */
130 	static char const *pfx_middle_000 = NULL;
131 	static char const *pfx_middle_024 = NULL;
132 	char *pfx;
133 	char const *pfx_middle;
134 	char const *i;
135 	long double cutoff;
136 
137 	if (NULL == pfx_000) {
138 		pfx_000 = _("yzafpnum kMGTPEZY");
139 		pfx_middle_000 = strchr(pfx_000, ' ');
140 	}
141 
142 	if (NULL == pfx_024) {
143 		pfx_024 = _("yzafpnum KMGTPEZY");
144 		pfx_middle_024 = strchr(pfx_024, ' ');
145 	}
146 
147 	pfx = pfx_000;
148 	pfx_middle = pfx_middle_000;
149 	if (is_bytes) {
150 		pfx = pfx_024;
151 		pfx_middle = pfx_middle_024;
152 	}
153 
154 	i = pfx_middle;
155 
156 	prefix[0] = ' ';		    /* Make the prefix start blank. */
157 	prefix[1] = 0;
158 
159 	/*
160 	 * Force an empty prefix if the value is zero to avoid "0yB".
161 	 */
162 	if (0.0 == *value)
163 		return;
164 
165 	cutoff = ratio * 0.97;
166 
167 	while ((*value > cutoff) && (*(i += 1) != '\0')) {
168 		*value /= ratio;
169 		prefix[0] = *i;
170 	}
171 
172 	while ((*value < 1.0) && ((i -= 1) != (pfx - 1))) {
173 		*value *= ratio;
174 		prefix[0] = *i;
175 	}
176 
177 	if (is_bytes && prefix[0] != ' ') {
178 		prefix[1] = 'i';
179 		prefix[2] = 0;
180 	}
181 }
182 
183 
184 /*
185  * Put a string in "buffer" (max length "bufsize") containing "amount"
186  * formatted such that it's 3 or 4 digits followed by an SI suffix and then
187  * whichever of "suffix_basic" or "suffix_bytes" is appropriate (whether
188  * "is_bytes" is 0 for non-byte amounts or 1 for byte amounts). If
189  * "is_bytes" is 1 then the SI units are KiB, MiB etc and the divisor is
190  * 1024 instead of 1000.
191  *
192  * The "format" string is in sprintf format and must contain exactly one %
193  * parameter (a %s) which will expand to the string described above.
194  */
pv__sizestr(char * buffer,int bufsize,char * format,long double amount,char * suffix_basic,char * suffix_bytes,int is_bytes)195 static void pv__sizestr(char *buffer, int bufsize, char *format,
196 			long double amount, char *suffix_basic,
197 			char *suffix_bytes, int is_bytes)
198 {
199 	char sizestr_buffer[256];
200 	char si_prefix[8] = " ";
201 	long double divider;
202 	long double display_amount;
203 	char *suffix;
204 
205 	if (is_bytes) {
206 		suffix = suffix_bytes;
207 		divider = 1024.0;
208 	} else {
209 		suffix = suffix_basic;
210 		divider = 1000.0;
211 	}
212 
213 	display_amount = amount;
214 
215 	pv__si_prefix(&display_amount, si_prefix, divider, is_bytes);
216 
217 	/* Make sure we don't overrun our buffer. */
218 	if (display_amount > 100000)
219 		display_amount = 100000;
220 
221 	/* Fix for display of "1.01e+03" instead of "1010" */
222 	if (display_amount > 99.9) {
223 		sprintf(sizestr_buffer, "%4ld%.2s%.16s",
224 			(long) display_amount, si_prefix, suffix);
225 	} else {
226 		/*
227 		 * AIX blows up with %4.3Lg%.2s%.16s for some reason, so we
228 		 * write display_amount separately first.
229 		 */
230 		char str_disp[64];
231 		/* # to get 13.0GB instead of 13GB (#1477) */
232 		sprintf(str_disp, "%#4.3Lg", display_amount);
233 		sprintf(sizestr_buffer, "%s%.2s%.16s",
234 			str_disp, si_prefix, suffix);
235 	}
236 
237 #ifdef HAVE_SNPRINTF
238 	snprintf(buffer, bufsize, format, sizestr_buffer);
239 #else
240 	sprintf(buffer, format, sizestr_buffer);
241 #endif
242 }
243 
244 
245 /*
246  * Initialise the output format structure, based on the current options.
247  */
pv__format_init(pvstate_t state)248 static void pv__format_init(pvstate_t state)
249 {
250 	const char *formatstr;
251 	const char *searchptr;
252 	int strpos;
253 	int segment;
254 
255 	if (NULL == state)
256 		return;
257 
258 	state->str_name[0] = 0;
259 	state->str_transferred[0] = 0;
260 	state->str_timer[0] = 0;
261 	state->str_rate[0] = 0;
262 	state->str_average_rate[0] = 0;
263 	state->str_progress[0] = 0;
264 	state->str_eta[0] = 0;
265 	memset(state->format, 0, sizeof(state->format));
266 
267 	if (state->name) {
268 		sprintf(state->str_name, "%9.500s:", state->name);
269 	}
270 
271 	formatstr =
272 	    state->format_string ? state->
273 	    format_string : state->default_format;
274 
275 	state->components_used = 0;
276 
277 	/*
278 	 * Split the format string into segments.  Each segment consists
279 	 * of a string pointer and a length.
280 	 *
281 	 * A length of zero indicates that the segment is a fixed-size
282 	 * component updated by pv__format(), so it is a pointer to one
283 	 * of the state->str_* buffers that pv__format() updates.
284 	 *
285 	 * A length below zero indicates that the segment is a variable
286 	 * sized component which will be recalculated by pv__format()
287 	 * after the length of all fixed-size segments is known, and so
288 	 * the string is a pointer to another state->str_* buffer
289 	 * (currently it will only ever be state->str_progress).
290 	 *
291 	 * A length above zero indicates that the segment is a constant
292 	 * string of the given length (not necessarily null terminated).
293 	 *
294 	 * In pv__format(), after the state->str_* buffers have all been
295 	 * filled in, the output string is generated by sticking all of
296 	 * these segments together.
297 	 */
298 	segment = 0;
299 	for (strpos = 0; formatstr[strpos] != 0 && segment < 99;
300 	     strpos++, segment++) {
301 		if ('%' == formatstr[strpos]) {
302 			unsigned int num;
303 			strpos++;
304 			num = 0;
305 			while (isdigit(formatstr[strpos])) {
306 				num = num * 10;
307 				num += formatstr[strpos] - '0';
308 				strpos++;
309 			}
310 			switch (formatstr[strpos]) {
311 			case 'p':
312 				state->format[segment].string =
313 				    state->str_progress;
314 				state->format[segment].length = -1;
315 				state->components_used |=
316 				    PV_DISPLAY_PROGRESS;
317 				break;
318 			case 't':
319 				state->format[segment].string =
320 				    state->str_timer;
321 				state->format[segment].length = 0;
322 				state->components_used |= PV_DISPLAY_TIMER;
323 				break;
324 			case 'e':
325 				state->format[segment].string =
326 				    state->str_eta;
327 				state->format[segment].length = 0;
328 				state->components_used |= PV_DISPLAY_ETA;
329 				break;
330 			case 'I':
331 				state->format[segment].string =
332 				    state->str_fineta;
333 				state->format[segment].length = 0;
334 				state->components_used |=
335 				    PV_DISPLAY_FINETA;
336 				break;
337 			case 'A':
338 				state->format[segment].string =
339 				    state->str_lastoutput;
340 				state->format[segment].length = 0;
341 				if (num > sizeof(state->lastoutput_buffer))
342 					num =
343 					    sizeof
344 					    (state->lastoutput_buffer);
345 				if (num < 1)
346 					num = 1;
347 				state->lastoutput_length = num;
348 				state->components_used |=
349 				    PV_DISPLAY_OUTPUTBUF;
350 				break;
351 			case 'r':
352 				state->format[segment].string =
353 				    state->str_rate;
354 				state->format[segment].length = 0;
355 				state->components_used |= PV_DISPLAY_RATE;
356 				break;
357 			case 'a':
358 				state->format[segment].string =
359 				    state->str_average_rate;
360 				state->format[segment].length = 0;
361 				state->components_used |=
362 				    PV_DISPLAY_AVERAGERATE;
363 				break;
364 			case 'b':
365 				state->format[segment].string =
366 				    state->str_transferred;
367 				state->format[segment].length = 0;
368 				state->components_used |= PV_DISPLAY_BYTES;
369 				break;
370 			case 'T':
371 				state->format[segment].string =
372 				    state->str_bufpercent;
373 				state->format[segment].length = 0;
374 				state->components_used |=
375 				    PV_DISPLAY_BUFPERCENT;
376 				break;
377 			case 'N':
378 				state->format[segment].string =
379 				    state->str_name;
380 				state->format[segment].length =
381 				    strlen(state->str_name);
382 				state->components_used |= PV_DISPLAY_NAME;
383 				break;
384 			case '%':
385 				/* %% => % */
386 				state->format[segment].string =
387 				    &(formatstr[strpos]);
388 				state->format[segment].length = 1;
389 				break;
390 			case 0:
391 				/* % at end => just % */
392 				state->format[segment].string =
393 				    &(formatstr[--strpos]);
394 				state->format[segment].length = 1;
395 				break;
396 			default:
397 				/* %z (unknown) => %z */
398 				state->format[segment].string =
399 				    &(formatstr[--strpos]);
400 				state->format[segment].length = 2;
401 				strpos++;
402 				break;
403 			}
404 		} else {
405 			int foundlength;
406 			searchptr = strchr(&(formatstr[strpos]), '%');
407 			if (NULL == searchptr) {
408 				foundlength = strlen(&(formatstr[strpos]));
409 			} else {
410 				foundlength =
411 				    searchptr - &(formatstr[strpos]);
412 			}
413 			state->format[segment].string =
414 			    &(formatstr[strpos]);
415 			state->format[segment].length = foundlength;
416 			strpos += foundlength - 1;
417 		}
418 	}
419 
420 	state->format[segment].string = 0;
421 	state->format[segment].length = 0;
422 }
423 
424 /*
425  * Return the original value x so that it has been clamped between
426  * [min..max]
427  */
bound_long(long x,long min,long max)428 static long bound_long(long x, long min, long max)
429 {
430 	return x < min ? min : x > max ? max : x;
431 }
432 
433 
434 /*
435  * Return a pointer to a string (which must not be freed), containing status
436  * information formatted according to the state held within the given
437  * structure, where "elapsed_sec" is the seconds elapsed since the transfer
438  * started, "bytes_since_last" is the number of bytes transferred since the
439  * last update, and "total_bytes" is the total number of bytes transferred
440  * so far.
441  *
442  * If "bytes_since_last" is negative, this is the final update so the rate
443  * is given as an an average over the whole transfer; otherwise the current
444  * rate is shown.
445  *
446  * In line mode, "bytes_since_last" and "total_bytes" are in lines, not bytes.
447  *
448  * If "total_bytes" is negative, then free all allocated memory and return
449  * NULL.
450  */
pv__format(pvstate_t state,long double elapsed_sec,long long bytes_since_last,long long total_bytes)451 static char *pv__format(pvstate_t state,
452 			long double elapsed_sec,
453 			long long bytes_since_last, long long total_bytes)
454 {
455 	long double time_since_last, rate, average_rate;
456 	long eta;
457 	int static_portion_size;
458 	int segment;
459 	int output_length;
460 	int display_string_length;
461 
462 	/* Quick sanity check - state must exist */
463 	if (NULL == state)
464 		return NULL;
465 
466 	/* Negative total transfer - free memory and exit */
467 	if (total_bytes < 0) {
468 		if (state->display_buffer)
469 			free(state->display_buffer);
470 		state->display_buffer = NULL;
471 		return NULL;
472 	}
473 
474 	/*
475 	 * In case the time since the last update is very small, we keep
476 	 * track of amount transferred since the last update, and just keep
477 	 * adding to that until a reasonable amount of time has passed to
478 	 * avoid rate spikes or division by zero.
479 	 */
480 	time_since_last = elapsed_sec - state->prev_elapsed_sec;
481 	if (time_since_last <= 0.01) {
482 		rate = state->prev_rate;
483 		state->prev_trans += bytes_since_last;
484 	} else {
485 		rate =
486 		    ((long double) bytes_since_last +
487 		     state->prev_trans) / time_since_last;
488 		state->prev_elapsed_sec = elapsed_sec;
489 		state->prev_trans = 0;
490 	}
491 	state->prev_rate = rate;
492 
493 	/*
494 	 * We only calculate the overall average rate if this is the last
495 	 * update or if the average rate display is enabled. Otherwise it's
496 	 * not worth the extra CPU cycles.
497 	 */
498 	average_rate = 0;
499 	if ((bytes_since_last < 0)
500 	    || ((state->components_used & PV_DISPLAY_AVERAGERATE) != 0)) {
501 		/* Sanity check to avoid division by zero */
502 		if (elapsed_sec < 0.000001)
503 			elapsed_sec = 0.000001;
504 		average_rate =
505 		    (((long double) total_bytes) -
506 		     ((long double) state->initial_offset)) /
507 		    (long double) elapsed_sec;
508 		if (bytes_since_last < 0)
509 			rate = average_rate;
510 	}
511 
512 	if (state->size <= 0) {
513 		/*
514 		 * If we don't know the total size of the incoming data,
515 		 * then for a percentage, we gradually increase the
516 		 * percentage completion as data arrives, to a maximum of
517 		 * 200, then reset it - we use this if we can't calculate
518 		 * it, so that the numeric percentage output will go
519 		 * 0%-100%, 100%-0%, 0%-100%, and so on.
520 		 */
521 		if (rate > 0)
522 			state->percentage += 2;
523 		if (state->percentage > 199)
524 			state->percentage = 0;
525 	} else if (state->numeric
526 		   || ((state->components_used & PV_DISPLAY_PROGRESS) !=
527 		       0)) {
528 		/*
529 		 * If we do know the total size, and we're going to show
530 		 * the percentage (numeric mode or a progress bar),
531 		 * calculate the percentage completion.
532 		 */
533 		state->percentage =
534 		    pv__calc_percentage(total_bytes, state->size);
535 	}
536 
537 	/*
538 	 * Reallocate output buffer if width changes.
539 	 */
540 	if (state->display_buffer != NULL
541 	    && state->display_buffer_size < (state->width * 2)) {
542 		free(state->display_buffer);
543 		state->display_buffer = NULL;
544 		state->display_buffer_size = 0;
545 	}
546 
547 	/*
548 	 * Allocate output buffer if there isn't one.
549 	 */
550 	if (NULL == state->display_buffer) {
551 		state->display_buffer_size = (2 * state->width) + 80;
552 		if (state->name)
553 			state->display_buffer_size += strlen(state->name);
554 		state->display_buffer =
555 		    malloc(state->display_buffer_size + 16);
556 		if (NULL == state->display_buffer) {
557 			pv_error(state, "%s: %s",
558 				 _("buffer allocation failed"),
559 				 strerror(errno));
560 			state->exit_status |= 64;
561 			return NULL;
562 		}
563 		state->display_buffer[0] = 0;
564 	}
565 
566 	/*
567 	 * In numeric output mode, our output is just a number.
568 	 *
569 	 * Patch from Sami Liedes:
570 	 * With --timer we prefix the output with the elapsed time.
571 	 * With --bytes we output the bytes transferred so far instead
572 	 * of the percentage. (Or lines, if --lines was given with --bytes).
573 	 */
574 	if (state->numeric) {
575 		char numericprefix[128];
576 
577 		numericprefix[0] = 0;
578 
579 		if ((state->components_used & PV_DISPLAY_TIMER) != 0)
580 			sprintf(numericprefix, "%.4Lf ", elapsed_sec);
581 
582 		if ((state->components_used & PV_DISPLAY_BYTES) != 0) {
583 			sprintf(state->display_buffer, "%.99s%lld\n",
584 				numericprefix, total_bytes);
585 		} else if (state->percentage > 100) {
586 			/* As mentioned above, we go 0-100, then 100-0. */
587 			sprintf(state->display_buffer, "%.99s%ld\n",
588 				numericprefix, 200 - state->percentage);
589 		} else {
590 			sprintf(state->display_buffer, "%.99s%ld\n",
591 				numericprefix, state->percentage);
592 		}
593 
594 		return state->display_buffer;
595 	}
596 
597 	/*
598 	 * First, work out what components we will be putting in the output
599 	 * buffer, and for those that don't depend on the total width
600 	 * available (i.e. all but the progress bar), prepare their strings
601 	 * to be placed in the output buffer.
602 	 */
603 
604 	state->str_transferred[0] = 0;
605 	state->str_bufpercent[0] = 0;
606 	state->str_timer[0] = 0;
607 	state->str_rate[0] = 0;
608 	state->str_average_rate[0] = 0;
609 	state->str_progress[0] = 0;
610 	state->str_lastoutput[0] = 0;
611 	state->str_eta[0] = 0;
612 	state->str_fineta[0] = 0;
613 
614 	/* If we're showing bytes transferred, set up the display string. */
615 	if ((state->components_used & PV_DISPLAY_BYTES) != 0) {
616 		pv__sizestr(state->str_transferred,
617 			    sizeof(state->str_transferred), "%s",
618 			    (long double) total_bytes, "", _("B"),
619 			    state->linemode ? 0 : 1);
620 	}
621 
622 	/* Transfer buffer percentage - set up the display string. */
623 	if ((state->components_used & PV_DISPLAY_BUFPERCENT) != 0) {
624 		if (state->buffer_size > 0)
625 			sprintf(state->str_bufpercent, "{%3ld%%}",
626 				pv__calc_percentage(state->read_position -
627 						    state->write_position,
628 						    state->buffer_size));
629 #ifdef HAVE_SPLICE
630 		if (state->splice_used)
631 			strcpy(state->str_bufpercent, "{----}");
632 #endif
633 	}
634 
635 	/* Timer - set up the display string. */
636 	if ((state->components_used & PV_DISPLAY_TIMER) != 0) {
637 		/*
638 		 * Bounds check, so we don't overrun the prefix buffer. This
639 		 * does mean that the timer will stop at a 100,000 hours,
640 		 * but since that's 11 years, it shouldn't be a problem.
641 		 */
642 		if (elapsed_sec > (long double) 360000000.0L)
643 			elapsed_sec = (long double) 360000000.0L;
644 
645 		sprintf(state->str_timer, "%ld:%02ld:%02ld",
646 			((long) elapsed_sec) / 3600,
647 			(((long) elapsed_sec) / 60) % 60,
648 			((long) elapsed_sec) % 60);
649 	}
650 
651 	/* Rate - set up the display string. */
652 	if ((state->components_used & PV_DISPLAY_RATE) != 0) {
653 		pv__sizestr(state->str_rate, sizeof(state->str_rate),
654 			    "[%s]", rate, _("/s"), _("B/s"),
655 			    state->linemode ? 0 : 1);
656 	}
657 
658 	/* Average rate - set up the display string. */
659 	if ((state->components_used & PV_DISPLAY_AVERAGERATE) != 0) {
660 		pv__sizestr(state->str_average_rate,
661 			    sizeof(state->str_average_rate), "[%s]",
662 			    average_rate, _("/s"), _("B/s"),
663 			    state->linemode ? 0 : 1);
664 	}
665 
666 	/* Last output bytes - set up the display string. */
667 	if ((state->components_used & PV_DISPLAY_OUTPUTBUF) != 0) {
668 		int idx;
669 		for (idx = 0; idx < state->lastoutput_length; idx++) {
670 			int c;
671 			c = state->lastoutput_buffer[idx];
672 			state->str_lastoutput[idx] = isprint(c) ? c : '.';
673 		}
674 		state->str_lastoutput[idx] = 0;
675 	}
676 
677 	/* ETA (only if size is known) - set up the display string. */
678 	if (((state->components_used & PV_DISPLAY_ETA) != 0)
679 	    && (state->size > 0)) {
680 		eta =
681 		    pv__calc_eta(total_bytes - state->initial_offset,
682 				 state->size - state->initial_offset,
683 				 elapsed_sec);
684 
685 		/*
686 		 * Bounds check, so we don't overrun the suffix buffer. This
687 		 * means the ETA will always be less than 100,000 hours.
688 		 */
689 		eta = bound_long(eta, 0, (long) 360000000L);
690 
691 		/*
692 		 * If the ETA is more than a day, include a day count as
693 		 * well as hours, minutes, and seconds.
694 		 */
695 		if (eta > 86400L) {
696 			sprintf(state->str_eta,
697 				"%.16s %ld:%02ld:%02ld:%02ld", _("ETA"),
698 				eta / 86400, (eta / 3600) % 24,
699 				(eta / 60) % 60, eta % 60);
700 		} else {
701 			sprintf(state->str_eta, "%.16s %ld:%02ld:%02ld",
702 				_("ETA"), eta / 3600, (eta / 60) % 60,
703 				eta % 60);
704 		}
705 
706 		/*
707 		 * If this is the final update, show a blank space where the
708 		 * ETA used to be.
709 		 */
710 		if (bytes_since_last < 0) {
711 			unsigned int i;
712 			for (i = 0; i < sizeof(state->str_eta)
713 			     && state->str_eta[i] != 0; i++) {
714 				state->str_eta[i] = ' ';
715 			}
716 		}
717 	}
718 
719 	/* ETA as clock time (as above) - set up the display string. */
720 	if (((state->components_used & PV_DISPLAY_FINETA) != 0)
721 	    && (state->size > 0)) {
722 		/*
723 		 * The ETA may be hidden by a failed ETA string
724 		 * generation.
725 		 */
726 		int show_eta = 1;
727 		time_t now = time(NULL);
728 		time_t then;
729 		struct tm *time_ptr;
730 		char *time_format = NULL;
731 
732 		eta =
733 		    pv__calc_eta(total_bytes - state->initial_offset,
734 				 state->size - state->initial_offset,
735 				 elapsed_sec);
736 
737 		/*
738 		 * Bounds check, so we don't overrun the suffix buffer. This
739 		 * means the ETA will always be less than 100,000 hours.
740 		 */
741 		eta = bound_long(eta, 0, (long) 360000000L);
742 
743 		/*
744 		 * Only include the date if the ETA is more than 6 hours
745 		 * away.
746 		 */
747 		if (eta > (long) (6 * 3600)) {
748 			time_format = "%Y-%m-%d %H:%M:%S";
749 		} else {
750 			time_format = "%H:%M:%S";
751 		}
752 
753 		then = now + eta;
754 		time_ptr = localtime(&then);
755 
756 		if (NULL == time_ptr) {
757 			show_eta = 0;
758 		} else {
759 			/* Localtime keeps data stored in a
760 			 * static buffer that gets overwritten
761 			 * by time functions. */
762 			struct tm time = *time_ptr;
763 
764 			sprintf(state->str_fineta, "%.16s ", _("ETA"));
765 			strftime(state->str_fineta +
766 				 strlen(state->str_fineta),
767 				 sizeof(state->str_fineta) - 1 -
768 				 strlen(state->str_fineta),
769 				 time_format, &time);
770 		}
771 
772 		if (!show_eta) {
773 			unsigned int i;
774 			for (i = 0; i < sizeof(state->str_fineta)
775 			     && state->str_fineta[i] != 0; i++) {
776 				state->str_fineta[i] = ' ';
777 			}
778 		}
779 	}
780 
781 	/*
782 	 * Now go through all the static portions of the format to work
783 	 * out how much space will be left for any dynamic portions
784 	 * (i.e. the progress bar).
785 	 */
786 	static_portion_size = 0;
787 	for (segment = 0; state->format[segment].string; segment++) {
788 		if (state->format[segment].length < 0) {
789 			continue;
790 		} else if (state->format[segment].length > 0) {
791 			static_portion_size +=
792 			    state->format[segment].length;
793 		} else {
794 			static_portion_size +=
795 			    strlen(state->format[segment].string);
796 		}
797 	}
798 
799 	debug("static_portion_size: %d", static_portion_size);
800 
801 	/*
802 	 * Assemble the progress bar now we know how big it should be.
803 	 */
804 	if ((state->components_used & PV_DISPLAY_PROGRESS) != 0) {
805 		char pct[16];
806 		int available_width, i;
807 
808 		strcpy(state->str_progress, "[");
809 
810 		if (state->size > 0) {
811 			if (state->percentage < 0)
812 				state->percentage = 0;
813 			if (state->percentage > 100000)
814 				state->percentage = 100000;
815 			sprintf(pct, "%2ld%%", state->percentage);
816 
817 			available_width =
818 			    state->width - static_portion_size -
819 			    strlen(pct) - 3;
820 
821 			if (available_width < 0)
822 				available_width = 0;
823 
824 			if (available_width >
825 			    (int) (sizeof(state->str_progress)) - 16)
826 				available_width =
827 				    sizeof(state->str_progress) - 16;
828 
829 			for (i = 0;
830 			     i <
831 			     (available_width * state->percentage) / 100 -
832 			     1; i++) {
833 				if (i < available_width)
834 					strcat(state->str_progress, "=");
835 			}
836 			if (i < available_width) {
837 				strcat(state->str_progress, ">");
838 				i++;
839 			}
840 			for (; i < available_width; i++) {
841 				strcat(state->str_progress, " ");
842 			}
843 			strcat(state->str_progress, "] ");
844 			strcat(state->str_progress, pct);
845 		} else {
846 			int p = state->percentage;
847 
848 			available_width =
849 			    state->width - static_portion_size - 5;
850 
851 			if (available_width < 0)
852 				available_width = 0;
853 
854 			if (available_width >
855 			    (int) (sizeof(state->str_progress)) - 16)
856 				available_width =
857 				    sizeof(state->str_progress) - 16;
858 
859 			debug("available_width: %d", available_width);
860 
861 			if (p > 100)
862 				p = 200 - p;
863 			for (i = 0; i < (available_width * p) / 100; i++) {
864 				if (i < available_width)
865 					strcat(state->str_progress, " ");
866 			}
867 			strcat(state->str_progress, "<=>");
868 			for (; i < available_width; i++) {
869 				strcat(state->str_progress, " ");
870 			}
871 			strcat(state->str_progress, "]");
872 		}
873 
874 		/*
875 		 * If the progress bar won't fit, drop it.
876 		 */
877 		if (strlen(state->str_progress) + static_portion_size >
878 		    state->width)
879 			state->str_progress[0] = 0;
880 	}
881 
882 	/*
883 	 * We can now build the output string using the format structure.
884 	 */
885 
886 	state->display_buffer[0] = 0;
887 	display_string_length = 0;
888 	for (segment = 0; state->format[segment].string; segment++) {
889 		int segment_length;
890 		if (state->format[segment].length > 0) {
891 			segment_length = state->format[segment].length;
892 		} else {
893 			segment_length =
894 			    strlen(state->format[segment].string);
895 		}
896 		/* Skip empty segments */
897 		if (segment_length == 0)
898 			continue;
899 		/*
900 		 * Truncate segment if it would make the display string
901 		 * overflow the buffer
902 		 */
903 		if (segment_length + display_string_length >
904 		    state->display_buffer_size - 2)
905 			segment_length =
906 			    state->display_buffer_size -
907 			    display_string_length - 2;
908 		if (segment_length < 1)
909 			break;
910 		/* Skip segment if it would make the display too wide */
911 		if (segment_length + display_string_length >
912 		    (int) (state->width))
913 			break;
914 		strncat(state->display_buffer,
915 			state->format[segment].string, segment_length);
916 		display_string_length += segment_length;
917 	}
918 
919 	/*
920 	 * If the size of our output shrinks, we need to keep appending
921 	 * spaces at the end, so that we don't leave dangling bits behind.
922 	 */
923 	output_length = strlen(state->display_buffer);
924 	if ((output_length < state->prev_length)
925 	    && ((int) (state->width) >= state->prev_width)) {
926 		char spaces[32];
927 		int spaces_to_add;
928 		spaces_to_add = state->prev_length - output_length;
929 		/* Upper boundary on number of spaces */
930 		if (spaces_to_add > 15) {
931 			spaces_to_add = 15;
932 		}
933 		output_length += spaces_to_add;
934 		spaces[spaces_to_add] = 0;
935 		while (--spaces_to_add >= 0) {
936 			spaces[spaces_to_add] = ' ';
937 		}
938 		strcat(state->display_buffer, spaces);
939 	}
940 	state->prev_width = state->width;
941 	state->prev_length = output_length;
942 
943 	return state->display_buffer;
944 }
945 
946 
947 /*
948  * Output status information on standard error, where "esec" is the seconds
949  * elapsed since the transfer started, "sl" is the number of bytes transferred
950  * since the last update, and "tot" is the total number of bytes transferred
951  * so far.
952  *
953  * If "sl" is negative, this is the final update so the rate is given as an
954  * an average over the whole transfer; otherwise the current rate is shown.
955  *
956  * In line mode, "sl" and "tot" are in lines, not bytes.
957  */
pv_display(pvstate_t state,long double esec,long long sl,long long tot)958 void pv_display(pvstate_t state, long double esec, long long sl,
959 		long long tot)
960 {
961 	char *display;
962 
963 	if (NULL == state)
964 		return;
965 
966 	/*
967 	 * If the display options need reparsing, do so to generate new
968 	 * formatting parameters.
969 	 */
970 	if (state->reparse_display) {
971 		pv__format_init(state);
972 		state->reparse_display = 0;
973 	}
974 
975 	pv_sig_checkbg();
976 
977 	display = pv__format(state, esec, sl, tot);
978 	if (NULL == display)
979 		return;
980 
981 	if (state->numeric) {
982 		write(STDERR_FILENO, display, strlen(display));
983 	} else if (state->cursor) {
984 		if (pv_in_foreground()) {
985 			pv_crs_update(state, display);
986 			state->display_visible = true;
987 		}
988 	} else {
989 		if (pv_in_foreground()) {
990 			write(STDERR_FILENO, display, strlen(display));
991 			write(STDERR_FILENO, "\r", 1);
992 			state->display_visible = true;
993 		}
994 	}
995 
996 	debug("%s: [%s]", "display", display);
997 }
998 
999 /* EOF */
1000