11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: progressmeter.c,v 1.37 2006/08/03 03:34:42 deraadt Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2003 Nils Nordman. All rights reserved. 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/ioctl.h> 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/uio.h> 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h> 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h> 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <time.h> 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h> 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "progressmeter.h" 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "atomicio.h" 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h" 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DEFAULT_WINSIZE 80 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define MAX_WINSIZE 512 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define PADDING 1 /* padding between the progress indicators */ 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define UPDATE_INTERVAL 1 /* update the progress meter every second */ 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define STALL_TIME 5 /* we're stalled after this many seconds */ 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* determines whether we can output to the terminal */ 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int can_output(void); 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* formats and inserts the specified size into the given buffer */ 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void format_size(char *, int, off_t); 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void format_rate(char *, int, off_t); 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* window resizing */ 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void sig_winch(int); 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void setscreensize(void); 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* updates the progressmeter to reflect the current state of the transfer */ 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid refresh_progress_meter(void); 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* signal handler for updating the progress meter */ 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void update_progress_meter(int); 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic time_t start; /* start progress */ 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic time_t last_update; /* last progress update */ 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic char *file; /* name of the file being transferred */ 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic off_t end_pos; /* ending position of transfer */ 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic off_t cur_pos; /* transfer position as of last refresh */ 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic volatile off_t *counter; /* progress counter */ 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic long stalled; /* how long we have been stalled */ 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int bytes_per_second; /* current speed in bytes per second */ 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int win_size; /* terminal window size */ 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic volatile sig_atomic_t win_resized; /* for window resizing */ 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* units for format_size */ 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic const char unit[] = " KMGT"; 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcan_output(void) 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (getpgrp() == tcgetpgrp(STDOUT_FILENO)); 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodformat_rate(char *buf, int size, off_t bytes) 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes *= 100; 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; bytes >= 100*1000 && unit[i] != 'T'; i++) 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes = (bytes + 512) / 1024; 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i == 0) { 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood i++; 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes = (bytes + 512) / 1024; 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, size, "%3lld.%1lld%c%s", 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (long long) (bytes + 5) / 100, 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (long long) (bytes + 5) / 10 % 10, 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unit[i], 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood i ? "B" : " "); 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodformat_size(char *buf, int size, off_t bytes) 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++) 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes = (bytes + 512) / 1024; 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf, size, "%4lld%c%s", 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (long long) bytes, 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood unit[i], 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood i ? "B" : " "); 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodrefresh_progress_meter(void) 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[MAX_WINSIZE + 1]; 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood time_t now; 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood off_t transferred; 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood double elapsed; 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int percent; 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood off_t bytes_left; 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int cur_speed; 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int hours, minutes, seconds; 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i, len; 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int file_len; 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood transferred = *counter - cur_pos; 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cur_pos = *counter; 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood now = time(NULL); 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes_left = end_pos - cur_pos; 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bytes_left > 0) 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood elapsed = now - last_update; 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else { 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood elapsed = now - start; 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Calculate true total speed when done */ 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood transferred = end_pos; 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes_per_second = 0; 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* calculate speed */ 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (elapsed != 0) 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cur_speed = (transferred / elapsed); 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cur_speed = transferred; 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define AGE_FACTOR 0.9 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bytes_per_second != 0) { 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes_per_second = (bytes_per_second * AGE_FACTOR) + 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (cur_speed * (1.0 - AGE_FACTOR)); 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes_per_second = cur_speed; 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* filename */ 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buf[0] = '\0'; 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood file_len = win_size - 35; 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (file_len > 0) { 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = snprintf(buf, file_len + 1, "\r%s", file); 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len < 0) 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = 0; 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (len >= file_len + 1) 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = file_len; 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = len; i < file_len; i++) 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buf[i] = ' '; 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buf[file_len] = '\0'; 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* percent of transfer done */ 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (end_pos != 0) 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood percent = ((float)cur_pos / end_pos) * 100; 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood percent = 100; 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf + strlen(buf), win_size - strlen(buf), 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood " %3d%% ", percent); 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* amount transferred */ 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood format_size(buf + strlen(buf), win_size - strlen(buf), 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cur_pos); 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(buf, " ", win_size); 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* bandwidth usage */ 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood format_rate(buf + strlen(buf), win_size - strlen(buf), 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (off_t)bytes_per_second); 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(buf, "/s ", win_size); 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* ETA */ 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!transferred) 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood stalled += elapsed; 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood stalled = 0; 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (stalled >= STALL_TIME) 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(buf, "- stalled -", win_size); 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else if (bytes_per_second == 0 && bytes_left) 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(buf, " --:-- ETA", win_size); 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else { 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bytes_left > 0) 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood seconds = bytes_left / bytes_per_second; 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood seconds = elapsed; 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hours = seconds / 3600; 2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood seconds -= hours * 3600; 2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood minutes = seconds / 60; 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood seconds -= minutes * 60; 2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (hours != 0) 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf + strlen(buf), win_size - strlen(buf), 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood "%d:%02d:%02d", hours, minutes, seconds); 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(buf + strlen(buf), win_size - strlen(buf), 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood " %02d:%02d", minutes, seconds); 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bytes_left > 0) 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(buf, " ETA", win_size); 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(buf, " ", win_size); 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1); 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood last_update = now; 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*ARGSUSED*/ 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodupdate_progress_meter(int ignore) 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int save_errno; 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood save_errno = errno; 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (win_resized) { 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setscreensize(); 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood win_resized = 0; 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (can_output()) 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood refresh_progress_meter(); 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGALRM, update_progress_meter); 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood alarm(UPDATE_INTERVAL); 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno = save_errno; 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstart_progress_meter(char *f, off_t filesize, off_t *ctr) 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood start = last_update = time(NULL); 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood file = f; 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood end_pos = filesize; 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood cur_pos = 0; 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood counter = ctr; 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood stalled = 0; 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bytes_per_second = 0; 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood setscreensize(); 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (can_output()) 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood refresh_progress_meter(); 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGALRM, update_progress_meter); 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood signal(SIGWINCH, sig_winch); 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood alarm(UPDATE_INTERVAL); 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstop_progress_meter(void) 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood alarm(0); 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!can_output()) 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Ensure we complete the progress */ 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cur_pos != end_pos) 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood refresh_progress_meter(); 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood atomicio(vwrite, STDOUT_FILENO, "\n", 1); 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*ARGSUSED*/ 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsig_winch(int sig) 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood win_resized = 1; 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsetscreensize(void) 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct winsize winsize; 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 && 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood winsize.ws_col != 0) { 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (winsize.ws_col > MAX_WINSIZE) 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood win_size = MAX_WINSIZE; 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood win_size = winsize.ws_col; 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood win_size = DEFAULT_WINSIZE; 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood win_size += 1; /* trailing \0 */ 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 306