diff options
author | gavin <gavin@FreeBSD.org> | 2011-06-19 16:54:06 +0000 |
---|---|---|
committer | gavin <gavin@FreeBSD.org> | 2011-06-19 16:54:06 +0000 |
commit | cd23bc1631ac018f140ef5d8cfa8fd8afa0d28e1 (patch) | |
tree | d536f826304d5d1048670212a5e33e4818109b14 /contrib/lukemftp/src/progressbar.c | |
parent | 7e8a9605b1b776a2e6c8f20d00d300a4c160d2fc (diff) | |
download | FreeBSD-src-cd23bc1631ac018f140ef5d8cfa8fd8afa0d28e1.zip FreeBSD-src-cd23bc1631ac018f140ef5d8cfa8fd8afa0d28e1.tar.gz |
Bootstrap lukemftp vendor area
Diffstat (limited to 'contrib/lukemftp/src/progressbar.c')
-rw-r--r-- | contrib/lukemftp/src/progressbar.c | 464 |
1 files changed, 0 insertions, 464 deletions
diff --git a/contrib/lukemftp/src/progressbar.c b/contrib/lukemftp/src/progressbar.c deleted file mode 100644 index d0bd35f..0000000 --- a/contrib/lukemftp/src/progressbar.c +++ /dev/null @@ -1,464 +0,0 @@ -/* $NetBSD: progressbar.c,v 1.7 2005/04/11 01:49:31 lukem Exp $ */ - -/*- - * Copyright (c) 1997-2003 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Luke Mewburn. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -#ifndef lint -__RCSID("$NetBSD: progressbar.c,v 1.7 2005/04/11 01:49:31 lukem Exp $"); -#endif /* not lint */ - -/* - * FTP User Program -- Misc support routines - */ -#include <sys/types.h> -#include <sys/param.h> -#include <sys/time.h> - -#include <err.h> -#include <errno.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#include "progressbar.h" - -#define SECSPERHOUR (60 * 60) -#define SECSPERDAY ((long)60 * 60 * 24) - -#if !defined(NO_PROGRESS) -/* - * return non-zero if we're the current foreground process - */ -int -foregroundproc(void) -{ - static pid_t pgrp = -1; - - if (pgrp == -1) - pgrp = getpgrp(); - - return (tcgetpgrp(fileno(ttyout)) == pgrp); -} -#endif /* !defined(NO_PROGRESS) */ - - -static void updateprogressmeter(int); - -/* - * SIGALRM handler to update the progress meter - */ -static void -updateprogressmeter(int dummy) -{ - int oerrno = errno; - - progressmeter(0); - errno = oerrno; -} - -/* - * List of order of magnitude prefixes. - * The last is `P', as 2^64 = 16384 Petabytes - */ -static const char prefixes[] = " KMGTP"; - -/* - * Display a transfer progress bar if progress is non-zero. - * SIGALRM is hijacked for use by this function. - * - Before the transfer, set filesize to size of file (or -1 if unknown), - * and call with flag = -1. This starts the once per second timer, - * and a call to updateprogressmeter() upon SIGALRM. - * - During the transfer, updateprogressmeter will call progressmeter - * with flag = 0 - * - After the transfer, call with flag = 1 - */ -static struct timeval start; -static struct timeval lastupdate; - -#define BUFLEFT (sizeof(buf) - len) - -void -progressmeter(int flag) -{ - static off_t lastsize; - off_t cursize; - struct timeval now, wait; -#ifndef NO_PROGRESS - struct timeval td; - off_t abbrevsize, bytespersec; - double elapsed; - int ratio, barlength, i, remaining; - - /* - * Work variables for progress bar. - * - * XXX: if the format of the progress bar changes - * (especially the number of characters in the - * `static' portion of it), be sure to update - * these appropriately. - */ -#endif - int len; - char buf[256]; /* workspace for progress bar */ -#ifndef NO_PROGRESS -#define BAROVERHEAD 43 /* non `*' portion of progress bar */ - /* - * stars should contain at least - * sizeof(buf) - BAROVERHEAD entries - */ - static const char stars[] = -"*****************************************************************************" -"*****************************************************************************" -"*****************************************************************************"; - -#endif - - if (flag == -1) { - (void)gettimeofday(&start, NULL); - lastupdate = start; - lastsize = restart_point; - } - - (void)gettimeofday(&now, NULL); - cursize = bytes + restart_point; - timersub(&now, &lastupdate, &wait); - if (cursize > lastsize) { - lastupdate = now; - lastsize = cursize; - wait.tv_sec = 0; - } else { -#ifndef STANDALONE_PROGRESS - if (quit_time > 0 && wait.tv_sec > quit_time) { - len = snprintf(buf, sizeof(buf), "\r\n%s: " - "transfer aborted because stalled for %lu sec.\r\n", - getprogname(), (unsigned long)wait.tv_sec); - (void)write(fileno(ttyout), buf, len); - (void)xsignal(SIGALRM, SIG_DFL); - alarmtimer(0); - siglongjmp(toplevel, 1); - } -#endif /* !STANDALONE_PROGRESS */ - } - /* - * Always set the handler even if we are not the foreground process. - */ -#ifdef STANDALONE_PROGRESS - if (progress) { -#else - if (quit_time > 0 || progress) { -#endif /* !STANDALONE_PROGRESS */ - if (flag == -1) { - (void)xsignal_restart(SIGALRM, updateprogressmeter, 1); - alarmtimer(1); /* set alarm timer for 1 Hz */ - } else if (flag == 1) { - (void)xsignal(SIGALRM, SIG_DFL); - alarmtimer(0); - } - } -#ifndef NO_PROGRESS - if (!progress) - return; - len = 0; - - /* - * print progress bar only if we are foreground process. - */ - if (! foregroundproc()) - return; - - len += snprintf(buf + len, BUFLEFT, "\r"); - if (prefix) - len += snprintf(buf + len, BUFLEFT, "%s", prefix); - if (filesize > 0) { - ratio = (int)((double)cursize * 100.0 / (double)filesize); - ratio = MAX(ratio, 0); - ratio = MIN(ratio, 100); - len += snprintf(buf + len, BUFLEFT, "%3d%% ", ratio); - - /* - * calculate the length of the `*' bar, ensuring that - * the number of stars won't exceed the buffer size - */ - barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD; - if (prefix) - barlength -= strlen(prefix); - if (barlength > 0) { - i = barlength * ratio / 100; - len += snprintf(buf + len, BUFLEFT, - "|%.*s%*s|", i, stars, barlength - i, ""); - } - } - - abbrevsize = cursize; - for (i = 0; abbrevsize >= 100000 && i < sizeof(prefixes); i++) - abbrevsize >>= 10; - len += snprintf(buf + len, BUFLEFT, " " LLFP("5") " %c%c ", - (LLT)abbrevsize, - prefixes[i], - i == 0 ? ' ' : 'B'); - - timersub(&now, &start, &td); - elapsed = td.tv_sec + (td.tv_usec / 1000000.0); - - bytespersec = 0; - if (bytes > 0) { - bytespersec = bytes; - if (elapsed > 0.0) - bytespersec /= elapsed; - } - for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++) - bytespersec >>= 10; - len += snprintf(buf + len, BUFLEFT, - " " LLFP("3") ".%02d %cB/s ", - (LLT)(bytespersec / 1024), - (int)((bytespersec % 1024) * 100 / 1024), - prefixes[i]); - - if (filesize > 0) { - if (bytes <= 0 || elapsed <= 0.0 || cursize > filesize) { - len += snprintf(buf + len, BUFLEFT, " --:-- ETA"); - } else if (wait.tv_sec >= STALLTIME) { - len += snprintf(buf + len, BUFLEFT, " - stalled -"); - } else { - remaining = (int) - ((filesize - restart_point) / (bytes / elapsed) - - elapsed); - if (remaining >= 100 * SECSPERHOUR) - len += snprintf(buf + len, BUFLEFT, - " --:-- ETA"); - else { - i = remaining / SECSPERHOUR; - if (i) - len += snprintf(buf + len, BUFLEFT, - "%2d:", i); - else - len += snprintf(buf + len, BUFLEFT, - " "); - i = remaining % SECSPERHOUR; - len += snprintf(buf + len, BUFLEFT, - "%02d:%02d ETA", i / 60, i % 60); - } - } - } - if (flag == 1) - len += snprintf(buf + len, BUFLEFT, "\n"); - (void)write(fileno(ttyout), buf, len); - -#endif /* !NO_PROGRESS */ -} - -#ifndef STANDALONE_PROGRESS -/* - * Display transfer statistics. - * Requires start to be initialised by progressmeter(-1), - * direction to be defined by xfer routines, and filesize and bytes - * to be updated by xfer routines - * If siginfo is nonzero, an ETA is displayed, and the output goes to stderr - * instead of ttyout. - */ -void -ptransfer(int siginfo) -{ - struct timeval now, td, wait; - double elapsed; - off_t bytespersec; - int remaining, hh, i, len; - - char buf[256]; /* Work variable for transfer status. */ - - if (!verbose && !progress && !siginfo) - return; - - (void)gettimeofday(&now, NULL); - timersub(&now, &start, &td); - elapsed = td.tv_sec + (td.tv_usec / 1000000.0); - bytespersec = 0; - if (bytes > 0) { - bytespersec = bytes; - if (elapsed > 0.0) - bytespersec /= elapsed; - } - len = 0; - len += snprintf(buf + len, BUFLEFT, LLF " byte%s %s in ", - (LLT)bytes, bytes == 1 ? "" : "s", direction); - remaining = (int)elapsed; - if (remaining > SECSPERDAY) { - int days; - - days = remaining / SECSPERDAY; - remaining %= SECSPERDAY; - len += snprintf(buf + len, BUFLEFT, - "%d day%s ", days, days == 1 ? "" : "s"); - } - hh = remaining / SECSPERHOUR; - remaining %= SECSPERHOUR; - if (hh) - len += snprintf(buf + len, BUFLEFT, "%2d:", hh); - len += snprintf(buf + len, BUFLEFT, - "%02d:%02d ", remaining / 60, remaining % 60); - - for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++) - bytespersec >>= 10; - len += snprintf(buf + len, BUFLEFT, "(" LLF ".%02d %cB/s)", - (LLT)(bytespersec / 1024), - (int)((bytespersec % 1024) * 100 / 1024), - prefixes[i]); - - if (siginfo && bytes > 0 && elapsed > 0.0 && filesize >= 0 - && bytes + restart_point <= filesize) { - remaining = (int)((filesize - restart_point) / - (bytes / elapsed) - elapsed); - hh = remaining / SECSPERHOUR; - remaining %= SECSPERHOUR; - len += snprintf(buf + len, BUFLEFT, " ETA: "); - if (hh) - len += snprintf(buf + len, BUFLEFT, "%2d:", hh); - len += snprintf(buf + len, BUFLEFT, "%02d:%02d", - remaining / 60, remaining % 60); - timersub(&now, &lastupdate, &wait); - if (wait.tv_sec >= STALLTIME) - len += snprintf(buf + len, BUFLEFT, " (stalled)"); - } - len += snprintf(buf + len, BUFLEFT, "\n"); - (void)write(siginfo ? STDERR_FILENO : fileno(ttyout), buf, len); -} - -/* - * SIG{INFO,QUIT} handler to print transfer stats if a transfer is in progress - */ -void -psummary(int notused) -{ - int oerrno = errno; - - if (bytes > 0) { - if (fromatty) - write(fileno(ttyout), "\n", 1); - ptransfer(1); - } - errno = oerrno; -} -#endif /* !STANDALONE_PROGRESS */ - - -/* - * Set the SIGALRM interval timer for wait seconds, 0 to disable. - */ -void -alarmtimer(int wait) -{ - struct itimerval itv; - - itv.it_value.tv_sec = wait; - itv.it_value.tv_usec = 0; - itv.it_interval = itv.it_value; - setitimer(ITIMER_REAL, &itv, NULL); -} - - -/* - * Install a POSIX signal handler, allowing the invoker to set whether - * the signal should be restartable or not - */ -sigfunc -xsignal_restart(int sig, sigfunc func, int restartable) -{ - struct sigaction act, oact; - act.sa_handler = func; - - sigemptyset(&act.sa_mask); -#if defined(SA_RESTART) /* 4.4BSD, Posix(?), SVR4 */ - act.sa_flags = restartable ? SA_RESTART : 0; -#elif defined(SA_INTERRUPT) /* SunOS 4.x */ - act.sa_flags = restartable ? 0 : SA_INTERRUPT; -#else -#error "system must have SA_RESTART or SA_INTERRUPT" -#endif - if (sigaction(sig, &act, &oact) < 0) - return (SIG_ERR); - return (oact.sa_handler); -} - -/* - * Install a signal handler with the `restartable' flag set dependent upon - * which signal is being set. (This is a wrapper to xsignal_restart()) - */ -sigfunc -xsignal(int sig, sigfunc func) -{ - int restartable; - - /* - * Some signals print output or change the state of the process. - * There should be restartable, so that reads and writes are - * not affected. Some signals should cause program flow to change; - * these signals should not be restartable, so that the system call - * will return with EINTR, and the program will go do something - * different. If the signal handler calls longjmp() or siglongjmp(), - * it doesn't matter if it's restartable. - */ - - switch(sig) { -#ifdef SIGINFO - case SIGINFO: -#endif - case SIGQUIT: - case SIGUSR1: - case SIGUSR2: - case SIGWINCH: - restartable = 1; - break; - - case SIGALRM: - case SIGINT: - case SIGPIPE: - restartable = 0; - break; - - default: - /* - * This is unpleasant, but I don't know what would be better. - * Right now, this "can't happen" - */ - errx(1, "xsignal_restart called with signal %d", sig); - } - - return(xsignal_restart(sig, func, restartable)); -} |