summaryrefslogtreecommitdiff
path: root/scp.c
diff options
context:
space:
mode:
Diffstat (limited to 'scp.c')
-rw-r--r--scp.c80
1 files changed, 76 insertions, 4 deletions
diff --git a/scp.c b/scp.c
index 616dd3783..ae0a1ead6 100644
--- a/scp.c
+++ b/scp.c
@@ -75,7 +75,7 @@
75 */ 75 */
76 76
77#include "includes.h" 77#include "includes.h"
78RCSID("$OpenBSD: scp.c,v 1.98 2003/01/10 10:29:35 djm Exp $"); 78RCSID("$OpenBSD: scp.c,v 1.99 2003/01/23 14:01:53 markus Exp $");
79 79
80#include "xmalloc.h" 80#include "xmalloc.h"
81#include "atomicio.h" 81#include "atomicio.h"
@@ -90,9 +90,14 @@ extern char *__progname;
90char *__progname; 90char *__progname;
91#endif 91#endif
92 92
93void bwlimit(int);
94
93/* Struct for addargs */ 95/* Struct for addargs */
94arglist args; 96arglist args;
95 97
98/* Bandwidth limit */
99off_t limit = 0;
100
96/* Name of current file being transferred. */ 101/* Name of current file being transferred. */
97char *curfile; 102char *curfile;
98 103
@@ -206,7 +211,8 @@ main(argc, argv)
206 char *argv[]; 211 char *argv[];
207{ 212{
208 int ch, fflag, tflag, status; 213 int ch, fflag, tflag, status;
209 char *targ; 214 double speed;
215 char *targ, *endp;
210 extern char *optarg; 216 extern char *optarg;
211 extern int optind; 217 extern int optind;
212 218
@@ -219,7 +225,7 @@ main(argc, argv)
219 addargs(&args, "-oClearAllForwardings yes"); 225 addargs(&args, "-oClearAllForwardings yes");
220 226
221 fflag = tflag = 0; 227 fflag = tflag = 0;
222 while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:F:")) != -1) 228 while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q46S:o:F:")) != -1)
223 switch (ch) { 229 switch (ch) {
224 /* User-visible flags. */ 230 /* User-visible flags. */
225 case '4': 231 case '4':
@@ -239,6 +245,12 @@ main(argc, argv)
239 case 'B': 245 case 'B':
240 addargs(&args, "-oBatchmode yes"); 246 addargs(&args, "-oBatchmode yes");
241 break; 247 break;
248 case 'l':
249 speed = strtod(optarg, &endp);
250 if (speed <= 0 || *endp != '\0')
251 usage();
252 limit = speed * 1024;
253 break;
242 case 'p': 254 case 'p':
243 pflag = 1; 255 pflag = 1;
244 break; 256 break;
@@ -578,6 +590,8 @@ next: (void) close(fd);
578 haderr = result >= 0 ? EIO : errno; 590 haderr = result >= 0 ? EIO : errno;
579 statbytes += result; 591 statbytes += result;
580 } 592 }
593 if (limit)
594 bwlimit(amt);
581 } 595 }
582 if (showprogress) 596 if (showprogress)
583 stop_progress_meter(); 597 stop_progress_meter();
@@ -648,6 +662,60 @@ rsource(name, statp)
648} 662}
649 663
650void 664void
665bwlimit(int amount)
666{
667 static struct timeval bwstart, bwend;
668 static int lamt, thresh = 16384;
669 u_int64_t wait;
670 struct timespec ts, rm;
671
672 if (!timerisset(&bwstart)) {
673 gettimeofday(&bwstart, NULL);
674 return;
675 }
676
677 lamt += amount;
678 if (lamt < thresh)
679 return;
680
681 gettimeofday(&bwend, NULL);
682 timersub(&bwend, &bwstart, &bwend);
683 if (!timerisset(&bwend))
684 return;
685
686 lamt *= 8;
687 wait = (double)1000000L * lamt / limit;
688
689 bwstart.tv_sec = wait / 1000000L;
690 bwstart.tv_usec = wait % 1000000L;
691
692 if (timercmp(&bwstart, &bwend, >)) {
693 timersub(&bwstart, &bwend, &bwend);
694
695 /* Adjust the wait time */
696 if (bwend.tv_sec) {
697 thresh /= 2;
698 if (thresh < 2048)
699 thresh = 2048;
700 } else if (bwend.tv_usec < 100) {
701 thresh *= 2;
702 if (thresh > 32768)
703 thresh = 32768;
704 }
705
706 TIMEVAL_TO_TIMESPEC(&bwend, &ts);
707 while (nanosleep(&ts, &rm) == -1) {
708 if (errno != EINTR)
709 break;
710 ts = rm;
711 }
712 }
713
714 lamt = 0;
715 gettimeofday(&bwstart, NULL);
716}
717
718void
651sink(argc, argv) 719sink(argc, argv)
652 int argc; 720 int argc;
653 char *argv[]; 721 char *argv[];
@@ -844,6 +912,10 @@ bad: run_err("%s: %s", np, strerror(errno));
844 cp += j; 912 cp += j;
845 statbytes += j; 913 statbytes += j;
846 } while (amt > 0); 914 } while (amt > 0);
915
916 if (limit)
917 bwlimit(4096);
918
847 if (count == bp->cnt) { 919 if (count == bp->cnt) {
848 /* Keep reading so we stay sync'd up. */ 920 /* Keep reading so we stay sync'd up. */
849 if (wrerr == NO) { 921 if (wrerr == NO) {
@@ -954,7 +1026,7 @@ usage(void)
954{ 1026{
955 (void) fprintf(stderr, 1027 (void) fprintf(stderr,
956 "usage: scp [-pqrvBC46] [-F config] [-S program] [-P port]\n" 1028 "usage: scp [-pqrvBC46] [-F config] [-S program] [-P port]\n"
957 " [-c cipher] [-i identity] [-o option]\n" 1029 " [-c cipher] [-i identity] [-l limit] [-o option]\n"
958 " [[user@]host1:]file1 [...] [[user@]host2:]file2\n"); 1030 " [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
959 exit(1); 1031 exit(1);
960} 1032}