summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/examples/README.txt8
-rwxr-xr-xapps/examples/ftpc/ftpc_cmds.c9
-rw-r--r--apps/include/ftpc.h5
-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
-rw-r--r--apps/nshlib/nsh_apps.c28
-rw-r--r--apps/nshlib/nsh_parse.c19
-rwxr-xr-xnuttx/configs/olimex-lpc1766stk/README.txt8
-rw-r--r--nuttx/lib/stdio/lib_sscanf.c85
25 files changed, 413 insertions, 233 deletions
diff --git a/apps/examples/README.txt b/apps/examples/README.txt
index 2a15dac5d..a67d9ad04 100644
--- a/apps/examples/README.txt
+++ b/apps/examples/README.txt
@@ -56,9 +56,13 @@ examples/ftpc
to that it will only work as a "built-in" program that can be run from
NSH when CONFIG_NSH_BUILTIN_APPS is defined.
- From NSH, the startup command line is then:
+ From NSH, the startup command sequence is as follows. This is only
+ an example, your configration could have different mass storage devices,
+ mount paths, and FTP directories:
- ftpc xx.xx.xx.xx[:pp]
+ mount -t vfat /dev/mmcsd0 /tmp # Mount the SD card at /tmp
+ cd /tmp # cd into the /tmp directory
+ ftpc xx.xx.xx.xx[:pp] # Start the FTP client
where xx.xx.xx.xx is the IP address of the FTP server and pp is an
optional port number.
diff --git a/apps/examples/ftpc/ftpc_cmds.c b/apps/examples/ftpc/ftpc_cmds.c
index fd07a68ca..f0a0a2413 100755
--- a/apps/examples/ftpc/ftpc_cmds.c
+++ b/apps/examples/ftpc/ftpc_cmds.c
@@ -108,7 +108,7 @@ int cmd_rchdir(SESSION handle, int argc, char **argv)
int cmd_rpwd(SESSION handle, int argc, char **argv)
{
- FAR char *pwd = ftpc_pwd(handle);
+ FAR char *pwd = ftpc_rpwd(handle);
if (pwd)
{
printf("PWD: %s\n", pwd);
@@ -178,8 +178,8 @@ int cmd_rrename(SESSION handle, int argc, char **argv)
int cmd_rsize(SESSION handle, int argc, char **argv)
{
- uint64_t size = ftpc_filesize(handle, argv[1]);
- printf("SIZE: %ull\n", size);
+ off_t size = ftpc_filesize(handle, argv[1]);
+ printf("SIZE: %lu\n", size);
return OK;
}
@@ -190,7 +190,7 @@ int cmd_rsize(SESSION handle, int argc, char **argv)
int cmd_rtime(SESSION handle, int argc, char **argv)
{
time_t filetime = ftpc_filetime(handle, argv[1]);
- printf("TIME: %ul\n", (long)filetime);
+ printf("TIME: %lu\n", (long)filetime);
return OK;
}
@@ -264,6 +264,7 @@ int cmd_rls(SESSION handle, int argc, char **argv)
{
printf(" %s\n", dirlist->name[i]);
}
+ FFLUSH();
ftpc_dirfree(dirlist);
return OK;
diff --git a/apps/include/ftpc.h b/apps/include/ftpc.h
index 3f373dad8..ed5e3fab9 100644
--- a/apps/include/ftpc.h
+++ b/apps/include/ftpc.h
@@ -42,6 +42,7 @@
#include <nuttx/config.h>
+#include <sys/types.h>
#include <stdbool.h>
#include <signal.h>
#include <time.h>
@@ -184,7 +185,7 @@ EXTERN int ftpc_login(SESSION handle, FAR struct ftpc_login_s *login);
EXTERN int ftpc_quit(SESSION handle);
EXTERN int ftpc_chdir(SESSION handle, FAR const char *path);
-EXTERN FAR char *ftpc_pwd(SESSION handle);
+EXTERN FAR char *ftpc_rpwd(SESSION handle);
EXTERN int ftpc_cdup(SESSION handle);
EXTERN int ftpc_mkdir(SESSION handle, FAR const char *path);
EXTERN int ftpc_rmdir(SESSION handle, FAR const char *path);
@@ -192,7 +193,7 @@ EXTERN int ftpc_rmdir(SESSION handle, FAR const char *path);
EXTERN int ftpc_unlink(SESSION handle, FAR const char *path);
EXTERN int ftpc_chmod(SESSION handle, FAR const char *path, FAR const char *mode);
EXTERN int ftpc_rename(SESSION handle, FAR const char *oldname, FAR const char *newname);
-EXTERN uint64_t ftpc_filesize(SESSION handle, FAR const char *path);
+EXTERN off_t ftpc_filesize(SESSION handle, FAR const char *path);
EXTERN time_t ftpc_filetime(SESSION handle, FAR const char *filename);
EXTERN int ftpc_idle(SESSION handle, unsigned int idletime);
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
}
/****************************************************************************
diff --git a/apps/nshlib/nsh_apps.c b/apps/nshlib/nsh_apps.c
index 0d460a391..ec3d6ec88 100644
--- a/apps/nshlib/nsh_apps.c
+++ b/apps/nshlib/nsh_apps.c
@@ -89,9 +89,6 @@
int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
FAR char *argv[])
{
-#ifndef CONFIG_APPS_BINDIR
- FAR const char * name;
-#endif
int ret = OK;
/* Try to find command within pre-built application list. */
@@ -99,30 +96,7 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
ret = exec_namedapp(cmd, argv);
if (ret < 0)
{
- int err = -errno;
-#ifndef CONFIG_APPS_BINDIR
- int i;
-
- /* On failure, list the set of available built-in commands */
-
- nsh_output(vtbl, "Builtin Apps: ");
- for (i = 0; (name = namedapp_getname(i)) != NULL; i++)
- {
- nsh_output(vtbl, "%s ", name);
- }
- nsh_output(vtbl, "\nand type 'help' for more NSH commands.\n\n");
-
- /* If the failing command was '?', then do not report an error */
-
- if (strcmp(cmd, "?") != 0)
- {
- return err;
- }
-
- return OK;
-#else
- return err;
-#endif
+ return -errno;
}
#ifdef CONFIG_SCHED_WAITPID
diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c
index f6a778a03..5819def75 100644
--- a/apps/nshlib/nsh_parse.c
+++ b/apps/nshlib/nsh_parse.c
@@ -140,6 +140,10 @@ static const struct cmdmap_s g_cmdmap[] =
{ "[", cmd_lbracket, 4, NSH_MAX_ARGUMENTS, "<expression> ]" },
#endif
+#ifndef CONFIG_NSH_DISABLE_HELP
+ { "?", cmd_help, 1, 1, NULL },
+#endif
+
#if CONFIG_NFILE_DESCRIPTORS > 0
# ifndef CONFIG_NSH_DISABLE_CAT
{ "cat", cmd_cat, 2, NSH_MAX_ARGUMENTS, "<path> [<path> [<path> ...]]" },
@@ -391,6 +395,10 @@ const char g_fmtsignalrecvd[] = "nsh: %s: Interrupted by signal\n";
static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
const struct cmdmap_s *ptr;
+#ifdef CONFIG_NSH_BUILTIN_APPS
+ FAR const char * name;
+ int i;
+#endif
nsh_output(vtbl, "NSH command forms:\n");
#ifndef CONFIG_NSH_DISABLEBG
@@ -419,6 +427,17 @@ static int cmd_help(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
nsh_output(vtbl, " %s\n", ptr->cmd);
}
}
+
+ /* List the set of available built-in commands */
+
+#ifdef CONFIG_NSH_BUILTIN_APPS
+ nsh_output(vtbl, "\nBuiltin Apps: ");
+ for (i = 0; (name = namedapp_getname(i)) != NULL; i++)
+ {
+ nsh_output(vtbl, " %s\n", name);
+ }
+#endif
+
return OK;
}
#endif
diff --git a/nuttx/configs/olimex-lpc1766stk/README.txt b/nuttx/configs/olimex-lpc1766stk/README.txt
index 417f64619..d9368d4b7 100755
--- a/nuttx/configs/olimex-lpc1766stk/README.txt
+++ b/nuttx/configs/olimex-lpc1766stk/README.txt
@@ -787,12 +787,14 @@ Where <subdir> is one of the following:
to that it will only work as a "built-in" program that can be run from
NSH when CONFIG_NSH_BUILTIN_APPS is defined.
- From NSH, the startup command line is then:
+ From NSH, the startup command sequence is then:
- ftpc xx.xx.xx.xx[:pp]
+ mount -t vfat /dev/mmcsd0 /tmp # Mount the SD card at /tmp
+ cd /tmp # cd into the /tmp directory
+ ftpc xx.xx.xx.xx[:pp] # Start the FTP client
where xx.xx.xx.xx is the IP address of the FTP server and pp is an
- optional port number.
+ optional port number (default is the standard FTP port number 21).
hidkbd:
This configuration directory, performs a simple test of the USB host
diff --git a/nuttx/lib/stdio/lib_sscanf.c b/nuttx/lib/stdio/lib_sscanf.c
index 9f2a411a4..3430aa0a0 100644
--- a/nuttx/lib/stdio/lib_sscanf.c
+++ b/nuttx/lib/stdio/lib_sscanf.c
@@ -100,8 +100,7 @@ int sscanf(const char *buf, const char *fmt, ...)
count = vsscanf((char*)buf, fmt, ap);
va_end(ap);
return count;
-
-} /* end sscanf */
+}
/****************************************************************************
* Function: vsscanf
@@ -129,7 +128,9 @@ int vsscanf(char *buf, const char *s, va_list ap)
/* Skip over white space */
while (isspace(*s))
- s++;
+ {
+ s++;
+ }
/* Check for a conversion specifier */
@@ -144,19 +145,26 @@ int vsscanf(char *buf, const char *s, va_list ap)
lvdbg("vsscanf: Processing %c\n", *s);
if (strchr("dibouxcsefg%", *s))
- break;
+ {
+ break;
+ }
+
if (*s == '*')
- noassign = 1;
+ {
+ noassign = 1;
+ }
else if (*s == 'l' || *s == 'L')
- lflag = 1;
- else if (*s >= '1' && *s <= '9') {
- for (tc = s; isdigit(*s); s++);
- strncpy(tmp, tc, s - tc);
- tmp[s - tc] = '\0';
- width = atoi(tmp);
- /* atob(&width, tmp, 10); */
- s--;
- }
+ {
+ lflag = 1;
+ }
+ else if (*s >= '1' && *s <= '9')
+ {
+ for (tc = s; isdigit(*s); s++);
+ strncpy(tmp, tc, s - tc);
+ tmp[s - tc] = '\0';
+ width = atoi(tmp);
+ s--;
+ }
}
/* Process %s: String conversion */
@@ -166,11 +174,15 @@ int vsscanf(char *buf, const char *s, va_list ap)
lvdbg("vsscanf: Performing string conversion\n");
while (isspace(*buf))
- buf++;
+ {
+ buf++;
+ }
+
if (!width)
{
width = strcspn(buf, spaces);
}
+
if (!noassign)
{
tv = va_arg(ap, char*);
@@ -187,7 +199,10 @@ int vsscanf(char *buf, const char *s, va_list ap)
lvdbg("vsscanf: Performing character conversion\n");
if (!width)
- width = 1;
+ {
+ width = 1;
+ }
+
if (!noassign)
{
tv = va_arg(ap, char*);
@@ -206,20 +221,30 @@ int vsscanf(char *buf, const char *s, va_list ap)
/* Skip over any white space before the integer string */
while (isspace(*buf))
- buf++;
+ {
+ buf++;
+ }
/* The base of the integer conversion depends on the specific
* conversion specification.
*/
if (*s == 'd' || *s == 'u')
- base = 10;
+ {
+ base = 10;
+ }
else if (*s == 'x')
- base = 16;
+ {
+ base = 16;
+ }
else if (*s == 'o')
- base = 8;
+ {
+ base = 8;
+ }
else if (*s == 'b')
- base = 2;
+ {
+ base = 2;
+ }
/* Copy the integer string into a temporary working buffer. */
@@ -234,6 +259,7 @@ int vsscanf(char *buf, const char *s, va_list ap)
width = strchr(buf, *(s + 1)) - buf;
}
}
+
strncpy(tmp, buf, width);
tmp[width] = '\0';
@@ -290,6 +316,7 @@ int vsscanf(char *buf, const char *s, va_list ap)
width = strchr(buf, *(s + 1)) - buf;
}
}
+
strncpy(tmp, buf, width);
tmp[width] = '\0';
buf += width;
@@ -333,6 +360,7 @@ int vsscanf(char *buf, const char *s, va_list ap)
{
count++;
}
+
width = noassign = lflag = 0;
s++;
}
@@ -342,12 +370,21 @@ int vsscanf(char *buf, const char *s, va_list ap)
else
{
while (isspace(*buf))
- buf++;
+ {
+ buf++;
+ }
+
if (*s != *buf)
- break;
+ {
+ break;
+ }
else
- s++, buf++;
+ {
+ s++;
+ buf++;
+ }
}
}
+
return count;
}