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:
parent
7232a7819b
commit
0d964dcdd6
@ -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 */
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user