version 1.12, 1997/02/05 04:55:18 |
version 1.13, 1997/03/14 04:32:16 |
|
|
/* $OpenBSD$ */ |
/* $OpenBSD$ */ |
/* $NetBSD: ftp.c,v 1.22 1997/02/01 10:45:03 lukem Exp $ */ |
/* $NetBSD: ftp.c,v 1.23 1997/03/13 06:23:17 lukem Exp $ */ |
|
|
/* |
/* |
* Copyright (c) 1985, 1989, 1993, 1994 |
* Copyright (c) 1985, 1989, 1993, 1994 |
|
|
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
#include <utime.h> |
#include <utime.h> |
|
#ifdef __STDC__ |
|
#include <stdarg.h> |
|
#else |
#include <varargs.h> |
#include <varargs.h> |
|
#endif |
|
|
#include "ftp_var.h" |
#include "ftp_var.h" |
|
|
|
|
|
|
/*VARARGS*/ |
/*VARARGS*/ |
int |
int |
|
#ifdef __STDC__ |
|
command(const char *fmt, ...) |
|
#else |
command(va_alist) |
command(va_alist) |
va_dcl |
va_dcl |
|
#endif |
{ |
{ |
va_list ap; |
va_list ap; |
char *fmt; |
|
int r; |
int r; |
sig_t oldintr; |
sig_t oldintr; |
|
#ifndef __STDC__ |
|
const char *fmt; |
|
#endif |
|
|
abrtflag = 0; |
abrtflag = 0; |
if (debug) { |
if (debug) { |
fputs("---> ", stdout); |
fputs("---> ", stdout); |
|
#ifdef __STDC__ |
|
va_start(ap, fmt); |
|
#else |
va_start(ap); |
va_start(ap); |
fmt = va_arg(ap, char *); |
fmt = va_arg(ap, const char *); |
|
#endif |
if (strncmp("PASS ", fmt, 5) == 0) |
if (strncmp("PASS ", fmt, 5) == 0) |
fputs("PASS XXXX", stdout); |
fputs("PASS XXXX", stdout); |
else if (strncmp("ACCT ", fmt, 5) == 0) |
else if (strncmp("ACCT ", fmt, 5) == 0) |
|
|
(void)fflush(stdout); |
(void)fflush(stdout); |
} |
} |
if (cout == NULL) { |
if (cout == NULL) { |
warn("No control connection for command"); |
warnx("No control connection for command."); |
code = -1; |
code = -1; |
return (0); |
return (0); |
} |
} |
oldintr = signal(SIGINT, cmdabort); |
oldintr = signal(SIGINT, cmdabort); |
|
#ifdef __STDC__ |
|
va_start(ap, fmt); |
|
#else |
va_start(ap); |
va_start(ap); |
fmt = va_arg(ap, char *); |
fmt = va_arg(ap, char *); |
|
#endif |
vfprintf(cout, fmt, ap); |
vfprintf(cout, fmt, ap); |
va_end(ap); |
va_end(ap); |
fputs("\r\n", cout); |
fputs("\r\n", cout); |
|
|
lostpeer(); |
lostpeer(); |
if (verbose) { |
if (verbose) { |
puts( |
puts( |
"421 Service not available, remote server has closed connection"); |
"421 Service not available, remote server has closed connection."); |
(void)fflush(stdout); |
(void)fflush(stdout); |
} |
} |
code = 421; |
code = 421; |
|
|
alarmtimer(0); |
alarmtimer(0); |
mflag = 0; |
mflag = 0; |
abrtflag = 0; |
abrtflag = 0; |
puts("\nsend aborted\nwaiting for remote to finish abort"); |
puts("\nsend aborted\nwaiting for remote to finish abort."); |
(void)fflush(stdout); |
(void)fflush(stdout); |
longjmp(sendabort, 1); |
longjmp(sendabort, 1); |
} |
} |
|
|
sig_t oldinti, oldintr, oldintp; |
sig_t oldinti, oldintr, oldintp; |
off_t hashbytes; |
off_t hashbytes; |
char *lmode, buf[BUFSIZ], *bufp; |
char *lmode, buf[BUFSIZ], *bufp; |
|
int oprogress; |
|
|
hashbytes = mark; |
hashbytes = mark; |
direction = "sent"; |
direction = "sent"; |
bytes = 0; |
bytes = 0; |
filesize = -1; |
filesize = -1; |
|
oprogress = progress; |
if (verbose && printnames) { |
if (verbose && printnames) { |
if (local && *local != '-') |
if (local && *local != '-') |
printf("local: %s ", local); |
printf("local: %s ", local); |
|
|
(void)signal(SIGPIPE, oldintp); |
(void)signal(SIGPIPE, oldintp); |
if (oldinti) |
if (oldinti) |
(void)signal(SIGINFO, oldinti); |
(void)signal(SIGINFO, oldinti); |
|
progress = oprogress; |
code = -1; |
code = -1; |
return; |
return; |
} |
} |
oldintr = signal(SIGINT, abortsend); |
oldintr = signal(SIGINT, abortsend); |
oldinti = signal(SIGINFO, psummary); |
oldinti = signal(SIGINFO, psummary); |
if (strcmp(local, "-") == 0) |
if (strcmp(local, "-") == 0) { |
fin = stdin; |
fin = stdin; |
else if (*local == '|') { |
progress = 0; |
|
} else if (*local == '|') { |
oldintp = signal(SIGPIPE, SIG_IGN); |
oldintp = signal(SIGPIPE, SIG_IGN); |
fin = popen(local + 1, "r"); |
fin = popen(local + 1, "r"); |
if (fin == NULL) { |
if (fin == NULL) { |
|
|
code = -1; |
code = -1; |
return; |
return; |
} |
} |
|
progress = 0; |
closefunc = pclose; |
closefunc = pclose; |
} else { |
} else { |
fin = fopen(local, "r"); |
fin = fopen(local, "r"); |
|
|
if (oldintp) |
if (oldintp) |
(void)signal(SIGPIPE, oldintp); |
(void)signal(SIGPIPE, oldintp); |
code = -1; |
code = -1; |
|
progress = oprogress; |
if (closefunc != NULL) |
if (closefunc != NULL) |
(*closefunc)(fin); |
(*closefunc)(fin); |
return; |
return; |
|
|
if (rc < 0) { |
if (rc < 0) { |
warn("local: %s", local); |
warn("local: %s", local); |
restart_point = 0; |
restart_point = 0; |
|
progress = oprogress; |
if (closefunc != NULL) |
if (closefunc != NULL) |
(*closefunc)(fin); |
(*closefunc)(fin); |
return; |
return; |
|
|
if (command("REST %ld", (long) restart_point) |
if (command("REST %ld", (long) restart_point) |
!= CONTINUE) { |
!= CONTINUE) { |
restart_point = 0; |
restart_point = 0; |
|
progress = oprogress; |
if (closefunc != NULL) |
if (closefunc != NULL) |
(*closefunc)(fin); |
(*closefunc)(fin); |
return; |
return; |
|
|
if (command("%s %s", cmd, remote) != PRELIM) { |
if (command("%s %s", cmd, remote) != PRELIM) { |
(void)signal(SIGINT, oldintr); |
(void)signal(SIGINT, oldintr); |
(void)signal(SIGINFO, oldinti); |
(void)signal(SIGINFO, oldinti); |
|
progress = oprogress; |
if (oldintp) |
if (oldintp) |
(void)signal(SIGPIPE, oldintp); |
(void)signal(SIGPIPE, oldintp); |
if (closefunc != NULL) |
if (closefunc != NULL) |
|
|
if (command("%s", cmd) != PRELIM) { |
if (command("%s", cmd) != PRELIM) { |
(void)signal(SIGINT, oldintr); |
(void)signal(SIGINT, oldintr); |
(void)signal(SIGINFO, oldinti); |
(void)signal(SIGINFO, oldinti); |
|
progress = oprogress; |
if (oldintp) |
if (oldintp) |
(void)signal(SIGPIPE, oldintp); |
(void)signal(SIGPIPE, oldintp); |
if (closefunc != NULL) |
if (closefunc != NULL) |
|
|
break; |
break; |
} |
} |
progressmeter(1); |
progressmeter(1); |
|
progress = oprogress; |
if (closefunc != NULL) |
if (closefunc != NULL) |
(*closefunc)(fin); |
(*closefunc)(fin); |
(void)fclose(dout); |
(void)fclose(dout); |
|
|
abort: |
abort: |
(void)signal(SIGINT, oldintr); |
(void)signal(SIGINT, oldintr); |
(void)signal(SIGINFO, oldinti); |
(void)signal(SIGINFO, oldinti); |
|
progress = oprogress; |
if (oldintp) |
if (oldintp) |
(void)signal(SIGPIPE, oldintp); |
(void)signal(SIGPIPE, oldintp); |
if (!cpend) { |
if (!cpend) { |
|
|
alarmtimer(0); |
alarmtimer(0); |
mflag = 0; |
mflag = 0; |
abrtflag = 0; |
abrtflag = 0; |
puts("\nreceive aborted\nwaiting for remote to finish abort"); |
puts("\nreceive aborted\nwaiting for remote to finish abort."); |
(void)fflush(stdout); |
(void)fflush(stdout); |
longjmp(recvabort, 1); |
longjmp(recvabort, 1); |
} |
} |
|
|
off_t hashbytes; |
off_t hashbytes; |
struct stat st; |
struct stat st; |
time_t mtime; |
time_t mtime; |
|
int oprogress; |
|
|
hashbytes = mark; |
hashbytes = mark; |
direction = "received"; |
direction = "received"; |
bytes = 0; |
bytes = 0; |
filesize = -1; |
filesize = -1; |
|
oprogress = progress; |
is_retr = strcmp(cmd, "RETR") == 0; |
is_retr = strcmp(cmd, "RETR") == 0; |
if (is_retr && verbose && printnames) { |
if (is_retr && verbose && printnames) { |
if (local && *local != '-') |
if (local && *local != '-') |
|
|
din = dataconn("r"); |
din = dataconn("r"); |
if (din == NULL) |
if (din == NULL) |
goto abort; |
goto abort; |
if (strcmp(local, "-") == 0) |
if (strcmp(local, "-") == 0) { |
fout = stdout; |
fout = stdout; |
else if (*local == '|') { |
progress = 0; |
|
} else if (*local == '|') { |
oldintp = signal(SIGPIPE, SIG_IGN); |
oldintp = signal(SIGPIPE, SIG_IGN); |
fout = popen(local + 1, "w"); |
fout = popen(local + 1, "w"); |
if (fout == NULL) { |
if (fout == NULL) { |
warn("%s", local+1); |
warn("%s", local+1); |
goto abort; |
goto abort; |
} |
} |
|
progress = 0; |
closefunc = pclose; |
closefunc = pclose; |
} else { |
} else { |
fout = fopen(local, lmode); |
fout = fopen(local, lmode); |
|
|
} |
} |
bufsize = st.st_blksize; |
bufsize = st.st_blksize; |
} |
} |
|
if (!(st.st_mode & S_IFREG)) { |
|
progress = 0; |
|
preserve = 0; |
|
} |
progressmeter(-1); |
progressmeter(-1); |
switch (curtype) { |
switch (curtype) { |
|
|
|
|
if (restart_point && |
if (restart_point && |
lseek(fileno(fout), restart_point, SEEK_SET) < 0) { |
lseek(fileno(fout), restart_point, SEEK_SET) < 0) { |
warn("local: %s", local); |
warn("local: %s", local); |
|
progress = oprogress; |
if (closefunc != NULL) |
if (closefunc != NULL) |
(*closefunc)(fout); |
(*closefunc)(fout); |
return; |
return; |
|
|
if (fseek(fout, 0L, SEEK_CUR) < 0) { |
if (fseek(fout, 0L, SEEK_CUR) < 0) { |
done: |
done: |
warn("local: %s", local); |
warn("local: %s", local); |
|
progress = oprogress; |
if (closefunc != NULL) |
if (closefunc != NULL) |
(*closefunc)(fout); |
(*closefunc)(fout); |
return; |
return; |
|
|
} |
} |
break2: |
break2: |
if (bare_lfs) { |
if (bare_lfs) { |
printf("WARNING! %d bare linefeeds received in ASCII mode\n", |
printf( |
bare_lfs); |
"WARNING! %d bare linefeeds received in ASCII mode.\n", bare_lfs); |
puts("File may not have transferred correctly."); |
puts("File may not have transferred correctly."); |
} |
} |
if (hash && (!progress || filesize < 0)) { |
if (hash && (!progress || filesize < 0)) { |
|
|
break; |
break; |
} |
} |
progressmeter(1); |
progressmeter(1); |
|
progress = oprogress; |
if (closefunc != NULL) |
if (closefunc != NULL) |
(*closefunc)(fout); |
(*closefunc)(fout); |
(void)signal(SIGINT, oldintr); |
(void)signal(SIGINT, oldintr); |
|
|
ut.actime = time(NULL); |
ut.actime = time(NULL); |
ut.modtime = mtime; |
ut.modtime = mtime; |
if (utime(local, &ut) == -1) |
if (utime(local, &ut) == -1) |
printf("Can't change modification time on %s to %s", |
printf( |
|
"Can't change modification time on %s to %s", |
local, asctime(localtime(&mtime))); |
local, asctime(localtime(&mtime))); |
} |
} |
} |
} |
} |
} |
return; |
return; |
|
|
abort: |
abort: |
|
|
/* abort using RFC959 recommended IP,SYNC sequence */ |
/* abort using RFC959 recommended IP,SYNC sequence */ |
|
|
|
progress = oprogress; |
if (oldintp) |
if (oldintp) |
(void)signal(SIGPIPE, oldintp); |
(void)signal(SIGPIPE, oldintp); |
(void)signal(SIGINT, SIG_IGN); |
(void)signal(SIGINT, SIG_IGN); |
|
|
|
|
if (sscanf(pasv, "%d,%d,%d,%d,%d,%d", |
if (sscanf(pasv, "%d,%d,%d,%d,%d,%d", |
&a0, &a1, &a2, &a3, &p0, &p1) != 6) { |
&a0, &a1, &a2, &a3, &p0, &p1) != 6) { |
puts("Passive mode address scan failure. Shouldn't happen!"); |
puts( |
|
"Passive mode address scan failure. Shouldn't happen!"); |
goto bad; |
goto bad; |
} |
} |
|
|
|
|
const char *lmode; |
const char *lmode; |
{ |
{ |
struct sockaddr_in from; |
struct sockaddr_in from; |
int s, fromlen = sizeof(from), tos; |
int s, fromlen, tos; |
|
|
|
fromlen = sizeof(from); |
|
|
if (passivemode) |
if (passivemode) |
return (fdopen(data, lmode)); |
return (fdopen(data, lmode)); |
|
|
|
|
} |
} |
pswitch(0); |
pswitch(0); |
if (!connected) { |
if (!connected) { |
puts("No primary connection"); |
puts("No primary connection."); |
pswitch(1); |
pswitch(1); |
code = -1; |
code = -1; |
return; |
return; |
|
|
char buf[BUFSIZ]; |
char buf[BUFSIZ]; |
int nfnd; |
int nfnd; |
struct fd_set mask; |
struct fd_set mask; |
|
|
|
if (cout == NULL) { |
|
warnx("Lost control connection for abort."); |
|
if (ptabflg) |
|
code = -1; |
|
lostpeer(); |
|
return; |
|
} |
|
|
/* |
/* |
* send IAC in urgent mode instead of DM because 4.3BSD places oob mark |
* send IAC in urgent mode instead of DM because 4.3BSD places oob mark |