-/* $OpenBSD: scp.c,v 1.139 2006/03/25 13:17:02 djm Exp $ */
+/* $OpenBSD: scp.c,v 1.155 2006/08/03 03:34:42 deraadt Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
#include "includes.h"
#include <sys/types.h>
+#include <sys/param.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
#include <sys/wait.h>
+#include <sys/uio.h>
#include <ctype.h>
#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pwd.h>
#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
#include "xmalloc.h"
#include "atomicio.h"
extern char *__progname;
+int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);
+
void bwlimit(int);
/* Struct for addargs */
*/
int
-do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
+do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
{
int pin[2], pout[2], reserved[2];
* Reserve two descriptors so that the real pipes won't get
* descriptors 0 and 1 because that will screw up dup2 below.
*/
- pipe(reserved);
+ if (pipe(reserved) < 0)
+ fatal("pipe: %s", strerror(errno));
/* Create a socket pair for communicating with ssh. */
if (pipe(pin) < 0)
BUF *allocbuf(BUF *, int, int);
void lostconn(int);
-void nospace(void);
int okname(char *);
void run_err(const char *,...);
void verifydir(char *);
int
main(int argc, char **argv)
{
- int ch, fflag, tflag, status;
+ int ch, fflag, tflag, status, n;
double speed;
- char *targ, *endp;
+ char *targ, *endp, **newargv;
extern char *optarg;
extern int optind;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
+ /* Copy argv, because we modify it */
+ newargv = xcalloc(MAX(argc + 1, 1), sizeof(*newargv));
+ for (n = 0; n < argc; n++)
+ newargv[n] = xstrdup(argv[n]);
+ argv = newargv;
+
__progname = ssh_get_progname(argv[0]);
memset(&args, '\0', sizeof(args));
void
toremote(char *targ, int argc, char **argv)
{
- int i, len;
char *bp, *host, *src, *suser, *thost, *tuser, *arg;
arglist alist;
+ int i;
memset(&alist, '\0', sizeof(alist));
alist.list = NULL;
errs = 1;
} else { /* local to remote */
if (remin == -1) {
- len = strlen(targ) + CMDNEEDS + 20;
- bp = xmalloc(len);
- (void) snprintf(bp, len, "%s -t %s", cmd, targ);
+ xasprintf(&bp, "%s -t %s", cmd, targ);
host = cleanhostname(thost);
if (do_cmd(host, tuser, bp, &remin,
- &remout, argc) < 0)
+ &remout) < 0)
exit(1);
if (response() < 0)
exit(1);
source(1, argv + i);
}
}
+ xfree(arg);
}
void
tolocal(int argc, char **argv)
{
- int i, len;
char *bp, *host, *src, *suser;
arglist alist;
+ int i;
memset(&alist, '\0', sizeof(alist));
alist.list = NULL;
suser = pwd->pw_name;
}
host = cleanhostname(host);
- len = strlen(src) + CMDNEEDS + 20;
- bp = xmalloc(len);
- (void) snprintf(bp, len, "%s -f %s", cmd, src);
- if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) {
+ xasprintf(&bp, "%s -f %s", cmd, src);
+ if (do_cmd(host, suser, bp, &remin, &remout) < 0) {
(void) xfree(bp);
++errs;
continue;
BUF *bp;
off_t i;
size_t j, count;
- int amt, exists, first, mask, mode, ofd, omode;
+ int amt, exists, first, ofd;
+ mode_t mode, omode, mask;
off_t size, statbytes;
int setimes, targisdir, wrerrno = 0;
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];