More FTP client fixes

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3661 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-06-02 20:45:35 +00:00
parent 7232a7819b
commit 0d964dcdd6
4 changed files with 47 additions and 70 deletions

View File

@ -95,6 +95,7 @@ static const struct cmdmap_s g_cmdmap[] =
{ "size", cmd_rsize, 2, 2, "<filepath>" }, { "size", cmd_rsize, 2, 2, "<filepath>" },
{ "time", cmd_rtime, 2, 2, "<filepath>" }, { "time", cmd_rtime, 2, 2, "<filepath>" },
{ "up", cmd_rcdup, 1, 1, "" }, { "up", cmd_rcdup, 1, 1, "" },
{ NULL, NULL, 1, 1, NULL }
}; };
static char g_line[CONFIG_FTPC_LINELEN]; static char g_line[CONFIG_FTPC_LINELEN];
@ -383,7 +384,7 @@ int ftpc_main(int argc, char **argv, char **envp)
/* Present a greeting */ /* Present a greeting */
printf("FTPC:\n"); printf("NuttX FTP Client:\n");
FFLUSH(); FFLUSH();
/* Then enter the command line parsing loop */ /* Then enter the command line parsing loop */
@ -392,7 +393,7 @@ int ftpc_main(int argc, char **argv, char **envp)
{ {
/* Display the prompt string */ /* Display the prompt string */
fputs("FTPC>", stdout); fputs("nfc> ", stdout);
FFLUSH(); FFLUSH();
/* Get the next line of input */ /* Get the next line of input */

View File

@ -220,10 +220,10 @@ int ftpc_reconnect(FAR struct ftpc_session_s *session)
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
ndbg("Connected\n"); ndbg("Connected\n");
tmp = inet_ntoa(session->cmd.raddr.sin_addr); tmp = inet_ntoa(addr.sin_addr);
ndbg(" Remote address: %s:%d\n", tmp, ntohs(session->cmd.raddr.sin_port)); ndbg(" Remote address: %s:%d\n", tmp, ntohs(addr.sin_port));
tmp = inet_ntoa(session->cmd.laddr.sin_addr); tmp = inet_ntoa(session->cmd.laddr.sin_addr);
ndbg(" Local address: %s:d\n", tmp, ntohs(session->cmd.laddr.sin_port)); ndbg(" Local address: %s:%d\n", tmp, ntohs(session->cmd.laddr.sin_port));
#endif #endif
return OK; return OK;

View File

@ -140,7 +140,6 @@ struct ftpc_socket_s
FILE *instream; /* Incoming stream */ FILE *instream; /* Incoming stream */
FILE *outstream; /* Outgoing stream */ FILE *outstream; /* Outgoing stream */
struct sockaddr_in laddr; /* Local address */ struct sockaddr_in laddr; /* Local address */
struct sockaddr_in raddr; /* Remote address */
bool connected; /* True: socket is connected */ bool connected; /* True: socket is connected */
}; };

View File

