1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef PROGRESS_METER 2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* 3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Copyright (c) 2003 Nils Nordman. All rights reserved. 4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Redistribution and use in source and binary forms, with or without 6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * modification, are permitted provided that the following conditions 7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * are met: 8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * notice, this list of conditions and the following disclaimer. 10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * documentation and/or other materials provided with the distribution. 13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "includes.h" 27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/*RCSID("$OpenBSD: progressmeter.c,v 1.24 2005/06/07 13:25:23 jaredy Exp $");*/ 28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "progressmeter.h" 30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "atomicio.h" 31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "scpmisc.h" 32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define DEFAULT_WINSIZE 40 34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define MAX_WINSIZE 512 35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define PADDING 1 /* padding between the progress indicators */ 36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define UPDATE_INTERVAL 1 /* update the progress meter every second */ 37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define STALL_TIME 5 /* we're stalled after this many seconds */ 38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* determines whether we can output to the terminal */ 40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int can_output(void); 41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* formats and inserts the specified size into the given buffer */ 43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void format_size(char *, int, off_t); 44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void format_rate(char *, int, off_t); 45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* window resizing */ 47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void sig_winch(int); 48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void setscreensize(void); 49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* updates the progressmeter to reflect the current state of the transfer */ 51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid refresh_progress_meter(void); 52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* signal handler for updating the progress meter */ 54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void update_progress_meter(int); 55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic time_t start; /* start progress */ 57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic time_t last_update; /* last progress update */ 58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic char *file; /* name of the file being transferred */ 59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic off_t end_pos; /* ending position of transfer */ 60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic off_t cur_pos; /* transfer position as of last refresh */ 61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic volatile off_t *counter; /* progress counter */ 62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic long stalled; /* how long we have been stalled */ 63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int bytes_per_second; /* current speed in bytes per second */ 64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int win_size; /* terminal window size */ 65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic volatile sig_atomic_t win_resized; /* for window resizing */ 66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* units for format_size */ 68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic const char unit[] = " KMGT"; 69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic int 71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectcan_output(void) 72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return (getpgrp() == tcgetpgrp(STDOUT_FILENO)); 74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void 77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectformat_rate(char *buf, int size, off_t bytes) 78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i; 80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes *= 100; 82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; bytes >= 100*1000 && unit[i] != 'T'; i++) 83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes = (bytes + 512) / 1024; 84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (i == 0) { 85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project i++; 86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes = (bytes + 512) / 1024; 87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project snprintf(buf, size, "%3lld.%1lld%c%s", 89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (long long) (bytes + 5) / 100, 90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (long long) (bytes + 5) / 10 % 10, 91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unit[i], 92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project i ? "B" : " "); 93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void 96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectformat_size(char *buf, int size, off_t bytes) 97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i; 99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; bytes >= 10000 && unit[i] != 'T'; i++) 101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes = (bytes + 512) / 1024; 102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project snprintf(buf, size, "%4lld%c%s", 103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (long long) bytes, 104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unit[i], 105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project i ? "B" : " "); 106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid 109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectrefresh_progress_meter(void) 110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project char buf[MAX_WINSIZE + 1]; 112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project time_t now; 113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project off_t transferred; 114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project double elapsed; 115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int percent; 116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project off_t bytes_left; 117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int cur_speed; 118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int hours, minutes, seconds; 119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int i, len; 120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int file_len; 121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project transferred = *counter - cur_pos; 123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project cur_pos = *counter; 124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project now = time(NULL); 125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes_left = end_pos - cur_pos; 126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (bytes_left > 0) 128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project elapsed = now - last_update; 129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project else { 130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project elapsed = now - start; 131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Calculate true total speed when done */ 132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project transferred = end_pos; 133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes_per_second = 0; 134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* calculate speed */ 137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (elapsed != 0) 138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project cur_speed = (transferred / elapsed); 139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project else 140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project cur_speed = transferred; 141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define AGE_FACTOR 0.9 143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (bytes_per_second != 0) { 144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes_per_second = (bytes_per_second * AGE_FACTOR) + 145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (cur_speed * (1.0 - AGE_FACTOR)); 146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } else 147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes_per_second = cur_speed; 148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* filename */ 150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf[0] = '\0'; 151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project file_len = win_size - 35; 152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (file_len > 0) { 153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project len = snprintf(buf, file_len + 1, "\r%s", file); 154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (len < 0) 155f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project len = 0; 156f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (len >= file_len + 1) 157f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project len = file_len; 158f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = len; i < file_len; i++ ) 159f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf[i] = ' '; 160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf[file_len] = '\0'; 161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* percent of transfer done */ 164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (end_pos != 0) 165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project percent = ((float)cur_pos / end_pos) * 100; 166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project else 167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project percent = 100; 168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project snprintf(buf + strlen(buf), win_size - strlen(buf), 169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project " %3d%% ", percent); 170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* amount transferred */ 172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project format_size(buf + strlen(buf), win_size - strlen(buf), 173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project cur_pos); 174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project strlcat(buf, " ", win_size); 175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* bandwidth usage */ 177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project format_rate(buf + strlen(buf), win_size - strlen(buf), 178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project (off_t)bytes_per_second); 179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project strlcat(buf, "/s ", win_size); 180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* ETA */ 182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (!transferred) 183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project stalled += elapsed; 184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project else 185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project stalled = 0; 186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (stalled >= STALL_TIME) 188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project strlcat(buf, "- stalled -", win_size); 189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project else if (bytes_per_second == 0 && bytes_left) 190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project strlcat(buf, " --:-- ETA", win_size); 191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project else { 192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (bytes_left > 0) 193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project seconds = bytes_left / bytes_per_second; 194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project else 195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project seconds = elapsed; 196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project hours = seconds / 3600; 198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project seconds -= hours * 3600; 199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project minutes = seconds / 60; 200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project seconds -= minutes * 60; 201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (hours != 0) 203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project snprintf(buf + strlen(buf), win_size - strlen(buf), 204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project "%d:%02d:%02d", hours, minutes, seconds); 205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project else 206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project snprintf(buf + strlen(buf), win_size - strlen(buf), 207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project " %02d:%02d", minutes, seconds); 208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (bytes_left > 0) 210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project strlcat(buf, " ETA", win_size); 211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project else 212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project strlcat(buf, " ", win_size); 213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1); 216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project last_update = now; 217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void 220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectupdate_progress_meter(int ignore) 221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int save_errno; 223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project save_errno = errno; 225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (win_resized) { 227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project setscreensize(); 228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project win_resized = 0; 229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (can_output()) 231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project refresh_progress_meter(); 232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project signal(SIGALRM, update_progress_meter); 234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project alarm(UPDATE_INTERVAL); 235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project errno = save_errno; 236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid 239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstart_progress_meter(char *f, off_t filesize, off_t *ctr) 240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project start = last_update = time(NULL); 242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project file = f; 243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project end_pos = filesize; 244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project cur_pos = 0; 245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project counter = ctr; 246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project stalled = 0; 247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes_per_second = 0; 248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project setscreensize(); 250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (can_output()) 251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project refresh_progress_meter(); 252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project signal(SIGALRM, update_progress_meter); 254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project signal(SIGWINCH, sig_winch); 255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project alarm(UPDATE_INTERVAL); 256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid 259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstop_progress_meter(void) 260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project alarm(0); 262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (!can_output()) 264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return; 265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* Ensure we complete the progress */ 267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (cur_pos != end_pos) 268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project refresh_progress_meter(); 269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project atomicio(vwrite, STDOUT_FILENO, "\n", 1); 271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void 274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectsig_winch(int sig) 275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project win_resized = 1; 277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void 280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectsetscreensize(void) 281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project{ 282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project struct winsize winsize; 283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize) != -1 && 285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project winsize.ws_col != 0) { 286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (winsize.ws_col > MAX_WINSIZE) 287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project win_size = MAX_WINSIZE; 288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project else 289f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project win_size = winsize.ws_col; 290f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } else 291f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project win_size = DEFAULT_WINSIZE; 292f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project win_size += 1; /* trailing \0 */ 293f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 294f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* PROGRESS_METER */ 295