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:
parent
d67c58120a
commit
f277cacccf
@ -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.
|
||||
|
@ -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
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user