@ -82,12 +82,9 @@
int ftpc_sockinit(FAR struct ftpc_socket_s *sock) int ftpc_sockinit(FAR struct ftpc_socket_s *sock)
{ {
int dupsd;
/* Initialize the socket structure */ /* Initialize the socket structure */
memset(sock, 0, sizeof(struct ftpc_socket_s)); memset(sock, 0, sizeof(struct ftpc_socket_s));
sock->raddr.sin_family = AF_INET;
/* Create a socket descriptor */ /* Create a socket descriptor */
@ -98,50 +95,40 @@ int ftpc_sockinit(FAR struct ftpc_socket_s *sock)
goto errout; goto errout;
} }
/* 'dup' the socket descriptor to create an independent input stream */ /* Call fdopen to "wrap" the socket descriptor as an input stream using C
* buffered I/O.
*/
dupsd = dup(sock->sd); sock->instream = fdopen(sock->sd, "r");
if (dupsd < 0)
{
ndbg("socket() failed: %d\n", errno);
goto errout_with_sd;
}
/* Call fdopen to "wrap" the input stream with C buffered I/O */
sock->instream = fdopen(dupsd, "r");
if (!sock->instream) if (!sock->instream)
{ {
ndbg("fdopen() failed: %d\n", errno); ndbg("fdopen() failed: %d\n", errno);
close(dupsd);
goto errout_with_sd; goto errout_with_sd;
} }
/* 'dup' the socket descriptor to create an independent output stream */ /* Call fdopen to "wrap" the socket descriptor as an output stream using C
* buffered I/O.
*/
dupsd = dup(sock->sd); sock->outstream = fdopen(sock->sd, "w");
if (dupsd < 0)
{
ndbg("socket() failed: %d\n", errno);
goto errout_with_instream;
}
/* Call fdopen to "wrap" the output stream with C buffered I/O */
sock->outstream = fdopen(dupsd, "w");
if (!sock->outstream) if (!sock->outstream)
{ {
ndbg("fdopen() failed: %d\n", errno); ndbg("fdopen() failed: %d\n", errno);
close(dupsd);
goto errout_with_instream; goto errout_with_instream;
} }
return OK; return OK;
/* Close the instream. NOTE: Since the underlying socket descriptor is
* *not* dup'ed, the following close should fail harmlessly.
*/
errout_with_instream: errout_with_instream:
fclose(sock->instream); fclose(sock->instream);
sock->instream = NULL;
errout_with_sd: errout_with_sd:
close(sock->sd); close(sock->sd);
sock->sd = -1;
errout: errout:
return ERROR; return ERROR;
} }
@ -156,17 +143,23 @@ errout:
void ftpc_sockclose(struct ftpc_socket_s *sock) void ftpc_sockclose(struct ftpc_socket_s *sock)
{ {
/* Note that the same underlying socket descriptor is used for both streams.
* There should be harmless failures on the second fclose and the close.
*/
fclose(sock->instream); fclose(sock->instream);
fclose(sock->outstream); fclose(sock->outstream);
close(sock->sd); close(sock->sd);
memset(sock, 0, sizeof(struct ftpc_socket_s)); memset(sock, 0, sizeof(struct ftpc_socket_s));
sock->sd = -1;
} }
/**************************************************************************** /****************************************************************************
* Name: ftpc_sockconnect * Name: ftpc_sockconnect
* *
* Description: * Description:
* Connect the socket to the host * Connect the socket to the host. On a failure, the caller should call.
* ftpc_sockclose() to clean up.
* *
****************************************************************************/ ****************************************************************************/
@ -174,13 +167,12 @@ int ftpc_sockconnect(struct ftpc_socket_s *sock, struct sockaddr_in *addr)
{ {
int ret; int ret;
/* Connect to the socket */ /* Connect to the server */
ret = connect(sock->sd, (struct sockaddr *)addr, sizeof(struct sockaddr)); ret = connect(sock->sd, (struct sockaddr *)addr, sizeof(struct sockaddr));
if (ret < 0) if (ret < 0)
{ {
ndbg("connect() failed: %d\n", errno); ndbg("connect() failed: %d\n", errno);
close(sock->sd);
return ERROR; return ERROR;
} }
@ -190,7 +182,6 @@ int ftpc_sockconnect(struct ftpc_socket_s *sock, struct sockaddr_in *addr)
if (ret < 0) if (ret < 0)
{ {
ndbg("ftpc_sockgetsockname() failed: %d\n", errno); ndbg("ftpc_sockgetsockname() failed: %d\n", errno);
close(sock->sd);
return ERROR; return ERROR;
} }
sock->connected = true; sock->connected = true;
@ -209,7 +200,6 @@ int ftpc_sockconnect(struct ftpc_socket_s *sock, struct sockaddr_in *addr)
void ftpc_sockcopy(FAR struct ftpc_socket_s *dest, void ftpc_sockcopy(FAR struct ftpc_socket_s *dest,
FAR const struct ftpc_socket_s *src) FAR const struct ftpc_socket_s *src)
{ {
memcpy(&dest->raddr, &src->raddr, sizeof(struct sockaddr_in));
memcpy(&dest->laddr, &src->laddr, sizeof(struct sockaddr_in)); memcpy(&dest->laddr, &src->laddr, sizeof(struct sockaddr_in));
dest->connected = ftpc_sockconnected(src); dest->connected = ftpc_sockconnected(src);
} }
@ -226,9 +216,14 @@ int ftpc_sockaccept(struct ftpc_socket_s *sock, const char *mode, bool passive)
{ {
struct sockaddr addr; struct sockaddr addr;
socklen_t addrlen; socklen_t addrlen;
int dupsd;
int sd; int sd;
/* Any previous socket should have been uninitialized (0) or explicitly
* closed (-1).
*/
DEBUGASSERT(sock->sd == 0 || sock->sd == -1);
/* In active mode FTP the client connects from a random port (N>1023) to the /* In active mode FTP the client connects from a random port (N>1023) to the
* FTP server's command port, port 21. Then, the client starts listening to * FTP server's command port, port 21. Then, the client starts listening to
* port N+1 and sends the FTP command PORT N+1 to the FTP server. The server * port N+1 and sends the FTP command PORT N+1 to the FTP server. The server
@ -249,62 +244,44 @@ int ftpc_sockaccept(struct ftpc_socket_s *sock, const char *mode, bool passive)
if (!passive) if (!passive)
{ {
addrlen = sizeof(addr); addrlen = sizeof(addr);
sd = accept(sock->sd, &addr, &addrlen); sock->sd = accept(sock->sd, &addr, &addrlen);
close(sock->sd);
if (sd == -1) if (sd == -1)
{ {
ndbg("accept() failed: %d\n", errno); ndbg("accept() failed: %d\n", errno);
sock->sd = -1;
return ERROR; return ERROR;
} }
sock->sd = sd;
memcpy(&sock->laddr, &addr, sizeof(sock->laddr)); memcpy(&sock->laddr, &addr, sizeof(sock->laddr));
} }
/* Create in/out C buffer I/O streams on the cmd channel */ /* Create in/out C buffer I/O streams on the data channel. First, create
* the incoming buffered stream.
*/
fclose(sock->instream); sock->instream = fdopen(sock->sd, mode);
fclose(sock->outstream);
/* Dup the socket descriptor and create the incoming stream */
dupsd = dup(sock->sd);
if (dupsd < 0)
{
ndbg("dup() failed: %d\n", errno);
goto errout_with_sd;
}
sock->instream = fdopen(dupsd, mode);
if (!sock->instream) if (!sock->instream)
{ {
ndbg("fdopen() failed: %d\n", errno); ndbg("fdopen() failed: %d\n", errno);
close(dupsd);
goto errout_with_sd; goto errout_with_sd;
} }
/* Dup the socket descriptor and create the outgoing stream */ /* Create the outgoing stream */
dupsd = dup(sock->sd); sock->outstream = fdopen(sock->sd, mode);
if (dupsd < 0)
{
ndbg("dup() failed: %d\n", errno);
goto errout_with_instream;
}
sock->outstream = fdopen(dupsd, mode);
if (!sock->outstream) if (!sock->outstream)
{ {
ndbg("fdopen() failed: %d\n", errno); ndbg("fdopen() failed: %d\n", errno);
close(dupsd);
goto errout_with_instream; goto errout_with_instream;
} }
return OK; return OK;
/* Close the instream. NOTE: Since the underlying socket descriptor is
* *not* dup'ed, the following close should fail harmlessly.
*/
errout_with_instream: errout_with_instream:
fclose(sock->instream); fclose(sock->instream);
sock->instream = NULL;
errout_with_sd: errout_with_sd:
close(sock->sd); close(sock->sd);
sock->sd = -1; sock->sd = -1;