forked from nuttx/nuttx-update
Add TELNET front end to NSH
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@421 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
4c54d7d07e
commit
3e64d53637
28 changed files with 1041 additions and 180 deletions
|
@ -266,3 +266,4 @@
|
|||
* Correct processing of input UDP broadcast packets.
|
||||
* Verfied basic DHCP client functionality (netutils/dhcpc)
|
||||
* Implemented send() timeout logic
|
||||
* Add TELNETD front end to NSH (examples/nsh)
|
||||
|
|
|
@ -754,6 +754,7 @@ Other memory:
|
|||
* Correct processing of input UDP broadcast packets.
|
||||
* Verfied basic DHCP client functionality (netutils/dhcpc)
|
||||
* Implemented send() timeout logic
|
||||
* Add TELNETD front end to NSH (examples/nsh)
|
||||
</pre></ul>
|
||||
|
||||
<table width ="100%">
|
||||
|
|
2
TODO
2
TODO
|
@ -68,6 +68,7 @@ o Build system
|
|||
- Dependencies do not work correctly under configs/<board>/src (same as arch/<arch>/src/board).
|
||||
|
||||
o Applications & Tests
|
||||
- Verify TELNET frontend to nsh
|
||||
|
||||
o ARM
|
||||
- Add option to use a separate stack for interrupt handling. At present,
|
||||
|
@ -75,6 +76,7 @@ o ARM
|
|||
user stack allocation larger than needed.
|
||||
|
||||
o ARM/C5471
|
||||
- Needs an Ethernet driver
|
||||
|
||||
o ARM/DM320
|
||||
- It seems that when a lot of debug statements are added, the system no
|
||||
|
|
|
@ -284,7 +284,7 @@ __start:
|
|||
#endif
|
||||
/* Perform early serial initialization */
|
||||
|
||||
#ifdef CONFIG_DEV_CONSOLE
|
||||
#if defined(CONFIG_DEV_CONSOLE) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||
bl up_earlyserialinit
|
||||
#endif
|
||||
|
||||
|
|
|
@ -104,10 +104,13 @@ __start:
|
|||
blt 1b
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_DEV_CONSOLE) && CONFIG_NFILE_DESCRIPTORS >0
|
||||
/* Perform early serial initialization */
|
||||
|
||||
mov fp, #0
|
||||
bl up_earlyserialinit
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
mov r0, #'C'
|
||||
|
|
|
@ -299,6 +299,18 @@ CONFIG_NET_BROADCAST=n
|
|||
CONFIG_NET_DHCP_LIGHT=n
|
||||
CONFIG_NET_RESOLV_ENTRIES=4
|
||||
|
||||
#
|
||||
# Settings for examples/nsh
|
||||
CONFIG_EXAMPLES_NSH_TELNET=n
|
||||
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE=512
|
||||
CONFIG_EXAMPLES_NSH_CMD_SIZE=40
|
||||
CONFIG_EXAMPLES_NSH_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_NSH_DHCPC=n
|
||||
CONFIG_EXAMPLES_NSH_NOMAC=n
|
||||
CONFIG_EXAMPLES_NSH_IPADDR=(10<<24|0<<16|0<<8|2)
|
||||
CONFIG_EXAMPLES_NSH_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
||||
CONFIG_EXAMPLES_NSH_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
#
|
||||
|
|
|
@ -288,6 +288,18 @@ CONFIG_NET_BROADCAST=n
|
|||
CONFIG_NET_DHCP_LIGHT=n
|
||||
CONFIG_NET_RESOLV_ENTRIES=4
|
||||
|
||||
#
|
||||
# Settings for examples/nsh
|
||||
CONFIG_EXAMPLES_NSH_TELNET=n
|
||||
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE=512
|
||||
CONFIG_EXAMPLES_NSH_CMD_SIZE=40
|
||||
CONFIG_EXAMPLES_NSH_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_NSH_DHCPC=n
|
||||
CONFIG_EXAMPLES_NSH_NOMAC=n
|
||||
CONFIG_EXAMPLES_NSH_IPADDR=(10<<24|0<<16|0<<8|2)
|
||||
CONFIG_EXAMPLES_NSH_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
||||
CONFIG_EXAMPLES_NSH_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
#
|
||||
|
|
|
@ -312,6 +312,18 @@ CONFIG_NET_BROADCAST=n
|
|||
CONFIG_NET_DHCP_LIGHT=n
|
||||
CONFIG_NET_RESOLV_ENTRIES=4
|
||||
|
||||
#
|
||||
# Settings for examples/nsh
|
||||
CONFIG_EXAMPLES_NSH_TELNET=n
|
||||
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE=512
|
||||
CONFIG_EXAMPLES_NSH_CMD_SIZE=40
|
||||
CONFIG_EXAMPLES_NSH_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_NSH_DHCPC=n
|
||||
CONFIG_EXAMPLES_NSH_NOMAC=n
|
||||
CONFIG_EXAMPLES_NSH_IPADDR=(10<<24|0<<16|0<<8|2)
|
||||
CONFIG_EXAMPLES_NSH_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
||||
CONFIG_EXAMPLES_NSH_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
#
|
||||
|
|
|
@ -317,6 +317,18 @@ CONFIG_EXAMPLE_NETTEST_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
|||
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
CONFIG_EXAMPLE_NETTEST_CLIENTIP=(10<<24|0<<16|0<<8|1)
|
||||
|
||||
#
|
||||
# Settings for examples/nsh
|
||||
CONFIG_EXAMPLES_NSH_TELNET=n
|
||||
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE=512
|
||||
CONFIG_EXAMPLES_NSH_CMD_SIZE=40
|
||||
CONFIG_EXAMPLES_NSH_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_NSH_DHCPC=n
|
||||
CONFIG_EXAMPLES_NSH_NOMAC=n
|
||||
CONFIG_EXAMPLES_NSH_IPADDR=(10<<24|0<<16|0<<8|2)
|
||||
CONFIG_EXAMPLES_NSH_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
||||
CONFIG_EXAMPLES_NSH_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
|
||||
#
|
||||
# DM90x0 Driver Settings
|
||||
CONFIG_NET_DM90x0=n
|
||||
|
|
|
@ -317,6 +317,18 @@ CONFIG_EXAMPLE_NETTEST_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
|||
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
CONFIG_EXAMPLE_NETTEST_CLIENTIP=(10<<24|0<<16|0<<8|1)
|
||||
|
||||
#
|
||||
# Settings for examples/nsh
|
||||
CONFIG_EXAMPLES_NSH_TELNET=n
|
||||
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE=512
|
||||
CONFIG_EXAMPLES_NSH_CMD_SIZE=40
|
||||
CONFIG_EXAMPLES_NSH_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_NSH_DHCPC=n
|
||||
CONFIG_EXAMPLES_NSH_NOMAC=n
|
||||
CONFIG_EXAMPLES_NSH_IPADDR=(10<<24|0<<16|0<<8|2)
|
||||
CONFIG_EXAMPLES_NSH_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
||||
CONFIG_EXAMPLES_NSH_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
|
||||
#
|
||||
# DM90x0 Driver Settings
|
||||
CONFIG_NET_DM90x0=y
|
||||
|
|
|
@ -325,6 +325,18 @@ CONFIG_EXAMPLE_UDP_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
|||
CONFIG_EXAMPLE_UDP_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
CONFIG_EXAMPLE_UDP_SERVERIP=(10<<24|0<<16|0<<8|1)
|
||||
|
||||
#
|
||||
# Settings for examples/nsh
|
||||
CONFIG_EXAMPLES_NSH_TELNET=n
|
||||
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE=512
|
||||
CONFIG_EXAMPLES_NSH_CMD_SIZE=40
|
||||
CONFIG_EXAMPLES_NSH_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_NSH_DHCPC=n
|
||||
CONFIG_EXAMPLES_NSH_NOMAC=n
|
||||
CONFIG_EXAMPLES_NSH_IPADDR=(10<<24|0<<16|0<<8|2)
|
||||
CONFIG_EXAMPLES_NSH_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
||||
CONFIG_EXAMPLES_NSH_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
|
||||
#
|
||||
# DM90x0 Driver Settings
|
||||
CONFIG_NET_DM90x0=y
|
||||
|
|
|
@ -317,6 +317,18 @@ CONFIG_EXAMPLE_NETTEST_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
|||
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
CONFIG_EXAMPLE_NETTEST_CLIENTIP=(10<<24|0<<16|0<<8|1)
|
||||
|
||||
#
|
||||
# Settings for examples/nsh
|
||||
CONFIG_EXAMPLES_NSH_TELNET=n
|
||||
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE=512
|
||||
CONFIG_EXAMPLES_NSH_CMD_SIZE=40
|
||||
CONFIG_EXAMPLES_NSH_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_NSH_DHCPC=n
|
||||
CONFIG_EXAMPLES_NSH_NOMAC=n
|
||||
CONFIG_EXAMPLES_NSH_IPADDR=(10<<24|0<<16|0<<8|2)
|
||||
CONFIG_EXAMPLES_NSH_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
||||
CONFIG_EXAMPLES_NSH_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
|
||||
#
|
||||
# DM90x0 Driver Settings
|
||||
CONFIG_NET_DM90x0=y
|
||||
|
|
|
@ -285,6 +285,18 @@ CONFIG_NET_BROADCAST=n
|
|||
CONFIG_NET_DHCP_LIGHT=n
|
||||
CONFIG_NET_RESOLV_ENTRIES=4
|
||||
|
||||
#
|
||||
# Settings for examples/nsh
|
||||
CONFIG_EXAMPLES_NSH_TELNET=n
|
||||
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE=512
|
||||
CONFIG_EXAMPLES_NSH_CMD_SIZE=40
|
||||
CONFIG_EXAMPLES_NSH_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_NSH_DHCPC=n
|
||||
CONFIG_EXAMPLES_NSH_NOMAC=n
|
||||
CONFIG_EXAMPLES_NSH_IPADDR=(10<<24|0<<16|0<<8|2)
|
||||
CONFIG_EXAMPLES_NSH_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
||||
CONFIG_EXAMPLES_NSH_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
#
|
||||
|
|
|
@ -279,6 +279,18 @@ CONFIG_EXAMPLE_NETTEST_DRIPADDR=(192<<24|168<<16|0<<8|1)
|
|||
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
CONFIG_EXAMPLE_NETTEST_CLIENTIP=(192<<24|168<<16|0<<8|106)
|
||||
|
||||
#
|
||||
# Settings for examples/nsh
|
||||
CONFIG_EXAMPLES_NSH_TELNET=n
|
||||
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE=512
|
||||
CONFIG_EXAMPLES_NSH_CMD_SIZE=40
|
||||
CONFIG_EXAMPLES_NSH_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_NSH_DHCPC=n
|
||||
CONFIG_EXAMPLES_NSH_NOMAC=n
|
||||
CONFIG_EXAMPLES_NSH_IPADDR=(10<<24|0<<16|0<<8|2)
|
||||
CONFIG_EXAMPLES_NSH_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
||||
CONFIG_EXAMPLES_NSH_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
|
||||
#
|
||||
# Stack and heap information
|
||||
#
|
||||
|
|
|
@ -280,6 +280,18 @@ CONFIG_EXAMPLE_NETTEST_DRIPADDR=(192<<24|168<<16|0<<8|1)
|
|||
CONFIG_EXAMPLE_NETTEST_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
CONFIG_EXAMPLE_NETTEST_CLIENTIP=(192<<24|168<<16|0<<8|106)
|
||||
|
||||
#
|
||||
# Settings for examples/nsh
|
||||
CONFIG_EXAMPLES_NSH_TELNET=n
|
||||
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE=512
|
||||
CONFIG_EXAMPLES_NSH_CMD_SIZE=40
|
||||
CONFIG_EXAMPLES_NSH_STACKSIZE=4096
|
||||
CONFIG_EXAMPLES_NSH_DHCPC=n
|
||||
CONFIG_EXAMPLES_NSH_NOMAC=n
|
||||
CONFIG_EXAMPLES_NSH_IPADDR=(10<<24|0<<16|0<<8|2)
|
||||
CONFIG_EXAMPLES_NSH_DRIPADDR=(10<<24|0<<16|0<<8|1)
|
||||
CONFIG_EXAMPLES_NSH_NETMASK=(255<<24|255<<16|255<<8|0)
|
||||
|
||||
# Stack and heap information
|
||||
#
|
||||
# CONFIG_BOOT_FROM_FLASH - Some configurations support XIP
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
############################################################
|
||||
# Makefile
|
||||
############################################################################
|
||||
# examples/nsh/Makefile
|
||||
#
|
||||
# Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
|
@ -31,7 +31,7 @@
|
|||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################
|
||||
############################################################################
|
||||
|
||||
-include $(TOPDIR)/.config
|
||||
-include $(TOPDIR)/Make.defs
|
||||
|
@ -39,8 +39,15 @@
|
|||
MKDEP = $(TOPDIR)/tools/mkdeps.sh
|
||||
|
||||
ASRCS =
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
CSRCS = nsh_main.c nsh_fscmds.c nsh_proccmds.c nsh_envcmds.c
|
||||
|
||||
ifeq ($(CONFIG_EXAMPLES_NSH_TELNET),y)
|
||||
CSRCS += nsh_telnetd.c
|
||||
else
|
||||
CSRCS += nsh_serial.c
|
||||
endif
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS)
|
||||
|
|
|
@ -41,23 +41,30 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#ifdef CONFIG_EXAMPLES_NSH_TELNET
|
||||
#else
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define NSH_MAX_ARGUMENTS 6
|
||||
|
||||
#define errno (*get_errno_ptr())
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
typedef void (*cmd_t)(int argc, char **argv);
|
||||
typedef void (*cmd_t)(FAR void *handle, int argc, char **argv);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
extern const char g_nshprompt[];
|
||||
extern const char g_fmtargrequired[];
|
||||
extern const char g_fmtarginvalid[];
|
||||
extern const char g_fmtcmdnotfound[];
|
||||
|
@ -71,30 +78,56 @@ extern const char g_fmtcmdoutofmemory[];
|
|||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
extern void cmd_cat(int argc, char **argv);
|
||||
extern void cmd_cp(int argc, char **argv);
|
||||
/* Message handler */
|
||||
|
||||
extern int nsh_parse(FAR void *handle, char *cmdline);
|
||||
|
||||
/* I/O interfaces */
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_NSH_TELNET
|
||||
|
||||
extern int nsh_telnetmain(void);
|
||||
extern int nsh_telnetout(FAR void *handle, const char *fmt, ...);
|
||||
|
||||
# define nsh_main() nsh_telnetmain()
|
||||
# define nsh_output(handle, ...) nsh_telnetout(handle, __VA_ARGS__)
|
||||
|
||||
#else
|
||||
|
||||
extern int nsh_serialmain(void);
|
||||
|
||||
# define nsh_main() nsh_serialmain()
|
||||
# define nsh_output(handle, ...) printf(__VA_ARGS__)
|
||||
|
||||
#endif
|
||||
extern void cmd_echo(int argc, char **argv);
|
||||
extern void cmd_exec(int argc, char **argv);
|
||||
|
||||
/* Shell command handlers */
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
extern void cmd_ls(int argc, char **argv);
|
||||
extern void cmd_cat(FAR void *handle, int argc, char **argv);
|
||||
extern void cmd_cp(FAR void *handle, int argc, char **argv);
|
||||
#endif
|
||||
extern void cmd_echo(FAR void *handle, int argc, char **argv);
|
||||
extern void cmd_exec(FAR void *handle, int argc, char **argv);
|
||||
extern void cmd_exit(FAR void *handle, int argc, char **argv);
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
extern void cmd_ls(FAR void *handle, int argc, char **argv);
|
||||
#endif
|
||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||
extern void cmd_mkdir(int argc, char **argv);
|
||||
extern void cmd_mount(int argc, char **argv);
|
||||
extern void cmd_mkdir(FAR void *handle, int argc, char **argv);
|
||||
extern void cmd_mount(FAR void *handle, int argc, char **argv);
|
||||
#endif
|
||||
extern void cmd_ps(int argc, char **argv);
|
||||
extern void cmd_ps(FAR void *handle, int argc, char **argv);
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
extern void cmd_set(int argc, char **argv);
|
||||
extern void cmd_set(FAR void *handle, int argc, char **argv);
|
||||
#endif
|
||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||
extern void cmd_rm(int argc, char **argv);
|
||||
extern void cmd_rmdir(int argc, char **argv);
|
||||
extern void cmd_umount(int argc, char **argv);
|
||||
extern void cmd_rm(FAR void *handle, int argc, char **argv);
|
||||
extern void cmd_rmdir(FAR void *handle, int argc, char **argv);
|
||||
extern void cmd_umount(FAR void *handle, int argc, char **argv);
|
||||
#endif
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
extern void cmd_unset(int argc, char **argv);
|
||||
extern void cmd_unset(FAR void *handle, int argc, char **argv);
|
||||
#endif
|
||||
|
||||
#endif /* __NSH_H */
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
* Name: cmd_echo
|
||||
****************************************************************************/
|
||||
|
||||
void cmd_echo(int argc, char **argv)
|
||||
void cmd_echo(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -97,16 +97,16 @@ void cmd_echo(int argc, char **argv)
|
|||
char *value = getenv(argv[i]+1);
|
||||
if (value)
|
||||
{
|
||||
printf("%s ", value);
|
||||
nsh_output(handle, "%s ", value);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
printf("%s ", argv[i]);
|
||||
nsh_output(handle, "%s ", argv[i]);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
nsh_output(handle, "\n");
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -114,11 +114,11 @@ void cmd_echo(int argc, char **argv)
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
void cmd_set(int argc, char **argv)
|
||||
void cmd_set(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
if (setenv(argv[1], argv[2], TRUE) < 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "setenv", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "setenv", strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -128,11 +128,11 @@ void cmd_set(int argc, char **argv)
|
|||
****************************************************************************/
|
||||
|
||||
#ifndef CONFIG_DISABLE_ENVIRON
|
||||
void cmd_unset(int argc, char **argv)
|
||||
void cmd_unset(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
if (unsetenv(argv[1]) < 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "unsetenv", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "unsetenv", strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
typedef int (*direntry_handler_t)(const char *, struct dirent *, void *);
|
||||
typedef int (*direntry_handler_t)(FAR void *, const char *, struct dirent *, void *);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
|
@ -151,7 +151,8 @@ static char *getdirpath(const char *path, const char *file)
|
|||
* Name: foreach_direntry
|
||||
****************************************************************************/
|
||||
|
||||
static int foreach_direntry(const char *cmd, const char *dirpath,
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
static int foreach_direntry(FAR void *handle, const char *cmd, const char *dirpath,
|
||||
direntry_handler_t handler, void *pvarg)
|
||||
{
|
||||
DIR *dirp;
|
||||
|
@ -171,7 +172,7 @@ static int foreach_direntry(const char *cmd, const char *dirpath,
|
|||
{
|
||||
/* Failed to open the directory */
|
||||
|
||||
printf(g_fmtnosuch, cmd, "directory", dirpath);
|
||||
nsh_output(handle, g_fmtnosuch, cmd, "directory", dirpath);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
@ -189,7 +190,7 @@ static int foreach_direntry(const char *cmd, const char *dirpath,
|
|||
|
||||
/* Call the handler with this directory entry */
|
||||
|
||||
if (handler(dirpath, entryp, pvarg) < 0)
|
||||
if (handler(handle, dirpath, entryp, pvarg) < 0)
|
||||
{
|
||||
/* The handler reported a problem */
|
||||
|
||||
|
@ -201,13 +202,14 @@ static int foreach_direntry(const char *cmd, const char *dirpath,
|
|||
closedir(dirp);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: ls_handler
|
||||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
static int ls_handler(const char *dirpath, struct dirent *entryp, void *pvarg)
|
||||
static int ls_handler(FAR void *handle, const char *dirpath, struct dirent *entryp, void *pvarg)
|
||||
{
|
||||
unsigned int lsflags = (unsigned int)pvarg;
|
||||
int ret;
|
||||
|
@ -225,7 +227,7 @@ static int ls_handler(const char *dirpath, struct dirent *entryp, void *pvarg)
|
|||
free(fullpath);
|
||||
if (ret != 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, "ls", "stat", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, "ls", "stat", strerror(errno));
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
@ -290,30 +292,30 @@ static int ls_handler(const char *dirpath, struct dirent *entryp, void *pvarg)
|
|||
details[9]='x';
|
||||
}
|
||||
|
||||
printf(" %s", details);
|
||||
nsh_output(handle, " %s", details);
|
||||
}
|
||||
|
||||
if ((lsflags & LSFLAGS_SIZE) != 0)
|
||||
{
|
||||
printf("%8d", buf.st_size);
|
||||
nsh_output(handle, "%8d", buf.st_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* then provide the filename that is common to normal and verbose output */
|
||||
|
||||
#ifdef CONFIG_FULL_PATH
|
||||
printf(" %s/%s", arg, entryp->d_name);
|
||||
nsh_output(handle, " %s/%s", arg, entryp->d_name);
|
||||
#else
|
||||
printf(" %s", entryp->d_name);
|
||||
nsh_output(handle, " %s", entryp->d_name);
|
||||
#endif
|
||||
|
||||
if (DIRENT_ISDIRECTORY(entryp->d_type))
|
||||
{
|
||||
printf("/\n");
|
||||
nsh_output(handle, "/\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
putchar('\n');
|
||||
nsh_output(handle, "\n");
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
@ -324,7 +326,7 @@ static int ls_handler(const char *dirpath, struct dirent *entryp, void *pvarg)
|
|||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
static int ls_recursive(const char *dirpath, struct dirent *entryp, void *pvarg)
|
||||
static int ls_recursive(FAR void *handle, const char *dirpath, struct dirent *entryp, void *pvarg)
|
||||
{
|
||||
/* Is this entry a directory? */
|
||||
|
||||
|
@ -337,12 +339,12 @@ static int ls_recursive(const char *dirpath, struct dirent *entryp, void *pvarg)
|
|||
|
||||
/* List the directory contents */
|
||||
|
||||
printf("%s:\n", newpath);
|
||||
foreach_direntry("ls", newpath, ls_handler, pvarg);
|
||||
nsh_output(handle, "%s:\n", newpath);
|
||||
foreach_direntry(handle, "ls", newpath, ls_handler, pvarg);
|
||||
|
||||
/* Then recurse to list each directory within the directory */
|
||||
|
||||
foreach_direntry("ls", newpath, ls_recursive, pvarg);
|
||||
foreach_direntry(handle, "ls", newpath, ls_recursive, pvarg);
|
||||
free(newpath);
|
||||
}
|
||||
return OK;
|
||||
|
@ -358,7 +360,7 @@ static int ls_recursive(const char *dirpath, struct dirent *entryp, void *pvarg)
|
|||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
void cmd_cat(int argc, char **argv)
|
||||
void cmd_cat(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
char buffer[1024];
|
||||
|
||||
|
@ -367,7 +369,7 @@ void cmd_cat(int argc, char **argv)
|
|||
int fd = open(argv[1], O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "open", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "open", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -385,7 +387,7 @@ void cmd_cat(int argc, char **argv)
|
|||
|
||||
if (errno != EINTR)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "read", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "read", strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +407,7 @@ void cmd_cat(int argc, char **argv)
|
|||
|
||||
if (errno != EINTR)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "write", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "write", strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -433,7 +435,7 @@ void cmd_cat(int argc, char **argv)
|
|||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
void cmd_cp(int argc, char **argv)
|
||||
void cmd_cp(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
struct stat buf;
|
||||
char *fullpath = NULL;
|
||||
|
@ -448,7 +450,7 @@ void cmd_cp(int argc, char **argv)
|
|||
rdfd = open(argv[1], O_RDONLY);
|
||||
if (rdfd < 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "open", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "open", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -470,7 +472,7 @@ void cmd_cp(int argc, char **argv)
|
|||
fullpath = getdirpath(argv[2], basename(argv[1]) );
|
||||
if (!fullpath)
|
||||
{
|
||||
printf(g_fmtcmdoutofmemory, argv[0]);
|
||||
nsh_output(handle, g_fmtcmdoutofmemory, argv[0]);
|
||||
goto out_with_rdfd;
|
||||
}
|
||||
|
||||
|
@ -490,7 +492,7 @@ void cmd_cp(int argc, char **argv)
|
|||
wrfd = open(wrpath, oflags, 0666);
|
||||
if (wrfd < 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "open", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "open", strerror(errno));
|
||||
goto out_with_fullpath;
|
||||
}
|
||||
|
||||
|
@ -514,7 +516,7 @@ void cmd_cp(int argc, char **argv)
|
|||
{
|
||||
/* Read error */
|
||||
|
||||
printf(g_fmtcmdfailed, argv[0], "read", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "read", strerror(errno));
|
||||
goto out_with_wrfd;
|
||||
}
|
||||
}
|
||||
|
@ -531,7 +533,7 @@ void cmd_cp(int argc, char **argv)
|
|||
{
|
||||
/* Read error */
|
||||
|
||||
printf(g_fmtcmdfailed, argv[0], "write", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "write", strerror(errno));
|
||||
goto out_with_wrfd;
|
||||
}
|
||||
}
|
||||
|
@ -557,7 +559,7 @@ out_with_rdfd:
|
|||
****************************************************************************/
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
void cmd_ls(int argc, char **argv)
|
||||
void cmd_ls(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
unsigned int lsflags = 0;
|
||||
int ret;
|
||||
|
@ -583,7 +585,7 @@ void cmd_ls(int argc, char **argv)
|
|||
|
||||
case '?':
|
||||
default:
|
||||
printf(g_fmtarginvalid, argv[0]);
|
||||
nsh_output(handle, g_fmtarginvalid, argv[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -592,24 +594,24 @@ void cmd_ls(int argc, char **argv)
|
|||
|
||||
if (optind + 1 < argc)
|
||||
{
|
||||
printf(g_fmttoomanyargs, argv[0]);
|
||||
nsh_output(handle, g_fmttoomanyargs, argv[0]);
|
||||
return;
|
||||
}
|
||||
else if (optind + 1 > argc)
|
||||
{
|
||||
printf(g_fmtargrequired, argv[0]);
|
||||
nsh_output(handle, g_fmtargrequired, argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* List the directory contents */
|
||||
|
||||
printf("%s:\n", argv[optind]);
|
||||
ret = foreach_direntry("ls", argv[optind], ls_handler, (void*)lsflags);
|
||||
nsh_output(handle, "%s:\n", argv[optind]);
|
||||
ret = foreach_direntry(handle, "ls", argv[optind], ls_handler, (void*)lsflags);
|
||||
if (ret == OK && (lsflags & LSFLAGS_RECURSIVE) != 0)
|
||||
{
|
||||
/* Then recurse to list each directory within the directory */
|
||||
|
||||
ret = foreach_direntry("ls", argv[optind], ls_recursive, (void*)lsflags);
|
||||
ret = foreach_direntry(handle, "ls", argv[optind], ls_recursive, (void*)lsflags);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -619,12 +621,12 @@ void cmd_ls(int argc, char **argv)
|
|||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||
void cmd_mkdir(int argc, char **argv)
|
||||
void cmd_mkdir(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
int result = mkdir(argv[1], 0777);
|
||||
if ( result < 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "mkdir", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "mkdir", strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -634,7 +636,7 @@ void cmd_mkdir(int argc, char **argv)
|
|||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||
void cmd_mount(int argc, char **argv)
|
||||
void cmd_mount(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
char *filesystem = 0;
|
||||
int result;
|
||||
|
@ -651,12 +653,12 @@ void cmd_mount(int argc, char **argv)
|
|||
break;
|
||||
|
||||
case ':':
|
||||
printf(g_fmtargrequired, argv[0]);
|
||||
nsh_output(handle, g_fmtargrequired, argv[0]);
|
||||
return;
|
||||
|
||||
case '?':
|
||||
default:
|
||||
printf(g_fmtarginvalid, argv[0]);
|
||||
nsh_output(handle, g_fmtarginvalid, argv[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -665,12 +667,12 @@ void cmd_mount(int argc, char **argv)
|
|||
|
||||
if (optind + 2 < argc)
|
||||
{
|
||||
printf(g_fmttoomanyargs, argv[0]);
|
||||
nsh_output(handle, g_fmttoomanyargs, argv[0]);
|
||||
return;
|
||||
}
|
||||
else if (optind + 2 > argc)
|
||||
{
|
||||
printf(g_fmtargrequired, argv[0]);
|
||||
nsh_output(handle, g_fmtargrequired, argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -678,7 +680,7 @@ void cmd_mount(int argc, char **argv)
|
|||
result = mount(argv[optind], argv[optind+1], filesystem, 0, NULL);
|
||||
if ( result < 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "mount", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "mount", strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -688,11 +690,11 @@ void cmd_mount(int argc, char **argv)
|
|||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||
void cmd_rm(int argc, char **argv)
|
||||
void cmd_rm(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
if (unlink(argv[1]) < 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "unlink", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "unlink", strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -702,11 +704,11 @@ void cmd_rm(int argc, char **argv)
|
|||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||
void cmd_rmdir(int argc, char **argv)
|
||||
void cmd_rmdir(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
if (rmdir(argv[1]) < 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "rmdir", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "rmdir", strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -716,13 +718,13 @@ void cmd_rmdir(int argc, char **argv)
|
|||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_DISABLE_MOUNTPOINT) && CONFIG_NFILE_DESCRIPTORS > 0
|
||||
void cmd_umount(int argc, char **argv)
|
||||
void cmd_umount(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
/* Perform the umount */
|
||||
int result = umount(argv[1]);
|
||||
if ( result < 0)
|
||||
{
|
||||
printf(g_fmtcmdfailed, argv[0], "umount", strerror(errno));
|
||||
nsh_output(handle, g_fmtcmdfailed, argv[0], "umount", strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
|
||||
#define CONFIG_NSH_LINE_SIZE 80
|
||||
#undef CONFIG_FULL_PATH
|
||||
#define NSH_MAX_ARGUMENTS 6
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
|
@ -70,14 +69,13 @@ struct cmdmap_s
|
|||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
static void cmd_help(int argc, char **argv);
|
||||
static void cmd_unrecognized(int argc, char **argv);
|
||||
static void cmd_help(FAR void *handle, int argc, char **argv);
|
||||
static void cmd_unrecognized(FAR void *handle, int argc, char **argv);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static char line[CONFIG_NSH_LINE_SIZE];
|
||||
static const char delim[] = " \t\n";
|
||||
|
||||
static const struct cmdmap_s g_cmdmap[] =
|
||||
|
@ -92,6 +90,7 @@ static const struct cmdmap_s g_cmdmap[] =
|
|||
{ "echo", cmd_echo, 0, NSH_MAX_ARGUMENTS, "[<string> [<string>...]]" },
|
||||
#endif
|
||||
{ "exec", cmd_exec, 2, 3, "<hex-address>" },
|
||||
{ "exit", cmd_exit, 1, 1, NULL },
|
||||
{ "help", cmd_help, 1, 1, NULL },
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
{ "ls", cmd_ls, 2, 5, "[-lRs] <dir-path>" },
|
||||
|
@ -119,6 +118,7 @@ static const struct cmdmap_s g_cmdmap[] =
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
const char g_nshprompt[] = "nsh> ";
|
||||
const char g_fmtargrequired[] = "nsh: %s: missing required argument(s)\n";
|
||||
const char g_fmtarginvalid[] = "nsh: %s: argument invalid\n";
|
||||
const char g_fmtcmdnotfound[] = "nsh: %s: command not found\n";
|
||||
|
@ -136,20 +136,20 @@ const char g_fmtcmdoutofmemory[] = "nsh: %s: out of memory\n";
|
|||
* Name: cmd_help
|
||||
****************************************************************************/
|
||||
|
||||
static void cmd_help(int argc, char **argv)
|
||||
static void cmd_help(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
const struct cmdmap_s *ptr;
|
||||
|
||||
printf("NSH commands:\n");
|
||||
nsh_output(handle, "NSH commands:\n");
|
||||
for (ptr = g_cmdmap; ptr->cmd; ptr++)
|
||||
{
|
||||
if (ptr->usage)
|
||||
{
|
||||
printf(" %s %s\n", ptr->cmd, ptr->usage);
|
||||
nsh_output(handle, " %s %s\n", ptr->cmd, ptr->usage);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" %s\n", ptr->cmd);
|
||||
nsh_output(handle, " %s\n", ptr->cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -158,9 +158,9 @@ static void cmd_help(int argc, char **argv)
|
|||
* Name: cmd_unrecognized
|
||||
****************************************************************************/
|
||||
|
||||
static void cmd_unrecognized(int argc, char **argv)
|
||||
static void cmd_unrecognized(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
printf(g_fmtcmdnotfound, argv[0]);
|
||||
nsh_output(handle, g_fmtcmdnotfound, argv[0]);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -182,94 +182,86 @@ void user_initialize(void)
|
|||
|
||||
int user_start(int argc, char *argv[])
|
||||
{
|
||||
printf("NuttShell (NSH)\n");
|
||||
fflush(stdout);
|
||||
return nsh_main();
|
||||
}
|
||||
|
||||
for (;;)
|
||||
/****************************************************************************
|
||||
* Name: nsh_parse
|
||||
****************************************************************************/
|
||||
|
||||
int nsh_parse(FAR void *handle, char *cmdline)
|
||||
{
|
||||
const struct cmdmap_s *cmdmap;
|
||||
char *argv[NSH_MAX_ARGUMENTS+1];
|
||||
char *saveptr;
|
||||
char *cmd;
|
||||
int argc;
|
||||
|
||||
/* Parse out the command at the beginning of the line */
|
||||
|
||||
cmd = strtok_r(cmdline, " \t\n", &saveptr);
|
||||
if (cmd)
|
||||
{
|
||||
const struct cmdmap_s *cmdmap;
|
||||
char *saveptr;
|
||||
char *cmd;
|
||||
cmd_t handler = cmd_unrecognized;
|
||||
|
||||
/* Get the next line of input */
|
||||
/* Parse all of the arguments following the command name */
|
||||
|
||||
fgets(line, CONFIG_NSH_LINE_SIZE, stdin);
|
||||
|
||||
/* Parse out the command at the beginning of the line */
|
||||
|
||||
cmd = strtok_r(line, " \t\n", &saveptr);
|
||||
if (cmd)
|
||||
argv[0] = cmd;
|
||||
for (argc = 1; argc < NSH_MAX_ARGUMENTS+1; argc++)
|
||||
{
|
||||
cmd_t handler = cmd_unrecognized;
|
||||
|
||||
/* Parse all of the arguments following the command name */
|
||||
|
||||
char *cmd_argv[NSH_MAX_ARGUMENTS+1];
|
||||
int cmd_argc;
|
||||
|
||||
cmd_argv[0] = cmd;
|
||||
for (cmd_argc = 1; cmd_argc < NSH_MAX_ARGUMENTS+1; cmd_argc++)
|
||||
argv[argc] = strtok_r( NULL, " \t\n", &saveptr);
|
||||
if (!argv[argc])
|
||||
{
|
||||
cmd_argv[cmd_argc] = strtok_r( NULL, " \t\n", &saveptr);
|
||||
if ( !cmd_argv[cmd_argc] )
|
||||
{
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd_argc > NSH_MAX_ARGUMENTS)
|
||||
if (argc > NSH_MAX_ARGUMENTS)
|
||||
{
|
||||
nsh_output(handle, g_fmttoomanyargs, cmd);
|
||||
}
|
||||
|
||||
/* See if the command is one that we understand */
|
||||
|
||||
for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++)
|
||||
{
|
||||
if (strcmp(cmdmap->cmd, cmd) == 0)
|
||||
{
|
||||
printf(g_fmttoomanyargs, cmd);
|
||||
}
|
||||
|
||||
/* See if the command is one that we understand */
|
||||
|
||||
for (cmdmap = g_cmdmap; cmdmap->cmd; cmdmap++)
|
||||
{
|
||||
if (strcmp(cmdmap->cmd, cmd) == 0)
|
||||
{
|
||||
/* Check if a valid number of arguments was provided. We
|
||||
/* Check if a valid number of arguments was provided. We
|
||||
* do this simple, imperfect checking here so that it does
|
||||
* not have to be performed in each command.
|
||||
*/
|
||||
|
||||
if (cmd_argc < cmdmap->minargs)
|
||||
{
|
||||
/* Fewer than the minimum number were provided */
|
||||
if (argc < cmdmap->minargs)
|
||||
{
|
||||
/* Fewer than the minimum number were provided */
|
||||
|
||||
printf(g_fmtargrequired, cmd);
|
||||
handler = NULL;
|
||||
break;
|
||||
}
|
||||
else if (cmd_argc > cmdmap->maxargs)
|
||||
{
|
||||
/* More than the maximum number were provided */
|
||||
nsh_output(handle, g_fmtargrequired, cmd);
|
||||
return ERROR;
|
||||
}
|
||||
else if (argc > cmdmap->maxargs)
|
||||
{
|
||||
/* More than the maximum number were provided */
|
||||
|
||||
printf(g_fmttoomanyargs, cmd);
|
||||
handler = NULL;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A valid number of arguments were provided (this does
|
||||
* not mean they are right.
|
||||
*/
|
||||
nsh_output(handle, g_fmttoomanyargs, cmd);
|
||||
return ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A valid number of arguments were provided (this does
|
||||
* not mean they are right).
|
||||
*/
|
||||
|
||||
handler = cmdmap->handler;
|
||||
break;
|
||||
}
|
||||
handler = cmdmap->handler;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If a error was detected above, handler will be nullified to
|
||||
* prevent reporting multiple errors.
|
||||
*/
|
||||
|
||||
if (handler)
|
||||
{
|
||||
handler(cmd_argc, cmd_argv);
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
|
||||
handler(handle, argc, argv);
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
|
|
@ -97,27 +97,27 @@ static void ps_task(FAR _TCB *tcb, FAR void *arg)
|
|||
{
|
||||
boolean needcomma = FALSE;
|
||||
int i;
|
||||
printf("%5d %3d %4s %7s%c%c %8s ",
|
||||
tcb->pid, tcb->sched_priority,
|
||||
tcb->flags & TCB_FLAG_ROUND_ROBIN ? "RR " : "FIFO",
|
||||
tcb->flags & TCB_FLAG_PTHREAD ? "PTHREAD" : "TASK ",
|
||||
tcb->flags & TCB_FLAG_NONCANCELABLE ? 'N' : ' ',
|
||||
tcb->flags & TCB_FLAG_CANCEL_PENDING ? 'P' : ' ',
|
||||
g_statenames[tcb->task_state]);
|
||||
nsh_output(arg, "%5d %3d %4s %7s%c%c %8s ",
|
||||
tcb->pid, tcb->sched_priority,
|
||||
tcb->flags & TCB_FLAG_ROUND_ROBIN ? "RR " : "FIFO",
|
||||
tcb->flags & TCB_FLAG_PTHREAD ? "PTHREAD" : "TASK ",
|
||||
tcb->flags & TCB_FLAG_NONCANCELABLE ? 'N' : ' ',
|
||||
tcb->flags & TCB_FLAG_CANCEL_PENDING ? 'P' : ' ',
|
||||
g_statenames[tcb->task_state]);
|
||||
|
||||
printf("%s(", tcb->argv[0]);
|
||||
nsh_output(arg, "%s(", tcb->argv[0]);
|
||||
for (i = 1; i < CONFIG_MAX_TASK_ARGS+1 && tcb->argv[i]; i++)
|
||||
{
|
||||
if (needcomma)
|
||||
{
|
||||
printf(", %p", tcb->argv[i]);
|
||||
nsh_output(arg, ", %p", tcb->argv[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%p", tcb->argv[i]);
|
||||
nsh_output(arg, "%p", tcb->argv[i]);
|
||||
}
|
||||
}
|
||||
printf(")\n");
|
||||
nsh_output(arg, ")\n");
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -128,7 +128,7 @@ static void ps_task(FAR _TCB *tcb, FAR void *arg)
|
|||
* Name: cmd_exec
|
||||
****************************************************************************/
|
||||
|
||||
void cmd_exec(int argc, char **argv)
|
||||
void cmd_exec(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
char *endptr;
|
||||
long addr;
|
||||
|
@ -136,11 +136,11 @@ void cmd_exec(int argc, char **argv)
|
|||
addr = strtol(argv[1], &endptr, 0);
|
||||
if (!addr || endptr == argv[1] || *endptr != '\0')
|
||||
{
|
||||
printf(g_fmtarginvalid, argv[0]);
|
||||
nsh_output(handle, g_fmtarginvalid, argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Calling %p\n", (exec_t)addr);
|
||||
nsh_output(handle, "Calling %p\n", (exec_t)addr);
|
||||
((exec_t)addr)();
|
||||
}
|
||||
|
||||
|
@ -148,8 +148,8 @@ void cmd_exec(int argc, char **argv)
|
|||
* Name: cmd_ps
|
||||
****************************************************************************/
|
||||
|
||||
void cmd_ps(int argc, char **argv)
|
||||
void cmd_ps(FAR void *handle, int argc, char **argv)
|
||||
{
|
||||
printf("PID PRI SCHD TYPE NP STATE NAME\n");
|
||||
sched_foreach(ps_task, NULL);
|
||||
nsh_output(handle, "PID PRI SCHD TYPE NP STATE NAME\n");
|
||||
sched_foreach(ps_task, handle);
|
||||
}
|
||||
|
|
129
examples/nsh/nsh_serial.c
Normal file
129
examples/nsh/nsh_serial.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
/****************************************************************************
|
||||
* examples/nsh/nsh_serial.h
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name Gregory Nutt nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nsh.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define CONFIG_NSH_LINE_SIZE 80
|
||||
#undef CONFIG_FULL_PATH
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct cmdmap_s
|
||||
{
|
||||
const char *cmd; /* Name of the command */
|
||||
cmd_t handler; /* Function that handles the command */
|
||||
ubyte minargs; /* Minimum number of arguments (including command) */
|
||||
ubyte maxargs; /* Maximum number of arguments (including command) */
|
||||
const char *usage; /* Usage instructions for 'help' command */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static char line[CONFIG_NSH_LINE_SIZE];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_main
|
||||
****************************************************************************/
|
||||
|
||||
int nsh_serialmain(void)
|
||||
{
|
||||
printf("NuttShell (NSH)\n");
|
||||
fflush(stdout);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Display the prompt string */
|
||||
|
||||
fputs(g_nshprompt, stdout);
|
||||
fflush(stdout);
|
||||
|
||||
/* Get the next line of input */
|
||||
|
||||
fgets(line, CONFIG_NSH_LINE_SIZE, stdin);
|
||||
|
||||
/* Parse process the command */
|
||||
|
||||
(void)nsh_parse(NULL, line);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cmd_exit
|
||||
*
|
||||
* Description:
|
||||
* Exit the shell task
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void cmd_exit(void *handle, int argc, char **argv)
|
||||
{
|
||||
exit(0);
|
||||
}
|
565
examples/nsh/nsh_telnetd.c
Normal file
565
examples/nsh/nsh_telnetd.c
Normal file
|
@ -0,0 +1,565 @@
|
|||
/****************************************************************************
|
||||
* examples/nsh/nsh_telnetd.c
|
||||
*
|
||||
* Copyright (C) 2007 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* This is a leverage of similar logic from uIP:
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
* Copyright (c) 2003, Adam Dunkels.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <net/uip/uip-lib.h>
|
||||
|
||||
#include "nsh.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ISO_nl 0x0a
|
||||
#define ISO_cr 0x0d
|
||||
|
||||
#define STATE_NORMAL 0
|
||||
#define STATE_IAC 1
|
||||
#define STATE_WILL 2
|
||||
#define STATE_WONT 3
|
||||
#define STATE_DO 4
|
||||
#define STATE_DONT 5
|
||||
#define STATE_CLOSE 6
|
||||
|
||||
#define TELNET_IAC 255
|
||||
#define TELNET_WILL 251
|
||||
#define TELNET_WONT 252
|
||||
#define TELNET_DO 253
|
||||
#define TELNET_DONT 254
|
||||
|
||||
/* Configurable settings */
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE
|
||||
# define CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE 512
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_NSH_CMD_SIZE
|
||||
# define CONFIG_EXAMPLES_NSH_CMD_SIZE 40
|
||||
#endif
|
||||
|
||||
/* As threads are created to handle each request, a stack must be allocated
|
||||
* for the thread. Use a default if the user provided no stacksize.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_EXAMPLES_NSH_STACKSIZE
|
||||
# define CONFIG_EXAMPLES_NSH_STACKSIZE 4096
|
||||
#endif
|
||||
|
||||
/* Enabled dumping of all input/output buffers */
|
||||
|
||||
#undef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct telnetd_s
|
||||
{
|
||||
int tn_sockfd;
|
||||
char tn_iobuffer[CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE];
|
||||
char tn_cmd[CONFIG_EXAMPLES_NSH_CMD_SIZE];
|
||||
uint8 tn_bufndx;
|
||||
uint8 tn_state;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_dumpbuffer
|
||||
*
|
||||
* Description:
|
||||
* Dump a buffer of data (debug only)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER
|
||||
static void nsh_dumpbuffer(const char *msg, const char *buffer, ssize_t nbytes)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG
|
||||
char line[128];
|
||||
int ch;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
dbg("%s:\n", msg);
|
||||
for (i = 0; i < nbytes; i += 16)
|
||||
{
|
||||
sprintf(line, "%04x: ", i);
|
||||
|
||||
for ( j = 0; j < 16; j++)
|
||||
{
|
||||
if (i + j < nbytes)
|
||||
{
|
||||
sprintf(&line[strlen(line)], "%02x ", buffer[i+j] );
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(&line[strlen(line)], " ");
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 0; j < 16; j++)
|
||||
{
|
||||
if (i + j < nbytes)
|
||||
{
|
||||
ch = buffer[i+j];
|
||||
sprintf(&line[strlen(line)], "%c", ch >= 0x20 && ch <= 0x7e ? ch : '.');
|
||||
}
|
||||
}
|
||||
dbg("%s\n", line);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
# define nsh_dumpbuffer(msg,buffer,nbytes)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_putchar
|
||||
*
|
||||
* Description:
|
||||
* Add another parsed character to the TELNET command string
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void nsh_putchar(struct telnetd_s *pstate, uint8 ch)
|
||||
{
|
||||
/* Ignore carriage returns */
|
||||
|
||||
if (ch == ISO_cr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add all other characters to the cmd buffer */
|
||||
|
||||
pstate->tn_cmd[pstate->tn_bufndx] = ch;
|
||||
|
||||
/* If a newline was added or if the buffer is full, then process it now */
|
||||
|
||||
if (ch == ISO_nl || pstate->tn_bufndx == (CONFIG_EXAMPLES_NSH_CMD_SIZE - 1))
|
||||
{
|
||||
if (pstate->tn_bufndx > 0)
|
||||
{
|
||||
pstate->tn_cmd[pstate->tn_bufndx] = '\0';
|
||||
}
|
||||
|
||||
nsh_dumpbuffer("TELNET CMD", pstate->tn_cmd, strlen(pstate->tn_cmd));
|
||||
nsh_parse((void*)pstate, pstate->tn_cmd);
|
||||
pstate->tn_bufndx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pstate->tn_bufndx++;
|
||||
vdbg("Add '%c', bufndx=%d\n", ch, pstate->tn_bufndx);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_sendopt
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void nsh_sendopt(struct telnetd_s *pstate, uint8 option, uint8 value)
|
||||
{
|
||||
uint8 optbuf[4];
|
||||
optbuf[0] = TELNET_IAC;
|
||||
optbuf[1] = option;
|
||||
optbuf[2] = value;
|
||||
optbuf[3] = 0;
|
||||
|
||||
nsh_dumpbuffer("Send optbuf", optbuf, 4);
|
||||
if (send(pstate->tn_sockfd, optbuf, 4, 0) < 0)
|
||||
{
|
||||
dbg("[%d] Failed to send TELNET_IAC\n", pstate->tn_sockfd);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_receive
|
||||
*
|
||||
* Description:
|
||||
* Process a received TELENET buffer
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int nsh_receive(struct telnetd_s *pstate, size_t len)
|
||||
{
|
||||
char *ptr = pstate->tn_iobuffer;
|
||||
uint8 ch;
|
||||
|
||||
while (len > 0)
|
||||
{
|
||||
ch = *ptr++;
|
||||
len--;
|
||||
|
||||
vdbg("ch=%02x state=%d\n", ch, pstate->tn_state);
|
||||
switch (pstate->tn_state)
|
||||
{
|
||||
case STATE_IAC:
|
||||
if (ch == TELNET_IAC)
|
||||
{
|
||||
nsh_putchar(pstate, ch);
|
||||
pstate->tn_state = STATE_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case TELNET_WILL:
|
||||
pstate->tn_state = STATE_WILL;
|
||||
break;
|
||||
|
||||
case TELNET_WONT:
|
||||
pstate->tn_state = STATE_WONT;
|
||||
break;
|
||||
|
||||
case TELNET_DO:
|
||||
pstate->tn_state = STATE_DO;
|
||||
break;
|
||||
|
||||
case TELNET_DONT:
|
||||
pstate->tn_state = STATE_DONT;
|
||||
break;
|
||||
|
||||
default:
|
||||
pstate->tn_state = STATE_NORMAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case STATE_WILL:
|
||||
/* Reply with a DONT */
|
||||
|
||||
nsh_sendopt(pstate, TELNET_DONT, ch);
|
||||
pstate->tn_state = STATE_NORMAL;
|
||||
break;
|
||||
|
||||
case STATE_WONT:
|
||||
/* Reply with a DONT */
|
||||
|
||||
nsh_sendopt(pstate, TELNET_DONT, ch);
|
||||
pstate->tn_state = STATE_NORMAL;
|
||||
break;
|
||||
|
||||
case STATE_DO:
|
||||
/* Reply with a WONT */
|
||||
|
||||
nsh_sendopt(pstate, TELNET_WONT, ch);
|
||||
pstate->tn_state = STATE_NORMAL;
|
||||
break;
|
||||
|
||||
case STATE_DONT:
|
||||
/* Reply with a WONT */
|
||||
|
||||
nsh_sendopt(pstate, TELNET_WONT, ch);
|
||||
pstate->tn_state = STATE_NORMAL;
|
||||
break;
|
||||
|
||||
case STATE_NORMAL:
|
||||
if (ch == TELNET_IAC)
|
||||
{
|
||||
pstate->tn_state = STATE_IAC;
|
||||
}
|
||||
else
|
||||
{
|
||||
nsh_putchar(pstate, ch);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_prompt
|
||||
*
|
||||
* Description:
|
||||
* Print a prompt to the shell window.
|
||||
*
|
||||
* This function can be used by the shell back-end to print out a prompt
|
||||
* to the shell window.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void nsh_prompt(struct telnetd_s *pstate, const char *str)
|
||||
{
|
||||
int len = strlen(str);
|
||||
|
||||
strncpy(pstate->tn_iobuffer, str, len);
|
||||
nsh_dumpbuffer("Shell prompt", pstate->tn_iobuffer, len);
|
||||
if (send(pstate->tn_sockfd, pstate->tn_iobuffer, len, 0) < 0)
|
||||
{
|
||||
dbg("[%d] Failed to send prompt\n", pstate->tn_sockfd);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_connection
|
||||
*
|
||||
* Description:
|
||||
* Each time a new connection to port 23 is made, a new thread is created
|
||||
* that begins at this entry point. There should be exactly one argument
|
||||
* and it should be the socket descriptor (+1).
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void *nsh_connection(void *arg)
|
||||
{
|
||||
struct telnetd_s *pstate = (struct telnetd_s *)malloc(sizeof(struct telnetd_s));
|
||||
int sockfd = (int)arg;
|
||||
int ret = ERROR;
|
||||
|
||||
dbg("[%d] Started\n", sockfd);
|
||||
|
||||
/* Verify that the state structure was successfully allocated */
|
||||
|
||||
if (pstate)
|
||||
{
|
||||
/* Initialize the thread state structure */
|
||||
|
||||
memset(pstate, 0, sizeof(struct telnetd_s));
|
||||
pstate->tn_sockfd = sockfd;
|
||||
pstate->tn_state = STATE_NORMAL;
|
||||
|
||||
/* Loop processing each TELNET command */
|
||||
|
||||
do
|
||||
{
|
||||
/* Display the prompt string */
|
||||
|
||||
nsh_prompt(pstate, g_nshprompt);
|
||||
|
||||
/* Read a buffer of data from the TELNET client */
|
||||
|
||||
ret = recv(pstate->tn_sockfd, pstate->tn_iobuffer, CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE, 0);
|
||||
if (ret > 0)
|
||||
{
|
||||
|
||||
/* Process the received TELNET data */
|
||||
|
||||
nsh_dumpbuffer("Received buffer", pstate->tn_iobuffer, ret);
|
||||
ret = nsh_receive(pstate, ret);
|
||||
}
|
||||
}
|
||||
while (ret >= 0 && pstate->tn_state != STATE_CLOSE);
|
||||
dbg("[%d] ret=%d tn_state=%d\n", sockfd, ret, pstate->tn_state);
|
||||
|
||||
/* End of command processing -- Clean up and exit */
|
||||
|
||||
free(pstate);
|
||||
}
|
||||
|
||||
/* Exit the task */
|
||||
|
||||
dbg("[%d] Exitting\n", sockfd);
|
||||
close(sockfd);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_telnetmain
|
||||
*
|
||||
* Description:
|
||||
* This is the main processing thread for telnetd. It never returns
|
||||
* unless an error occurs
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nsh_telnetmain(void)
|
||||
{
|
||||
struct in_addr addr;
|
||||
#if defined(CONFIG_EXAMPLES_NSH_DHCPC) || defined(CONFIG_EXAMPLES_NSH_NOMAC)
|
||||
uint8 mac[IFHWADDRLEN];
|
||||
#endif
|
||||
|
||||
/* Many embedded network interfaces must have a software assigned MAC */
|
||||
|
||||
#ifdef CONFIG_EXAMPLES_NSH_NOMAC
|
||||
mac[0] = 0x00;
|
||||
mac[1] = 0xe0;
|
||||
mac[2] = 0xb0;
|
||||
mac[3] = 0x0b;
|
||||
mac[4] = 0xba;
|
||||
mac[5] = 0xbe;
|
||||
uip_setmacaddr("eth0", mac);
|
||||
#endif
|
||||
|
||||
/* Set up our host address */
|
||||
|
||||
#if !defined(CONFIG_EXAMPLES_NSH_DHCPC)
|
||||
addr.s_addr = HTONL(CONFIG_EXAMPLES_NSH_IPADDR);
|
||||
#else
|
||||
addr.s_addr = 0;
|
||||
#endif
|
||||
uip_sethostaddr("eth0", &addr);
|
||||
|
||||
/* Set up the default router address */
|
||||
|
||||
addr.s_addr = HTONL(CONFIG_EXAMPLES_NSH_DRIPADDR);
|
||||
uip_setdraddr("eth0", &addr);
|
||||
|
||||
/* Setup the subnet mask */
|
||||
|
||||
addr.s_addr = HTONL(CONFIG_EXAMPLES_NSH_NETMASK);
|
||||
uip_setnetmask("eth0", &addr);
|
||||
|
||||
#if defined(CONFIG_EXAMPLES_NSH_DHCPC)
|
||||
/* Set up the resolver */
|
||||
|
||||
resolv_init();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_EXAMPLES_NSH_DHCPC)
|
||||
/* Get the MAC address of the NIC */
|
||||
|
||||
uip_getmacaddr("eth0", mac);
|
||||
|
||||
/* Set up the DHCPC modules */
|
||||
|
||||
handle = dhcpc_open(&mac, IFHWADDRLEN);
|
||||
|
||||
/* Get an IP address */
|
||||
|
||||
if (handle)
|
||||
{
|
||||
struct dhcpc_state ds;
|
||||
(void)dhcpc_request(handle, &ds);
|
||||
uip_sethostaddr("eth1", &ds.ipaddr);
|
||||
if (ds.netmask.s_addr != 0)
|
||||
{
|
||||
uip_setnetmask("eth0", &ds.netmask);
|
||||
}
|
||||
if (ds.default_router.s_addr != 0)
|
||||
{
|
||||
uip_setdraddr("eth0", &ds.default_router);
|
||||
}
|
||||
if (ds.dnsaddr.s_addr != 0)
|
||||
{
|
||||
resolv_conf(&ds.dnsaddr);
|
||||
}
|
||||
dhcpc_close(handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Execute nsh_connection on each connection to port 23 */
|
||||
|
||||
uip_server(HTONS(23), nsh_connection, CONFIG_EXAMPLES_NSH_STACKSIZE);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nsh_telnetout
|
||||
*
|
||||
* Description:
|
||||
* Print a string to the remote shell window.
|
||||
*
|
||||
* This function is implemented by the shell GUI / telnet server and
|
||||
* can be called by the shell back-end to output a string in the
|
||||
* shell window. The string is automatically appended with a linebreak.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int nsh_telnetout(FAR void *handle, const char *fmt, ...)
|
||||
{
|
||||
struct telnetd_s *pstate = (struct telnetd_s *)handle;
|
||||
unsigned len;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(pstate->tn_iobuffer, CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
len = strlen(pstate->tn_iobuffer);
|
||||
if (len < (CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE - 1) && pstate->tn_iobuffer[len-1] == '\n')
|
||||
{
|
||||
pstate->tn_iobuffer[len-1] = ISO_cr;
|
||||
pstate->tn_iobuffer[len] = ISO_nl;
|
||||
pstate->tn_iobuffer[len+1] = '\0';
|
||||
len++;
|
||||
}
|
||||
|
||||
nsh_dumpbuffer("Shell output", pstate->tn_iobuffer, len);
|
||||
if (send(pstate->tn_sockfd, pstate->tn_iobuffer, len, 0) < 0)
|
||||
{
|
||||
dbg("[%d] Failed to send response\n", pstate->tn_sockfd);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: cmd_exit
|
||||
*
|
||||
* Description:
|
||||
* Quit the shell instance
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void cmd_exit(void *handle, int argc, char **argv)
|
||||
{
|
||||
struct telnetd_s *pstate = (struct telnetd_s *)handle;
|
||||
pstate->tn_state = STATE_CLOSE;
|
||||
}
|
||||
|
|
@ -134,9 +134,11 @@ int closedir(FAR DIR *dirp)
|
|||
free(idir);
|
||||
return OK;
|
||||
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
errout_with_inode:
|
||||
inode_release(inode);
|
||||
free(idir);
|
||||
#endif
|
||||
|
||||
errout:
|
||||
*get_errno_ptr() = ret;
|
||||
|
|
|
@ -219,10 +219,14 @@ FAR DIR *opendir(const char *path)
|
|||
|
||||
/* Nasty goto's make error handling simpler */
|
||||
|
||||
#ifndef CONFIG_DISABLE_MOUNTPOINT
|
||||
errout_with_inode:
|
||||
inode_release(inode);
|
||||
#endif
|
||||
|
||||
errout_with_direntry:
|
||||
free(dir);
|
||||
|
||||
errout_with_semaphore:
|
||||
inode_semgive();
|
||||
*get_errno_ptr() = ret;
|
||||
|
|
14
net/accept.c
14
net/accept.c
|
@ -62,14 +62,14 @@
|
|||
|
||||
struct accept_s
|
||||
{
|
||||
sem_t acpt_sem; /* Wait for interrupt event */
|
||||
sem_t acpt_sem; /* Wait for interrupt event */
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
FAR const struct sockaddr_in6 *acpt_addr; /* Return connection adress */
|
||||
FAR struct sockaddr_in6 *acpt_addr; /* Return connection adress */
|
||||
#else
|
||||
FAR const struct sockaddr_in *acpt_addr; /* Return connection adress */
|
||||
FAR struct sockaddr_in *acpt_addr; /* Return connection adress */
|
||||
#endif
|
||||
FAR struct uip_conn *acpt_newconn; /* The accepted connection */
|
||||
int acpt_result; /* The result of the wait */
|
||||
FAR struct uip_conn *acpt_newconn; /* The accepted connection */
|
||||
int acpt_result; /* The result of the wait */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -242,9 +242,9 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
|||
FAR struct uip_conn *conn;
|
||||
struct accept_s state;
|
||||
#ifdef CONFIG_NET_IPv6
|
||||
FAR const struct sockaddr_in6 *inaddr = (const struct sockaddr_in6 *)addr;
|
||||
FAR struct sockaddr_in6 *inaddr = (const struct sockaddr_in6 *)addr;
|
||||
#else
|
||||
FAR const struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr;
|
||||
FAR struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr;
|
||||
#endif
|
||||
irqstate_t save;
|
||||
int newfd;
|
||||
|
|
|
@ -831,7 +831,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
|
|||
struct uip_conn *conn;
|
||||
struct recvfrom_s state;
|
||||
irqstate_t save;
|
||||
int ret;
|
||||
int ret = OK;
|
||||
|
||||
/* Verify that the SOCK_STREAM has been connected */
|
||||
|
||||
|
|
|
@ -469,7 +469,7 @@ void shell_output(void *handle, const char *fmt, ...)
|
|||
telnetd_dumpbuffer("Shell output", pstate->tn_iobuffer, len+2);
|
||||
if (send(pstate->tn_sockfd, pstate->tn_iobuffer, len+2, 0) < 0)
|
||||
{
|
||||
dbg("[%d] Failed to send prompt\n", pstate->tn_sockfd);
|
||||
dbg("[%d] Failed to send response\n", pstate->tn_sockfd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue