summaryrefslogtreecommitdiffstats
path: root/scp.c
diff options
context:
space:
mode:
Diffstat (limited to 'scp.c')
-rw-r--r--scp.c155
1 files changed, 68 insertions, 87 deletions
diff --git a/scp.c b/scp.c
index 356d97e6..40cf7296 100644
--- a/scp.c
+++ b/scp.c
@@ -75,7 +75,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: scp.c,v 1.40 2000/09/21 11:11:42 markus Exp $");
+RCSID("$OpenBSD: scp.c,v 1.41 2000/10/11 20:03:27 markus Exp $");
#include "ssh.h"
#include "xmalloc.h"
@@ -102,6 +102,9 @@ void progressmeter(int);
int getttywidth(void);
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc);
+/* setup arguments for the call to ssh */
+void addargs(char *fmt, ...) __attribute__((format(printf, 1, 2)));
+
/* Time a transfer started. */
static struct timeval start;
@@ -114,12 +117,6 @@ off_t totalbytes = 0;
/* Name of current file being transferred. */
char *curfile;
-/* This is set to non-zero if IPv4 is desired. */
-int IPv4 = 0;
-
-/* This is set to non-zero if IPv6 is desired. */
-int IPv6 = 0;
-
/* This is set to non-zero to enable verbose mode. */
int verbose_mode = 0;
@@ -129,23 +126,16 @@ int compress_flag = 0;
/* This is set to zero if the progressmeter is not desired. */
int showprogress = 1;
-/* This is set to non-zero if running in batch mode (that is, password
- and passphrase queries are not allowed). */
-int batchmode = 0;
-
-/* This is set to the cipher type string if given on the command line. */
-char *cipher = NULL;
-
-/* This is set to the RSA authentication identity file name if given on
- the command line. */
-char *identity = NULL;
-
-/* This is the port to use in contacting the remote site (is non-NULL). */
-char *port = NULL;
-
/* This is the program to execute for the secured connection. ("ssh" or -S) */
char *ssh_program = SSH_PROGRAM;
+/* This is the list of arguments that scp passes to ssh */
+struct {
+ char **list;
+ int num;
+ int nalloc;
+} args;
+
/*
* This function executes the given command as the specified user on the
* given host. This returns < 0 if execution fails, and >= 0 otherwise. This
@@ -158,8 +148,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
int pin[2], pout[2], reserved[2];
if (verbose_mode)
- fprintf(stderr, "Executing: host %s, user %s, command %s\n",
- host, remuser ? remuser : "(unspecified)", cmd);
+ fprintf(stderr, "Executing: program %s host %s, user %s, command %s\n",
+ ssh_program, host, remuser ? remuser : "(unspecified)", cmd);
/*
* Reserve two descriptors so that the real pipes won't get
@@ -178,10 +168,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
close(reserved[1]);
/* For a child to execute the command on the remote host using ssh. */
- if (fork() == 0) {
- char *args[100]; /* XXX careful */
- unsigned int i;
-
+ if (fork() == 0) {
/* Child. */
close(pin[1]);
close(pout[0]);
@@ -190,41 +177,13 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
close(pin[0]);
close(pout[1]);
- i = 0;
- args[i++] = ssh_program;
- args[i++] = "-x";
- args[i++] = "-oFallBackToRsh no";
- if (IPv4)
- args[i++] = "-4";
- if (IPv6)
- args[i++] = "-6";
- if (verbose_mode)
- args[i++] = "-v";
- if (compress_flag)
- args[i++] = "-C";
- if (batchmode)
- args[i++] = "-oBatchMode yes";
- if (cipher != NULL) {
- args[i++] = "-c";
- args[i++] = cipher;
- }
- if (identity != NULL) {
- args[i++] = "-i";
- args[i++] = identity;
- }
- if (port != NULL) {
- args[i++] = "-p";
- args[i++] = port;
- }
- if (remuser != NULL) {
- args[i++] = "-l";
- args[i++] = remuser;
- }
- args[i++] = host;
- args[i++] = cmd;
- args[i++] = NULL;
+ args.list[0] = ssh_program;
+ if (remuser != NULL)
+ addargs("-l %s", remuser);
+ addargs("%s", host);
+ addargs("%s", cmd);
- execvp(ssh_program, args);
+ execvp(ssh_program, args.list);
perror(ssh_program);
exit(1);
}
@@ -290,27 +249,45 @@ main(argc, argv)
extern char *optarg;
extern int optind;
+ args.list = NULL;
+ addargs("ssh"); /* overwritten with ssh_program */
+ addargs("-x");
+ addargs("-oFallBackToRsh no");
+
fflag = tflag = 0;
- while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:")) != EOF)
+ while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != EOF)
switch (ch) {
/* User-visible flags. */
case '4':
- IPv4 = 1;
- break;
case '6':
- IPv6 = 1;
+ case 'C':
+ addargs("-%c", ch);
break;
- case 'p':
- pflag = 1;
+ case 'o':
+ case 'c':
+ case 'i':
+ addargs("-%c %s", ch, optarg);
break;
case 'P':
- port = optarg;
+ addargs("-p %s", optarg);
+ break;
+ case 'B':
+ addargs("-o Batchmode yes");
+ break;
+ case 'p':
+ pflag = 1;
break;
case 'r':
iamrecursive = 1;
break;
case 'S':
- ssh_program = optarg;
+ ssh_program = xstrdup(optarg);
+ break;
+ case 'v':
+ verbose_mode = 1;
+ break;
+ case 'q':
+ showprogress = 0;
break;
/* Server options. */
@@ -325,24 +302,6 @@ main(argc, argv)
iamremote = 1;
tflag = 1;
break;
- case 'c':
- cipher = optarg;
- break;
- case 'i':
- identity = optarg;
- break;
- case 'v':
- verbose_mode = 1;
- break;
- case 'B':
- batchmode = 1;
- break;
- case 'C':
- compress_flag = 1;
- break;
- case 'q':
- showprogress = 0;
- break;
case '?':
default:
usage();
@@ -1287,3 +1246,25 @@ getttywidth(void)
else
return (80);
}
+
+void
+addargs(char *fmt, ...)
+{
+ va_list ap;
+ char buf[1024];
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+
+ if (args.list == NULL) {
+ args.nalloc = 32;
+ args.num = 0;
+ args.list = xmalloc(args.nalloc * sizeof(char *));
+ } else if (args.num+2 >= args.nalloc) {
+ args.nalloc *= 2;
+ args.list = xrealloc(args.list, args.nalloc * sizeof(char *));
+ }
+ args.list[args.num++] = xstrdup(buf);
+ args.list[args.num] = NULL;
+}