]> andersk Git - openssh.git/commitdiff
- fgsch@cvs.openbsd.org 2003/01/10 08:19:07
authordjm <djm>
Fri, 10 Jan 2003 10:43:24 +0000 (10:43 +0000)
committerdjm <djm>
Fri, 10 Jan 2003 10:43:24 +0000 (10:43 +0000)
     [scp.c sftp.1 sftp.c sftp-client.c sftp-int.c]
     sftp progress meter support.
     original diffs by Nils Nordman <nino at nforced dot com> via
     markus@, merged to -current by me, djm@ ok.

ChangeLog
Makefile.in
scp.c
sftp-client.c
sftp-int.c
sftp.1
sftp.c

index 1c6ec3f714704b833fd9589926722624102ac82a..d07d5345e381cefc71df0b437104030d591b558d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,11 @@
      Allow blank lines and comments in input
      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]
+     sftp progress meter support.
+     original diffs by Nils Nordman <nino at nforced dot com> via 
+     markus@, merged to -current by me, djm@ ok.
 
 20030108
  - (djm) Sync openbsd-compat/ with OpenBSD -current
index 8639860e7c94d089161b144e9854479293435f0a..7bdd71034f78eaf86644da26a62a7f365a6d5d89 100644 (file)
@@ -117,8 +117,8 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
 sshd$(EXEEXT): libssh.a        $(LIBCOMPAT) $(SSHDOBJS)
        $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBS)
 
-scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o
-       $(LD) -o $@ scp.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
+       $(LD) -o $@ scp.o progressmeter.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o
        $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 
@@ -138,8 +138,8 @@ ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
 sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o
        $(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) 
 
-sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-int.o sftp-common.o sftp-glob.o
-       $(LD) -o $@ sftp.o sftp-client.o sftp-common.o sftp-int.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-int.o sftp-common.o sftp-glob.o progressmeter.o
+       $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-int.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
 
 ssh-rand-helper${EXEEXT}: $(LIBCOMPAT) libssh.a ssh-rand-helper.o
        $(LD) -o $@ ssh-rand-helper.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
diff --git a/scp.c b/scp.c
index 8324549d7c949369544d3cabfb8a038a7f7ea768..44b5b4582b204dc5e76769bce184ae79998b015a 100644 (file)
--- a/scp.c
+++ b/scp.c
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: scp.c,v 1.96 2002/12/13 15:20:52 markus Exp $");
+RCSID("$OpenBSD: scp.c,v 1.97 2003/01/10 08:19:07 fgsch Exp $");
 
 #include "xmalloc.h"
 #include "atomicio.h"
 #include "pathnames.h"
 #include "log.h"
 #include "misc.h"
+#include "progressmeter.h"
 
 #ifdef HAVE___PROGNAME
 extern char *__progname;
@@ -89,30 +90,9 @@ extern char *__progname;
 char *__progname;
 #endif
 
-/* For progressmeter() -- number of seconds before xfer considered "stalled" */
-#define STALLTIME      5
-/* alarm() interval for updating progress meter */
-#define PROGRESSTIME   1
-
-/* Visual statistics about files as they are transferred. */
-void progressmeter(int);
-
-/* Returns width of the terminal (for progress meter calculations). */
-int getttywidth(void);
-int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc);
-
 /* Struct for addargs */
 arglist args;
 
-/* Time a transfer started. */
-static struct timeval start;
-
-/* Number of bytes of current file transferred so far. */
-volatile off_t statbytes;
-
-/* Total size of current file. */
-off_t totalbytes = 0;
-
 /* Name of current file being transferred. */
 char *curfile;
 
@@ -505,7 +485,7 @@ source(argc, argv)
        struct stat stb;
        static BUF buffer;
        BUF *bp;
-       off_t i, amt, result;
+       off_t i, amt, result, statbytes;
        int fd, haderr, indx;
        char *last, *name, buf[2048];
        int len;
@@ -578,10 +558,8 @@ syserr:                    run_err("%s: %s", name, strerror(errno));
 next:                  (void) close(fd);
                        continue;
                }
-               if (showprogress) {
-                       totalbytes = stb.st_size;
-                       progressmeter(-1);
-               }
+               if (showprogress)
+                       start_progress_meter(curfile, stb.st_size, &statbytes);
                /* Keep writing after an error so that we stay sync'd up. */
                for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
                        amt = bp->cnt;
