]> andersk Git - openssh.git/blobdiff - scp.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / scp.c
diff --git a/scp.c b/scp.c
index 8febe12a1e801130bce59faad55c78df52ce30fb..09efb82acb3e91b798a925ffbd932d2813eb44b3 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: scp.c,v 1.161 2007/10/24 03:44:02 djm Exp $ */
+/* $OpenBSD: scp.c,v 1.165 2009/12/20 07:28:36 guenther Exp $ */
 /*
  * scp - secure remote copy.  This is basically patched BSD rcp which
  * uses ssh to do the data transfer (instead of using rcmd).
 #ifdef HAVE_SYS_STAT_H
 # include <sys/stat.h>
 #endif
-# include <sys/poll.h>
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#else
+# ifdef HAVE_SYS_POLL_H
+#  include <sys/poll.h>
+# endif
+#endif
 #ifdef HAVE_SYS_TIME_H
 # include <sys/time.h>
 #endif
@@ -238,8 +244,11 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
                close(pout[1]);
 
                replacearg(&args, 0, "%s", ssh_program);
-               if (remuser != NULL)
-                       addargs(&args, "-l%s", remuser);
+               if (remuser != NULL) {
+                       addargs(&args, "-l");
+                       addargs(&args, "%s", remuser);
+               }
+               addargs(&args, "--");
                addargs(&args, "%s", host);
                addargs(&args, "%s", cmd);
 
@@ -331,10 +340,12 @@ main(int argc, char **argv)
                case 'c':
                case 'i':
                case 'F':
-                       addargs(&args, "-%c%s", ch, optarg);
+                       addargs(&args, "-%c", ch);
+                       addargs(&args, "%s", optarg);
                        break;
                case 'P':
-                       addargs(&args, "-p%s", optarg);
+                       addargs(&args, "-p");
+                       addargs(&args, "%s", optarg);
                        break;
                case 'B':
                        addargs(&args, "-oBatchmode yes");
@@ -428,7 +439,7 @@ main(int argc, char **argv)
        }
        /*
         * Finally check the exit status of the ssh process, if one was forked
-        * and no error has occured yet
+        * and no error has occurred yet
         */
        if (do_cmd_pid != -1 && errs == 0) {
                if (remin != -1)
@@ -468,7 +479,7 @@ scpio(ssize_t (*f)(int, void *, size_t), int fd, void *_p, size_t l, off_t *c)
                if (r < 0) {
                        if (errno == EINTR)
                                continue;
-                       if (errno == EAGAIN) {
+                       if (errno == EAGAIN || errno == EWOULDBLOCK) {
                                (void)poll(&pfd, 1, -1); /* Ignore errors */
                                continue;
                        }
@@ -542,6 +553,7 @@ toremote(char *targ, int argc, char **argv)
                        } else {
                                host = cleanhostname(argv[i]);
                        }
+                       addargs(&alist, "--");
                        addargs(&alist, "%s", host);
                        addargs(&alist, "%s", cmd);
                        addargs(&alist, "%s", src);
@@ -552,7 +564,7 @@ toremote(char *targ, int argc, char **argv)
                                errs = 1;
                } else {        /* local to remote */
                        if (remin == -1) {
-                               xasprintf(&bp, "%s -t %s", cmd, targ);
+                               xasprintf(&bp, "%s -t -- %s", cmd, targ);
                                host = cleanhostname(thost);
                                if (do_cmd(host, tuser, bp, &remin,
                                    &remout) < 0)
@@ -585,6 +597,7 @@ tolocal(int argc, char **argv)
                                addargs(&alist, "-r");
                        if (pflag)
                                addargs(&alist, "-p");
+                       addargs(&alist, "--");
                        addargs(&alist, "%s", argv[i]);
                        addargs(&alist, "%s", argv[argc-1]);
                        if (do_local_cmd(&alist))
@@ -604,7 +617,7 @@ tolocal(int argc, char **argv)
                                suser = pwd->pw_name;
                }
                host = cleanhostname(host);
-               xasprintf(&bp, "%s -f %s", cmd, src);
+               xasprintf(&bp, "%s -f -- %s", cmd, src);
                if (do_cmd(host, suser, bp, &remin, &remout) < 0) {
                        (void) xfree(bp);
                        ++errs;
@@ -623,7 +636,8 @@ source(int argc, char **argv)
        struct stat stb;
        static BUF buffer;
        BUF *bp;
-       off_t i, amt, statbytes;
+       off_t i, statbytes;
+       size_t amt;
        int fd = -1, haderr, indx;
        char *last, *name, buf[2048], encname[MAXPATHLEN];
        int len;
@@ -644,6 +658,10 @@ source(int argc, char **argv)
 syserr:                        run_err("%s: %s", name, strerror(errno));
                        goto next;
                }
+               if (stb.st_size < 0) {
+                       run_err("%s: %s", name, "Negative file size");
+                       goto next;
+               }
                unset_nonblock(fd);
                switch (stb.st_mode & S_IFMT) {
                case S_IFREG:
@@ -669,8 +687,14 @@ syserr:                    run_err("%s: %s", name, strerror(errno));
                         * versions expecting microseconds.
                         */
                        (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n",
-                           (u_long) stb.st_mtime,
-                           (u_long) stb.st_atime);
+                           (u_long) (stb.st_mtime < 0 ? 0 : stb.st_mtime),
+                           (u_long) (stb.st_atime < 0 ? 0 : stb.st_atime));
+                       if (verbose_mode) {
+                               fprintf(stderr, "File mtime %ld atime %ld\n",
+                                   (long)stb.st_mtime, (long)stb.st_atime);
+                               fprintf(stderr, "Sending file timestamps: %s",
+                                   buf);
+                       }
                        (void) atomicio(vwrite, remout, buf, strlen(buf));
                        if (response() < 0)
                                goto next;
@@ -697,7 +721,7 @@ next:                       if (fd != -1) {
                set_nonblock(remout);
                for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
                        amt = bp->cnt;
-                       if (i + amt > stb.st_size)
+                       if (i + (off_t)amt > stb.st_size)
                                amt = stb.st_size - i;
                        if (!haderr) {
                                if (atomicio(read, fd, bp->buf, amt) != amt)
This page took 0.0434 seconds and 4 git commands to generate.