static char *rcsid
= "$Header: /f/osi/ftam-ftp/RCS/ftp.c,v 7.1 91/02/22 09:23:27 mrose Interim $"; /* from UCB 4.11 7/26/83 */
* $Header: /f/osi/ftam-ftp/RCS/ftp.c,v 7.1 91/02/22 09:23:27 mrose Interim $
* Revision 7.1 91/02/22 09:23:27 mrose
* Revision 7.0 89/11/23 21:55:04 mrose
* The MITRE Corporation (hereafter MITRE) makes this software available
* on an "as is" basis. No guarantees, either explicit or implied, are
* given as to performance or suitability.
* Shamelessly taken from UCB
struct sockaddr_in hisctladdr
;
struct sockaddr_in data_addr
;
struct sockaddr_in myctladdr
;
{ /* default ftp communication values */
(void)strcpy(typename
, "ascii"), type
= TYPE_A
;
(void)strcpy(formname
, "non-print"), form
= FORM_N
;
(void)strcpy(modename
, "stream"), mode
= MODE_S
;
(void)strcpy(structname
, "file"), stru
= STRU_F
;
(void)strcpy(bytename
, "8"), bytesize
= 8;
ftp_error
= ftp_error_buffer
;
verbose
= isatty (fileno (stderr
));
register struct hostent
*hp
;
bzero((char *)&hisctladdr
, sizeof (hisctladdr
));
hp
= gethostbyname(host
);
static char *addrs
= NULL
;
static struct hostent def
;
static struct in_addr defaddr
;
static char namebuf
[128];
defaddr
.s_addr
= inet_addr(host
);
if (defaddr
.s_addr
== -1) {
(void)sprintf(ftp_error
, "%s: Unknown host.", host
);
(void)strcpy(namebuf
, host
);
def
.h_addr_list
= &addrs
;
def
.h_addr
= (char *)&defaddr
;
def
.h_length
= sizeof (struct in_addr
);
def
.h_addrtype
= AF_INET
;
hisctladdr
.sin_family
= hp
->h_addrtype
;
s
= socket(hp
->h_addrtype
, SOCK_STREAM
, 0);
(void)sprintf(ftp_error
,"ftp: socket %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
if (bind(s
, (struct sockaddr
*)&hisctladdr
, sizeof (hisctladdr
)) < 0) {
(void)sprintf(ftp_error
,"ftp: bind %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
inaddr_copy (hp
, &hisctladdr
);
hisctladdr
.sin_port
= htons ((u_short
) port
);
if (connect(s
, (struct sockaddr
*)&hisctladdr
, sizeof (hisctladdr
)) < 0) {
(void)sprintf(ftp_error
,"ftp: connect %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
len
= sizeof (myctladdr
);
if (getsockname(s
, (struct sockaddr
*)&myctladdr
, &len
) < 0) {
(void)sprintf(ftp_error
,"ftp: getsockname %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
if (cin
== NULL
|| cout
== NULL
) {
(void)sprintf(ftp_error
, "ftp: fdopen failed.");
(void) getreply(0); /* read startup message from server */
char *user
, *pass
, *acct
;
(void)sprintf(ftp_error
, "Username required");
n
= command("USER %s", user
);
(void)sprintf(ftp_error
, "Password required");
n
= command("PASS %s", pass
);
(void)sprintf(ftp_error
, "Account required");
n
= command("ACCT %s", acct
);
(void)sprintf(ftp_error
, "Login failed.");
(void)sprintf(ftp_error
,"No control connection for command %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
_asprintf (buffer
, NULLCP
, ap
);
fprintf (cout
, "%s\r\n", buffer
);
advise (LLOG_DEBUG
, NULLCP
, "<--- %s", buffer
);
return (getreply(!strcmp(buffer
, "QUIT")));
int originalcode
= 0, continuation
= 0;
while ((c
= getc(cin
)) != '\n') {
advise (LLOG_EXCEPTIONS
,NULLCP
,"getreply: %s",
if (c
!= '\r') *mesg
++ = c
;
if (dig
< 4 && isdigit(c
))
code
= code
* 10 + (c
- '0');
if (dig
== 4 && c
== '-')
if (continuation
&& code
!= originalcode
) {
advise (LLOG_DEBUG
,NULLCP
,"---> %s",
* sendrequest and recvrequest routines have been modified to send the
* appropriate remote command then open and return a file descriptor (socket).
* The FTAM code treats this as though it were a local file (which
* is about what FTP does)
sendrequest(cmd
, /* local, */ remote
)
char *cmd
, /* *local, */ *remote
;
if (command("%s %s", cmd
, remote
) != PRELIM
)
if (command("%s", cmd
) != PRELIM
)
expectingreply
++; /* got preliminary reply, expecting final reply */
(void) close(data
), data
= -1;
recvrequest(cmd
, /* local,*/ remote
)
char *cmd
, /* *local,*/ *remote
;
if (command("%s %s", cmd
, remote
) != PRELIM
)
if (command("%s", cmd
) != PRELIM
)
expectingreply
++; /* got preliminary reply, expecting final reply */
(void) close(data
), data
= -1;
* Need to start a listen on the data channel
* before we send the command, otherwise the
* server's connect may fail.
data_addr
.sin_port
= 0; /* let system pick one */
data
= socket(AF_INET
, SOCK_STREAM
, 0);
(void)sprintf(ftp_error
,"ftp: socket %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
if (setsockopt(data
, SOL_SOCKET
, SO_REUSEADDR
, (char *) 0, 0) < 0) {
if (setsockopt(data
, SOL_SOCKET
, SO_REUSEADDR
, (char *)&on
, sizeof on
) < 0) {
(void)sprintf(ftp_error
,"ftp: setsockopt (reuse address) %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
if (bind(data
, (struct sockaddr
*)&data_addr
, sizeof (data_addr
)) < 0) {
(void)sprintf(ftp_error
,"ftp: bind %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
if (options
& SO_DEBUG
&&
setsockopt(data
, SOL_SOCKET
, SO_DEBUG
, (char *) 0, 0) < 0)
setsockopt(data
, SOL_SOCKET
, SO_DEBUG
, (char *) &on
, on
) < 0)
(void)sprintf(ftp_error
,"ftp: setsockopt (ignoreg) %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
len
= sizeof (data_addr
);
if (getsockname(data
, (struct sockaddr
*)&data_addr
, &len
) < 0) {
(void)sprintf(ftp_error
,"ftp: getsockname %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
if (listen(data
, 1) < 0) {
(void)sprintf(ftp_error
,"ftp: listen %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
a
= (char *)&data_addr
.sin_addr
;
p
= (char *)&data_addr
.sin_port
;
#define UC(b) (((int)b)&0xff)
command("PORT %d,%d,%d,%d,%d,%d",
UC(a
[0]), UC(a
[1]), UC(a
[2]), UC(a
[3]),
if (result
== ERROR
&& sendport
== -1) {
return ((result
== COMPLETE
)?OK
:NOTOK
);
(void) close(data
), data
= -1;
int s
, fromlen
= sizeof (from
);
s
= accept(data
, (struct sockaddr
*) &from
, &fromlen
);
(void)sprintf(ftp_error
,"ftp: accept %s",
(errno
<= sys_nerr
)? sys_errlist
[errno
]:"");
(void) close(data
), data
= -1;
(void)shutdown(fileno(cout
), 1+1);
(void) shutdown(data
, 1+1);