#ifndef SMALL
#include <sys/cdefs.h>
__RCSID("$NetBSD: progress.c,v 1.5 2009/04/11 06:48:36 lukem Exp $");
#include <sys/param.h>
#include <sys/tty.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "progress.h"
static size_t ttywidth = 80;
static int progress_onoff;
static int progress_lowlim;
static int progress_highlim;
#define BUFLEFT (sizeof(buf) - len)
void
progress_switch(int onoff)
{
progress_onoff = onoff;
}
void
progress_init(void)
{
progress_setrange(0, 100);
}
void
progress_setrange(int lowlim, int highlim)
{
progress_lowlim = lowlim;
progress_highlim = highlim;
}
void
progress_sethighlim(int highlim)
{
progress_setrange(progress_highlim, highlim);
}
void
progress_bar(const char *dev, const char *label, off_t current, off_t total)
{
static int lastpercentage = -1;
char buf[256];
int len, percentage;
int barlength;
int i;
int lengthextras;
#define BAROVERHEAD 10
static const char stars[] =
"*****************************************************************************"
"*****************************************************************************"
"*****************************************************************************";
if (progress_onoff == 0)
return;
len = 0;
lengthextras = strlen(dev) + (label != NULL ? strlen(label) : 0);
percentage = progress_lowlim +
(current * (progress_highlim - progress_lowlim)) / total;
percentage = MAX(percentage, 0);
percentage = MIN(percentage, 100);
if (percentage == lastpercentage)
return;
lastpercentage = percentage;
len += snprintf(buf + len, BUFLEFT, "%s: ", dev);
if (label != NULL)
len += snprintf(buf + len, BUFLEFT, "%s ", label);
barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD - lengthextras;
if (barlength > 0) {
i = barlength * percentage / 100;
len += snprintf(buf + len, BUFLEFT,
"|%.*s%*s| ", i, stars, barlength - i, "");
}
len += snprintf(buf + len, BUFLEFT, "%3d%%\r", percentage);
write(fileno(stdout), buf, len);
}
void
progress_done(void)
{
char buf[256];
int len;
if (progress_onoff == 0)
return;
len = MIN(sizeof(buf) - 2, ttywidth);
memset(buf, ' ', len);
buf[len] = '\r';
buf[len + 1] = '\0';
write(fileno(stdout), buf, len + 1);
}
void
progress_ttywidth(int a)
{
struct winsize winsize;
int oerrno = errno;
if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1 &&
winsize.ws_col != 0)
ttywidth = winsize.ws_col;
else
ttywidth = 80;
errno = oerrno;
}
#endif