@@ -602,7 +580,7 @@ next:                       (void) close(fd);
                        }
                }
                if (showprogress)
-                       progressmeter(1);
+                       stop_progress_meter();
 
                if (close(fd) < 0 && !haderr)
                        haderr = errno;
@@ -682,7 +660,7 @@ sink(argc, argv)
        BUF *bp;
        off_t i, j;
        int amt, count, exists, first, mask, mode, ofd, omode;
-       off_t size;
+       off_t size, statbytes;
        int setimes, targisdir, wrerrno = 0;
        char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
        struct timeval tv[2];
@@ -844,11 +822,9 @@ bad:                       run_err("%s: %s", np, strerror(errno));
                cp = bp->buf;
                wrerr = NO;
 
-               if (showprogress) {
-                       totalbytes = size;
-                       progressmeter(-1);
-               }
                statbytes = 0;
+               if (showprogress)
+                       start_progress_meter(curfile, size, &statbytes);
                for (count = i = 0; i < size; i += 4096) {
                        amt = 4096;
                        if (i + amt > size)
@@ -882,7 +858,7 @@ bad:                        run_err("%s: %s", np, strerror(errno));
                        }
                }
                if (showprogress)
-                       progressmeter(1);
+                       stop_progress_meter();
                if (count != 0 && wrerr == NO &&
                    (j = atomicio(write, ofd, bp->buf, count)) != count) {
                        wrerr = YES;
@@ -1086,170 +1062,3 @@ lostconn(signo)
        else
                exit(1);
 }
-
-static void
-updateprogressmeter(int ignore)
-{
-       int save_errno = errno;
-
-       progressmeter(0);
-       signal(SIGALRM, updateprogressmeter);
-       alarm(PROGRESSTIME);
-       errno = save_errno;
-}
-
-static int
-foregroundproc(void)
-{
-       static pid_t pgrp = -1;
-       int ctty_pgrp;
-
-       if (pgrp == -1)
-               pgrp = getpgrp();
-
-#ifdef HAVE_TCGETPGRP
-       return ((ctty_pgrp = tcgetpgrp(STDOUT_FILENO)) != -1 &&
-               ctty_pgrp == pgrp);
-#else
-       return ((ioctl(STDOUT_FILENO, TIOCGPGRP, &ctty_pgrp) != -1 &&
-                ctty_pgrp == pgrp));
-#endif
-}
-
-void
-progressmeter(int flag)
-{
-       static const char spaces[] = "                          "
-           "                                                   "
-           "                                                   "
-           "                                                   "
-           "                                                   "
-           "                                                   ";
-       static const char prefixes[] = " KMGTP";
-       static struct timeval lastupdate;
-       static off_t lastsize;
-       struct timeval now, td, wait;
-       off_t cursize, abbrevsize, bytespersec;
-       double elapsed;
-       int ratio, remaining, i, ai, bi, nspaces;
-       char buf[512];
-
-       if (flag == -1) {
-               (void) gettimeofday(&start, (struct timezone *) 0);
-               lastupdate = start;
-               lastsize = 0;
-       }
-       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 (statbytes > 0) {
-               bytespersec = statbytes;
-               if (elapsed > 0.0)
-                       bytespersec /= elapsed;
-       }
-       for (bi = 1; bytespersec >= 1024000 && bi < sizeof(prefixes); bi++)
-               bytespersec >>= 10;
-
-       nspaces = MIN(getttywidth() - 79, sizeof(spaces) - 1);
-
-#ifdef HAVE_LONG_LONG_INT
-       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]
-       );
-#else
-       snprintf(buf, sizeof(buf),
-           "\r%-45.45s%.*s%3d%% %4lld%c%c %3lu.%01d%cB/s",
-           curfile,
-           nspaces,
-           spaces,
-           ratio,
-           (u_long)abbrevsize,
-           prefixes[ai],
-           ai == 0 ? ' ' : 'B',
-           (u_long)(bytespersec / 1024),
-           (int)((bytespersec % 1024) * 10 / 1024),
-           prefixes[bi]
-       );
-#endif
-
-       if (flag != 1 &&
-           (statbytes <= 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 (flag != 1)
-                       remaining = (int)(totalbytes / (statbytes / 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,
-                   (flag != 1) ? " ETA" : "    ");
-       }
-       atomicio(write, fileno(stdout), buf, strlen(buf));
-
-       if (flag == -1) {
-               mysignal(SIGALRM, updateprogressmeter);
-               alarm(PROGRESSTIME);
-       } else if (flag == 1) {
-               alarm(0);
-               atomicio(write, fileno(stdout), "\n", 1);
-               statbytes = 0;
-       }
-}
-
-int
-getttywidth(void)
-{
-       struct winsize winsize;
-
-       if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1)
-               return (winsize.ws_col ? winsize.ws_col : 80);
-       else
-               return (80);
-}
index bff37073c4f44c719b98004d54950ceecfb86c99..e0d3ad5682342b363b96c02dfe2389377a3f1556 100644 (file)
@@ -28,7 +28,7 @@
 /* XXX: copy between two remote sites */
 
 #include "includes.h"
