version 1.43, 2000/10/18 18:23:02 |
version 1.43.2.1, 2001/02/16 20:13:12 |
|
|
#include "includes.h" |
#include "includes.h" |
RCSID("$OpenBSD$"); |
RCSID("$OpenBSD$"); |
|
|
#include "ssh.h" |
|
#include "xmalloc.h" |
#include "xmalloc.h" |
|
#include "atomicio.h" |
|
#include "pathnames.h" |
|
#include "log.h" |
|
|
#define _PATH_CP "cp" |
|
|
|
/* For progressmeter() -- number of seconds before xfer considered "stalled" */ |
/* For progressmeter() -- number of seconds before xfer considered "stalled" */ |
#define STALLTIME 5 |
#define STALLTIME 5 |
|
|
|
|
static struct timeval start; |
static struct timeval start; |
|
|
/* Number of bytes of current file transferred so far. */ |
/* Number of bytes of current file transferred so far. */ |
volatile unsigned long statbytes; |
volatile u_long statbytes; |
|
|
/* Total size of current file. */ |
/* Total size of current file. */ |
off_t totalbytes = 0; |
off_t totalbytes = 0; |
|
|
/* This is set to non-zero to enable verbose mode. */ |
/* This is set to non-zero to enable verbose mode. */ |
int verbose_mode = 0; |
int verbose_mode = 0; |
|
|
/* This is set to non-zero if compression is desired. */ |
|
int compress = 0; |
|
|
|
/* This is set to zero if the progressmeter is not desired. */ |
/* This is set to zero if the progressmeter is not desired. */ |
int showprogress = 1; |
int showprogress = 1; |
|
|
/* This is the program to execute for the secured connection. ("ssh" or -S) */ |
/* This is the program to execute for the secured connection. ("ssh" or -S) */ |
char *ssh_program = SSH_PROGRAM; |
char *ssh_program = _PATH_SSH_PROGRAM; |
|
|
/* This is the list of arguments that scp passes to ssh */ |
/* This is the list of arguments that scp passes to ssh */ |
struct { |
struct { |
|
|
return 0; |
return 0; |
} |
} |
|
|
void |
|
fatal(const char *fmt,...) |
|
{ |
|
va_list ap; |
|
char buf[1024]; |
|
|
|
va_start(ap, fmt); |
|
vsnprintf(buf, sizeof(buf), fmt, ap); |
|
va_end(ap); |
|
fprintf(stderr, "%s\n", buf); |
|
exit(255); |
|
} |
|
|
|
typedef struct { |
typedef struct { |
int cnt; |
int cnt; |
char *buf; |
char *buf; |
|
|
#define CMDNEEDS 64 |
#define CMDNEEDS 64 |
char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ |
char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */ |
|
|
|
int main(int, char *[]); |
int response(void); |
int response(void); |
void rsource(char *, struct stat *); |
void rsource(char *, struct stat *); |
void sink(int, char *[]); |
void sink(int, char *[]); |
void source(int, char *[]); |
void source(int, char *[]); |
void tolocal(int, char *[]); |
void tolocal(int, char *[]); |
|
char *cleanhostname(char *); |
void toremote(char *, int, char *[]); |
void toremote(char *, int, char *[]); |
void usage(void); |
void usage(void); |
|
|
|
|
addargs("-oFallBackToRsh no"); |
addargs("-oFallBackToRsh no"); |
|
|
fflag = tflag = 0; |
fflag = tflag = 0; |
while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != EOF) |
while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != -1) |
switch (ch) { |
switch (ch) { |
/* User-visible flags. */ |
/* User-visible flags. */ |
case '4': |
case '4': |
|
|
remin = STDIN_FILENO; |
remin = STDIN_FILENO; |
remout = STDOUT_FILENO; |
remout = STDOUT_FILENO; |
|
|
if (fflag) { |
if (fflag) { |
/* Follow "protocol", send data. */ |
/* Follow "protocol", send data. */ |
(void) response(); |
(void) response(); |
source(argc, argv); |
source(argc, argv); |
|
|
|
|
remin = remout = -1; |
remin = remout = -1; |
/* Command to be executed on remote system using "ssh". */ |
/* Command to be executed on remote system using "ssh". */ |
(void) sprintf(cmd, "scp%s%s%s%s", verbose_mode ? " -v" : "", |
(void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s", |
|
verbose_mode ? " -v" : "", |
iamrecursive ? " -r" : "", pflag ? " -p" : "", |
iamrecursive ? " -r" : "", pflag ? " -p" : "", |
targetshouldbedirectory ? " -d" : ""); |
targetshouldbedirectory ? " -d" : ""); |
|
|
|
|
suser = pwd->pw_name; |
suser = pwd->pw_name; |
else if (!okname(suser)) |
else if (!okname(suser)) |
continue; |
continue; |
(void) sprintf(bp, |
snprintf(bp, len, |
"%s%s -x -o'FallBackToRsh no' -n -l %s %s %s %s '%s%s%s:%s'", |
"%s%s -x -o'FallBackToRsh no' -n " |
ssh_program, verbose_mode ? " -v" : "", |
"-l %s %s %s %s '%s%s%s:%s'", |
suser, host, cmd, src, |
ssh_program, verbose_mode ? " -v" : "", |
tuser ? tuser : "", tuser ? "@" : "", |
suser, host, cmd, src, |
thost, targ); |
tuser ? tuser : "", tuser ? "@" : "", |
|
thost, targ); |
} else { |
} else { |
host = cleanhostname(argv[i]); |
host = cleanhostname(argv[i]); |
(void) sprintf(bp, |
snprintf(bp, len, |
"exec %s%s -x -o'FallBackToRsh no' -n %s %s %s '%s%s%s:%s'", |
"exec %s%s -x -o'FallBackToRsh no' -n %s " |
ssh_program, verbose_mode ? " -v" : "", |
"%s %s '%s%s%s:%s'", |
host, cmd, src, |
ssh_program, verbose_mode ? " -v" : "", |
tuser ? tuser : "", tuser ? "@" : "", |
host, cmd, src, |
thost, targ); |
tuser ? tuser : "", tuser ? "@" : "", |
|
thost, targ); |
} |
} |
if (verbose_mode) |
if (verbose_mode) |
fprintf(stderr, "Executing: %s\n", bp); |
fprintf(stderr, "Executing: %s\n", bp); |
|
|
if (remin == -1) { |
if (remin == -1) { |
len = strlen(targ) + CMDNEEDS + 20; |
len = strlen(targ) + CMDNEEDS + 20; |
bp = xmalloc(len); |
bp = xmalloc(len); |
(void) sprintf(bp, "%s -t %s", cmd, targ); |
(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, argc) < 0) |
|
|
len = strlen(_PATH_CP) + strlen(argv[i]) + |
len = strlen(_PATH_CP) + strlen(argv[i]) + |
strlen(argv[argc - 1]) + 20; |
strlen(argv[argc - 1]) + 20; |
bp = xmalloc(len); |
bp = xmalloc(len); |
(void) sprintf(bp, "exec %s%s%s %s %s", _PATH_CP, |
(void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP, |
iamrecursive ? " -r" : "", pflag ? " -p" : "", |
iamrecursive ? " -r" : "", pflag ? " -p" : "", |
argv[i], argv[argc - 1]); |
argv[i], argv[argc - 1]); |
if (verbose_mode) |
if (verbose_mode) |
|
|
host = cleanhostname(host); |
host = cleanhostname(host); |
len = strlen(src) + CMDNEEDS + 20; |
len = strlen(src) + CMDNEEDS + 20; |
bp = xmalloc(len); |
bp = xmalloc(len); |
(void) sprintf(bp, "%s -f %s", cmd, src); |
(void) snprintf(bp, len, "%s -f %s", cmd, src); |
if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) { |
if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) { |
(void) xfree(bp); |
(void) xfree(bp); |
++errs; |
++errs; |
|
|
* Make it compatible with possible future |
* Make it compatible with possible future |
* versions expecting microseconds. |
* versions expecting microseconds. |
*/ |
*/ |
(void) sprintf(buf, "T%lu 0 %lu 0\n", |
(void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n", |
(unsigned long) stb.st_mtime, |
(u_long) stb.st_mtime, |
(unsigned long) stb.st_atime); |
(u_long) stb.st_atime); |
(void) atomicio(write, remout, buf, strlen(buf)); |
(void) atomicio(write, remout, buf, strlen(buf)); |
if (response() < 0) |
if (response() < 0) |
goto next; |
goto next; |
} |
} |
#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) |
#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) |
(void) sprintf(buf, "C%04o %lu %s\n", |
snprintf(buf, sizeof buf, "C%04o %lu %s\n", |
(unsigned int) (stb.st_mode & FILEMODEMASK), |
(u_int) (stb.st_mode & FILEMODEMASK), |
(unsigned long) stb.st_size, |
(u_long) stb.st_size, last); |
last); |
|
if (verbose_mode) { |
if (verbose_mode) { |
fprintf(stderr, "Sending file modes: %s", buf); |
fprintf(stderr, "Sending file modes: %s", buf); |
fflush(stderr); |
fflush(stderr); |
|
|
else |
else |
last++; |
last++; |
if (pflag) { |
if (pflag) { |
(void) sprintf(path, "T%lu 0 %lu 0\n", |
(void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n", |
(unsigned long) statp->st_mtime, |
(u_long) statp->st_mtime, |
(unsigned long) statp->st_atime); |
(u_long) statp->st_atime); |
(void) atomicio(write, remout, path, strlen(path)); |
(void) atomicio(write, remout, path, strlen(path)); |
if (response() < 0) { |
if (response() < 0) { |
closedir(dirp); |
closedir(dirp); |
return; |
return; |
} |
} |
} |
} |
(void) sprintf(path, "D%04o %d %.1024s\n", |
(void) snprintf(path, sizeof path, "D%04o %d %.1024s\n", |
(unsigned int) (statp->st_mode & FILEMODEMASK), 0, last); |
(u_int) (statp->st_mode & FILEMODEMASK), 0, last); |
if (verbose_mode) |
if (verbose_mode) |
fprintf(stderr, "Entering directory: %s", path); |
fprintf(stderr, "Entering directory: %s", path); |
(void) atomicio(write, remout, path, strlen(path)); |
(void) atomicio(write, remout, path, strlen(path)); |
|
|
run_err("%s/%s: name too long", name, dp->d_name); |
run_err("%s/%s: name too long", name, dp->d_name); |
continue; |
continue; |
} |
} |
(void) sprintf(path, "%s/%s", name, dp->d_name); |
(void) snprintf(path, sizeof path, "%s/%s", name, dp->d_name); |
vect[0] = path; |
vect[0] = path; |
source(1, vect); |
source(1, vect); |
} |
} |
|
|
if (buf[0] == '\01' || buf[0] == '\02') { |
if (buf[0] == '\01' || buf[0] == '\02') { |
if (iamremote == 0) |
if (iamremote == 0) |
(void) atomicio(write, STDERR_FILENO, |
(void) atomicio(write, STDERR_FILENO, |
buf + 1, strlen(buf + 1)); |
buf + 1, strlen(buf + 1)); |
if (buf[0] == '\02') |
if (buf[0] == '\02') |
exit(1); |
exit(1); |
++errs; |
++errs; |
|
|
size_t need; |
size_t need; |
|
|
need = strlen(targ) + strlen(cp) + 250; |
need = strlen(targ) + strlen(cp) + 250; |
if (need > cursize) |
if (need > cursize) { |
|
if (namebuf) |
|
xfree(namebuf); |
namebuf = xmalloc(need); |
namebuf = xmalloc(need); |
(void) sprintf(namebuf, "%s%s%s", targ, |
cursize = need; |
|
} |
|
(void) snprintf(namebuf, need, "%s%s%s", targ, |
*targ ? "/" : "", cp); |
*targ ? "/" : "", cp); |
np = namebuf; |
np = namebuf; |
} else |
} else |
|
|
if (mkdir(np, mode | S_IRWXU) < 0) |
if (mkdir(np, mode | S_IRWXU) < 0) |
goto bad; |
goto bad; |
} |
} |
vect[0] = np; |
vect[0] = xstrdup(np); |
sink(1, vect); |
sink(1, vect); |
|
if (vect[0]) |
|
xfree(vect[0]); |
if (setimes) { |
if (setimes) { |
setimes = 0; |
setimes = 0; |
if (utimes(np, tv) < 0) |
if (utimes(np, tv) < 0) |
|
|
c = *cp; |
c = *cp; |
if (c & 0200) |
if (c & 0200) |
goto bad; |
goto bad; |
if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-' && c != '.') |
if (!isalpha(c) && !isdigit(c) && |
|
c != '_' && c != '-' && c != '.' && c != '+') |
goto bad; |
goto bad; |
} while (*++cp); |
} while (*++cp); |
return (1); |
return (1); |
|
|
} |
} |
|
|
int |
int |
foregroundproc() |
foregroundproc(void) |
{ |
{ |
static pid_t pgrp = -1; |
static pid_t pgrp = -1; |
int ctty_pgrp; |
int ctty_pgrp; |
|
|
i++; |
i++; |
abbrevsize >>= 10; |
abbrevsize >>= 10; |
} |
} |
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5qd %c%c ", |
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %5llu %c%c ", |
(quad_t) abbrevsize, prefixes[i], prefixes[i] == ' ' ? ' ' : |
(unsigned long long) abbrevsize, prefixes[i], |
'B'); |
prefixes[i] == ' ' ? ' ' : 'B'); |
|
|
timersub(&now, &lastupdate, &wait); |
timersub(&now, &lastupdate, &wait); |
if (cursize > lastsize) { |
if (cursize > lastsize) { |
|
|
timersub(&now, &start, &td); |
timersub(&now, &start, &td); |
elapsed = td.tv_sec + (td.tv_usec / 1000000.0); |
elapsed = td.tv_sec + (td.tv_usec / 1000000.0); |
|
|
if (statbytes <= 0 || elapsed <= 0.0 || cursize > totalbytes) { |
if (flag != 1 && |
|
(statbytes <= 0 || elapsed <= 0.0 || cursize > totalbytes)) { |
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), |
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), |
" --:-- ETA"); |
" --:-- ETA"); |
} else if (wait.tv_sec >= STALLTIME) { |
} else if (wait.tv_sec >= STALLTIME) { |
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), |
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), |
" - stalled -"); |
" - stalled -"); |
} else { |
} else { |
if (flag != 1) |
if (flag != 1) |
remaining = |
remaining = (int)(totalbytes / (statbytes / elapsed) - |
(int)(totalbytes / (statbytes / elapsed) - elapsed); |
elapsed); |
else |
else |
remaining = elapsed; |
remaining = elapsed; |
|
|