=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/scp.c,v retrieving revision 1.119.2.2 retrieving revision 1.120 diff -u -r1.119.2.2 -r1.120 --- src/usr.bin/ssh/scp.c 2006/02/03 02:53:44 1.119.2.2 +++ src/usr.bin/ssh/scp.c 2005/03/31 18:39:21 1.120 @@ -71,7 +71,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.119.2.2 2006/02/03 02:53:44 brad Exp $"); +RCSID("$OpenBSD: scp.c,v 1.120 2005/03/31 18:39:21 deraadt Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -109,57 +109,13 @@ killchild(int signo) { if (do_cmd_pid > 1) { - kill(do_cmd_pid, signo ? signo : SIGTERM); + kill(do_cmd_pid, signo); waitpid(do_cmd_pid, NULL, 0); } - if (signo) - _exit(1); - exit(1); + _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 @@ -204,7 +160,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); @@ -228,7 +184,7 @@ } typedef struct { - size_t cnt; + int cnt; char *buf; } BUF; @@ -264,15 +220,10 @@ extern char *optarg; extern int optind; - /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ - sanitise_stdfd(); - - 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; @@ -378,9 +329,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 @@ -406,16 +357,14 @@ { int i, len; char *bp, *host, *src, *suser, *thost, *tuser, *arg; - arglist alist; - memset(&alist, '\0', sizeof(alist)); - alist.list = NULL; - *targ++ = 0; if (*targ == 0) targ = "."; - arg = xstrdup(argv[argc - 1]); + arg = strdup(argv[argc - 1]); + if (!arg) + err(1, "malloc"); if ((thost = strrchr(arg, '@'))) { /* user@host */ *thost++ = 0; @@ -427,48 +376,56 @@ 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) { len = strlen(targ) + CMDNEEDS + 20; @@ -492,23 +449,20 @@ { int i, len; char *bp, *host, *src, *suser; - arglist alist; - 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; @@ -545,9 +499,8 @@ struct stat stb; static BUF buffer; BUF *bp; - off_t i, amt, statbytes; - size_t result; - int fd = -1, haderr, indx; + off_t i, amt, result, statbytes; + int fd, haderr, indx; char *last, *name, buf[2048]; int len; @@ -609,10 +562,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) @@ -625,14 +575,14 @@ if (!haderr) { result = atomicio(read, fd, bp->buf, amt); if (result != amt) - haderr = errno; + haderr = result >= 0 ? EIO : errno; } if (haderr) (void) atomicio(vwrite, remout, bp->buf, amt); else { result = atomicio(vwrite, remout, bp->buf, amt); if (result != amt) - haderr = errno; + haderr = result >= 0 ? EIO : errno; statbytes += result; } if (limit_rate) @@ -641,11 +591,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 @@ -770,9 +717,8 @@ YES, NO, DISPLAYED } wrerr; BUF *bp; - off_t i; - size_t j, count; - int amt, exists, first, mask, mode, ofd, omode; + off_t i, j; + int amt, count, 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]; @@ -799,7 +745,7 @@ targisdir = 1; for (first = 1;; first = 0) { cp = buf; - if (atomicio(read, remin, cp, 1) != 1) + if (atomicio(read, remin, cp, 1) <= 0) return; if (*cp++ == '\n') SCREWUP("unexpected "); @@ -880,7 +826,7 @@ } if (targisdir) { static char *namebuf; - static size_t cursize; + static int cursize; size_t need; need = strlen(targ) + strlen(cp) + 250; @@ -953,7 +899,7 @@ count += amt; do { j = atomicio(read, remin, cp, amt); - if (j == 0) { + if (j <= 0) { run_err("%s", j ? strerror(errno) : "dropped connection"); exit(1); @@ -969,10 +915,10 @@ if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ if (wrerr == NO) { - if (atomicio(vwrite, ofd, bp->buf, - count) != count) { + j = atomicio(vwrite, ofd, bp->buf, count); + if (j != count) { wrerr = YES; - wrerrno = errno; + wrerrno = j >= 0 ? EIO : errno; } } count = 0; @@ -982,9 +928,9 @@ if (showprogress) stop_progress_meter(); if (count != 0 && wrerr == NO && - atomicio(vwrite, ofd, bp->buf, count) != count) { + (j = atomicio(vwrite, ofd, bp->buf, count)) != count) { wrerr = YES; - wrerrno = errno; + wrerrno = j >= 0 ? EIO : errno; } if (wrerr == NO && ftruncate(ofd, size) != 0) { run_err("%s: truncate: %s", np, strerror(errno)); @@ -1113,7 +1059,7 @@ errno = ENOTDIR; } run_err("%s: %s", cp, strerror(errno)); - killchild(0); + exit(1); } int