-RCSID("$OpenBSD: sftp-client.c,v 1.38 2003/01/06 23:51:22 djm Exp $");
+RCSID("$OpenBSD: sftp-client.c,v 1.39 2003/01/10 08:19:07 fgsch Exp $");
 
 #include "openbsd-compat/sys-queue.h"
 
@@ -38,11 +38,14 @@ RCSID("$OpenBSD: sftp-client.c,v 1.38 2003/01/06 23:51:22 djm Exp $");
 #include "xmalloc.h"
 #include "log.h"
 #include "atomicio.h"
+#include "progressmeter.h"
 
 #include "sftp.h"
 #include "sftp-common.h"
 #include "sftp-client.h"
 
+extern int showprogress;
+
 /* Minimum amount of data to read at at time */
 #define MIN_READ_SIZE  512
 
@@ -741,6 +744,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
        int read_error, write_errno;
        u_int64_t offset, size;
        u_int handle_len, mode, type, id, buflen;
+       off_t progress_counter;
        struct request {
                u_int id;
                u_int len;
@@ -806,6 +810,16 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
        /* Read from remote and write to local */
        write_error = read_error = write_errno = num_req = offset = 0;
        max_req = 1;
+       progress_counter = 0;
+
+       if (showprogress) {
+               if (size)
+                       start_progress_meter(remote_path, size,
+                           &progress_counter);
+               else
+                       printf("Fetching %s to %s\n", remote_path, local_path);
+       }
+
        while (num_req > 0 || max_req > 0) {
                char *data;
                u_int len;
@@ -866,6 +880,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                                write_error = 1;
                                max_req = 0;
                        }
+                       progress_counter += len;
                        xfree(data);
 
                        if (len == req->len) {
@@ -908,6 +923,9 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
                }
        }
 
+       if (showprogress && size)
+               stop_progress_meter();
+
        /* Sanity check */
        if (TAILQ_FIRST(&requests) != NULL)
                fatal("Transfer complete, but requests still in queue");
@@ -1018,6 +1036,11 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
 
        /* Read from local and write to remote */
        offset = 0;
+       if (showprogress)
+               start_progress_meter(local_path, sb.st_size, &offset);
+       else
+               printf("Uploading %s to %s\n", local_path, remote_path);
+
        for (;;) {
                int len;
 
@@ -1094,6 +1117,8 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
                }
                offset += len;
        }
