=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/scp.c,v retrieving revision 1.125.2.2 retrieving revision 1.126 diff -u -r1.125.2.2 -r1.126 --- src/usr.bin/ssh/scp.c 2006/10/06 03:19:33 1.125.2.2 +++ src/usr.bin/ssh/scp.c 2005/09/13 23:40:07 1.126 @@ -1,4 +1,3 @@ -/* $OpenBSD: scp.c,v 1.125.2.2 2006/10/06 03:19:33 brad Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -71,26 +70,9 @@ * */ -#include -#include -#include -#include -#include -#include +#include "includes.h" +RCSID("$OpenBSD: scp.c,v 1.126 2005/09/13 23:40:07 djm Exp $"); -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "xmalloc.h" #include "atomicio.h" #include "pathnames.h" @@ -98,7 +80,7 @@ #include "misc.h" #include "progressmeter.h" -int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); +int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); void bwlimit(int); @@ -136,48 +118,6 @@ exit(1); } -static int -do_local_cmd(arglist *a) -{ - u_int i; - int status; - pid_t pid; - - if (a->num == 0) - fatal("do_local_cmd: no arguments"); - - if (verbose_mode) { - fprintf(stderr, "Executing:"); - for (i = 0; i < a->num; i++) - fprintf(stderr, " %s", a->list[i]); - fprintf(stderr, "\n"); - } - if ((pid = fork()) == -1) - fatal("do_local_cmd: fork: %s", strerror(errno)); - - if (pid == 0) { - execvp(a->list[0], a->list); - perror(a->list[0]); - exit(1); - } - - do_cmd_pid = pid; - signal(SIGTERM, killchild); - signal(SIGINT, killchild); - signal(SIGHUP, killchild); - - while (waitpid(pid, &status, 0) == -1) - if (errno != EINTR) - fatal("do_local_cmd: waitpid: %s", strerror(errno)); - - do_cmd_pid = -1; - - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - return (-1); - - return (0); -} - /* * This function executes the given command as the specified user on the * given host. This returns < 0 if execution fails, and >= 0 otherwise. This @@ -185,7 +125,7 @@ */ int -do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) +do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) { int pin[2], pout[2], reserved[2]; @@ -199,8 +139,7 @@ * Reserve two descriptors so that the real pipes won't get * descriptors 0 and 1 because that will screw up dup2 below. */ - if (pipe(reserved) < 0) - fatal("pipe: %s", strerror(errno)); + pipe(reserved); /* Create a socket pair for communicating with ssh. */ if (pipe(pin) < 0) @@ -223,7 +162,7 @@ close(pin[0]); close(pout[1]); - replacearg(&args, 0, "%s", ssh_program); + args.list[0] = ssh_program; if (remuser != NULL) addargs(&args, "-l%s", remuser); addargs(&args, "%s", host); @@ -253,6 +192,7 @@ BUF *allocbuf(BUF *, int, int); void lostconn(int); +void nospace(void); int okname(char *); void run_err(const char *,...); void verifydir(char *); @@ -276,27 +216,19 @@ int main(int argc, char **argv) { - int ch, fflag, tflag, status, n; + int ch, fflag, tflag, status; double speed; - char *targ, *endp, **newargv; + char *targ, *endp; extern char *optarg; extern int optind; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); - /* Copy argv, because we modify it */ - newargv = xcalloc(MAX(argc + 1, 1), sizeof(*newargv)); - for (n = 0; n < argc; n++) - newargv[n] = xstrdup(argv[n]); - argv = newargv; - - memset(&args, '\0', sizeof(args)); args.list = NULL; - addargs(&args, "%s", ssh_program); + addargs(&args, "ssh"); /* overwritten with ssh_program */ addargs(&args, "-x"); addargs(&args, "-oForwardAgent no"); - addargs(&args, "-oPermitLocalCommand no"); addargs(&args, "-oClearAllForwardings yes"); fflag = tflag = 0; @@ -402,9 +334,9 @@ if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */ toremote(targ, argc, argv); else { + tolocal(argc, argv); /* Dest is local host. */ if (targetshouldbedirectory) verifydir(argv[argc - 1]); - tolocal(argc, argv); /* Dest is local host. */ } /* * Finally check the exit status of the ssh process, if one was forked @@ -428,13 +360,9 @@ void toremote(char *targ, int argc, char **argv) { + int i, len; char *bp, *host, *src, *suser, *thost, *tuser, *arg; - arglist alist; - int i; - memset(&alist, '\0', sizeof(alist)); - alist.list = NULL; - *targ++ = 0; if (*targ == 0) targ = "."; @@ -451,54 +379,64 @@ tuser = NULL; } - if (tuser != NULL && !okname(tuser)) { - xfree(arg); - return; - } - for (i = 0; i < argc - 1; i++) { src = colon(argv[i]); if (src) { /* remote to remote */ - freeargs(&alist); - addargs(&alist, "%s", ssh_program); - if (verbose_mode) - addargs(&alist, "-v"); - addargs(&alist, "-x"); - addargs(&alist, "-oClearAllForwardings yes"); - addargs(&alist, "-n"); - + static char *ssh_options = + "-x -o'ClearAllForwardings yes'"; *src++ = 0; if (*src == 0) src = "."; host = strrchr(argv[i], '@'); - + len = strlen(ssh_program) + strlen(argv[i]) + + strlen(src) + (tuser ? strlen(tuser) : 0) + + strlen(thost) + strlen(targ) + + strlen(ssh_options) + CMDNEEDS + 20; + bp = xmalloc(len); if (host) { *host++ = 0; host = cleanhostname(host); suser = argv[i]; if (*suser == '\0') suser = pwd->pw_name; - else if (!okname(suser)) + else if (!okname(suser)) { + xfree(bp); continue; - addargs(&alist, "-l"); - addargs(&alist, "%s", suser); + } + if (tuser && !okname(tuser)) { + xfree(bp); + continue; + } + snprintf(bp, len, + "%s%s %s -n " + "-l %s %s %s %s '%s%s%s:%s'", + ssh_program, verbose_mode ? " -v" : "", + ssh_options, suser, host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); } else { host = cleanhostname(argv[i]); + snprintf(bp, len, + "exec %s%s %s -n %s " + "%s %s '%s%s%s:%s'", + ssh_program, verbose_mode ? " -v" : "", + ssh_options, host, cmd, src, + tuser ? tuser : "", tuser ? "@" : "", + thost, targ); } - addargs(&alist, "%s", host); - addargs(&alist, "%s", cmd); - addargs(&alist, "%s", src); - addargs(&alist, "%s%s%s:%s", - tuser ? tuser : "", tuser ? "@" : "", - thost, targ); - if (do_local_cmd(&alist) != 0) + if (verbose_mode) + fprintf(stderr, "Executing: %s\n", bp); + if (system(bp) != 0) errs = 1; + (void) xfree(bp); } else { /* local to remote */ if (remin == -1) { - xasprintf(&bp, "%s -t %s", cmd, targ); + len = strlen(targ) + CMDNEEDS + 20; + bp = xmalloc(len); + (void) snprintf(bp, len, "%s -t %s", cmd, targ); host = cleanhostname(thost); if (do_cmd(host, tuser, bp, &remin, - &remout) < 0) + &remout, argc) < 0) exit(1); if (response() < 0) exit(1); @@ -507,31 +445,27 @@ source(1, argv + i); } } - xfree(arg); } void tolocal(int argc, char **argv) { + int i, len; char *bp, *host, *src, *suser; - arglist alist; - int i; - memset(&alist, '\0', sizeof(alist)); - alist.list = NULL; - for (i = 0; i < argc - 1; i++) { if (!(src = colon(argv[i]))) { /* Local to local. */ - freeargs(&alist); - addargs(&alist, "%s", _PATH_CP); - if (iamrecursive) - addargs(&alist, "-r"); - if (pflag) - addargs(&alist, "-p"); - addargs(&alist, "%s", argv[i]); - addargs(&alist, "%s", argv[argc-1]); - if (do_local_cmd(&alist)) + len = strlen(_PATH_CP) + strlen(argv[i]) + + strlen(argv[argc - 1]) + 20; + bp = xmalloc(len); + (void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP, + iamrecursive ? " -r" : "", pflag ? " -p" : "", + argv[i], argv[argc - 1]); + if (verbose_mode) + fprintf(stderr, "Executing: %s\n", bp); + if (system(bp)) ++errs; + (void) xfree(bp); continue; } *src++ = 0; @@ -547,8 +481,10 @@ suser = pwd->pw_name; } host = cleanhostname(host); - xasprintf(&bp, "%s -f %s", cmd, src); - if (do_cmd(host, suser, bp, &remin, &remout) < 0) { + len = strlen(src) + CMDNEEDS + 20; + bp = xmalloc(len); + (void) snprintf(bp, len, "%s -f %s", cmd, src); + if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) { (void) xfree(bp); ++errs; continue; @@ -630,10 +566,7 @@ if (response() < 0) goto next; if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { -next: if (fd != -1) { - (void) close(fd); - fd = -1; - } +next: (void) close(fd); continue; } if (showprogress) @@ -662,11 +595,8 @@ if (showprogress) stop_progress_meter(); - if (fd != -1) { - if (close(fd) < 0 && !haderr) - haderr = errno; - fd = -1; - } + if (close(fd) < 0 && !haderr) + haderr = errno; if (!haderr) (void) atomicio(vwrite, remout, "", 1); else @@ -793,8 +723,7 @@ BUF *bp; off_t i; size_t j, count; - int amt, exists, first, ofd; - mode_t mode, omode, mask; + int amt, exists, first, mask, mode, ofd, omode; off_t size, statbytes; int setimes, targisdir, wrerrno = 0; char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; @@ -1106,15 +1035,15 @@ va_list ap; ++errs; - if (fp != NULL || (remout != -1 && (fp = fdopen(remout, "w")))) { - (void) fprintf(fp, "%c", 0x01); - (void) fprintf(fp, "scp: "); - va_start(ap, fmt); - (void) vfprintf(fp, fmt, ap); - va_end(ap); - (void) fprintf(fp, "\n"); - (void) fflush(fp); - } + if (fp == NULL && !(fp = fdopen(remout, "w"))) + return; + (void) fprintf(fp, "%c", 0x01); + (void) fprintf(fp, "scp: "); + va_start(ap, fmt); + (void) vfprintf(fp, fmt, ap); + va_end(ap); + (void) fprintf(fp, "\n"); + (void) fflush(fp); if (!iamremote) { va_start(ap, fmt); @@ -1186,7 +1115,7 @@ if (bp->buf == NULL) bp->buf = xmalloc(size); else - bp->buf = xrealloc(bp->buf, 1, size); + bp->buf = xrealloc(bp->buf, size); memset(bp->buf, 0, size); bp->cnt = size; return (bp);