=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/scp.c,v retrieving revision 1.40 retrieving revision 1.41 diff -u -r1.40 -r1.41 --- src/usr.bin/ssh/scp.c 2000/09/21 11:11:42 1.40 +++ src/usr.bin/ssh/scp.c 2000/10/11 20:03:27 1.41 @@ -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" @@ -92,6 +92,9 @@ 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; @@ -104,12 +107,6 @@ /* 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; @@ -119,23 +116,16 @@ /* 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 @@ -148,8 +138,8 @@ 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 @@ -168,10 +158,7 @@ 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]); @@ -180,41 +167,13 @@ 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) - 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); } @@ -280,28 +239,46 @@ 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. */ case 'd': @@ -315,24 +292,6 @@ 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 = 1; - break; - case 'q': - showprogress = 0; - break; case '?': default: usage(); @@ -1249,4 +1208,26 @@ return (winsize.ws_col ? winsize.ws_col : 80); 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; }