version 1.201, 2019/01/24 16:52:17 |
version 1.202, 2019/01/26 22:41:28 |
|
|
#include <dirent.h> |
#include <dirent.h> |
#include <errno.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <fcntl.h> |
|
#include <fnmatch.h> |
#include <locale.h> |
#include <locale.h> |
#include <pwd.h> |
#include <pwd.h> |
#include <signal.h> |
#include <signal.h> |
|
|
struct passwd *pwd; |
struct passwd *pwd; |
uid_t userid; |
uid_t userid; |
int errs, remin, remout; |
int errs, remin, remout; |
int pflag, iamremote, iamrecursive, targetshouldbedirectory; |
int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory; |
|
|
#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 response(void); |
int response(void); |
void rsource(char *, struct stat *); |
void rsource(char *, struct stat *); |
void sink(int, char *[]); |
void sink(int, char *[], const char *); |
void source(int, char *[]); |
void source(int, char *[]); |
void tolocal(int, char *[]); |
void tolocal(int, char *[]); |
void toremote(int, char *[]); |
void toremote(int, char *[]); |
|
|
addargs(&args, "-oRemoteCommand=none"); |
addargs(&args, "-oRemoteCommand=none"); |
addargs(&args, "-oRequestTTY=no"); |
addargs(&args, "-oRequestTTY=no"); |
|
|
fflag = tflag = 0; |
fflag = Tflag = tflag = 0; |
while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:J:")) != -1) |
while ((ch = getopt(argc, argv, |
|
"dfl:prtTvBCc:i:P:q12346S:o:F:J:")) != -1) { |
switch (ch) { |
switch (ch) { |
/* User-visible flags. */ |
/* User-visible flags. */ |
case '1': |
case '1': |
|
|
iamremote = 1; |
iamremote = 1; |
tflag = 1; |
tflag = 1; |
break; |
break; |
|
case 'T': |
|
Tflag = 1; |
|
break; |
default: |
default: |
usage(); |
usage(); |
} |
} |
|
} |
argc -= optind; |
argc -= optind; |
argv += optind; |
argv += optind; |
|
|
|
|
} |
} |
if (tflag) { |
if (tflag) { |
/* Receive data. */ |
/* Receive data. */ |
sink(argc, argv); |
sink(argc, argv, NULL); |
exit(errs != 0); |
exit(errs != 0); |
} |
} |
if (argc < 2) |
if (argc < 2) |
|
|
continue; |
continue; |
} |
} |
free(bp); |
free(bp); |
sink(1, argv + argc - 1); |
sink(1, argv + argc - 1, src); |
(void) close(remin); |
(void) close(remin); |
remin = remout = -1; |
remin = remout = -1; |
} |
} |
|
|
(sizeof(type) != 4 && sizeof(type) != 8)) |
(sizeof(type) != 4 && sizeof(type) != 8)) |
|
|
void |
void |
sink(int argc, char **argv) |
sink(int argc, char **argv, const char *src) |
{ |
{ |
static BUF buffer; |
static BUF buffer; |
struct stat stb; |
struct stat stb; |
|
|
unsigned long long ull; |
unsigned long long ull; |
int setimes, targisdir, wrerrno = 0; |
int setimes, targisdir, wrerrno = 0; |
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; |
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048]; |
|
char *src_copy = NULL, *restrict_pattern = NULL; |
struct timeval tv[2]; |
struct timeval tv[2]; |
|
|
#define atime tv[0] |
#define atime tv[0] |
|
|
(void) atomicio(vwrite, remout, "", 1); |
(void) atomicio(vwrite, remout, "", 1); |
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) |
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) |
targisdir = 1; |
targisdir = 1; |
|
if (src != NULL && !iamrecursive && !Tflag) { |
|
/* |
|
* Prepare to try to restrict incoming filenames to match |
|
* the requested destination file glob. |
|
*/ |
|
if ((src_copy = strdup(src)) == NULL) |
|
fatal("strdup failed"); |
|
if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) { |
|
*restrict_pattern++ = '\0'; |
|
} |
|
} |
for (first = 1;; first = 0) { |
for (first = 1;; first = 0) { |
cp = buf; |
cp = buf; |
if (atomicio(read, remin, cp, 1) != 1) |
if (atomicio(read, remin, cp, 1) != 1) |
|
|
run_err("error: unexpected filename: %s", cp); |
run_err("error: unexpected filename: %s", cp); |
exit(1); |
exit(1); |
} |
} |
|
if (restrict_pattern != NULL && |
|
fnmatch(restrict_pattern, cp, 0) != 0) |
|
SCREWUP("filename does not match request"); |
if (targisdir) { |
if (targisdir) { |
static char *namebuf; |
static char *namebuf; |
static size_t cursize; |
static size_t cursize; |
|
|
goto bad; |
goto bad; |
} |
} |
vect[0] = xstrdup(np); |
vect[0] = xstrdup(np); |
sink(1, vect); |
sink(1, vect, src); |
if (setimes) { |
if (setimes) { |
setimes = 0; |
setimes = 0; |
if (utimes(vect[0], tv) < 0) |
if (utimes(vect[0], tv) < 0) |