version 1.135, 2006/02/22 00:04:44 |
version 1.135.2.1, 2006/09/30 04:06:51 |
|
|
|
/* $OpenBSD$ */ |
/* |
/* |
* scp - secure remote copy. This is basically patched BSD rcp which |
* scp - secure remote copy. This is basically patched BSD rcp which |
* uses ssh to do the data transfer (instead of using rcmd). |
* uses ssh to do the data transfer (instead of using rcmd). |
|
|
* |
* |
*/ |
*/ |
|
|
#include "includes.h" |
#include <sys/param.h> |
RCSID("$OpenBSD$"); |
|
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/wait.h> |
#include <sys/wait.h> |
#include <sys/stat.h> |
#include <sys/stat.h> |
|
#include <sys/time.h> |
|
#include <sys/uio.h> |
|
|
#include <ctype.h> |
#include <ctype.h> |
#include <dirent.h> |
#include <dirent.h> |
|
#include <errno.h> |
|
#include <fcntl.h> |
|
#include <pwd.h> |
#include <signal.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 "xmalloc.h" |
#include "atomicio.h" |
#include "atomicio.h" |
|
|
#include "misc.h" |
#include "misc.h" |
#include "progressmeter.h" |
#include "progressmeter.h" |
|
|
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); |
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); |
|
|
void bwlimit(int); |
void bwlimit(int); |
|
|
|
|
*/ |
*/ |
|
|
int |
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]; |
int pin[2], pout[2], reserved[2]; |
|
|
|
|
* Reserve two descriptors so that the real pipes won't get |
* Reserve two descriptors so that the real pipes won't get |
* descriptors 0 and 1 because that will screw up dup2 below. |
* 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. */ |
/* Create a socket pair for communicating with ssh. */ |
if (pipe(pin) < 0) |
if (pipe(pin) < 0) |
|
|
|
|
BUF *allocbuf(BUF *, int, int); |
BUF *allocbuf(BUF *, int, int); |
void lostconn(int); |
void lostconn(int); |
void nospace(void); |
|
int okname(char *); |
int okname(char *); |
void run_err(const char *,...); |
void run_err(const char *,...); |
void verifydir(char *); |
void verifydir(char *); |
|
|
int |
int |
main(int argc, char **argv) |
main(int argc, char **argv) |
{ |
{ |
int ch, fflag, tflag, status; |
int ch, fflag, tflag, status, n; |
double speed; |
double speed; |
char *targ, *endp; |
char *targ, *endp, **newargv; |
extern char *optarg; |
extern char *optarg; |
extern int optind; |
extern int optind; |
|
|
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ |
sanitise_stdfd(); |
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; |
|
|
memset(&args, '\0', sizeof(args)); |
memset(&args, '\0', sizeof(args)); |
args.list = NULL; |
args.list = NULL; |
addargs(&args, "%s", ssh_program); |
addargs(&args, "%s", ssh_program); |
|
|
void |
void |
toremote(char *targ, int argc, char **argv) |
toremote(char *targ, int argc, char **argv) |
{ |
{ |
int i, len; |
|
char *bp, *host, *src, *suser, *thost, *tuser, *arg; |
char *bp, *host, *src, *suser, *thost, *tuser, *arg; |
arglist alist; |
arglist alist; |
|
int i; |
|
|
memset(&alist, '\0', sizeof(alist)); |
memset(&alist, '\0', sizeof(alist)); |
alist.list = NULL; |
alist.list = NULL; |
|
|
errs = 1; |
errs = 1; |
} else { /* local to remote */ |
} else { /* local to remote */ |
if (remin == -1) { |
if (remin == -1) { |
len = strlen(targ) + CMDNEEDS + 20; |
xasprintf(&bp, "%s -t %s", cmd, targ); |
bp = xmalloc(len); |
|
(void) snprintf(bp, len, "%s -t %s", cmd, targ); |
|
host = cleanhostname(thost); |
host = cleanhostname(thost); |
if (do_cmd(host, tuser, bp, &remin, |
if (do_cmd(host, tuser, bp, &remin, |
&remout, argc) < 0) |
&remout) < 0) |
exit(1); |
exit(1); |
if (response() < 0) |
if (response() < 0) |
exit(1); |
exit(1); |
|
|
source(1, argv + i); |
source(1, argv + i); |
} |
} |
} |
} |
|
xfree(arg); |
} |
} |
|
|
void |
void |
tolocal(int argc, char **argv) |
tolocal(int argc, char **argv) |
{ |
{ |
int i, len; |
|
char *bp, *host, *src, *suser; |
char *bp, *host, *src, *suser; |
arglist alist; |
arglist alist; |
|
int i; |
|
|
memset(&alist, '\0', sizeof(alist)); |
memset(&alist, '\0', sizeof(alist)); |
alist.list = NULL; |
alist.list = NULL; |
|
|
suser = pwd->pw_name; |
suser = pwd->pw_name; |
} |
} |
host = cleanhostname(host); |
host = cleanhostname(host); |
len = strlen(src) + CMDNEEDS + 20; |
xasprintf(&bp, "%s -f %s", cmd, src); |
bp = xmalloc(len); |
if (do_cmd(host, suser, bp, &remin, &remout) < 0) { |
(void) snprintf(bp, len, "%s -f %s", cmd, src); |
|
if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) { |
|
(void) xfree(bp); |
(void) xfree(bp); |
++errs; |
++errs; |
continue; |
continue; |
|
|
BUF *bp; |
BUF *bp; |
off_t i; |
off_t i; |
size_t j, count; |
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; |
off_t size, statbytes; |
int setimes, targisdir, wrerrno = 0; |
int setimes, targisdir, wrerrno = 0; |
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; |
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; |
|
|
va_list ap; |
va_list ap; |
|
|
++errs; |
++errs; |
if (fp == NULL && !(fp = fdopen(remout, "w"))) |
if (fp != NULL || (remout != -1 && (fp = fdopen(remout, "w")))) { |
return; |
(void) fprintf(fp, "%c", 0x01); |
(void) fprintf(fp, "%c", 0x01); |
(void) fprintf(fp, "scp: "); |
(void) fprintf(fp, "scp: "); |
va_start(ap, fmt); |
va_start(ap, fmt); |
(void) vfprintf(fp, fmt, ap); |
(void) vfprintf(fp, fmt, ap); |
va_end(ap); |
va_end(ap); |
(void) fprintf(fp, "\n"); |
(void) fprintf(fp, "\n"); |
(void) fflush(fp); |
(void) fflush(fp); |
} |
|
|
if (!iamremote) { |
if (!iamremote) { |
va_start(ap, fmt); |
va_start(ap, fmt); |
|
|
if (bp->buf == NULL) |
if (bp->buf == NULL) |
bp->buf = xmalloc(size); |
bp->buf = xmalloc(size); |
else |
else |
bp->buf = xrealloc(bp->buf, size); |
bp->buf = xrealloc(bp->buf, 1, size); |
memset(bp->buf, 0, size); |
memset(bp->buf, 0, size); |
bp->cnt = size; |
bp->cnt = size; |
return (bp); |
return (bp); |