=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/scp.c,v retrieving revision 1.68.2.4 retrieving revision 1.69 diff -u -r1.68.2.4 -r1.69 --- src/usr.bin/ssh/scp.c 2002/06/02 22:56:10 1.68.2.4 +++ src/usr.bin/ssh/scp.c 2001/05/03 23:09:53 1.69 @@ -75,7 +75,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.68.2.4 2002/06/02 22:56:10 miod Exp $"); +RCSID("$OpenBSD: scp.c,v 1.69 2001/05/03 23:09:53 mouring Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -85,8 +85,6 @@ /* For progressmeter() -- number of seconds before xfer considered "stalled" */ #define STALLTIME 5 -/* alarm() interval for updating progress meter */ -#define PROGRESSTIME 1 /* Visual statistics about files as they are transferred. */ void progressmeter(int); @@ -95,8 +93,8 @@ int getttywidth(void); int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); -/* Struct for addargs */ -arglist args; +/* setup arguments for the call to ssh */ +void addargs(char *fmt, ...) __attribute__((format(printf, 1, 2))); /* Time a transfer started. */ static struct timeval start; @@ -119,6 +117,13 @@ /* This is the program to execute for the secured connection. ("ssh" or -S) */ char *ssh_program = _PATH_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 @@ -131,10 +136,8 @@ int pin[2], pout[2], reserved[2]; if (verbose_mode) - fprintf(stderr, - "Executing: program %s host %s, user %s, command %s\n", - ssh_program, 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 @@ -164,9 +167,9 @@ args.list[0] = ssh_program; if (remuser != NULL) - addargs(&args, "-l%s", remuser); - addargs(&args, "%s", host); - addargs(&args, "%s", cmd); + addargs("-l%s", remuser); + addargs("%s", host); + addargs("%s", cmd); execvp(ssh_program, args.list); perror(ssh_program); @@ -219,32 +222,29 @@ extern int optind; args.list = NULL; - addargs(&args, "ssh"); /* overwritten with ssh_program */ - addargs(&args, "-x"); - addargs(&args, "-oForwardAgent no"); - addargs(&args, "-oFallBackToRsh no"); - addargs(&args, "-oClearAllForwardings yes"); + addargs("ssh"); /* overwritten with ssh_program */ + addargs("-x"); + addargs("-oFallBackToRsh no"); fflag = tflag = 0; - while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:F:")) != -1) + while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != -1) switch (ch) { /* User-visible flags. */ case '4': case '6': case 'C': - addargs(&args, "-%c", ch); + addargs("-%c", ch); break; case 'o': case 'c': case 'i': - case 'F': - addargs(&args, "-%c%s", ch, optarg); + addargs("-%c%s", ch, optarg); break; case 'P': - addargs(&args, "-p%s", optarg); + addargs("-p%s", optarg); break; case 'B': - addargs(&args, "-oBatchmode yes"); + addargs("-oBatchmode yes"); break; case 'p': pflag = 1; @@ -256,7 +256,6 @@ ssh_program = xstrdup(optarg); break; case 'v': - addargs(&args, "-v"); verbose_mode = 1; break; case 'q': @@ -353,17 +352,13 @@ for (i = 0; i < argc - 1; i++) { src = colon(argv[i]); if (src) { /* remote to remote */ - static char *ssh_options = - "-x -o'FallBackToRsh no' " - "-o'ClearAllForwardings yes'"; *src++ = 0; if (*src == 0) src = "."; host = strchr(argv[i], '@'); len = strlen(ssh_program) + strlen(argv[i]) + strlen(src) + (tuser ? strlen(tuser) : 0) + - strlen(thost) + strlen(targ) + - strlen(ssh_options) + CMDNEEDS + 20; + strlen(thost) + strlen(targ) + CMDNEEDS + 32; bp = xmalloc(len); if (host) { *host++ = 0; @@ -374,19 +369,19 @@ else if (!okname(suser)) continue; snprintf(bp, len, - "%s%s %s -n " + "%s%s -x -o'FallBackToRsh no' -n " "-l %s %s %s %s '%s%s%s:%s'", ssh_program, verbose_mode ? " -v" : "", - ssh_options, suser, host, cmd, src, + suser, host, cmd, src, tuser ? tuser : "", tuser ? "@" : "", thost, targ); } else { host = cleanhostname(argv[i]); snprintf(bp, len, - "exec %s%s %s -n %s " + "exec %s%s -x -o'FallBackToRsh no' -n %s " "%s %s '%s%s%s:%s'", ssh_program, verbose_mode ? " -v" : "", - ssh_options, host, cmd, src, + host, cmd, src, tuser ? tuser : "", tuser ? "@" : "", thost, targ); } @@ -484,11 +479,6 @@ len = strlen(name); while (len > 1 && name[len-1] == '/') name[--len] = '\0'; - if (strchr(name, '\n') != NULL) { - run_err("%s: skipping, filename contains a newline", - name); - goto next; - } if ((fd = open(name, O_RDONLY, 0)) < 0) goto syserr; if (fstat(fd, &stb) < 0) { @@ -651,7 +641,7 @@ #define atime tv[0] #define mtime tv[1] -#define SCREWUP(str) do { why = str; goto screwup; } while (0) +#define SCREWUP(str) { why = str; goto screwup; } setimes = targisdir = 0; mask = umask(0); @@ -756,7 +746,7 @@ cursize = need; } (void) snprintf(namebuf, need, "%s%s%s", targ, - strcmp(targ, "/") ? "/" : "", cp); + *targ ? "/" : "", cp); np = namebuf; } else np = targ; @@ -794,7 +784,7 @@ } omode = mode; mode |= S_IWRITE; - if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { + if ((ofd = open(np, O_WRONLY | O_CREAT | O_TRUNC, mode)) < 0) { bad: run_err("%s: %s", np, strerror(errno)); continue; } @@ -818,8 +808,7 @@ count += amt; do { j = read(remin, cp, amt); - if (j == -1 && (errno == EINTR || - errno == EAGAIN)) { + if (j == -1 && (errno == EINTR || errno == EAGAIN)) { continue; } else if (j <= 0) { run_err("%s", j ? strerror(errno) : @@ -850,10 +839,12 @@ wrerr = YES; wrerrno = j >= 0 ? EIO : errno; } +#if 0 if (ftruncate(ofd, size)) { run_err("%s: truncate: %s", np, strerror(errno)); wrerr = DISPLAYED; } +#endif if (pflag) { if (exists || omode != mode) if (fchmod(ofd, omode)) @@ -895,7 +886,7 @@ } int -response(void) +response() { char ch, *cp, resp, rbuf[2048]; @@ -928,11 +919,10 @@ } void -usage(void) +usage() { - (void) fprintf(stderr, - "usage: scp [-pqrvBC46] [-F config] [-S ssh] [-P port] [-c cipher] [-i identity]\n" - " [-o option] f1 f2\n" + (void) fprintf(stderr, "usage: scp " + "[-pqrvBC46] [-S ssh] [-P port] [-c cipher] [-i identity] f1 f2\n" " or: scp [options] f1 ... fn directory\n"); exit(1); } @@ -942,24 +932,22 @@ { static FILE *fp; va_list ap; + va_start(ap, fmt); ++errs; 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); vfprintf(stderr, fmt, ap); - va_end(ap); fprintf(stderr, "\n"); } + va_end(ap); } void @@ -986,7 +974,7 @@ cp = cp0; do { - c = (int)*cp; + c = *cp; if (c & 0200) goto bad; if (!isalpha(c) && !isdigit(c) && @@ -1022,7 +1010,6 @@ bp->buf = xmalloc(size); else bp->buf = xrealloc(bp->buf, size); - memset(bp->buf, 0, size); bp->cnt = size; return (bp); } @@ -1032,25 +1019,32 @@ int signo; { if (!iamremote) - write(STDERR_FILENO, "lost connection\n", 16); - if (signo) - _exit(1); - else - exit(1); + fprintf(stderr, "lost connection\n"); + exit(1); } -static void + +void +alarmtimer(int wait) +{ + struct itimerval itv; + + itv.it_value.tv_sec = wait; + itv.it_value.tv_usec = 0; + itv.it_interval = itv.it_value; + setitimer(ITIMER_REAL, &itv, NULL); +} + +void updateprogressmeter(int ignore) { int save_errno = errno; progressmeter(0); - signal(SIGALRM, updateprogressmeter); - alarm(PROGRESSTIME); errno = save_errno; } -static int +int foregroundproc(void) { static pid_t pgrp = -1; @@ -1073,7 +1067,7 @@ off_t cursize, abbrevsize; double elapsed; int ratio, barlength, i, remaining; - char buf[512]; + char buf[256]; if (flag == -1) { (void) gettimeofday(&start, (struct timezone *) 0); @@ -1099,13 +1093,8 @@ i = barlength * ratio / 100; snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "|%.*s%*s|", i, - "*******************************************************" - "*******************************************************" - "*******************************************************" - "*******************************************************" - "*******************************************************" - "*******************************************************" - "*******************************************************", + "*****************************************************************************" + "*****************************************************************************", barlength - i, ""); } i = 0; @@ -1161,9 +1150,9 @@ if (flag == -1) { signal(SIGALRM, updateprogressmeter); - alarm(PROGRESSTIME); + alarmtimer(1); } else if (flag == 1) { - alarm(0); + alarmtimer(0); atomicio(write, fileno(stdout), "\n", 1); statbytes = 0; } @@ -1178,4 +1167,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; }