diff options
author | djm@openbsd.org <djm@openbsd.org> | 2022-12-16 04:40:03 +0100 |
---|---|---|
committer | Darren Tucker <dtucker@dtucker.net> | 2023-01-03 07:53:05 +0100 |
commit | e555d5cad5afae7d5ef2bbc02ca591178fe16fed (patch) | |
tree | f2e5e2745aff59bc4fd6d9cc96822d6ce7d92a9d /scp.c | |
parent | upstream: The idiomatic way of coping with signed char vs unsigned (diff) | |
download | openssh-e555d5cad5afae7d5ef2bbc02ca591178fe16fed.tar.xz openssh-e555d5cad5afae7d5ef2bbc02ca591178fe16fed.zip |
upstream: add a -X option to both scp(1) and sftp(1) to allow
control over some SFTP protocol knobs: the copy buffer length and
the number of inflight requests, both of which are used during
upload/download.
Previously these could be controlled in sftp(1) using the -b/-R options.
This makes them available in both SFTP protocol clients using the same
option character sequence.
ok dtucker@
OpenBSD-Commit-ID: 27502bffc589776f5da1f31df8cb51abe9a15f1c
Diffstat (limited to 'scp.c')
-rw-r--r-- | scp.c | 42 |
1 files changed, 38 insertions, 4 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.249 2022/10/24 21:51:55 djm Exp $ */ +/* $OpenBSD: scp.c,v 1.250 2022/12/16 03:40:03 djm Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -106,6 +106,9 @@ #include <libgen.h> #endif #include <limits.h> +#ifdef HAVE_UTIL_H +# include <util.h> +#endif #include <locale.h> #include <pwd.h> #include <signal.h> @@ -176,6 +179,10 @@ char *ssh_program = _PATH_SSH_PROGRAM; pid_t do_cmd_pid = -1; pid_t do_cmd_pid2 = -1; +/* SFTP copy parameters */ +size_t sftp_copy_buflen; +size_t sftp_nrequests; + /* Needed for sftp */ volatile sig_atomic_t interrupted = 0; @@ -444,13 +451,14 @@ void throughlocal_sftp(struct sftp_conn *, struct sftp_conn *, int main(int argc, char **argv) { - int ch, fflag, tflag, status, n; + int ch, fflag, tflag, status, r, n; char **newargv, *argv0; const char *errstr; extern char *optarg; extern int optind; enum scp_mode_e mode = MODE_SFTP; char *sftp_direct = NULL; + long long llv; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); @@ -480,7 +488,7 @@ main(int argc, char **argv) fflag = Tflag = tflag = 0; while ((ch = getopt(argc, argv, - "12346ABCTdfOpqRrstvD:F:J:M:P:S:c:i:l:o:")) != -1) { + "12346ABCTdfOpqRrstvD:F:J:M:P:S:c:i:l:o:X:")) != -1) { switch (ch) { /* User-visible flags. */ case '1': @@ -561,6 +569,31 @@ main(int argc, char **argv) addargs(&remote_remote_args, "-q"); showprogress = 0; break; + case 'X': + /* Please keep in sync with sftp.c -X */ + if (strncmp(optarg, "buffer=", 7) == 0) { + r = scan_scaled(optarg + 7, &llv); + if (r == 0 && (llv <= 0 || llv > 256 * 1024)) { + r = -1; + errno = EINVAL; + } + if (r == -1) { + fatal("Invalid buffer size \"%s\": %s", + optarg + 7, strerror(errno)); + } + sftp_copy_buflen = (size_t)llv; + } else if (strncmp(optarg, "nrequests=", 10) == 0) { + llv = strtonum(optarg + 10, 1, 256 * 1024, + &errstr); + if (errstr != NULL) { + fatal("Invalid number of requests " + "\"%s\": %s", optarg + 10, errstr); + } + sftp_nrequests = (size_t)llv; + } else { + fatal("Invalid -X option"); + } + break; /* Server options. */ case 'd': @@ -972,7 +1005,8 @@ do_sftp_connect(char *host, char *user, int port, char *sftp_direct, reminp, remoutp, pidp) < 0) return NULL; } - return do_init(*reminp, *remoutp, 32768, 64, limit_kbps); + return do_init(*reminp, *remoutp, + sftp_copy_buflen, sftp_nrequests, limit_kbps); } void |