FTPC simplification and size reduction

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3701 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-06-13 15:43:56 +00:00
parent d67c58120a
commit f277cacccf
11 changed files with 49 additions and 132 deletions

View File

@ -58,3 +58,5 @@
this simple FTP shell to transfer files to/from a remote FTP server.
6.5 2011-xx-xx Gregory Nutt <spudmonkey@racsa.co.cr>
* netutils/ftpc: Simpflication and size reduction.

View File

@ -73,6 +73,13 @@ examples/ftpc
not work from NSH over a telnet NSH connection (Well, it will work you
just won't be able to access the command line).
You may also want to define the following in your configuration file.
Otherwise, you will have not feeback about what is going on:
CONFIG_DEBUG=y
CONFIG_DEBUG_VERBOSE=y
CONFIG_DEBUG_FTPC=y
examples/hello
^^^^^^^^^^^^^^

View File

@ -81,7 +81,7 @@ int ftpc_cdup(SESSION handle)
int ret;
ret = ftpc_cmd(session, "CDUP");
ftpc_currdir(session);
session->currdir = ftpc_rpwd(handle);
return ret;
}

View File

@ -86,6 +86,6 @@ int ftpc_chdir(SESSION handle, FAR const char *path)
return ret;
}
ftpc_currdir(session);
session->currdir = ftpc_rpwd(handle);
return OK;
}

View File

@ -94,9 +94,6 @@ void ftpc_disconnect(SESSION handle)
free(session->initrdir);
free(session->homerdir);
free(session->currdir);
free(session->prevrdir);
free(session->rname);
free(session->lname);
/* Then destroy the session */

View File

