SFTP Status Bar..

mouring mouring at etoh.eviladmin.org
Thu Feb 7 07:56:54 EST 2002


It is default on, but as what William pointed out single gets
seem not to trigger it for some odd reason (looking into it now).

- Ben

> how do you "turn it on"?  is it automatic/default?
> 
> mouring wrote:
> > 
> > This is the LAST version I plan on doing.. If I hear no feed back good
> > or bad.  Then I'll assume I've wasted my time on a feature that people
> > whine about but don't care to try.  This is against 3.0.2pX so it
> > should be VERY easy for anyone to test.
> > 
> > - Ben
> > 
> > diff -ur openssh-3.0.2p1/misc.c openssh/misc.c
> > --- openssh-3.0.2p1/misc.c      Tue Jul  3 23:46:58 2001
> > +++ openssh/misc.c      Wed Feb  6 13:15:55 2002
> > @@ -30,6 +30,7 @@
> >  #include "misc.h"
> >  #include "log.h"
> >  #include "xmalloc.h"
> > +#include "atomicio.h"
> > 
> >  /* remove newline at end of string */
> >  char *
> > @@ -304,6 +305,139 @@
> >         args->list = xrealloc(args->list, args->nalloc * sizeof(char *));
> >         args->list[args->num++] = xstrdup(buf);
> >         args->list[args->num] = NULL;
> > +}
> > +
> > +/* scp/sftp progression meter (from src/usr.bin/ftp/util.c) */
> > +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));
> > +}
> > +
> > +int
> > +getttywidth(void)
> > +{
> > +       struct winsize winsize;
> > +
> > +       if (ioctl(fileno(stdout), TIOCGWINSZ, &winsize) != -1)
> > +               return (winsize.ws_col ? winsize.ws_col : 80);
> > +       else
> > +               return (80);
> > +}
> > +
> > +void
> > +progressmeter(off_t statbytes, off_t totalbytes, char *filename)
> > +{
> > +#define STALLTIME       5 /* number of seconds before xfer assumed "stalled" */
> > +       static const char prefixes[] = " KMGTP";
> > +       static char *progressbar = NULL;
> > +       static struct timeval *start = NULL, lastupdate;
> > +       static off_t lastsize;
> > +       static size_t progressbar_size = 0;
> > +       struct timeval now, td, wait;
> > +       off_t cursize, abbrevsize;
> > +       double elapsed;
> > +       int ratio, barlength, i, remaining;
> > +       char buf[256];
> > +
> > +       if (!start) {
> > +               start = xmalloc(sizeof(struct timeval));
> > +               (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;
> > +
> > +       barlength = getttywidth() - 51;
> > +       if (barlength > progressbar_size) {
> > +               progressbar_size = barlength;
> > +               progressbar = xrealloc(progressbar, barlength);
> > +               memset(progressbar, '*', barlength);
> > +       }
> > +
> > +       snprintf(buf, sizeof(buf), "\r%-20.20s %3d%% ",
> > +           (filename?filename:""), ratio);
> > +       if (barlength > 0) {
> > +               i = barlength * ratio / 100;
> > +               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
> > +                        "|%.*s%*s|", i, progressbar, barlength - i, "");
> > +       }
> > +       i = 0;
> > +       abbrevsize = cursize;
> > +       while (abbrevsize >= 100000 && i < sizeof(prefixes)) {
> > +               i++;
> > +               abbrevsize >>= 10;
> > +       }
> > +       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5llu %c%c ",
> > +           (unsigned long long) abbrevsize, prefixes[i],
> > +           prefixes[i] == ' ' ? ' ' : 'B');
> > +
> > +       timersub(&now, &lastupdate, &wait);
> > +       if (cursize > lastsize) {
> > +               lastupdate = now;
> > +               lastsize = cursize;
> > +               if (wait.tv_sec >= STALLTIME) {
> > +                       start->tv_sec += wait.tv_sec;
> > +                       start->tv_usec += wait.tv_usec;
> > +               }
> > +               wait.tv_sec = 0;
> > +       }
> > +       timersub(&now, start, &td);
> > +       elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
> > +
> > +       if ((totalbytes != statbytes) &&
> > +           (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 (totalbytes != statbytes)
> > +                       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,
> > +                     (totalbytes != statbytes) ? " ETA" : "    ");
> > +       }
> > +       atomicio(write, fileno(stdout), buf, strlen(buf));
> > +
> > +       if (totalbytes == statbytes) {
> > +               atomicio(write, fileno(stdout), "\n", 1);
> > +
> > +               /* Clean up for next usage */
> > +               xfree(start);
> > +               start = NULL;
> > +               statbytes = 0;
> > +       }
> >  }
> > 
> >  mysig_t
> > Only in openssh: misc.c.orig
> > diff -ur openssh-3.0.2p1/misc.h openssh/misc.h
> > --- openssh-3.0.2p1/misc.h      Wed Jul  4 12:25:55 2001
> > +++ openssh/misc.h      Wed Feb  6 13:02:33 2002
> > @@ -29,7 +29,11 @@
> >          int     num;
> >          int     nalloc;
> >  };
> > +
> >  void    addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3)));
> > +void    progressmeter(off_t statbytes, off_t totalbytes, char *curfile);
> > +
> > +#define PROGRESSTIME    1 /* alarm() interval for updating progress meter */
> > 
> >  /* wrapper for signal interface */
> >  typedef void (*mysig_t)(int);
> > diff -ur openssh-3.0.2p1/scp.c openssh/scp.c
> > --- openssh-3.0.2p1/scp.c       Sun Oct 21 19:53:59 2001
> > +++ openssh/scp.c       Wed Feb  6 13:07:33 2002
> > @@ -89,32 +89,12 @@
> >  char *__progname;
> >  #endif
> > 
> > -/* For progressmeter() -- number of seconds before xfer considered "stalled" */
> > -#define STALLTIME      5
> > -/* alarm() interval for updating progress meter */
> > -#define PROGRESSTIME   1
> > -
> > -/* Progress meter bar */
> > -#define BAR \
> > -       "************************************************************"\
> > -       "************************************************************"\
> > -       "************************************************************"\
> > -       "************************************************************"
> > -#define MAX_BARLENGTH (sizeof(BAR) - 1)
> > -
> > -/* Visual statistics about files as they are transferred. */
> > -void progressmeter(int);
> > -
> > -/* Returns width of the terminal (for progress meter calculations). */
> > -int getttywidth(void);
> > +static void updateprogressmeter(int done);
> >  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;
> > 
> > @@ -569,7 +549,7 @@
> >                 }
> >                 if (showprogress) {
> >                         totalbytes = stb.st_size;
> > -                       progressmeter(-1);
> > +                       updateprogressmeter(0);
> >                 }
> >                 /* Keep writing after an error so that we stay sync'd up. */
> >                 for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
> > @@ -591,7 +571,7 @@
> >                         }
> >                 }
> >                 if (showprogress)
> > -                       progressmeter(1);
> > +                       updateprogressmeter(1);
> > 
> >                 if (close(fd) < 0 && !haderr)
> >                         haderr = errno;
> > @@ -835,7 +815,7 @@
> > 
> >                 if (showprogress) {
> >                         totalbytes = size;
> > -                       progressmeter(-1);
> > +                       updateprogressmeter(0);
> >                 }
> >                 statbytes = 0;
> >                 for (count = i = 0; i < size; i += 4096) {
> > @@ -871,7 +851,8 @@
> >                         }
> >                 }
> >                 if (showprogress)
> > -                       progressmeter(1);
> > +                       updateprogressmeter(1);
> > +
> >                 if (count != 0 && wrerr == NO &&
> >                     (j = atomicio(write, ofd, bp->buf, count)) != count) {
> >                         wrerr = YES;
> > @@ -1079,140 +1060,17 @@
> >  }
> > 
> >  static void
> > -updateprogressmeter(int ignore)
> > +updateprogressmeter(int done)
> >  {
> > -       int save_errno = errno;
> > -
> > -       progressmeter(0);
> > -       mysignal(SIGALRM, updateprogressmeter);
> > -       alarm(PROGRESSTIME);
> > -       errno = save_errno;
> > -}
> > -
> > -static int
> > -foregroundproc(void)
> > -{
> > -       static pid_t pgrp = -1;
> > -       int ctty_pgrp;
> > -
> > -       if (pgrp == -1)
> > -               pgrp = getpgrp();
> > +        int save_errno = errno;
> > 
> > -#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 prefixes[] = " KMGTP";
> > -       static struct timeval lastupdate;
> > -       static off_t lastsize;
> > -       struct timeval now, td, wait;
> > -       off_t cursize, abbrevsize;
> > -       double elapsed;
> > -       int ratio, barlength, i, remaining;
> > -       char buf[256];
> > -
> > -       if (flag == -1) {
> > -               (void) gettimeofday(&start, (struct timezone *) 0);
> > -               lastupdate = start;
> > -               lastsize = 0;
> > -       }
> > -       if (foregroundproc() == 0)
> > -               return;
> > +        progressmeter(statbytes, totalbytes, curfile);
> > +        if (done == 0) {
> > +                mysignal(SIGALRM, updateprogressmeter);
> > +                alarm(PROGRESSTIME);
> > +        } else
> > +                alarm(0);
> > 
> > -       (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;
> > -
> > -       snprintf(buf, sizeof(buf), "\r%-20.20s %3d%% ", curfile, ratio);
> > -
> > -       barlength = getttywidth() - 51;
> > -       barlength = (barlength <= MAX_BARLENGTH)?barlength:MAX_BARLENGTH;
> > -       if (barlength > 0) {
> > -               i = barlength * ratio / 100;
> > -               snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
> > -                        "|%.*s%*s|", i, BAR, barlength - i, "");
> > -       }
> > -       i = 0;
> > -       abbrevsize = cursize;
> > -       while (abbrevsize >= 100000 && i < sizeof(prefixes)) {
> > -               i++;
> > -               abbrevsize >>= 10;
> > -       }
> > -       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5lu %c%c ",
> > -           (unsigned long) abbrevsize, prefixes[i],
> > -           prefixes[i] == ' ' ? ' ' : 'B');
> > -
> > -       timersub(&now, &lastupdate, &wait);
> > -       if (cursize > lastsize) {
> > -               lastupdate = now;
> > -               lastsize = cursize;
> > -               if (wait.tv_sec >= STALLTIME) {
> > -                       start.tv_sec += wait.tv_sec;
> > -                       start.tv_usec += wait.tv_usec;
> > -               }
> > -               wait.tv_sec = 0;
> > -       }
> > -       timersub(&now, &start, &td);
> > -       elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
> > -
> > -       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);
> > +        errno = save_errno;
> >  }
> > diff -ur openssh-3.0.2p1/sftp-client.c openssh/sftp-client.c
> > --- openssh-3.0.2p1/sftp-client.c       Wed Jul 18 10:45:45 2001
> > +++ openssh/sftp-client.c       Wed Feb  6 13:02:34 2002
> > @@ -49,6 +49,11 @@
> >  /* Message ID */
> >  static u_int msg_id = 1;
> > 
> > +/* Progress Meter items */
> > +off_t statbytes = 0;
> > +off_t totalbytes = 0;
> > +char *curfile = NULL;
> > +
> >  static void
> >  send_msg(int fd, Buffer *m)
> >  {
> > @@ -671,7 +676,7 @@
> > 
> >  int
> >  do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
> > -    int pflag)
> > +    int pflag, void (*progressbar)(int))
> >  {
> >         int local_fd;
> >         u_int expected_id, handle_len, mode, type, id;
> > @@ -724,6 +729,11 @@
> >                 return(-1);
> >         }
> > 
> > +       totalbytes  = a->size;
> > +       curfile = remote_path;
> > +       if (progressbar)
> > +               (progressbar)(0);
> > +
> >         /* Read from remote and write to local */
> >         offset = 0;
> >         for(;;) {
> > @@ -785,6 +795,7 @@
> > 
> >                 offset += len;
> >                 xfree(data);
> > +               statbytes = offset;
> >         }
> >         status = do_close(fd_in, fd_out, handle, handle_len);
> > 
> > @@ -807,15 +818,18 @@
> >         }
> > 
> >  done:
> > +       if (progressbar)
> > +               (progressbar)(1);
> >         close(local_fd);
> >         buffer_free(&msg);
> >         xfree(handle);
> > +
> >         return status;
> >  }
> > 
> >  int
> >  do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
> > -    int pflag)
> > +    int pflag, void (*progressbar)(int))
> >  {
> >         int local_fd;
> >         u_int handle_len, id;
> > @@ -865,6 +879,10 @@
> >                 buffer_free(&msg);
> >                 return(-1);
> >         }
> > +       totalbytes  = a.size;
> > +       curfile = local_path;
> > +       if (progressbar)
> > +               (progressbar)(0);
> > 
> >         /* Read from local and write to remote */
> >         offset = 0;
> > @@ -908,6 +926,7 @@
> >                     (u_int64_t)offset);
> > 
> >                 offset += len;
> > +               statbytes = offset;
> >         }
> > 
> >         if (close(local_fd) == -1) {
> > @@ -925,8 +944,10 @@
> >         status = do_close(fd_in, fd_out, handle, handle_len);
> > 
> >  done:
> > +       if (progressbar)
> > +               (progressbar)(1);
> >         xfree(handle);
> >         buffer_free(&msg);
> > +
> >         return status;
> >  }
> > -
> > diff -ur openssh-3.0.2p1/sftp-client.h openssh/sftp-client.h
> > --- openssh-3.0.2p1/sftp-client.h       Tue Jul  3 23:07:13 2001
> > +++ openssh/sftp-client.h       Wed Feb  6 13:02:34 2002
> > @@ -88,16 +88,14 @@
> >  /* Return target of symlink 'path' - caller must free result */
> >  char *do_readlink(int, int, char *);
> > 
> > -/* XXX: add callbacks to do_download/do_upload so we can do progress meter */
> > -
> >  /*
> >   * Download 'remote_path' to 'local_path'. Preserve permissions and times
> >   * if 'pflag' is set
> >   */
> > -int do_download(int, int, char *, char *, int);
> > +int do_download(int, int, char *, char *, int, void (*)(int));
> > 
> >  /*
> >   * Upload 'local_path' to 'remote_path'. Preserve permissions and times
> >   * if 'pflag' is set
> >   */
> > -int do_upload(int, int, char *, char *, int);
> > +int do_upload(int, int, char *, char *, int, void (*)(int));
> > diff -ur openssh-3.0.2p1/sftp-int.c openssh/sftp-int.c
> > --- openssh-3.0.2p1/sftp-int.c  Wed Aug 15 18:22:57 2001
> > +++ openssh/sftp-int.c  Wed Feb  6 13:02:34 2002
> > @@ -32,6 +32,7 @@
> >  #include "xmalloc.h"
> >  #include "log.h"
> >  #include "pathnames.h"
> > +#include "misc.h"
> > 
> >  #include "sftp.h"
> >  #include "sftp-common.h"
> > @@ -113,6 +114,24 @@
> >  };
> > 
> >  static void
> > +updateprogressmeter(int done)
> > +{
> > +        int save_errno = errno;
> > +       extern off_t statbytes;
> > +       extern off_t totalbytes;
> > +       extern char *curfile;
> > +
> > +        progressmeter(statbytes, totalbytes, curfile);
> > +       if (done == 0) {
> > +               mysignal(SIGALRM, updateprogressmeter);
> > +               alarm(PROGRESSTIME);
> > +       } else
> > +               alarm(0);
> > +
> > +        errno = save_errno;
> > +}
> > +
> > +static void
> >  help(void)
> >  {
> >         printf("Available commands:\n");
> > @@ -380,8 +399,8 @@
> >                         err = -1;
> >                         goto out;
> >                 }
> > -               printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);
> > -               err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag);
> > +               err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag,
> > +                   NULL);
> >                 goto out;
> >         }
> > 
> > @@ -404,8 +423,8 @@
> >                 } else
> >                         abs_dst = tmp;
> > 
> > -               printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
> > -               if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
> > +               if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag,
> > +                   updateprogressmeter) == -1)
> >                         err = -1;
> >                 xfree(abs_dst);
> >                 abs_dst = NULL;
> > @@ -462,8 +481,8 @@
> >                         }
> >                         abs_dst = make_absolute(abs_dst, pwd);
> >                 }
> > -               printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst);
> > -               err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag);
> > +               err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag,
> > +                   updateprogressmeter);
> >                 goto out;
> >         }
> > 
> > @@ -486,8 +505,8 @@
> >                 } else
> >                         abs_dst = make_absolute(tmp, pwd);
> > 
> > -               printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
> > -               if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
> > +               if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag,
> > +                   updateprogressmeter) == -1)
> >                         err = -1;
> >         }
> > 
> > _______________________________________________
> > openssh-unix-dev at mindrot.org mailing list
> > http://www.mindrot.org/mailman/listinfo/openssh-unix-dev
> 
> -- 
> wendy palm
> Cray OS Sustaining Engineering, Cray Inc.
> wendyp at cray.com, 651-605-9154
> 




More information about the openssh-unix-dev mailing list