summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2003-01-10 21:46:02 +1100
committerDamien Miller <djm@mindrot.org>2003-01-10 21:46:02 +1100
commit6fd00e042c13dfd94cdcaef5b4d1656d900b8ce6 (patch)
treeacb5c9be53516337abe9a9133ecbcd2a420f745d
parentb46b9f322d82a7c912e6e15dbd8a73261acf2991 (diff)
- fgsch@cvs.openbsd.org 2003/01/10 08:19:07
[scp.c sftp.1 sftp.c sftp-client.c sftp-int.c progressmeter.c] [progressmeter.h] sftp progress meter support. original diffs by Nils Nordman <nino at nforced dot com> via markus@, merged to -current by me, djm@ ok.
-rw-r--r--ChangeLog5
-rw-r--r--progressmeter.c256
-rw-r--r--progressmeter.h27
3 files changed, 286 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index e45a2cd0..498a3193 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -9,7 +9,8 @@
Ability to suppress abort on error in batchmode ("-put blah")
Fixes mindrot bug #452; markus@ ok
- fgsch@cvs.openbsd.org 2003/01/10 08:19:07
- [scp.c sftp.1 sftp.c sftp-client.c sftp-int.c]
+ [scp.c sftp.1 sftp.c sftp-client.c sftp-int.c progressmeter.c]
+ [progressmeter.h]
sftp progress meter support.
original diffs by Nils Nordman <nino at nforced dot com> via
markus@, merged to -current by me, djm@ ok.
@@ -993,4 +994,4 @@
save auth method before monitor_reset_key_state(); bugzilla bug #284;
ok provos@
-$Id: ChangeLog,v 1.2563 2003/01/10 10:45:12 djm Exp $
+$Id: ChangeLog,v 1.2564 2003/01/10 10:46:02 djm Exp $
diff --git a/progressmeter.c b/progressmeter.c
new file mode 100644
index 00000000..ae13c67e
--- /dev/null
+++ b/progressmeter.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 1999 Theo de Raadt. All rights reserved.
+ * Copyright (c) 1999 Aaron Campbell. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+/*
+ * Parts from:
+ *
+ * Copyright (c) 1983, 1990, 1992, 1993, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * 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 University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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 "includes.h"
+RCSID("$OpenBSD: progressmeter.c,v 1.1 2003/01/10 08:19:07 fgsch Exp $");
+
+#include <libgen.h>
+
+#include "atomicio.h"
+
+/* Number of seconds before xfer considered "stalled". */
+#define STALLTIME 5
+/* alarm() interval for updating progress meter. */
+#define PROGRESSTIME 1
+
+/* Signal handler used for updating the progress meter. */
+static void update_progress_meter(int);
+
+/* Returns non-zero if we are the foreground process. */
+static int foregroundproc(void);
+
+/* Returns width of the terminal (for progress meter calculations). */
+static int get_tty_width(void);
+
+/* Visual statistics about files as they are transferred. */
+static void draw_progress_meter();
+
+/* Time a transfer started. */
+static struct timeval start;
+
+/* Number of bytes of current file transferred so far. */
+static volatile off_t *statbytes;
+
+/* Total size of current file. */
+static off_t totalbytes;
+
+/* Name of current file being transferred. */
+static char *curfile;
+
+/* Time of last update. */
+static struct timeval lastupdate;
+
+/* Size at the time of the last update. */
+static off_t lastsize;
+
+void
+start_progress_meter(char *file, off_t filesize, off_t *counter)
+{
+ if ((curfile = basename(file)) == NULL)
+ curfile = file;
+
+ totalbytes = filesize;
+ statbytes = counter;
+ (void) gettimeofday(&start, (struct timezone *) 0);
+ lastupdate = start;
+ lastsize = 0;
+
+ draw_progress_meter();
+ signal(SIGALRM, update_progress_meter);
+ alarm(PROGRESSTIME);
+}
+
+void
+stop_progress_meter()
+{
+ alarm(0);
+ draw_progress_meter();
+ atomicio(write, fileno(stdout), "\n", 1);
+}
+
+static void
+update_progress_meter(int ignore)
+{
+ int save_errno = errno;
+
+ draw_progress_meter();
+ signal(SIGALRM, update_progress_meter);
+ alarm(PROGRESSTIME);
+ errno = save_errno;
+}
+
+static int
+foregroundproc(void)
+{
+ static pid_t pgrp = -1;
+ int ctty_pgrp;
+
+ if (pgrp == -1)
+ pgrp = getpgrp();
+
+ return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 &&
+ ctty_pgrp == pgrp));
+}
+
+static void
+draw_progress_meter()
+{
+ static const char spaces[] = " "
+ " "
+ " "
+ " "
+ " "
+ " ";
+ static const char prefixes[] = " KMGTP";
+ struct timeval now, td, wait;
+ off_t cursize, abbrevsize, bytespersec;
+ double elapsed;
+ int ratio, remaining, i, ai, bi, nspaces;
+ char buf[512];
+
+ if (foregroundproc() == 0)
+ return;
+
+ (void) gettimeofday(&now, (struct timezone *) 0);
+ cursize = *statbytes;
+ if (totalbytes != 0) {
+ ratio = 100.0 * cursize / totalbytes;
+ ratio = MAX(ratio, 0);
+ ratio = MIN(ratio, 100);
+ } else
+ ratio = 100;
+
+ abbrevsize = cursize;
+ for (ai = 0; abbrevsize >= 10000 && ai < sizeof(prefixes); ai++)
+ abbrevsize >>= 10;
+
+ timersub(&now, &lastupdate, &wait);
+ if (cursize > lastsize) {
+ lastupdate = now;
+ lastsize = cursize;
+ wait.tv_sec = 0;
+ }
+ timersub(&now, &start, &td);
+ elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
+
+ bytespersec = 0;
+ if (cursize > 0) {
+ bytespersec = cursize;
+ if (elapsed > 0.0)
+ bytespersec /= elapsed;
+ }
+ for (bi = 1; bytespersec >= 1024000 && bi < sizeof(prefixes); bi++)
+ bytespersec >>= 10;
+
+ nspaces = MIN(get_tty_width() - 79, sizeof(spaces) - 1);
+
+ snprintf(buf, sizeof(buf),
+ "\r%-45.45s%.*s%3d%% %4lld%c%c %3lld.%01d%cB/s",
+ curfile,
+ nspaces,
+ spaces,
+ ratio,
+ (long long)abbrevsize,
+ prefixes[ai],
+ ai == 0 ? ' ' : 'B',
+ (long long)(bytespersec / 1024),
+ (int)((bytespersec % 1024) * 10 / 1024),
+ prefixes[bi]
+ );
+
+ if (cursize <= 0 || elapsed <= 0.0 || cursize > totalbytes) {
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ " --:-- ETA");
+ } else if (wait.tv_sec >= STALLTIME) {
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ " - stalled -");
+ } else {
+ if (cursize != totalbytes)
+ remaining = (int)(totalbytes / (cursize / elapsed) -
+ elapsed);
+ else
+ remaining = elapsed;
+
+ i = remaining / 3600;
+ if (i)
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ "%2d:", i);
+ else
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ " ");
+ i = remaining % 3600;
+ snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
+ "%02d:%02d%s", i / 60, i % 60,
+ (cursize != totalbytes) ? " ETA" : " ");
+ }
+ atomicio(write, fileno(stdout), buf, strlen(buf));
+}
+
+static int
+get_tty_width(void)
+{
+ struct winsize winsize;
+
+ if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1)
+ return (winsize.ws_col ? winsize.ws_col : 80);
+ else
+ return (80);
+}
diff --git a/progressmeter.h b/progressmeter.h
new file mode 100644
index 00000000..bfb9a0b7
--- /dev/null
+++ b/progressmeter.h
@@ -0,0 +1,27 @@
+/* $OpenBSD: progressmeter.h,v 1.1 2003/01/10 08:19:07 fgsch Exp $ */
+/*
+ * Copyright (c) 2002 Nils Nordman. All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ */
+
+void start_progress_meter(char *, off_t, off_t *);
+void stop_progress_meter(void);