]> andersk Git - openssh.git/commitdiff
- markus@cvs.openbsd.org 2003/01/23 14:01:53
authordjm <djm>
Fri, 24 Jan 2003 00:36:58 +0000 (00:36 +0000)
committerdjm <djm>
Fri, 24 Jan 2003 00:36:58 +0000 (00:36 +0000)
     [scp.c]
     bandwidth limitation patch (scp -l) from niels@; ok todd@, deraadt@

ChangeLog
scp.c

index 43c50412fda6212c227b74e4ba339ebf09834b08..56197a2d0e4166c098d845a6de939d0adfa98e85 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,9 @@
      ssh-add -c, prompt user for confirmation (using ssh-askpass) when
      private agent key is used; with djm@; test by dugsong@, djm@; 
      ok deraadt@
+   - markus@cvs.openbsd.org 2003/01/23 14:01:53
+     [scp.c]
+     bandwidth limitation patch (scp -l) from niels@; ok todd@, deraadt@
 
 20030123
  - (djm) OpenBSD CVS Sync
diff --git a/scp.c b/scp.c
index 616dd3783a3d0e2664a7405a7ee7898813a62f13..ae0a1ead66c676198abb4d5e6c1eb75eba31b190 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -75,7 +75,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: scp.c,v 1.98 2003/01/10 10:29:35 djm Exp $");
+RCSID("$OpenBSD: scp.c,v 1.99 2003/01/23 14:01:53 markus Exp $");
 
 #include "xmalloc.h"
 #include "atomicio.h"
@@ -90,9 +90,14 @@ extern char *__progname;
 char *__progname;
 #endif
 
+void bwlimit(int);
+
 /* Struct for addargs */
 arglist args;
 
+/* Bandwidth limit */
+off_t limit = 0;
+
 /* Name of current file being transferred. */
 char *curfile;
 
@@ -206,7 +211,8 @@ main(argc, argv)
        char *argv[];
 {
        int ch, fflag, tflag, status;
-       char *targ;
+       double speed;
+       char *targ, *endp;
        extern char *optarg;
        extern int optind;
 
@@ -219,7 +225,7 @@ main(argc, argv)
        addargs(&args, "-oClearAllForwardings yes");
 
        fflag = tflag = 0;
-       while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:F:")) != -1)
+       while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q46S:o:F:")) != -1)
                switch (ch) {
                /* User-visible flags. */
                case '4':
@@ -239,6 +245,12 @@ main(argc, argv)
                case 'B':
                        addargs(&args, "-oBatchmode yes");
                        break;
+               case 'l':
+                       speed = strtod(optarg, &endp);
+                       if (speed <= 0 || *endp != '\0')
+                               usage();
+                       limit = speed * 1024;
+                       break;
                case 'p':
                        pflag = 1;
                        break;
@@ -578,6 +590,8 @@ next:                       (void) close(fd);
                                        haderr = result >= 0 ? EIO : errno;
                                statbytes += result;
                        }
+                       if (limit)
+                               bwlimit(amt);
                }
                if (showprogress)
                        stop_progress_meter();
@@ -647,6 +661,60 @@ rsource(name, statp)
        (void) response();
 }
 
+void
+bwlimit(int amount)
+{
+       static struct timeval bwstart, bwend;
+       static int lamt, thresh = 16384;
+       u_int64_t wait;
+       struct timespec ts, rm;
+
+       if (!timerisset(&bwstart)) {
+               gettimeofday(&bwstart, NULL);
+               return;
+       }
+
+       lamt += amount;
+       if (lamt < thresh)
+               return;
+
+       gettimeofday(&bwend, NULL);
+       timersub(&bwend, &bwstart, &bwend);
+       if (!timerisset(&bwend))
+               return;
+
+       lamt *= 8;
+       wait = (double)1000000L * lamt / limit;
+
+       bwstart.tv_sec = wait / 1000000L;
+       bwstart.tv_usec = wait % 1000000L;
+
+       if (timercmp(&bwstart, &bwend, >)) {
+               timersub(&bwstart, &bwend, &bwend);
+
+               /* Adjust the wait time */
+               if (bwend.tv_sec) {
+                       thresh /= 2;
+                       if (thresh < 2048)
+                               thresh = 2048;
+               } else if (bwend.tv_usec < 100) {
+                       thresh *= 2;
+                       if (thresh > 32768)
+                               thresh = 32768;
+               }
+
+               TIMEVAL_TO_TIMESPEC(&bwend, &ts);
+               while (nanosleep(&ts, &rm) == -1) {
+                       if (errno != EINTR)
+                               break;
+                       ts = rm;
+               }
+       }
+
+       lamt = 0;
+       gettimeofday(&bwstart, NULL);
+}
+
 void
 sink(argc, argv)
        int argc;
@@ -844,6 +912,10 @@ bad:                       run_err("%s: %s", np, strerror(errno));
                                cp += j;
                                statbytes += j;
                        } while (amt > 0);
+               
+                       if (limit)
+                               bwlimit(4096);
+
                        if (count == bp->cnt) {
                                /* Keep reading so we stay sync'd up. */
                                if (wrerr == NO) {
@@ -954,7 +1026,7 @@ usage(void)
 {
        (void) fprintf(stderr,
            "usage: scp [-pqrvBC46] [-F config] [-S program] [-P port]\n"
-           "           [-c cipher] [-i identity] [-o option]\n"
+           "           [-c cipher] [-i identity] [-l limit] [-o option]\n"
            "           [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
        exit(1);
 }
This page took 0.813229 seconds and 5 git commands to generate.