X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/f3c7c61373d79f23a88ffa48a4937138128113c9..5a5da1b6d4e665a310538545a980466a90a891c5:/scp.c diff --git a/scp.c b/scp.c index c8bb2d33..89f05ad9 100644 --- a/scp.c +++ b/scp.c @@ -75,7 +75,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: scp.c,v 1.60 2001/03/02 18:54:31 deraadt Exp $"); +RCSID("$OpenBSD: scp.c,v 1.71 2001/05/19 16:05:41 markus Exp $"); #include "xmalloc.h" #include "atomicio.h" @@ -107,14 +107,14 @@ void progressmeter(int); 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))); +/* Struct for addargs */ +arglist args; /* Time a transfer started. */ static struct timeval start; /* Number of bytes of current file transferred so far. */ -volatile u_long statbytes; +volatile off_t statbytes; /* Total size of current file. */ off_t totalbytes = 0; @@ -131,13 +131,6 @@ int showprogress = 1; /* 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 @@ -181,9 +174,9 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) args.list[0] = ssh_program; if (remuser != NULL) - addargs("-l%s", remuser); - addargs("%s", host); - addargs("%s", cmd); + addargs(&args, "-l%s", remuser); + addargs(&args, "%s", host); + addargs(&args, "%s", cmd); execvp(ssh_program, args.list); perror(ssh_program); @@ -202,10 +195,7 @@ typedef struct { char *buf; } BUF; -extern int iamremote; - BUF *allocbuf(BUF *, int, int); -char *colon(char *); void lostconn(int); void nospace(void); int okname(char *); @@ -220,13 +210,11 @@ int pflag, iamremote, iamrecursive, targetshouldbedirectory; #define CMDNEEDS 64 char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ -int main(int, char *[]); int response(void); void rsource(char *, struct stat *); void sink(int, char *[]); void source(int, char *[]); void tolocal(int, char *[]); -char *cleanhostname(char *); void toremote(char *, int, char *[]); void usage(void); @@ -243,9 +231,9 @@ main(argc, argv) __progname = get_progname(argv[0]); args.list = NULL; - addargs("ssh"); /* overwritten with ssh_program */ - addargs("-x"); - addargs("-oFallBackToRsh no"); + addargs(&args, "ssh"); /* overwritten with ssh_program */ + addargs(&args, "-x"); + addargs(&args, "-oFallBackToRsh no"); fflag = tflag = 0; while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != -1) @@ -254,18 +242,18 @@ main(argc, argv) case '4': case '6': case 'C': - addargs("-%c", ch); + addargs(&args, "-%c", ch); break; case 'o': case 'c': case 'i': - addargs("-%c%s", ch, optarg); + addargs(&args, "-%c%s", ch, optarg); break; case 'P': - addargs("-p%s", optarg); + addargs(&args, "-p%s", optarg); break; case 'B': - addargs("-oBatchmode yes"); + addargs(&args, "-oBatchmode yes"); break; case 'p': pflag = 1; @@ -294,8 +282,10 @@ main(argc, argv) case 't': /* "to" */ iamremote = 1; tflag = 1; +#ifdef HAVE_CYGWIN + setmode(0, O_BINARY); +#endif break; - case '?': default: usage(); } @@ -346,17 +336,6 @@ main(argc, argv) exit(errs != 0); } -char * -cleanhostname(host) - char *host; -{ - if (*host == '[' && host[strlen(host) - 1] == ']') { - host[strlen(host) - 1] = '\0'; - return (host + 1); - } else - return host; -} - void toremote(targ, argc, argv) char *targ, *argv[]; @@ -501,13 +480,17 @@ source(argc, argv) struct stat stb; static BUF buffer; BUF *bp; - off_t i; - int amt, fd, haderr, indx, result; + off_t i, amt, result; + int fd, haderr, indx; char *last, *name, buf[2048]; + int len; for (indx = 0; indx < argc; ++indx) { name = argv[indx]; statbytes = 0; + len = strlen(name); + while (len > 1 && name[len-1] == '/') + name[--len] = '\0'; if ((fd = open(name, O_RDONLY, 0)) < 0) goto syserr; if (fstat(fd, &stb) < 0) { @@ -545,9 +528,17 @@ syserr: run_err("%s: %s", name, strerror(errno)); goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) +#ifdef HAVE_LONG_LONG_INT + snprintf(buf, sizeof buf, "C%04o %lld %s\n", + (u_int) (stb.st_mode & FILEMODEMASK), + (long long) stb.st_size, last); +#else + /* XXX: Handle integer overflow? */ snprintf(buf, sizeof buf, "C%04o %lu %s\n", (u_int) (stb.st_mode & FILEMODEMASK), (u_long) stb.st_size, last); +#endif + if (verbose_mode) { fprintf(stderr, "Sending file modes: %s", buf); fflush(stderr); @@ -632,7 +623,7 @@ rsource(name, statp) closedir(dirp); return; } - while ((dp = readdir(dirp))) { + while ((dp = readdir(dirp)) != NULL) { if (dp->d_ino == 0) continue; if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) @@ -666,9 +657,10 @@ sink(argc, argv) off_t size; int setimes, targisdir, wrerrno = 0; char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; - int dummy_usec; struct timeval tv[2]; +#define atime tv[0] +#define mtime tv[1] #define SCREWUP(str) { why = str; goto screwup; } setimes = targisdir = 0; @@ -715,25 +707,21 @@ sink(argc, argv) if (ch == '\n') *--cp = 0; -#define getnum(t) (t) = 0; \ - while (*cp >= '0' && *cp <= '9') (t) = (t) * 10 + (*cp++ - '0'); cp = buf; if (*cp == 'T') { setimes++; cp++; - getnum(tv[1].tv_sec); - if (*cp++ != ' ') + mtime.tv_sec = strtol(cp, &cp, 10); + if (!cp || *cp++ != ' ') SCREWUP("mtime.sec not delimited"); - getnum(dummy_usec); - tv[1].tv_usec = 0; - if (*cp++ != ' ') + mtime.tv_usec = strtol(cp, &cp, 10); + if (!cp || *cp++ != ' ') SCREWUP("mtime.usec not delimited"); - getnum(tv[0].tv_sec); - if (*cp++ != ' ') + atime.tv_sec = strtol(cp, &cp, 10); + if (!cp || *cp++ != ' ') SCREWUP("atime.sec not delimited"); - getnum(dummy_usec); - tv[0].tv_usec = 0; - if (*cp++ != '\0') + atime.tv_usec = strtol(cp, &cp, 10); + if (!cp || *cp++ != '\0') SCREWUP("atime.usec not delimited"); (void) atomicio(write, remout, "", 1); continue; @@ -761,7 +749,7 @@ sink(argc, argv) if (*cp++ != ' ') SCREWUP("mode not delimited"); - for (size = 0; *cp >= '0' && *cp <= '9';) + for (size = 0; isdigit(*cp);) size = size * 10 + (*cp++ - '0'); if (*cp++ != ' ') SCREWUP("size not delimited"); @@ -816,7 +804,7 @@ sink(argc, argv) } omode = mode; mode |= S_IWRITE; - if ((ofd = open(np, O_WRONLY | O_CREAT | O_TRUNC, mode)) < 0) { + if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { bad: run_err("%s: %s", np, strerror(errno)); continue; } @@ -844,7 +832,7 @@ bad: run_err("%s: %s", np, strerror(errno)); continue; } else if (j <= 0) { run_err("%s", j ? strerror(errno) : - "dropped connection"); + "dropped connection"); exit(1); } amt -= j; @@ -871,12 +859,10 @@ bad: run_err("%s: %s", np, strerror(errno)); 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) #ifdef HAVE_FCHMOD @@ -885,7 +871,7 @@ bad: run_err("%s: %s", np, strerror(errno)); if (chmod(np, omode)) #endif /* HAVE_FCHMOD */ run_err("%s: set mode: %s", - np, strerror(errno)); + np, strerror(errno)); } else { if (!exists && omode != mode) #ifdef HAVE_FCHMOD @@ -894,7 +880,7 @@ bad: run_err("%s: %s", np, strerror(errno)); if (chmod(np, omode & ~mask)) #endif /* HAVE_FCHMOD */ run_err("%s: set mode: %s", - np, strerror(errno)); + np, strerror(errno)); } if (close(ofd) == -1) { wrerr = YES; @@ -905,7 +891,7 @@ bad: run_err("%s: %s", np, strerror(errno)); setimes = 0; if (utimes(np, tv) < 0) { run_err("%s: set times: %s", - np, strerror(errno)); + np, strerror(errno)); wrerr = DISPLAYED; } } @@ -962,8 +948,8 @@ void usage() { (void) fprintf(stderr, "usage: scp " - "[-pqrvC46] [-S ssh] [-P port] [-c cipher] [-i identity] f1 f2; or:\n" - " scp [options] f1 ... fn directory\n"); + "[-pqrvBC46] [-S ssh] [-P port] [-c cipher] [-i identity] f1 f2\n" + " or: scp [options] f1 ... fn directory\n"); exit(1); } @@ -992,30 +978,6 @@ run_err(const char *fmt,...) } } -char * -colon(cp) - char *cp; -{ - int flag = 0; - - if (*cp == ':') /* Leading colon is part of file name. */ - return (0); - if (*cp == '[') - flag = 1; - - for (; *cp; ++cp) { - if (*cp == '@' && *(cp+1) == '[') - flag = 1; - if (*cp == ']' && *(cp+1) == ':' && flag) - return (cp+1); - if (*cp == ':' && !flag) - return (cp); - if (*cp == '/') - return (0); - } - return (0); -} - void verifydir(cp) char *cp; @@ -1241,25 +1203,3 @@ getttywidth(void) 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; -}