+       if (showprogress)
+               stop_progress_meter();
        xfree(data);
 
        if (close(local_fd) == -1) {
index f2c8fa6dc5c7a03f55ee80c418d6ef459f4c0065..88b0530ab94c7c7ba32e89b22eb4a4f85507df6e 100644 (file)
@@ -25,7 +25,7 @@
 /* XXX: recursive operations */
 
 #include "includes.h"
-RCSID("$OpenBSD: sftp-int.c,v 1.51 2003/01/08 23:53:26 djm Exp $");
+RCSID("$OpenBSD: sftp-int.c,v 1.52 2003/01/10 08:19:07 fgsch Exp $");
 
 #include "buffer.h"
 #include "xmalloc.h"
@@ -47,6 +47,9 @@ extern size_t copy_buffer_len;
 /* Number of concurrent outstanding requests */
 extern int num_requests;
 
+/* This is set to 0 if the progressmeter is not desired. */
+int showprogress = 1;
+
 /* Seperators for interactive commands */
 #define WHITESPACE " \t\r\n"
 
@@ -73,6 +76,7 @@ extern int num_requests;
 #define I_SHELL                20
 #define I_SYMLINK      21
 #define I_VERSION      22
+#define I_PROGRESS     23
 
 struct CMD {
        const char *c;
@@ -100,6 +104,7 @@ const struct CMD cmds[] = {
        { "ls",         I_LS },
        { "lumask",     I_LUMASK },
        { "mkdir",      I_MKDIR },
+       { "progress",   I_PROGRESS },
        { "put",        I_PUT },
        { "mput",       I_PUT },
        { "pwd",        I_PWD },
@@ -132,6 +137,7 @@ help(void)
        printf("ls [path]                     Display remote directory listing\n");
        printf("lumask umask                  Set local umask to 'umask'\n");
        printf("mkdir path                    Create remote directory\n");
+       printf("preogress                     Toggle display of progress meter\n");
        printf("put local-path [remote-path]  Upload file\n");
        printf("pwd                           Display remote working directory\n");
        printf("exit                          Quit sftp\n");
@@ -425,7 +431,6 @@ process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
                        err = -1;
                        goto out;
                }
-               printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);
                err = do_download(conn, g.gl_pathv[0], abs_dst, pflag);
                goto out;
        }
@@ -507,7 +512,6 @@ process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
                        }
                        abs_dst = make_absolute(abs_dst, pwd);
                }
-               printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst);
                err = do_upload(conn, g.gl_pathv[0], abs_dst, pflag);
                goto out;
        }
@@ -810,6 +814,7 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
        case I_LPWD:
        case I_HELP:
        case I_VERSION:
+       case I_PROGRESS:
                break;
        default:
                fatal("Command not implemented");
@@ -1015,6 +1020,13 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
        case I_VERSION:
                printf("SFTP protocol version %u\n", sftp_proto_version(conn));
                break;
+       case I_PROGRESS:
+               showprogress = !showprogress;
+               if (showprogress)
+                       printf("Progress meter enabled\n");
+               else
+                       printf("Progress meter disabled\n");
+               break;
        default:
                fatal("%d is not implemented", cmdnum);
        }
diff --git a/sftp.1 b/sftp.1
index 67086bdaa58cf9bc4e65764af8c6ebf4cd9f036b..ecd4d31748c8adba0421246536df7fddedf1e803 100644 (file)
--- a/sftp.1
+++ b/sftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.39 2003/01/08 23:53:26 djm Exp $
+.\" $OpenBSD: sftp.1,v 1.40 2003/01/10 08:19:07 fgsch Exp $
 .\"
 .\" Copyright (c) 2001 Damien Miller.  All rights reserved.
 .\"
@@ -228,6 +228,8 @@ Set local umask to
 .It Ic mkdir Ar path
 Create remote directory specified by
 .Ar path .
+.It Ic progress
+Toggle display of progress meter.
 .It Xo Ic put
 .Op Ar flags
 .Ar local-path
diff --git a/sftp.c b/sftp.c
index d62e9e42c80b25de4bc7d46845f0d8a7180a2f93..e8adcba18f656d1adb060c2486d78df11c58ae79 100644 (file)
--- a/sftp.c
+++ b/sftp.c
@@ -24,7 +24,7 @@
 
 #include "includes.h"
 
-RCSID("$OpenBSD: sftp.c,v 1.33 2003/01/08 23:53:26 djm Exp $");
+RCSID("$OpenBSD: sftp.c,v 1.34 2003/01/10 08:19:07 fgsch Exp $");
 
 /* XXX: short-form remote directory listings (like 'ls -C') */
 
@@ -49,6 +49,8 @@ FILE* infile;
 size_t copy_buffer_len = 32768;
 size_t num_requests = 16;
 
+extern int showprogress;
+
 static void
 connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid)
 {
@@ -162,6 +164,7 @@ main(int argc, char **argv)
                                        fatal("%s (%s).", strerror(errno), optarg);
                        } else
                                fatal("Filename already specified.");
+                       showprogress = 0;
                        break;
                case 'P':
                        sftp_direct = optarg;
This page took 1.964084 seconds and 5 git commands to generate.