summaryrefslogtreecommitdiff
path: root/apps/netutils/ftpc
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-06-03 20:27:30 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-06-03 20:27:30 +0000
commit92fd8f5221ca528c2def13897c712d558adf1675 (patch)
tree0c9d63fe3408864b46597a4eb1c20eace2ffc783 /apps/netutils/ftpc
parent90e92459a9c7a33fb8a005f87ec3f512b760c487 (diff)
downloadnuttx-92fd8f5221ca528c2def13897c712d558adf1675.tar.gz
nuttx-92fd8f5221ca528c2def13897c712d558adf1675.tar.bz2
nuttx-92fd8f5221ca528c2def13897c712d558adf1675.zip
More FTP bugfixes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3665 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'apps/netutils/ftpc')
-rw-r--r--apps/netutils/ftpc/Makefile2
-rw-r--r--apps/netutils/ftpc/ftpc_cdup.c4
-rw-r--r--apps/netutils/ftpc/ftpc_chdir.c2
-rw-r--r--apps/netutils/ftpc/ftpc_chmod.c2
-rw-r--r--apps/netutils/ftpc/ftpc_cmd.c4
-rw-r--r--apps/netutils/ftpc/ftpc_connect.c10
-rw-r--r--apps/netutils/ftpc/ftpc_disconnect.c8
-rw-r--r--apps/netutils/ftpc/ftpc_filesize.c8
-rw-r--r--apps/netutils/ftpc/ftpc_getfile.c65
-rw-r--r--apps/netutils/ftpc/ftpc_idle.c7
-rw-r--r--apps/netutils/ftpc/ftpc_internal.h31
-rw-r--r--apps/netutils/ftpc/ftpc_listdir.c101
-rw-r--r--apps/netutils/ftpc/ftpc_login.c16
-rw-r--r--apps/netutils/ftpc/ftpc_putfile.c60
-rw-r--r--apps/netutils/ftpc/ftpc_rpwd.c (renamed from apps/netutils/ftpc/ftpc_pwd.c)6
-rw-r--r--apps/netutils/ftpc/ftpc_socket.c3
-rw-r--r--apps/netutils/ftpc/ftpc_transfer.c114
-rw-r--r--apps/netutils/ftpc/ftpc_utils.c41
18 files changed, 313 insertions, 171 deletions
diff --git a/apps/netutils/ftpc/Makefile b/apps/netutils/ftpc/Makefile
index 9c5862a53..59121e3b7 100644
--- a/apps/netutils/ftpc/Makefile
+++ b/apps/netutils/ftpc/Makefile
@@ -49,7 +49,7 @@ CSRCS = ftpc_connect.c ftpc_disconnect.c
# FTP commands
CSRCS += ftpc_cdup.c ftpc_chdir.c ftpc_chmod.c ftpc_filesize.c ftpc_filetime.c
CSRCS += ftpc_help.c ftpc_idle.c ftpc_listdir.c ftpc_login.c ftpc_mkdir.c
-CSRCS += ftpc_noop.c ftpc_pwd.c ftpc_quit.c ftpc_rename.c ftpc_rmdir.c ftpc_unlink.c
+CSRCS += ftpc_noop.c ftpc_rpwd.c ftpc_quit.c ftpc_rename.c ftpc_rmdir.c ftpc_unlink.c
CSRCS += ftpc_cmd.c
# FTP transfers
diff --git a/apps/netutils/ftpc/ftpc_cdup.c b/apps/netutils/ftpc/ftpc_cdup.c
index a5f22bbc2..75c02bd96 100644
--- a/apps/netutils/ftpc/ftpc_cdup.c
+++ b/apps/netutils/ftpc/ftpc_cdup.c
@@ -75,13 +75,13 @@
*
****************************************************************************/
- int ftpc_cdup(SESSION handle)
+int ftpc_cdup(SESSION handle)
{
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
int ret;
ret = ftpc_cmd(session, "CDUP");
- ftpc_curdir(session);
+ ftpc_currdir(session);
return ret;
}
diff --git a/apps/netutils/ftpc/ftpc_chdir.c b/apps/netutils/ftpc/ftpc_chdir.c
index 0bc47ddf8..0081b4870 100644
--- a/apps/netutils/ftpc/ftpc_chdir.c
+++ b/apps/netutils/ftpc/ftpc_chdir.c
@@ -86,6 +86,6 @@ int ftpc_chdir(SESSION handle, FAR const char *path)
return ret;
}
- ftpc_curdir(session);
+ ftpc_currdir(session);
return OK;
}
diff --git a/apps/netutils/ftpc/ftpc_chmod.c b/apps/netutils/ftpc/ftpc_chmod.c
index f349edb09..13d06f403 100644
--- a/apps/netutils/ftpc/ftpc_chmod.c
+++ b/apps/netutils/ftpc/ftpc_chmod.c
@@ -85,7 +85,7 @@ int ftpc_chmod(SESSION handle, FAR const char *path, FAR const char *mode)
if (FTPC_HAS_CHMOD(session))
{
- ret = ftpc_cmd(session, "SITE CHMOD %s %s", mode, path);
+ ret = ftpc_cmd(session, "SITE CHMOD %s %s", path, mode);
/* Check for "502 Command not implemented" */
diff --git a/apps/netutils/ftpc/ftpc_cmd.c b/apps/netutils/ftpc/ftpc_cmd.c
index ec89050ba..dc031790d 100644
--- a/apps/netutils/ftpc/ftpc_cmd.c
+++ b/apps/netutils/ftpc/ftpc_cmd.c
@@ -87,8 +87,8 @@ static int ftpc_restore(struct ftpc_session_s *session)
{
/* Set the initial directory to the last valid current directory */
- free(session->initdir);
- session->initdir = ftpc_dequote(session->curdir);
+ free(session->initrdir);
+ session->initrdir = ftpc_dequote(session->currdir);
/* Reconnect to the server */
diff --git a/apps/netutils/ftpc/ftpc_connect.c b/apps/netutils/ftpc/ftpc_connect.c
index 3af6ef65f..8affbdade 100644
--- a/apps/netutils/ftpc/ftpc_connect.c
+++ b/apps/netutils/ftpc/ftpc_connect.c
@@ -41,6 +41,7 @@
#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
#include <errno.h>
#include <debug.h>
@@ -114,6 +115,15 @@ SESSION ftpc_connect(FAR struct ftpc_connect_s *server)
session->port = htons(server->port);
}
+ /* Get the local home directory, i.e., the value of the PWD environment
+ * variable at the time of the connection. We keep a local copy so that
+ * we can change the current working directory without effecting any other
+ * logic that may be in same context.
+ */
+
+ session->homeldir = strdup(ftpc_lpwd());
+/* session->curldir = strdup(sssion->homeldir); */
+
/* Create up a timer to prevent hangs */
session->wdog = wd_create();
diff --git a/apps/netutils/ftpc/ftpc_disconnect.c b/apps/netutils/ftpc/ftpc_disconnect.c
index 90c47ee1d..787de5f1b 100644
--- a/apps/netutils/ftpc/ftpc_disconnect.c
+++ b/apps/netutils/ftpc/ftpc_disconnect.c
@@ -91,10 +91,10 @@ void ftpc_disconnect(SESSION handle)
free(session->uname);
free(session->pwd);
- free(session->initdir);
- free(session->homedir);
- free(session->curdir);
- free(session->prevdir);
+ free(session->initrdir);
+ free(session->homerdir);
+ free(session->currdir);
+ free(session->prevrdir);
free(session->rname);
free(session->lname);
diff --git a/apps/netutils/ftpc/ftpc_filesize.c b/apps/netutils/ftpc/ftpc_filesize.c
index 18561eb1d..d827f736e 100644
--- a/apps/netutils/ftpc/ftpc_filesize.c
+++ b/apps/netutils/ftpc/ftpc_filesize.c
@@ -78,10 +78,10 @@
*
****************************************************************************/
- uint64_t ftpc_filesize(SESSION handle, FAR const char *path)
+off_t ftpc_filesize(SESSION handle, FAR const char *path)
{
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
- uint64_t ret;
+ unsigned long ret;
/* Check if the host supports the SIZE command */
@@ -107,6 +107,6 @@
return ERROR;
}
- sscanf(session->reply, "%*s %llu", &ret);
- return ret;
+ sscanf(session->reply, "%*s %lu", &ret);
+ return (off_t)ret;
}
diff --git a/apps/netutils/ftpc/ftpc_getfile.c b/apps/netutils/ftpc/ftpc_getfile.c
index e9816e5b4..bf9fc69ea 100644
--- a/apps/netutils/ftpc/ftpc_getfile.c
+++ b/apps/netutils/ftpc/ftpc_getfile.c
@@ -270,20 +270,30 @@ int ftpc_getfile(SESSION handle, FAR const char *rname, FAR const char *lname,
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
struct stat statbuf;
FILE *loutstream;
+ FAR char *abslpath;
off_t offset;
int ret;
+ /* Get the full path to the local file */
+
+ abslpath = ftpc_abslpath(session, lname);
+ if (!abslpath)
+ {
+ ndbg("ftpc_abslpath(%s) failed: %d\n", errno);
+ goto errout;
+ }
+
/* Get information about the local file */
- ret = stat(lname, &statbuf);
+ ret = stat(abslpath, &statbuf);
if (ret == 0)
{
/* It already exists. Is it a directory? */
if (S_ISDIR(statbuf.st_mode))
{
- ndbg("'%s' is a directory\n", lname);
- return ERROR;
+ ndbg("'%s' is a directory\n", abslpath);
+ goto errout_with_abspath;
}
}
@@ -292,8 +302,8 @@ int ftpc_getfile(SESSION handle, FAR const char *rname, FAR const char *lname,
#ifdef S_IWRITE
if (!(statbuf.st_mode & S_IWRITE))
{
- ndbg("'%s' permission denied\n", lname);
- return ERROR;
+ ndbg("'%s' permission denied\n", abslpath);
+ goto errout_with_abspath;
}
#endif
@@ -316,36 +326,33 @@ int ftpc_getfile(SESSION handle, FAR const char *rname, FAR const char *lname,
if (ret != OK)
{
ndbg("ftpc_recvinit failed\n");
- return ERROR;
+ goto errout_with_abspath;
}
- loutstream = fopen(lname, (offset > 0 || (how == FTPC_GET_APPEND)) ? "a" : "w");
+ loutstream = fopen(abslpath, (offset > 0 || (how == FTPC_GET_APPEND)) ? "a" : "w");
if (!loutstream)
{
ndbg("fopen failed: %d\n", errno);
- session->offset = 0;
- return ERROR;
+ 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 (offset > 0)
{
ret = fseek(loutstream, offset, SEEK_SET);
if (ret != OK)
{
ndbg("fseek failed: %d\n", errno);
- fclose(loutstream);
- session->offset = 0;
- return ERROR;
+ goto errout_with_outstream;
}
}
- /* Save the new local and remote file names */
-
- free(session->rname);
- free(session->lname);
- session->rname = strdup(rname);
- session->lname = strdup(lname);
-
/* And receive the new file data */
if (xfrmode == FTPC_XFRMODE_ASCII)
@@ -364,8 +371,26 @@ 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 */
+
+ if (ret == OK && !FTPC_INTERRUPTED(session))
+ {
+ fclose(loutstream);
+ return OK;
+ }
+
+ /* Various error exits */
+
+errout_with_outstream:
fclose(loutstream);
- return (ret == OK && !FTPC_INTERRUPTED(session)) ? OK : ERROR;
+ free(session->rname);
+ session->rname = NULL;
+ session->lname = NULL;
+errout_with_abspath:
+ free(abslpath);
+ session->offset = 0;
+errout:
+ return ERROR;
}
/****************************************************************************
diff --git a/apps/netutils/ftpc/ftpc_idle.c b/apps/netutils/ftpc/ftpc_idle.c
index 2d049f8b4..95a94d233 100644
--- a/apps/netutils/ftpc/ftpc_idle.c
+++ b/apps/netutils/ftpc/ftpc_idle.c
@@ -91,7 +91,7 @@ int ftpc_idle(SESSION handle, unsigned int idletime)
if (!FTPC_HAS_IDLE(session))
{
- ndbg("Server doesn't support SITE IDLE\n");
+ ndbg("Server does not support SITE IDLE\n");
return ERROR;
}
@@ -108,12 +108,13 @@ int ftpc_idle(SESSION handle, unsigned int idletime)
ret = ftpc_cmd(session, "SITE IDLE");
}
- /* Check for "502 Command not implemented" */
+ /* Check for "502 Command not implemented" or 500 "Unknown SITE command" */
- if (session->code == 502)
+ if (session->code == 500 || session->code == 502)
{
/* Server does not support SITE IDLE */
+ ndbg("Server does not support SITE IDLE\n");
FTPC_CLR_IDLE(session);
}
diff --git a/apps/netutils/ftpc/ftpc_internal.h b/apps/netutils/ftpc/ftpc_internal.h
index 5e177b36b..6eab632a5 100644
--- a/apps/netutils/ftpc/ftpc_internal.h
+++ b/apps/netutils/ftpc/ftpc_internal.h
@@ -153,11 +153,12 @@ struct ftpc_session_s
WDOG_ID wdog; /* Timer */
FAR char *uname; /* Login uname */
FAR char *pwd; /* Login pwd */
- FAR char *initdir; /* Initial remote directory */
- FAR char *homedir; /* Home directory (curdir on startup) */
- FAR char *curdir; /* Current directory */
- FAR char *prevdir; /* Previous directory */
+ 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) */
@@ -174,6 +175,13 @@ struct ftpc_session_s
char reply[CONFIG_FTP_MAXREPLY+1]; /* Last reply string from server */
};
+/* There is not yet any want to change the local working directly (an lcd
+ * command), but the following definition is provided to reserve the name
+ * for the storage location for the local current working directory.
+ */
+
+#define curldir homeldir
+
/****************************************************************************
* Public Data
****************************************************************************/
@@ -212,16 +220,23 @@ EXTERN void ftpc_stripcrlf(FAR char *str);
EXTERN void ftpc_stripslash(FAR char *str);
EXTERN FAR char *ftpc_dequote(FAR const char *hostname);
+/* Connection helpers */
+
+EXTERN int ftpc_reconnect(FAR struct ftpc_session_s *session);
+EXTERN int ftpc_relogin(FAR struct ftpc_session_s *session);
+
/* FTP helpers */
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_curdir(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 int ftpc_reconnect(FAR struct ftpc_session_s *session);
-EXTERN int ftpc_relogin(FAR struct ftpc_session_s *session);
+EXTERN FAR char *ftpc_absrpath(FAR struct ftpc_session_s *session,
+ FAR const char *relpath);
+EXTERN FAR char *ftpc_abslpath(FAR struct ftpc_session_s *session,
+ FAR const char *relpath);
/* Socket helpers */
diff --git a/apps/netutils/ftpc/ftpc_listdir.c b/apps/netutils/ftpc/ftpc_listdir.c
index 4c36445ad..e5309daed 100644
--- a/apps/netutils/ftpc/ftpc_listdir.c
+++ b/apps/netutils/ftpc/ftpc_listdir.c
@@ -74,79 +74,6 @@ typedef void (*callback_t)(FAR const char *name, FAR void *arg);
****************************************************************************/
/****************************************************************************
- * Name: ftpc_abspath
- *
- * Description:
- * Get the absolute path to a file, handling tilde expansion.
- *
- ****************************************************************************/
-
-static FAR char *ftpc_abspath(FAR struct ftpc_session_s *session,
- FAR const char *relpath)
-{
- FAR char *ptr = NULL;
- int ret = OK;
-
- /* If no relative path was provide, then use the current working directory */
-
- if (!relpath)
- {
- return strdup(session->curdir);
- }
-
- /* Handle tilde expansion */
-
- if (relpath[0] == '~')
- {
- /* Is the relative path only '~' */
-
- if (relpath[1] == '\0')
- {
- return strdup(session->homedir);
- }
-
- /* No... then a '/' better follow the tilde */
-
- else if (relpath[1] == '/')
- {
- ret = asprintf(&ptr, "%s%s", session->homedir, &relpath[1]);
- }
-
- /* Hmmm... this prety much guaranteed to fail */
-
- else
- {
- ptr = strdup(relpath);
- }
- }
-
- /* No tilde expansion. Check for a path relative to the current
- * directory.
- */
-
- else if (strncmp(relpath, "./", 2) == 0)
- {
- ret = asprintf(&ptr, "%s%s", session->curdir, relpath+1);
- }
-
- /* Check for an absolute path */
-
- else if (relpath[0] == '/' && relpath[1] == ':' && relpath[2] == '\\')
- {
- ptr = strdup(relpath);
- }
-
- /* Take a wild guess */
-
- else
- {
- ret = asprintf(&ptr, "%s/%s", session->curdir, relpath);
- }
-
- return ptr;
-}
-
-/****************************************************************************
* Name: ftpc_dircount
*
* Description:
@@ -342,30 +269,30 @@ FAR struct ftpc_dirlist_s *ftpc_listdir(SESSION handle,
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
struct ftpc_dirlist_s *dirlist;
FILE *filestream;
- FAR char *abspath;
+ FAR char *absrpath;
FAR char *tmpfname;
- bool iscurdir;
+ bool iscurrdir;
unsigned int nnames;
int allocsize;
int ret;
/* Get the absolute path to the directory */
- abspath = ftpc_abspath(session, dirpath);
- ftpc_stripslash(abspath);
+ absrpath = ftpc_absrpath(session, dirpath);
+ ftpc_stripslash(absrpath);
/* Is the directory also the remote current working directory? */
- iscurdir = (strcmp(abspath, session->curdir) == 0);
+ iscurrdir = (strcmp(absrpath, session->currdir) == 0);
/* Create a temporary file to hold the directory listing */
- asprintf(&tmpfname, "%s/TMP%s.dat", CONFIG_FTP_TMPDIR, getpid());
+ asprintf(&tmpfname, "%s/TMP%d.dat", CONFIG_FTP_TMPDIR, getpid());
filestream = fopen(tmpfname, "w+");
if (!filestream)
{
ndbg("Failed to create %s: %d\n", tmpfname, errno);
- free(abspath);
+ free(absrpath);
free(tmpfname);
return NULL;
}
@@ -374,12 +301,12 @@ FAR struct ftpc_dirlist_s *ftpc_listdir(SESSION handle,
* directory itself.
*/
- if (!iscurdir)
+ if (!iscurrdir)
{
- ret = ftpc_cmd(session, "CWD %s", abspath);
+ ret = ftpc_cmd(session, "CWD %s", absrpath);
if (ret != OK)
{
- ndbg("CWD to %s failed\n", abspath);
+ ndbg("CWD to %s failed\n", absrpath);
}
}
@@ -391,12 +318,12 @@ FAR struct ftpc_dirlist_s *ftpc_listdir(SESSION handle,
/* Go back to the correct current working directory */
- if (!iscurdir)
+ if (!iscurrdir)
{
- int tmpret = ftpc_cmd(session, "CWD %s", session->curdir);
+ int tmpret = ftpc_cmd(session, "CWD %s", session->currdir);
if (tmpret != OK)
{
- ndbg("CWD back to to %s failed\n", session->curdir);
+ ndbg("CWD back to to %s failed\n", session->currdir);
}
}
@@ -435,7 +362,7 @@ FAR struct ftpc_dirlist_s *ftpc_listdir(SESSION handle,
errout:
fclose(filestream);
- free(abspath);
+ free(absrpath);
unlink(tmpfname);
free(tmpfname);
return dirlist;
diff --git a/apps/netutils/ftpc/ftpc_login.c b/apps/netutils/ftpc/ftpc_login.c
index 83d2cde05..1d6ff395c 100644
--- a/apps/netutils/ftpc/ftpc_login.c
+++ b/apps/netutils/ftpc/ftpc_login.c
@@ -105,9 +105,9 @@ int ftpc_login(SESSION handle, FAR struct ftpc_login_s *login)
/* Save the login parameter */
- session->uname = ftpc_dequote(login->uname);
- session->pwd = ftpc_dequote(login->pwd);
- session->initdir = ftpc_dequote(login->rdir);
+ session->uname = ftpc_dequote(login->uname);
+ session->pwd = ftpc_dequote(login->pwd);
+ session->initrdir = ftpc_dequote(login->rdir);
/* Is passive mode requested? */
@@ -198,17 +198,17 @@ int ftpc_relogin(FAR struct ftpc_session_s *session)
*/
FTPC_SET_LOGGEDIN(session);
- session->homedir = ftpc_pwd((SESSION)session);
- session->curdir = strdup(session->homedir);
- session->prevdir = strdup(session->homedir);
+ 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.
*/
- if (session->initdir)
+ if (session->initrdir)
{
- ftpc_chdir((SESSION)session, session->initdir);
+ ftpc_chdir((SESSION)session, session->initrdir);
}
return OK;
diff --git a/apps/netutils/ftpc/ftpc_putfile.c b/apps/netutils/ftpc/ftpc_putfile.c
index f0e85a0bc..c465cc66d 100644
--- a/apps/netutils/ftpc/ftpc_putfile.c
+++ b/apps/netutils/ftpc/ftpc_putfile.c
@@ -286,15 +286,15 @@ static int ftpc_sendfile(struct ftpc_session_s *session, const char *path,
len = strlen(str);
if (len)
{
- free(session->lname);
+ free(session->rname);
if (*str == '\'')
{
- session->lname = strndup(str+1, len-3);
+ session->rname = strndup(str+1, len-3);
}
else
{
- session->lname = strndup(str, len-1);
- nvdbg("Unique filename is: %s\n", session->lname);
+ session->rname = strndup(str, len-1);
+ nvdbg("Unique filename is: %s\n", session->rname);
}
}
}
@@ -383,34 +383,45 @@ int ftp_putfile(SESSION handle, const char *lname, const char *rname,
uint8_t how, uint8_t xfrmode)
{
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
+ FAR char *abslpath;
struct stat statbuf;
FILE *finstream;
int ret;
+ /* Get the full path to the local file */
+
+ abslpath = ftpc_abslpath(session, lname);
+ if (!abslpath)
+ {
+ ndbg("ftpc_abslpath(%s) failed: %d\n", errno);
+ goto errout;
+ }
+
/* Make sure that the local file exists */
- ret = stat(lname, &statbuf);
+ ret = stat(abslpath, &statbuf);
if (ret != OK)
{
- ndbg("stat() failed: %d\n", errno);
- return ERROR;
+ ndbg("stat(%s) failed: %d\n", errno);
+ free(abslpath);
+ goto errout;
}
/* Make sure that the local name does not refer to a directory */
if (S_ISDIR(statbuf.st_mode))
{
- ndbg("%s is a directory\n", lname);
- return ERROR;
+ ndbg("%s is a directory\n", abslpath);
+ goto errout_with_abspath;
}
/* Open the local file for reading */
- finstream = fopen(lname, "r");
+ finstream = fopen(abslpath, "r");
if (!finstream == 0)
{
ndbg("fopen() failed: %d\n", errno);
- return ERROR;
+ goto errout_with_abspath;
}
/* Configure for the transfer */
@@ -418,8 +429,8 @@ int ftp_putfile(SESSION handle, const char *lname, const char *rname,
session->filesize = statbuf.st_size;
free(session->rname);
free(session->lname);
- session->rname = strdup(lname);
- session->lname = strdup(rname);
+ session->rname = strdup(rname);
+ session->lname = abslpath;
/* Are we resuming a transfer? */
@@ -434,6 +445,7 @@ int ftp_putfile(SESSION handle, const char *lname, const char *rname,
if (session->offset == (off_t)ERROR)
{
ndbg("Failed to get size of remote file: %s\n", rname);
+ goto errout_with_instream;
}
else
{
@@ -445,13 +457,29 @@ int ftp_putfile(SESSION handle, const char *lname, const char *rname,
if (ret != OK)
{
ndbg("fseek failed: %d\n", errno);
- fclose(finstream);
- return ERROR;
+ goto errout_with_instream;
}
}
}
+ /* On success, the last rname and lname are retained for debug purpose */
+
ret = ftpc_sendfile(session, rname, finstream, how, xfrmode);
+ if (ret == OK)
+ {
+ fclose(finstream);
+ return OK;
+ }
+
+ /* Various error exits */
+
+errout_with_instream:
fclose(finstream);
- return ret;
+ free(session->rname);
+ session->rname = NULL;
+ session->lname = NULL;
+errout_with_abspath:
+ free(abslpath);
+errout:
+ return ERROR;
}
diff --git a/apps/netutils/ftpc/ftpc_pwd.c b/apps/netutils/ftpc/ftpc_rpwd.c
index e8cfaef70..091a12944 100644
--- a/apps/netutils/ftpc/ftpc_pwd.c
+++ b/apps/netutils/ftpc/ftpc_rpwd.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * apps/netutils/ftpc/ftpc_pwd.c
+ * apps/netutils/ftpc/ftpc_rpwd.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
@@ -72,14 +72,14 @@
****************************************************************************/
/****************************************************************************
- * Name: ftpc_pwd
+ * Name: ftpc_rpwd
*
* Descripton:
* Returns the current working directory on the remote server.
*
****************************************************************************/
-FAR char *ftpc_pwd(SESSION handle)
+FAR char *ftpc_rpwd(SESSION handle)
{
FAR struct ftpc_session_s *session = (FAR struct ftpc_session_s *)handle;
FAR char *start;
diff --git a/apps/netutils/ftpc/ftpc_socket.c b/apps/netutils/ftpc/ftpc_socket.c
index 129e6f565..d70bf1d63 100644
--- a/apps/netutils/ftpc/ftpc_socket.c
+++ b/apps/netutils/ftpc/ftpc_socket.c
@@ -216,7 +216,6 @@ int ftpc_sockaccept(struct ftpc_socket_s *sock, const char *mode, bool passive)
{
struct sockaddr addr;
socklen_t addrlen;
- int sd;
/* Any previous socket should have been uninitialized (0) or explicitly
* closed (-1).
@@ -245,7 +244,7 @@ int ftpc_sockaccept(struct ftpc_socket_s *sock, const char *mode, bool passive)
{
addrlen = sizeof(addr);
sock->sd = accept(sock->sd, &addr, &addrlen);
- if (sd == -1)
+ if (sock->sd == -1)
{
ndbg("accept() failed: %d\n", errno);
return ERROR;
diff --git a/apps/netutils/ftpc/ftpc_transfer.c b/apps/netutils/ftpc/ftpc_transfer.c
index bc0ca8b03..8d1a577e9 100644
--- a/apps/netutils/ftpc/ftpc_transfer.c
+++ b/apps/netutils/ftpc/ftpc_transfer.c
@@ -159,6 +159,80 @@ static int ftp_pasvmode(struct ftpc_session_s *session,
}
/****************************************************************************
+ * Name: ftpc_abspath
+ *
+ * Description:
+ * Get the absolute path to a file, handling tilde expansion.
+ *
+ ****************************************************************************/
+
+static FAR char *ftpc_abspath(FAR struct ftpc_session_s *session,
+ FAR const char *relpath, FAR const char *homedir,
+ FAR const char *curdir)
+{
+ FAR char *ptr = NULL;
+ int ret = OK;
+
+ /* If no relative path was provide, then use the current working directory */
+
+ if (!relpath)
+ {
+ return strdup(curdir);
+ }
+
+ /* Handle tilde expansion */
+
+ if (relpath[0] == '~')
+ {
+ /* Is the relative path only '~' */
+
+ if (relpath[1] == '\0')
+ {
+ return strdup(homedir);
+ }
+
+ /* No... then a '/' better follow the tilde */
+
+ else if (relpath[1] == '/')
+ {
+ ret = asprintf(&ptr, "%s%s", homedir, &relpath[1]);
+ }
+
+ /* Hmmm... this pretty much guaranteed to fail */
+
+ else
+ {
+ ptr = strdup(relpath);
+ }
+ }
+
+ /* No tilde expansion. Check for a path relative to the current
+ * directory.
+ */
+
+ else if (strncmp(relpath, "./", 2) == 0)
+ {
+ ret = asprintf(&ptr, "%s%s", curdir, relpath+1);
+ }
+
+ /* Check for an absolute path */
+
+ else if (relpath[0] == '/' && relpath[1] == ':' && relpath[2] == '\\')
+ {
+ ptr = strdup(relpath);
+ }
+
+ /* Assume it a relative path */
+
+ else
+ {
+ ret = asprintf(&ptr, "%s/%s", curdir, relpath);
+ }
+
+ return ptr;
+}
+
+/****************************************************************************
* Public Functions
****************************************************************************/
@@ -182,6 +256,7 @@ int ftpc_xfrinit(FAR struct ftpc_session_s *session)
if (!ftpc_connected(session))
{
+ ndbg("Not connected\n");
goto errout;
}
@@ -207,6 +282,7 @@ int ftpc_xfrinit(FAR struct ftpc_session_s *session)
ret = ftp_pasvmode(session, addrport);
if (ret != OK)
{
+ ndbg("ftp_pasvmode() failed: %d\n", errno);
goto errout_with_data;
}
}
@@ -343,7 +419,7 @@ int ftpc_xfrabort(FAR struct ftpc_session_s *session, FAR FILE *stream)
* <IAC IP><IAC DM>ABORT<CR><LF>
*/
- ndbg("Telnet ABORt sequence\n");
+ nvdbg("Telnet ABORt sequence\n");
ftpc_sockprintf(&session->cmd, "%c%c", TELNET_IAC, TELNET_IP); /* Interrupt process */
ftpc_sockprintf(&session->cmd, "%c%c", TELNET_IAC, TELNET_DM); /* Telnet synch signal */
ftpc_sockprintf(&session->cmd, "ABOR\r\n"); /* Abort */
@@ -435,3 +511,39 @@ void ftpc_timeout(int argc, uint32_t arg1, ...)
DEBUGASSERT(argc == 1 && session);
kill(session->pid, CONFIG_FTP_SIGNAL);
}
+
+/****************************************************************************
+ * Name: ftpc_absrpath
+ *
+ * Description:
+ * Get the absolute path to a remote file, handling tilde expansion.
+ *
+ ****************************************************************************/
+
+FAR char *ftpc_absrpath(FAR struct ftpc_session_s *session,
+ FAR const char *relpath)
+{
+ FAR char *absrpath = ftpc_abspath(session, relpath,
+ session->homerdir, session->currdir);
+ nvdbg("%s -> %s\n", relpath, absrpath);
+ return absrpath;
+}
+
+/****************************************************************************
+ * Name: ftpc_abslpath
+ *
+ * Description:
+ * Get the absolute path to a local file, handling tilde expansion.
+ *
+ ****************************************************************************/
+
+FAR char *ftpc_abslpath(FAR struct ftpc_session_s *session,
+ FAR const char *relpath)
+{
+ FAR char *abslpath = ftpc_abspath(session, relpath,
+ session->homeldir, session->curldir);
+ nvdbg("%s -> %s\n", relpath, abslpath);
+ return abslpath;
+}
+
+
diff --git a/apps/netutils/ftpc/ftpc_utils.c b/apps/netutils/ftpc/ftpc_utils.c
index 9692cae4f..eec52ec8f 100644
--- a/apps/netutils/ftpc/ftpc_utils.c
+++ b/apps/netutils/ftpc/ftpc_utils.c
@@ -109,8 +109,8 @@ void ftpc_reset(struct ftpc_session_s *session)
session->uname = NULL;
free(session->pwd);
session->pwd = NULL;
- free(session->initdir);
- session->initdir = NULL;
+ free(session->initrdir);
+ session->initrdir = NULL;
session->flags = FTPC_FLAGS_INIT;
session->xfrmode = FTPC_XFRMODE_UNKNOWN;
session->code = 0;
@@ -119,18 +119,43 @@ void ftpc_reset(struct ftpc_session_s *session)
}
/****************************************************************************
- * Name: ftpc_curdir
+ * Name: ftpc_currdir
*
* Description:
- * Update the current working directory
+ * Update the remote current working directory
*
****************************************************************************/
-void ftpc_curdir(struct ftpc_session_s *session)
+void ftpc_currdir(struct ftpc_session_s *session)
{
- free(session->prevdir);
- session->prevdir = session->curdir;
- session->curdir = ftpc_pwd((SESSION)session);
+ free(session->prevrdir);
+ session->prevrdir = session->currdir;
+ session->currdir = ftpc_rpwd((SESSION)session);
+}
+
+/****************************************************************************
+ * Name: ftpc_lpwd
+ *
+ * Description:
+ * Return the local current working directory. NOTE: This is a peek at
+ * a global copy. The caller should call strdup if it wants to keep it.
+ *
+ ****************************************************************************/
+
+FAR const char *ftpc_lpwd(void)
+{
+#ifndef CONFIG_DISABLE_ENVIRON
+ FAR const char *val;
+
+ val = getenv("PWD");
+ if (!val)
+ {
+ val = CONFIG_FTP_TMPDIR;
+ }
+ return val;
+#else
+ return CONFIG_FTP_TMPDIR;
+#endif
}
/****************************************************************************