=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/scp.c,v retrieving revision 1.108 retrieving revision 1.108.2.2 diff -u -r1.108 -r1.108.2.2 --- src/usr.bin/ssh/scp.c 2003/07/18 01:54:25 1.108 +++ src/usr.bin/ssh/scp.c 2004/08/19 22:37:32 1.108.2.2 @@ -71,7 +71,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.108 2003/07/18 01:54:25 deraadt Exp $"); +RCSID("$OpenBSD: scp.c,v 1.108.2.2 2004/08/19 22:37:32 brad Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -88,7 +88,7 @@ arglist args; /* Bandwidth limit */ -off_t limit = 0; +off_t limit_rate = 0; /* Name of current file being transferred. */ char *curfile; @@ -251,7 +251,7 @@ speed = strtod(optarg, &endp); if (speed <= 0 || *endp != '\0') usage(); - limit = speed * 1024; + limit_rate = speed * 1024; break; case 'p': pflag = 1; @@ -267,6 +267,7 @@ verbose_mode = 1; break; case 'q': + addargs(&args, "-q"); showprogress = 0; break; @@ -417,7 +418,8 @@ } if (verbose_mode) fprintf(stderr, "Executing: %s\n", bp); - (void) system(bp); + if (system(bp) != 0) + errs = 1; (void) xfree(bp); } else { /* local to remote */ if (remin == -1) { @@ -578,7 +580,7 @@ haderr = result >= 0 ? EIO : errno; statbytes += result; } - if (limit) + if (limit_rate) bwlimit(amt); } if (showprogress) @@ -652,7 +654,7 @@ { static struct timeval bwstart, bwend; static int lamt, thresh = 16384; - u_int64_t wait; + u_int64_t waitlen; struct timespec ts, rm; if (!timerisset(&bwstart)) { @@ -670,10 +672,10 @@ return; lamt *= 8; - wait = (double)1000000L * lamt / limit; + waitlen = (double)1000000L * lamt / limit_rate; - bwstart.tv_sec = wait / 1000000L; - bwstart.tv_usec = wait % 1000000L; + bwstart.tv_sec = waitlen / 1000000L; + bwstart.tv_usec = waitlen % 1000000L; if (timercmp(&bwstart, &bwend, >)) { timersub(&bwstart, &bwend, &bwend); @@ -748,6 +750,8 @@ *cp++ = ch; } while (cp < &buf[sizeof(buf) - 1] && ch != '\n'); *cp = 0; + if (verbose_mode) + fprintf(stderr, "Sink: %s", buf); if (buf[0] == '\01' || buf[0] == '\02') { if (iamremote == 0) @@ -811,6 +815,10 @@ size = size * 10 + (*cp++ - '0'); if (*cp++ != ' ') SCREWUP("size not delimited"); + if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { + run_err("error: unexpected filename: %s", cp); + exit(1); + } if (targisdir) { static char *namebuf; static int cursize; @@ -832,6 +840,8 @@ exists = stat(np, &stb) == 0; if (buf[0] == 'D') { int mod_flag = pflag; + if (!iamrecursive) + SCREWUP("received directory without -r"); if (exists) { if (!S_ISDIR(stb.st_mode)) { errno = ENOTDIR; @@ -883,11 +893,8 @@ amt = size - i; count += amt; do { - j = read(remin, cp, amt); - if (j == -1 && (errno == EINTR || - errno == EAGAIN)) { - continue; - } else if (j <= 0) { + j = atomicio(read, remin, cp, amt); + if (j <= 0) { run_err("%s", j ? strerror(errno) : "dropped connection"); exit(1); @@ -896,8 +903,8 @@ cp += j; statbytes += j; } while (amt > 0); - - if (limit) + + if (limit_rate) bwlimit(4096); if (count == bp->cnt) { @@ -926,14 +933,18 @@ } if (pflag) { if (exists || omode != mode) - if (fchmod(ofd, omode)) + if (fchmod(ofd, omode)) { run_err("%s: set mode: %s", np, strerror(errno)); + wrerr = DISPLAYED; + } } else { if (!exists && omode != mode) - if (fchmod(ofd, omode & ~mask)) + if (fchmod(ofd, omode & ~mask)) { run_err("%s: set mode: %s", np, strerror(errno)); + wrerr = DISPLAYED; + } } if (close(ofd) == -1) { wrerr = YES; @@ -1001,8 +1012,8 @@ usage(void) { (void) fprintf(stderr, - "usage: scp [-pqrvBC1246] [-F config] [-S program] [-P port]\n" - " [-c cipher] [-i identity] [-l limit] [-o option]\n" + "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" + " [-l limit] [-o ssh_option] [-P port] [-S program]\n" " [[user@]host1:]file1 [...] [[user@]host2:]file2\n"); exit(1); }