-/* $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
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);
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");
}
/*
* 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)
if (r < 0) {
if (errno == EINTR)
continue;
- if (errno == EAGAIN) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
(void)poll(&pfd, 1, -1); /* Ignore errors */
continue;
}
} else {
host = cleanhostname(argv[i]);
}
+ addargs(&alist, "--");
addargs(&alist, "%s", host);
addargs(&alist, "%s", cmd);
addargs(&alist, "%s", src);
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)
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))
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;
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;
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:
* 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;
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)