@ -95,8 +95,7 @@ static int ftpc_recvinit(struct ftpc_session_s *session, FAR const char *path,
/* Configure the transfer: Initial file offset and tranfer mode */
session->offset = 0;
session->filesize = -1;
session->offset = 0;
ftpc_xfrmode(session, xfrmode);
/* Handle the resume offset (caller is responsible for fseeking in the
@ -116,8 +115,7 @@ static int ftpc_recvinit(struct ftpc_session_s *session, FAR const char *path,
return ERROR;
}
session->size = offset;
session->rstrsize = offset;
session->size = offset;
}
/* Send the RETR (Retrieve a remote file) command. Normally the server
@ -177,25 +175,16 @@ static int ftpc_recvinit(struct ftpc_session_s *session, FAR const char *path,
static int ftpc_recvbinary(FAR struct ftpc_session_s *session,
FAR FILE *rinstream, FAR FILE *loutstream)
{
FAR char *buf;
ssize_t nread;
ssize_t nwritten;
int err;
/* Allocate an I/O buffer */
buf = (FAR char *)malloc(CONFIG_FTP_BUFSIZE);
if (!buf)
{
err = ENOMEM;
goto errout_with_err;
}
/* Loop until the entire file is received */
for (;;)
{
/* Read the data from the socket */
nread = fread(buf, sizeof(char), CONFIG_FTP_BUFSIZE, rinstream);
nread = fread(session->buffer, sizeof(char), CONFIG_FTP_BUFSIZE, rinstream);
if (nread <= 0)
{
/* nread < 0 is an error */
@ -205,18 +194,17 @@ static int ftpc_recvbinary(FAR struct ftpc_session_s *session,
/* errno should already be set by fread */
(void)ftpc_xfrabort(session, rinstream);
goto errout_with_buf;
return ERROR;
}
/* nread == 0 means end of file. Return success */
free(buf);
return OK;
}
/* Write the data to the file */
nwritten = fwrite(buf, sizeof(char), nread, loutstream);
nwritten = fwrite(session->buffer, sizeof(char), nread, loutstream);
if (nwritten != nread)
{
(void)ftpc_xfrabort(session, loutstream);
@ -225,21 +213,13 @@ static int ftpc_recvbinary(FAR struct ftpc_session_s *session,
* What would a short write mean?
*/
goto errout_with_buf;
return ERROR;
}
/* Increment the size of the file written */
session->size += nwritten;
}
errout_with_buf: /* Buffer allocated, errno already set */
free(buf);
return ERROR;
errout_with_err: /* Buffer not allocated, errno needs to be set */
set_errno(err);
return ERROR;
}
/****************************************************************************
@ -339,12 +319,7 @@ int ftpc_getfile(SESSION handle, FAR const char *rname, FAR const char *lname,
goto errout_with_abspath;
}
/* Save the new local and remote file names */
free(session->rname);
free(session->lname);
session->rname = strdup(rname);
session->lname = abslpath;
/* If the offset is non-zero, then seek to that offset in the file */
if (offset > 0)
{
@ -374,11 +349,12 @@ int ftpc_getfile(SESSION handle, FAR const char *rname, FAR const char *lname,
fptc_getreply(session);
}
/* On success, the last rname and lname are retained for debug purpose */
/* Check for success */
if (ret == OK && !FTPC_INTERRUPTED(session))
{
fclose(loutstream);
free(abslpath);
return OK;
}
@ -386,9 +362,6 @@ int ftpc_getfile(SESSION handle, FAR const char *rname, FAR const char *lname,
errout_with_outstream:
fclose(loutstream);
free(session->rname);
session->rname = NULL;
session->lname = NULL;
errout_with_abspath:
free(abslpath);
session->offset = 0;
@ -397,7 +370,7 @@ errout:
}
/****************************************************************************
* Name: ftpc_recvbinary
* Name: ftpc_recvtext
*
* Description:
* Receive a text file.
@ -407,18 +380,7 @@ errout:
int ftpc_recvtext(FAR struct ftpc_session_s *session,
FAR FILE *rinstream, FAR FILE *loutstream)
{
FAR char *buf;
int ch;
int ret = OK;
/* Allocate an I/O buffer */
buf = (FAR char *)malloc(CONFIG_FTP_BUFSIZE);
if (!buf)
{
set_errno(ENOMEM);
return ERROR;
}
/* Read the next character from the incoming data stream */
@ -436,8 +398,7 @@ int ftpc_recvtext(FAR struct ftpc_session_s *session,
/* Ooops... */
(void)ftpc_xfrabort(session, rinstream);
ret = ERROR;
break;
return ERROR;
}
/* If its not a newline, then keep the carriage return */
@ -454,8 +415,7 @@ int ftpc_recvtext(FAR struct ftpc_session_s *session,
if (fputc(ch, loutstream) == EOF)
{
(void)ftpc_xfrabort(session, loutstream);
ret = ERROR;
break;
return ERROR;
}
/* Increase the actual size of the file by one */
@ -463,8 +423,7 @@ int ftpc_recvtext(FAR struct ftpc_session_s *session,
session->size++;
}
free(buf);
return ret;
return OK;
}

View File

@ -167,10 +167,7 @@ struct ftpc_session_s
FAR char *initrdir; /* Initial remote directory */
FAR char *homerdir; /* Remote home directory (currdir on startup) */
FAR char *currdir; /* Remote current directory */
FAR char *prevrdir; /* Previous remote directory */
FAR char *rname; /* Remote file name */
FAR char *homeldir; /* Local home directory (PWD on startup) */
FAR char *lname; /* Local file name */
pid_t pid; /* Task ID of FTP client */
uint8_t xfrmode; /* Previous data transfer type (See FTPC_XFRMODE_* defines) */
uint16_t port; /* Server/proxy port number (probably 21) */
@ -178,12 +175,11 @@ struct ftpc_session_s
uint16_t code; /* Last 3-digit replay code */
uint32_t replytimeo; /* Server replay timeout (ticks) */
uint32_t conntimeo; /* Connection timeout (ticks) */
off_t filesize; /* Total file size to transfer */
off_t offset; /* Transfer file offset */
off_t size; /* Number of bytes transferred */
off_t rstrsize; /* restart size */
char reply[CONFIG_FTP_MAXREPLY+1]; /* Last reply string from server */
char buffer[CONFIG_FTP_BUFSIZE]; /* Used to buffer file data during transfers */
};
/* There is not yet any want to change the local working directly (an lcd
@ -241,7 +237,6 @@ EXTERN int ftpc_relogin(FAR struct ftpc_session_s *session);
EXTERN void ftpc_reset(struct ftpc_session_s *session);
EXTERN int ftpc_cmd(struct ftpc_session_s *session, const char *cmd, ...);
EXTERN int fptc_getreply(struct ftpc_session_s *session);
EXTERN void ftpc_currdir(struct ftpc_session_s *session);
EXTERN FAR const char *ftpc_lpwd(void);
EXTERN int ftpc_xfrmode(struct ftpc_session_s *session, uint8_t xfrmode);
EXTERN FAR char *ftpc_absrpath(FAR struct ftpc_session_s *session,

View File

@ -201,7 +201,6 @@ int ftpc_relogin(FAR struct ftpc_session_s *session)
FTPC_SET_LOGGEDIN(session);
session->homerdir = ftpc_rpwd((SESSION)session);
session->currdir = strdup(session->homerdir);
session->prevrdir = strdup(session->homerdir);
/* If the user has requested a special start up directory, then change to
* that directory now.

View File

@ -82,20 +82,8 @@
static int ftpc_sendbinary(FAR struct ftpc_session_s *session,
FAR FILE *linstream, FILE *routstream)
{
FAR char *buf;
ssize_t nread;
ssize_t nwritten;
int ret = OK;
/* Allocate a buffer to hold the binary data */
buf = (char *)malloc(CONFIG_FTP_BUFSIZE);
if (!buf)
{
ndbg("Failed to allocate an I/O buffer\n");
set_errno(ENOMEM);
return ERROR;
}
/* Loop until the entire file is sent */
@ -103,7 +91,7 @@ static int ftpc_sendbinary(FAR struct ftpc_session_s *session,
{
/* Read data from the file */
nread = fread(buf, sizeof(char), CONFIG_FTP_BUFSIZE, linstream);
nread = fread(session->buffer, sizeof(char), CONFIG_FTP_BUFSIZE, linstream);
if (nread <= 0)
{
/* nread == 0 is just EOF */
@ -111,34 +99,30 @@ static int ftpc_sendbinary(FAR struct ftpc_session_s *session,
if (nread < 0)
{
(void)ftpc_xfrabort(session, linstream);
ret = ERROR;
return ERROR;
}
/* Break out of the loop */
/* Return success */
break;
return OK;
}
/* Send the data */
nwritten = fwrite(buf, sizeof(char), nread, routstream);
nwritten = fwrite(session->buffer, sizeof(char), nread, routstream);
if (nwritten != nread)
{
(void)ftpc_xfrabort(session, routstream);
/* Break out of the loop and return failue */
/* Return failue */
ret = ERROR;
break;
return ERROR;
}
/* Increment the size of the file sent */
session->size += nread;
}
free(buf);
return ret;
}
/****************************************************************************
@ -152,7 +136,6 @@ static int ftpc_sendbinary(FAR struct ftpc_session_s *session,
static int ftpc_sendtext(FAR struct ftpc_session_s *session,
FAR FILE *linstream, FAR FILE *routstream)
{
char *buf = (char *)malloc(CONFIG_FTP_BUFSIZE);
int ch;
int ret = OK;
@ -190,7 +173,6 @@ static int ftpc_sendtext(FAR struct ftpc_session_s *session,
session->size++;
}
free(buf);
return ret;
}
@ -206,8 +188,11 @@ static int ftpc_sendfile(struct ftpc_session_s *session, const char *path,
FILE *stream, uint8_t how, uint8_t xfrmode)
{
long offset = session->offset;
#ifdef CONFIG_DEBUG
FAR char *rname;
FAR char *str;
int len;
#endif
int ret;
session->offset = 0;
@ -244,7 +229,6 @@ static int ftpc_sendfile(struct ftpc_session_s *session, const char *path,
{
ret = ftpc_cmd(session, "REST %ld", offset);
session->size = offset;
session->rstrsize = offset;
}
/* Send the file using STOR, STOU, or APPE:
@ -276,7 +260,8 @@ static int ftpc_sendfile(struct ftpc_session_s *session, const char *path,
}
/* Get the remote filename from the response */
#ifdef CONFIG_DEBUG
str = strstr(session->reply, " for ");
if (str)
{
@ -284,18 +269,19 @@ static int ftpc_sendfile(struct ftpc_session_s *session, const char *path,
len = strlen(str);
if (len)
{
free(session->rname);
if (*str == '\'')
{
session->rname = strndup(str+1, len-3);
rname = strndup(str+1, len-3);
}
else
{
session->rname = strndup(str, len-1);
nvdbg("Unique filename is: %s\n", session->rname);
rname = strndup(str, len-1);
nvdbg("Unique filename is: %s\n", rname);
}
free(rname);
}
}
#endif
}
break;
@ -424,8 +410,7 @@ int ftp_putfile(SESSION handle, const char *lname, const char *rname,
if (ret != OK)
{
ndbg("stat(%s) failed: %d\n", errno);
free(abslpath);
goto errout;
goto errout_with_abspath;
}
/* Make sure that the local name does not refer to a directory */
@ -445,14 +430,6 @@ int ftp_putfile(SESSION handle, const char *lname, const char *rname,
goto errout_with_abspath;
}
/* Configure for the transfer */
session->filesize = statbuf.st_size;
free(session->rname);
free(session->lname);
session->rname = strdup(rname);
session->lname = abslpath;
/* Are we resuming a transfer? */
session->offset = 0;
@ -483,12 +460,13 @@ int ftp_putfile(SESSION handle, const char *lname, const char *rname,
}
}
/* On success, the last rname and lname are retained for debug purpose */
/* Send the file */
ret = ftpc_sendfile(session, rname, finstream, how, xfrmode);
if (ret == OK)
{
fclose(finstream);
free(abslpath);
return OK;
}
@ -496,9 +474,6 @@ int ftp_putfile(SESSION handle, const char *lname, const char *rname,
errout_with_instream:
fclose(finstream);
free(session->rname);
session->rname = NULL;
session->lname = NULL;
errout_with_abspath:
free(abslpath);
errout:

View File

@ -341,7 +341,6 @@ void ftpc_xfrreset(struct ftpc_session_s *session)
{
session->size = 0;
session->flags &= ~FTPC_XFER_FLAGS;
session->rstrsize = 0;
}
/****************************************************************************
@ -388,7 +387,6 @@ int ftpc_xfrmode(struct ftpc_session_s *session, uint8_t xfrmode)
int ftpc_xfrabort(FAR struct ftpc_session_s *session, FAR FILE *stream)
{
char buffer[CONFIG_FTP_BUFSIZE];
FAR struct pollfd fds;
int ret;
@ -409,7 +407,7 @@ int ftpc_xfrabort(FAR struct ftpc_session_s *session, FAR FILE *stream)
/* Read data from command channel */
nvdbg("Flush cmd channel data\n");
while (stream && fread(buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0);
while (stream && fread(session->buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0);
return OK;
}
@ -427,8 +425,8 @@ int ftpc_xfrabort(FAR struct ftpc_session_s *session, FAR FILE *stream)
/* Read remaining bytes from connection */
while (stream && fread(buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0);
while(stream && fread(buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0)
while (stream && fread(session->buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0);
while(stream && fread(session->buffer, 1, CONFIG_FTP_BUFSIZE, stream) > 0)
/* Get the ABORt reply */

View File

@ -119,21 +119,6 @@ void ftpc_reset(struct ftpc_session_s *session)
session->conntimeo = CONFIG_FTP_DEFTIMEO * CLOCKS_PER_SEC;
}
/****************************************************************************
* Name: ftpc_currdir
*
* Description:
* Update the remote current working directory
*
****************************************************************************/
void ftpc_currdir(struct ftpc_session_s *session)
{
free(session->prevrdir);
session->prevrdir = session->currdir;
session->currdir = ftpc_rpwd((SESSION)session);
}
/****************************************************************************
* Name: ftpc_lpwd
*