Move NSH to apps/ as library

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3393 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-03-18 19:46:25 +00:00
parent 7bf5ad220a
commit 4923fdabc1
19 changed files with 9063 additions and 0 deletions

121
nshlib/Makefile Normal file
View File

@ -0,0 +1,121 @@
############################################################################
# apps/nshlib/Makefile
#
# Copyright (C) 2011 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 NuttX 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.
#
############################################################################
# TODO, this makefile should run make under the app dirs, instead of
# sourcing the Make.defs!
-include $(TOPDIR)/Make.defs
include ../Make.defs
ifeq ($(WINTOOL),y)
INCDIROPT = -w
endif
# NSH Library
ASRCS =
CSRCS = nsh_main.c nsh_fscmds.c nsh_ddcmd.c nsh_proccmds.c nsh_mmcmds.c \
nsh_envcmds.c nsh_dbgcmds.c
ifeq ($(CONFIG_EXAMPLES_NSH_BUILTIN_APPS),y)
CSRCS += nsh_apps.c
endif
ifeq ($(CONFIG_EXAMPLES_NSH_ROMFSETC),y)
CSRCS += nsh_romfsetc.c
endif
ifeq ($(CONFIG_NET),y)
CSRCS += nsh_netinit.c nsh_netcmds.c
endif
ifeq ($(CONFIG_EXAMPLES_NSH_CONSOLE),y)
CSRCS += nsh_serial.c
endif
ifeq ($(CONFIG_EXAMPLES_NSH_TELNET),y)
CSRCS += nsh_telnetd.c
endif
ifneq ($(CONFIG_EXAMPLES_NSH_DISABLESCRIPT),y)
CSRCS += nsh_test.c
endif
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS)
OBJS = $(AOBJS) $(COBJS)
BIN = ../libapps$(LIBEXT)
ROOTDEPPATH = --dep-path .
# Common build
VPATH =
all: .built
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
$(COBJS): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
$(BIN): $(OBJS)
@( for obj in $(OBJS) ; do \
$(call ARCHIVE, $@, $${obj}); \
done ; )
@touch .built
.built: $(BIN)
.depend: Makefile $(SRCS)
@$(MKDEP) $(ROOTDEPPATH) \
$(CC) -- $(CFLAGS) -- $(SRCS) >Make.dep
@touch $@
# Register application
depend: .depend
clean:
@rm -f $(BIN) *.o *~ .*.swp .built
$(call CLEAN)
distclean: clean
@rm -f Make.dep .depend
-include Make.dep

1016
nshlib/README.txt Normal file

File diff suppressed because it is too large Load Diff

490
nshlib/nsh.h Normal file
View File

@ -0,0 +1,490 @@
/****************************************************************************
* apps/nshlib/nsh.h
*
* Copyright (C) 2007-2011 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 NuttX 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.
*
****************************************************************************/
#ifndef __NSH_H
#define __HSH_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#ifdef CONFIG_EXAMPLES_NSH_CONSOLE
# include <stdio.h>
#endif
/****************************************************************************
* Definitions
****************************************************************************/
/* The telnetd interface and background commands require pthread support */
#ifdef CONFIG_DISABLE_PTHREAD
# undef CONFIG_EXAMPLES_NSH_TELNET
# ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
# define CONFIG_EXAMPLES_NSH_DISABLEBG 1
# endif
#endif
/* Telnetd requires networking support */
#ifndef CONFIG_NET
# undef CONFIG_EXAMPLES_NSH_TELNET
#endif
/* One front end must be defined */
#if !defined(CONFIG_EXAMPLES_NSH_CONSOLE) && !defined(CONFIG_EXAMPLES_NSH_TELNET)
# error "No NSH front end defined"
#endif
/* Verify support for ROMFS /etc directory support options */
#ifdef CONFIG_EXAMPLES_NSH_ROMFSETC
# ifdef CONFIG_DISABLE_MOUNTPOINT
# error "Mountpoint support is disabled"
# undef CONFIG_EXAMPLES_NSH_ROMFSETC
# endif
# if CONFIG_NFILE_DESCRIPTORS < 4
# error "Not enough file descriptors"
# undef CONFIG_EXAMPLES_NSH_ROMFSETC
# endif
# ifndef CONFIG_FS_ROMFS
# error "ROMFS support not enabled"
# undef CONFIG_EXAMPLES_NSH_ROMFSETC
# endif
# ifndef CONFIG_EXAMPLES_NSH_ROMFSMOUNTPT
# define CONFIG_EXAMPLES_NSH_ROMFSMOUNTPT "/etc"
# endif
# ifdef CONFIG_EXAMPLES_NSH_INIT
# ifndef CONFIG_EXAMPLES_NSH_INITSCRIPT
# define CONFIG_EXAMPLES_NSH_INITSCRIPT "init.d/rcS"
# endif
# endif
# undef NSH_INITPATH
# define NSH_INITPATH CONFIG_EXAMPLES_NSH_ROMFSMOUNTPT "/" CONFIG_EXAMPLES_NSH_INITSCRIPT
# ifndef CONFIG_EXAMPLES_NSH_ROMFSDEVNO
# define CONFIG_EXAMPLES_NSH_ROMFSDEVNO 0
# endif
# ifndef CONFIG_EXAMPLES_NSH_ROMFSSECTSIZE
# define CONFIG_EXAMPLES_NSH_ROMFSSECTSIZE 64
# endif
# define NSECTORS(b) (((b)+CONFIG_EXAMPLES_NSH_ROMFSSECTSIZE-1)/CONFIG_EXAMPLES_NSH_ROMFSSECTSIZE)
# define STR_RAMDEVNO(m) #m
# define MKMOUNT_DEVNAME(m) "/dev/ram" STR_RAMDEVNO(m)
# define MOUNT_DEVNAME MKMOUNT_DEVNAME(CONFIG_EXAMPLES_NSH_ROMFSDEVNO)
#else
# undef CONFIG_EXAMPLES_NSH_ROMFSMOUNTPT
# undef CONFIG_EXAMPLES_NSH_INIT
# undef CONFIG_EXAMPLES_NSH_INITSCRIPT
# undef CONFIG_EXAMPLES_NSH_ROMFSDEVNO
# undef CONFIG_EXAMPLES_NSH_ROMFSSECTSIZE
#endif
/* This is the maximum number of arguments that will be accepted for a command */
#define NSH_MAX_ARGUMENTS 6
/* strerror() produces much nicer output but is, however, quite large and
* will only be used if CONFIG_EXAMPLES_NSH_STRERROR is defined.
*/
#ifdef CONFIG_EXAMPLES_NSH_STRERROR
# define NSH_ERRNO strerror(errno)
# define NSH_ERRNO_OF(err) strerror(err)
#else
# define NSH_ERRNO (errno)
# define NSH_ERRNO_OF(err) (err)
#endif
/* Maximum size of one command line (telnet or serial) */
#ifndef CONFIG_EXAMPLES_NSH_LINELEN
# define CONFIG_EXAMPLES_NSH_LINELEN 80
#endif
/* The following two settings are used only in the telnetd interface */
#ifndef CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE
# define CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE 512
#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
/* The maximum number of nested if-then[-else]-fi sequences that
* are permissable.
*/
#ifndef CONFIG_EXAMPLES_NSH_NESTDEPTH
# define CONFIG_EXAMPLES_NSH_NESTDEPTH 3
#endif
/* Define to enable dumping of all input/output buffers */
#undef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER
#undef CONFIG_EXAMPLES_NSH_FULLPATH
/* Make sure that the home directory is defined */
#ifndef CONFIG_LIB_HOMEDIR
# define CONFIG_LIB_HOMEDIR "/"
#endif
/* Method access macros */
#define nsh_clone(v) (v)->clone(v)
#define nsh_release(v) (v)->release(v)
#define nsh_write(v,b,n) (v)->write(v,b,n)
#define nsh_linebuffer(v) (v)->linebuffer(v)
#define nsh_redirect(v,f,s) (v)->redirect(v,f,s)
#define nsh_undirect(v,s) (v)->undirect(v,s)
#define nsh_exit(v) (v)->exit(v)
#ifdef CONFIG_CPP_HAVE_VARARGS
# define nsh_output(v, fmt...) (v)->output(v, ##fmt)
#else
# define nsh_output vtbl->output
#endif
/* Size of info to be saved in call to nsh_redirect */
#define SAVE_SIZE (sizeof(int) + sizeof(FILE*) + sizeof(bool))
/* Stubs used when working directory is not supported */
#if CONFIG_NFILE_DESCRIPTORS <= 0 || defined(CONFIG_DISABLE_ENVIRON)
# define nsh_getfullpath(v,p) ((char*)(p))
# define nsh_freefullpath(p)
#endif
/****************************************************************************
* Public Types
****************************************************************************/
enum nsh_parser_e
{
NSH_PARSER_NORMAL = 0,
NSH_PARSER_IF,
NSH_PARSER_THEN,
NSH_PARSER_ELSE
};
struct nsh_state_s
{
uint8_t ns_ifcond : 1; /* Value of command in 'if' statement */
uint8_t ns_disabled : 1; /* TRUE: Unconditionally disabled */
uint8_t ns_unused : 4;
uint8_t ns_state : 2; /* Parser state (see enum nsh_parser_e) */
};
struct nsh_parser_s
{
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
bool np_bg; /* true: The last command executed in background */
#endif
bool np_redirect; /* true: Output from the last command was re-directed */
bool np_fail; /* true: The last command failed */
#ifndef CONFIG_EXAMPLES_NSH_DISABLESCRIPT
uint8_t np_ndx; /* Current index into np_st[] */
#endif
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
int np_nice; /* "nice" value applied to last background cmd */
#endif
/* This is a stack of parser state information. It supports nested
* execution of commands that span multiple lines (like if-then-else-fi)
*/
#ifndef CONFIG_EXAMPLES_NSH_DISABLESCRIPT
struct nsh_state_s np_st[CONFIG_EXAMPLES_NSH_NESTDEPTH];
#endif
};
struct nsh_vtbl_s
{
/* This function pointers are "hooks" into the front end logic to
* handle things like output of command results, redirection, etc.
* -- all of which must be done in a way that is unique to the nature
* of the front end.
*/
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
FAR struct nsh_vtbl_s *(*clone)(FAR struct nsh_vtbl_s *vtbl);
void (*addref)(FAR struct nsh_vtbl_s *vtbl);
void (*release)(FAR struct nsh_vtbl_s *vtbl);
#endif
ssize_t (*write)(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes);
int (*output)(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...);
FAR char *(*linebuffer)(FAR struct nsh_vtbl_s *vtbl);
void (*redirect)(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t *save);
void (*undirect)(FAR struct nsh_vtbl_s *vtbl, FAR uint8_t *save);
void (*exit)(FAR struct nsh_vtbl_s *vtbl);
/* Parser state data */
struct nsh_parser_s np;
};
typedef int (*cmd_t)(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
/****************************************************************************
* Public Data
****************************************************************************/
extern const char g_nshgreeting[];
extern const char g_nshprompt[];
extern const char g_nshsyntax[];
extern const char g_fmtargrequired[];
extern const char g_fmtarginvalid[];
extern const char g_fmtargrange[];
extern const char g_fmtcmdnotfound[];
extern const char g_fmtnosuch[];
extern const char g_fmttoomanyargs[];
extern const char g_fmtdeepnesting[];
extern const char g_fmtcontext[];
extern const char g_fmtcmdfailed[];
extern const char g_fmtcmdoutofmemory[];
extern const char g_fmtinternalerror[];
#ifndef CONFIG_DISABLE_SIGNALS
extern const char g_fmtsignalrecvd[];
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/* Initialization */
#ifdef CONFIG_EXAMPLES_NSH_ROMFSETC
extern int nsh_romfsetc(void);
#else
# define nsh_romfsetc() (-ENOSYS)
#endif
#ifdef CONFIG_NET
extern int nsh_netinit(void);
#else
# define nsh_netinit() (-ENOSYS)
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_NFILE_STREAMS > 0 && !defined(CONFIG_EXAMPLES_NSH_DISABLESCRIPT)
extern int nsh_script(FAR struct nsh_vtbl_s *vtbl, const char *cmd, const char *path);
#endif
/* Architecture-specific initialization */
#ifdef CONFIG_EXAMPLES_NSH_ARCHINIT
extern int nsh_archinitialize(void);
#else
# define nsh_archinitialize() (-ENOSYS)
#endif
/* Message handler */
extern int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline);
/* Application interface */
#ifdef CONFIG_EXAMPLES_NSH_BUILTIN_APPS
extern int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
FAR char *argv[]);
#endif
/* Working directory support */
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
extern FAR const char *nsh_getcwd(void);
extern char *nsh_getfullpath(FAR struct nsh_vtbl_s *vtbl, const char *relpath);
extern void nsh_freefullpath(char *relpath);
#endif
/* Debug */
extern void nsh_dumpbuffer(FAR struct nsh_vtbl_s *vtbl, const char *msg,
const uint8_t *buffer, ssize_t nbytes);
/* Shell command handlers */
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_ECHO
extern int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_EXEC
extern int cmd_exec(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_MB
extern int cmd_mb(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_MH
extern int cmd_mh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_MW
extern int cmd_mw(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_FREE
extern int cmd_free(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_PS
extern int cmd_ps(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_XD
extern int cmd_xd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#if !defined(CONFIG_EXAMPLES_NSH_DISABLESCRIPT) && !defined(CONFIG_EXAMPLES_NSH_DISABLE_TEST)
extern int cmd_test(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
extern int cmd_lbracket(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif
#if CONFIG_NFILE_DESCRIPTORS > 0
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_CAT
extern int cmd_cat(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_CP
extern int cmd_cp(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_DD
extern int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_LS
extern int cmd_ls(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# if CONFIG_NFILE_STREAMS > 0 && !defined(CONFIG_EXAMPLES_NSH_DISABLESCRIPT)
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_SH
extern int cmd_sh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# endif /* CONFIG_NFILE_STREAMS && !CONFIG_EXAMPLES_NSH_DISABLESCRIPT */
# ifndef CONFIG_DISABLE_MOUNTPOINT
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_LOSETUP
extern int cmd_losetup(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_MKFIFO
extern int cmd_mkfifo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifdef CONFIG_FS_READABLE
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_MOUNT
extern int cmd_mount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_UMOUNT
extern int cmd_umount(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifdef CONFIG_FS_WRITABLE
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_MKDIR
extern int cmd_mkdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_MKRD
extern int cmd_mkrd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_RM
extern int cmd_rm(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_RMDIR
extern int cmd_rmdir(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# endif /* CONFIG_FS_WRITABLE */
# endif /* CONFIG_FS_READABLE */
# ifdef CONFIG_FS_FAT
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_MKFATFS
extern int cmd_mkfatfs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# endif /* CONFIG_FS_FAT */
# endif /* !CONFIG_DISABLE_MOUNTPOINT */
# if !defined(CONFIG_DISABLE_ENVIRON)
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_CD
extern int cmd_cd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_PWD
extern int cmd_pwd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# endif /* !CONFIG_DISABLE_MOUNTPOINT */
#endif /* CONFIG_NFILE_DESCRIPTORS */
#if defined(CONFIG_NET)
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_IFCONFIG
extern int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_GET
extern int cmd_get(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_PUT
extern int cmd_put(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
#endif
#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_WGET
extern int cmd_wget(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
#endif
#if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \
!defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS)
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_PING
extern int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
#endif
#endif
#ifndef CONFIG_DISABLE_ENVIRON
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_SET
extern int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_UNSET
extern int cmd_unset(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
#endif /* CONFIG_DISABLE_ENVIRON */
#ifndef CONFIG_DISABLE_SIGNALS
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_KILL
extern int cmd_kill(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_SLEEP
extern int cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_USLEEP
extern int cmd_usleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
# endif
#endif /* CONFIG_DISABLE_SIGNALS */
#endif /* __NSH_H */

132
nshlib/nsh_apps.c Normal file
View File

@ -0,0 +1,132 @@
/****************************************************************************
* apps/nshlib/nsh_apps.c
*
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
* Copyright (C) 2011 Uros Platise. All rights reserved.
* Author: Uros Platise <uros.platise@isotel.eu>
*
* 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 NuttX 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>
#ifdef CONFIG_SCHED_WAITPID
# include <sys/wait.h>
#endif
#include <stdbool.h>
#include <errno.h>
#include <apps/apps.h>
#include "nsh.h"
#ifdef CONFIG_EXAMPLES_NSH_BUILTIN_APPS
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nsh_execute
****************************************************************************/
int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd,
FAR char *argv[])
{
int ret = OK;
FAR const char * name;
/* Try to find command within pre-built application list. */
ret = exec_nuttapp(cmd, argv);
if (ret < 0)
{
int err = -errno;
int i;
/* On failure, list the set of available built-in commands */
nsh_output(vtbl, "Builtin Apps: ");
for (i = 0; (name = nuttapp_getname(i)) != NULL; i++)
{
nsh_output(vtbl, "%s ", name);
}
nsh_output(vtbl, "\nand type 'help' for more NSH commands.\n\n");
return err;
}
#ifdef CONFIG_SCHED_WAITPID
if (vtbl->np.np_bg == false)
{
waitpid(ret, NULL, 0);
}
else
#endif
{
struct sched_param param;
sched_getparam(0, &param);
nsh_output(vtbl, "%s [%d:%d]\n", cmd, ret, param.sched_priority);
}
return OK;
}
#endif /* CONFIG_EXAMPLES_NSH_BUILTIN_APPS */

355
nshlib/nsh_dbgcmds.c Normal file
View File

@ -0,0 +1,355 @@
/****************************************************************************
* apps/nshlib/dbg_dbgcmds.c
*
* Copyright (C) 2008-2009, 2011 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 NuttX 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 <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "nsh.h"
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
struct dbgmem_s
{
bool dm_write; /* true: perfrom write operation */
void *dm_addr; /* Address to access */
uint32_t dm_value; /* Value to write */
unsigned int dm_count; /* The number of bytes to access */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: mem_parse
****************************************************************************/
int mem_parse(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv,
struct dbgmem_s *mem)
{
char *pcvalue = strchr(argv[1], '=');
unsigned long lvalue = 0;
/* Check if we are writing a value */
if (pcvalue)
{
*pcvalue = '\0';
pcvalue++;
lvalue = (unsigned long)strtol(pcvalue, NULL, 16);
if (lvalue > 0xffffffff)
{
return -EINVAL;
}
mem->dm_write = true;
mem->dm_value = (uint32_t)lvalue;
}
else
{
mem->dm_write = false;
mem->dm_value = 0;
}
/* Get the address to be accessed */
mem->dm_addr = (void*)strtol(argv[1], NULL, 16);
/* Get the number of bytes to access */
if (argc > 2)
{
mem->dm_count = (unsigned int)strtol(argv[2], NULL, 16);
}
else
{
mem->dm_count = 1;
}
return OK;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: cmd_mb
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_MB
int cmd_mb(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
struct dbgmem_s mem;
volatile uint8_t *ptr;
int ret;
int i;
ret = mem_parse(vtbl, argc, argv, &mem);
if (ret == 0)
{
/* Loop for the number of requested bytes */
for (i = 0, ptr = (volatile uint8_t*)mem.dm_addr; i < mem.dm_count; i++, ptr++)
{
/* Print the value at the address */
nsh_output(vtbl, " %p = 0x%02x", ptr, *ptr);
/* Are we supposed to write a value to this address? */
if (mem.dm_write)
{
/* Yes, was the supplied value within range? */
if (mem.dm_value > 0x000000ff)
{
nsh_output(vtbl, g_fmtargrange, argv[0]);
return ERROR;
}
/* Write the value and re-read the address so that we print its
* current value (if the address is a process address, then the
* value read might not necessarily be the value written).
*/
*ptr = (uint8_t)mem.dm_value;
nsh_output(vtbl, " -> 0x%02x", *ptr);
}
/* Make sure we end it with a newline */
nsh_output(vtbl, "\n", *ptr);
}
}
return ret;
}
#endif
/****************************************************************************
* Name: cmd_mh
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_MH
int cmd_mh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
struct dbgmem_s mem;
volatile uint16_t *ptr;
int ret;
int i;
ret = mem_parse(vtbl, argc, argv, &mem);
if (ret == 0)
{
/* Loop for the number of requested bytes */
for (i = 0, ptr = (volatile uint16_t*)mem.dm_addr; i < mem.dm_count; i += 2, ptr++)
{
/* Print the value at the address */
nsh_output(vtbl, " %p = 0x%04x", ptr, *ptr);
/* Are we supposed to write a value to this address? */
if (mem.dm_write)
{
/* Yes, was the supplied value within range? */
if (mem.dm_value > 0x0000ffff)
{
nsh_output(vtbl, g_fmtargrange, argv[0]);
return ERROR;
}
/* Write the value and re-read the address so that we print its
* current value (if the address is a process address, then the
* value read might not necessarily be the value written).
*/
*ptr = (uint16_t)mem.dm_value;
nsh_output(vtbl, " -> 0x%04x", *ptr);
}
/* Make sure we end it with a newline */
nsh_output(vtbl, "\n", *ptr);
}
}
return ret;
}
#endif
/****************************************************************************
* Name: cmd_mw
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_MW
int cmd_mw(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
struct dbgmem_s mem;
volatile uint32_t *ptr;
int ret;
int i;
ret = mem_parse(vtbl, argc, argv, &mem);
if (ret == 0)
{
/* Loop for the number of requested bytes */
for (i = 0, ptr = (volatile uint32_t*)mem.dm_addr; i < mem.dm_count; i += 4, ptr++)
{
/* Print the value at the address */
nsh_output(vtbl, " %p = 0x%08x", ptr, *ptr);
/* Are we supposed to write a value to this address? */
if (mem.dm_write)
{
/* Write the value and re-read the address so that we print its
* current value (if the address is a process address, then the
* value read might not necessarily be the value written).
*/
*ptr = mem.dm_value;
nsh_output(vtbl, " -> 0x%08x", *ptr);
}
/* Make sure we end it with a newline */
nsh_output(vtbl, "\n", *ptr);
}
}
return ret;
}
#endif
/****************************************************************************
* Name: nsh_dumpbuffer
****************************************************************************/
void nsh_dumpbuffer(FAR struct nsh_vtbl_s *vtbl, const char *msg,
const uint8_t *buffer, ssize_t nbytes)
{
char line[128];
int ch;
int i;
int j;
nsh_output(vtbl, "%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 : '.');
}
}
nsh_output(vtbl, "%s\n", line);
}
}
/****************************************************************************
* Name: cmd_xd
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_XD
int cmd_xd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
char *addr;
char *endptr;
int nbytes;
addr = (char*)strtol(argv[1], &endptr, 16);
if (argv[0][0] == '\0' || *endptr != '\0')
{
return ERROR;
}
nbytes = (int)strtol(argv[2], &endptr, 0);
if (argv[0][0] == '\0' || *endptr != '\0' || nbytes < 0)
{
return ERROR;
}
nsh_dumpbuffer(vtbl, "Hex dump", (uint8_t*)addr, nbytes);
return OK;
}
#endif

641
nshlib/nsh_ddcmd.c Normal file
View File

@ -0,0 +1,641 @@
/****************************************************************************
* apps/nshlib/nsh_ddcmd.c
*
* Copyright (C) 2008-2009 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 NuttX 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 <sys/stat.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/fs.h>
#include "nsh.h"
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_EXAMPLES_NSH_DISABLE_DD)
/****************************************************************************
* Definitions
****************************************************************************/
/* If no sector size is specified wity BS=, then the following default value
* is used.
*/
#define DEFAULT_SECTSIZE 512
/* At present, piping of input and output are not support, i.e., both of=
* and if= arguments are required.
*/
#undef CAN_PIPE_FROM_STD
/* Function pointer calls are only need if block drivers are supported
* (or, rather, if mount points are supported in the file system)
*/
#ifndef CONFIG_DISABLE_MOUNTPOINT
# define DD_INFD ((dd)->inf.fd)
# define DD_INHANDLE ((dd)->inf.handle)
# define DD_OUTFD ((dd)->outf.fd)
# define DD_OUTHANDLE ((dd)->outf.handle)
# define DD_READ(dd) ((dd)->infread(dd))
# define DD_WRITE(dd) ((dd)->outfwrite(dd))
# define DD_INCLOSE(dd) ((dd)->infclose(dd))
# define DD_OUTCLOSE(dd) ((dd)->outfclose(dd))
#else
# define DD_INFD ((dd)->infd)
# undef DD_INHANDLE
# define DD_OUTFD ((dd)->outfd)
# undef DD_OUTHANDLE
# define DD_READ(dd) dd_readch(dd)
# define DD_WRITE(dd) dd_writech(dd)
# define DD_INCLOSE(dd) dd_infclosech(dd)
# define DD_OUTCLOSE(dd) dd_outfclosech(dd)
#endif
/****************************************************************************
* Private Types
****************************************************************************/
struct dd_s
{
FAR struct nsh_vtbl_s *vtbl;
#ifndef CONFIG_DISABLE_MOUNTPOINT
union
{
FAR void *handle; /* BCH lib handle for block device*/
int fd; /* File descriptor of the character device */
} inf;
#else
int infd; /* File descriptor of the input device */
#endif
#ifndef CONFIG_DISABLE_MOUNTPOINT
union
{
FAR void *handle; /* BCH lib handle for block device*/
int fd; /* File descriptor of the character device */
} outf;
#else
int outfd; /* File descriptor of the output device */
#endif
uint32_t nsectors; /* Number of sectors to transfer */
uint32_t sector; /* The current sector number */
uint32_t skip; /* The number of sectors skipped on input */
bool eof; /* true: The of the input or output file has been hit */
uint16_t sectsize; /* Size of one sector */
uint16_t nbytes; /* Number of valid bytes in the buffer */
uint8_t *buffer; /* Buffer of data to write to the output file */
/* Function pointers to handle differences between block and character devices */
#ifndef CONFIG_DISABLE_MOUNTPOINT
int (*infread)(struct dd_s *dd);
void (*infclose)(struct dd_s *dd);
int (*outfwrite)(struct dd_s *dd);
void (*outfclose)(struct dd_s *dd);
#endif
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static const char g_dd[] = "dd";
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: dd_outfcloseblk
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
static void dd_outfcloseblk(struct dd_s *dd)
{
(void)bchlib_teardown(DD_OUTHANDLE);
}
#endif
/****************************************************************************
* Name: dd_outfclosech
****************************************************************************/
static void dd_outfclosech(struct dd_s *dd)
{
(void)close(DD_OUTFD);
}
/****************************************************************************
* Name: dd_infcloseblk
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
static void dd_infcloseblk(struct dd_s *dd)
{
(void)bchlib_teardown(DD_INHANDLE);
}
#endif
/****************************************************************************
* Name: dd_infclosech
****************************************************************************/
static void dd_infclosech(struct dd_s *dd)
{
(void)close(DD_INFD);
}
/****************************************************************************
* Name: dd_writeblk
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
static int dd_writeblk(struct dd_s *dd)
{
ssize_t nbytes;
off_t offset = (dd->sector - dd->skip) * dd->sectsize;
/* Write the sector at the specified offset */
nbytes = bchlib_write(DD_OUTHANDLE, (char*)dd->buffer, offset, dd->sectsize);
if (nbytes < 0)
{
/* bchlib_write return -EFBIG on attempts to write past the end of
* the device.
*/
if (nbytes == -EFBIG)
{
dd->eof = true; /* Set end-of-file */
}
else
{
FAR struct nsh_vtbl_s *vtbl = dd->vtbl;
nsh_output(vtbl, g_fmtcmdfailed, g_dd, "bshlib_write", NSH_ERRNO_OF(-nbytes));
return ERROR;
}
}
return OK;
}
#endif
/****************************************************************************
* Name: dd_writech
****************************************************************************/
static int dd_writech(struct dd_s *dd)
{
uint8_t *buffer = dd->buffer;
uint16_t written ;
ssize_t nbytes;
/* Is the out buffer full (or is this the last one)? */
written = 0;
do
{
nbytes = write(DD_OUTFD, buffer, dd->sectsize - written);
if (nbytes < 0)
{
FAR struct nsh_vtbl_s *vtbl = dd->vtbl;
nsh_output(vtbl, g_fmtcmdfailed, g_dd, "write", NSH_ERRNO_OF(-nbytes));
return ERROR;
}
written += nbytes;
buffer += nbytes;
}
while (written < dd->sectsize);
return OK;
}
/****************************************************************************
* Name: dd_readblk
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
static int dd_readblk(struct dd_s *dd)
{
ssize_t nbytes;
off_t offset = dd->sector * dd->sectsize;
nbytes = bchlib_read(DD_INHANDLE, (char*)dd->buffer, offset, dd->sectsize);
if (nbytes < 0)
{
FAR struct nsh_vtbl_s *vtbl = dd->vtbl;
nsh_output(vtbl, g_fmtcmdfailed, g_dd, "bshlib_read", NSH_ERRNO_OF(-nbytes));
return ERROR;
}
/* bchlib_read return 0 on attempts to write past the end of the device. */
dd->nbytes = nbytes;
dd->eof = (nbytes == 0);
return OK;
}
#endif
/****************************************************************************
* Name: dd_readch
****************************************************************************/
static int dd_readch(struct dd_s *dd)
{
uint8_t *buffer = dd->buffer;
ssize_t nbytes;
dd->nbytes = 0;
do
{
nbytes = read(DD_INFD, buffer, dd->sectsize - dd->nbytes);
if (nbytes < 0)
{
FAR struct nsh_vtbl_s *vtbl = dd->vtbl;
nsh_output(vtbl, g_fmtcmdfailed, g_dd, "read", NSH_ERRNO_OF(-nbytes));
return ERROR;
}
dd->nbytes += nbytes;
buffer += nbytes;
}
while (dd->nbytes < dd->sectsize && nbytes > 0);
dd->eof |= (dd->nbytes == 0);
return OK;
}
/****************************************************************************
* Name: dd_infopen
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
static int dd_filetype(const char *filename)
{
struct stat sb;
int ret;
/* Get the type of the file */
ret = stat(filename, &sb);
if (ret < 0)
{
return ERROR; /* Return -1 on failure */
}
return S_ISBLK(sb.st_mode); /* Return true(1) if block, false(0) if char */
}
#endif
/****************************************************************************
* Name: dd_infopen
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
static inline int dd_infopen(const char *name, struct dd_s *dd)
{
FAR struct nsh_vtbl_s *vtbl = dd->vtbl;
int ret;
int type;
/* Get the type of the input file */
type = dd_filetype(name);
if (type < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, g_dd, "stat", NSH_ERRNO_OF(-type));
return type;
}
/* Open the input file */
if (!type)
{
DD_INFD = open(name, O_RDONLY);
if (DD_INFD < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, g_dd, "open", NSH_ERRNO);
return ERROR;
}
dd->infread = dd_readch; /* Character oriented read */
dd->infclose = dd_infclosech;
}
else
{
ret = bchlib_setup(name, true, &DD_INHANDLE);
if (ret < 0)
{
return ERROR;
}
dd->infread = dd_readblk;
dd->infclose = dd_infcloseblk;
}
return OK;
}
#else
static inline int dd_infopen(const char *name, struct dd_s *dd)
{
DD_INFD = open(name, O_RDONLY);
if (DD_INFD < 0)
{
FAR struct nsh_vtbl_s *vtbl = dd->vtbl;
nsh_output(vtbl, g_fmtcmdfailed, g_dd, "open", NSH_ERRNO);
return ERROR;
}
return OK;
}
#endif
/****************************************************************************
* Name: dd_outfopen
****************************************************************************/
#ifndef CONFIG_DISABLE_MOUNTPOINT
static inline int dd_outfopen(const char *name, struct dd_s *dd)
{
int type;
int ret = OK;
/* Get the type of the output file */
type = dd_filetype(name);
/* Open the block driver for input */
if (type == true)
{
ret = bchlib_setup(name, true, &DD_OUTHANDLE);
if (ret < 0)
{
return ERROR;
}
dd->outfwrite = dd_writeblk; /* Block oriented write */
dd->outfclose = dd_outfcloseblk;
}
/* Otherwise, the file is character oriented or does not exist */
else
{
DD_OUTFD = open(name, O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (DD_OUTFD < 0)
{
FAR struct nsh_vtbl_s *vtbl = dd->vtbl;
nsh_output(vtbl, g_fmtcmdfailed, g_dd, "open", NSH_ERRNO);
return ERROR;
}
dd->outfwrite = dd_writech; /* Character oriented write */
dd->outfclose = dd_outfclosech;
}
return OK;
}
#else
static inline int dd_outfopen(const char *name, struct dd_s *dd)
{
DD_OUTFD = open(name, O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (DD_OUTFD < 0)
{
FAR struct nsh_vtbl_s *vtbl = dd->vtbl;
nsh_output(dd->vtbl, g_fmtcmdfailed, g_dd, "open", NSH_ERRNO);
return ERROR;
}
return OK;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: cmd_dd
****************************************************************************/
int cmd_dd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
struct dd_s dd;
char *infile = NULL;
char *outfile = NULL;
int ret = ERROR;
int i;
/* Initialize the dd structure */
memset(&dd, 0, sizeof(struct dd_s));
dd.vtbl = vtbl; /* For nsh_output */
dd.sectsize = DEFAULT_SECTSIZE; /* Sector size if 'bs=' not provided */
dd.nsectors = 0xffffffff; /* MAX_UINT32 */
/* If no IF= option is provided on the command line, then read
* from stdin.
*/
#ifdef CAN_PIPE_FROM_STD
DD_INFD = 0; /* stdin */
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_DD
dd.infread = readch; /* Character oriented read */
dd.infclose = noclose; /* Don't close stdin */
#endif
#endif
/* If no OF= option is provided on the command line, then write
* to stdout.
*/
#ifdef CAN_PIPE_FROM_STD
DD_OUTDF = 1; /* stdout */
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_DD
dd.outfwrite = writech; /* Character oriented write */
dd.outfclose = noclose; /* Don't close stdout */
#endif
#endif
/* Parse command line parameters */
for (i = 1; i < argc; i++)
{
if (strncmp(argv[i], "if=", 3) == 0)
{
infile = nsh_getfullpath(vtbl, &argv[i][3]);
}
else if (strncmp(argv[i], "of=", 3) == 0)
{
outfile = nsh_getfullpath(vtbl, &argv[i][3]);
}
else if (strncmp(argv[i], "bs=", 3) == 0)
{
dd.sectsize = atoi(&argv[i][3]);
}
else if (strncmp(argv[i], "count=", 6) == 0)
{
dd.nsectors = atoi(&argv[i][6]);
}
else if (strncmp(argv[i], "skip=", 5) == 0)
{
dd.skip = atoi(&argv[i][5]);
}
}
#ifndef CAN_PIPE_FROM_STD
if (!infile || !outfile)
{
nsh_output(vtbl, g_fmtargrequired, g_dd);
goto errout_with_paths;
}
#endif
if (dd.skip < 0 || dd.skip > dd.nsectors)
{
nsh_output(vtbl, g_fmtarginvalid, g_dd);
goto errout_with_paths;
}
/* Allocate the I/O buffer */
dd.buffer = malloc(dd.sectsize);
if (!dd.buffer)
{
nsh_output(vtbl, g_fmtcmdoutofmemory, g_dd);
goto errout_with_paths;
}
/* Open the input file */
ret = dd_infopen(infile, &dd);
if (ret < 0)
{
goto errout_with_paths;
}
/* Open the output file */
ret = dd_outfopen(outfile, &dd);
if (ret < 0)
{
goto errout_with_inf;
}
/* Then perform the data transfer */
dd.sector = 0;
while (!dd.eof && dd.nsectors > 0)
{
/* Read one sector from from the input */
ret = DD_READ(&dd);
if (ret < 0)
{
goto errout_with_outf;
}
/* Has the incoming data stream ended? */
if (!dd.eof)
{
/* Pad with zero if necessary (at the end of file only) */
for (i = dd.nbytes; i < dd.sectsize; i++)
{
dd.buffer[i] = 0;
}
/* Write one sector to the output file */
if (dd.sector >= dd.skip)
{
ret = DD_WRITE(&dd);
if (ret < 0)
{
goto errout_with_outf;
}
/* Decrement to show that a sector was written */
dd.nsectors--;
}
/* Increment the sector number */
dd.sector++;
}
}
ret = OK;
errout_with_outf:
DD_INCLOSE(&dd);
errout_with_inf:
DD_OUTCLOSE(&dd);
free(dd.buffer);
errout_with_paths:
if (infile)
{
free(infile);
}
if (outfile)
{
free(outfile);
}
return ret;
}
#endif /* CONFIG_NFILE_DESCRIPTORS && !CONFIG_EXAMPLES_NSH_DISABLE_DD */

335
nshlib/nsh_envcmds.c Normal file
View File

@ -0,0 +1,335 @@
/****************************************************************************
* apps/nshlib/nsh_envcmds.c
*
* Copyright (C) 2007-2009, 2011 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 NuttX 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <libgen.h>
#include <errno.h>
#include "nsh.h"
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
static const char g_pwd[] = "PWD";
static const char g_oldpwd[] = "OLDPWD";
static const char g_home[] = CONFIG_LIB_HOMEDIR;
#endif
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: nsh_getwd
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
static inline FAR const char *nsh_getwd(const char *wd)
{
const char *val;
/* If no working directory is defined, then default to the home directory */
val = getenv(wd);
if (!val)
{
val = g_home;
}
return val;
}
#endif
/****************************************************************************
* Name: nsh_getdirpath
****************************************************************************/
static inline char *nsh_getdirpath(FAR struct nsh_vtbl_s *vtbl,
const char *dirpath, const char *relpath)
{
char *alloc;
int len;
/* Handle the special case where the dirpath is simply */
if (strcmp(dirpath, "/") == 0)
{
len = strlen(relpath) + 2;
alloc = (char*)malloc(len);
if (alloc)
{
sprintf(alloc, "/%s", relpath);
}
}
else
{
len = strlen(dirpath) + strlen(relpath) + 2;
alloc = (char*)malloc(len);
if (alloc)
{
sprintf(alloc, "%s/%s", dirpath, relpath);
}
}
if (!alloc)
{
nsh_output(vtbl, g_fmtcmdoutofmemory, "nsh_getdirpath");
}
return alloc;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nsh_getwd
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
FAR const char *nsh_getcwd(void)
{
return nsh_getwd(g_pwd);
}
#endif
/****************************************************************************
* Name: nsh_getfullpath
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
char *nsh_getfullpath(FAR struct nsh_vtbl_s *vtbl, const char *relpath)
{
const char *wd;
/* Handle some special cases */
if (!relpath || relpath[0] == '\0')
{
/* No relative path provided */
return strdup(g_home);
}
else if (relpath[0] == '/')
{
return strdup(relpath);
}
/* Get the path to the current working directory */
wd = nsh_getcwd();
/* Fake the '.' directory */
if (strcmp(relpath, ".") == 0)
{
return strdup(wd);
}
/* Return the full path */
return nsh_getdirpath(vtbl, wd, relpath);
}
#endif
/****************************************************************************
* Name: nsh_freefullpath
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
void nsh_freefullpath(char *relpath)
{
if (relpath)
{
free(relpath);
}
}
#endif
/****************************************************************************
* Name: cmd_cd
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_CD
int cmd_cd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
const char *path = argv[1];
char *alloc = NULL;
char *fullpath = NULL;
int ret = OK;
/* Check for special arguments */
if (argc < 2 || strcmp(path, "~") == 0)
{
path = g_home;
}
else if (strcmp(path, "-") == 0)
{
alloc = strdup(nsh_getwd(g_oldpwd));
path = alloc;
}
else if (strcmp(path, "..") == 0)
{
alloc = strdup(nsh_getcwd());
path = dirname(alloc);
}
else
{
fullpath = nsh_getfullpath(vtbl, path);
path = fullpath;
}
/* Set the new workding directory */
if (chdir(path) != 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "chdir", NSH_ERRNO);
ret = ERROR;
}
/* Free any memory that was allocated */
if (alloc)
{
free(alloc);
}
if (fullpath)
{
nsh_freefullpath(fullpath);
}
return ret;
}
#endif
#endif
/****************************************************************************
* Name: cmd_echo
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_ECHO
int cmd_echo(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
int i;
/* echo each argument, separated by a space as it must have been on the
* command line
*/
for (i = 1; i < argc; i++)
{
nsh_output(vtbl, "%s ", argv[i]);
}
nsh_output(vtbl, "\n");
return OK;
}
#endif
/****************************************************************************
* Name: cmd_pwd
****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_DISABLE_ENVIRON)
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_PWD
int cmd_pwd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
nsh_output(vtbl, "%s\n", nsh_getcwd());
return OK;
}
#endif
#endif
/****************************************************************************
* Name: cmd_set
****************************************************************************/
#ifndef CONFIG_DISABLE_ENVIRON
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_SET
int cmd_set(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
int ret = setenv(argv[1], argv[2], TRUE);
if (ret < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "setenv", NSH_ERRNO);
}
return ret;
}
#endif
#endif
/****************************************************************************
* Name: cmd_unset
****************************************************************************/
#ifndef CONFIG_DISABLE_ENVIRON
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_UNSET
int cmd_unset(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
int ret = unsetenv(argv[1]);
if (ret < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "unsetenv", NSH_ERRNO);
}
return ret;
}
#endif
#endif

1341
nshlib/nsh_fscmds.c Normal file

File diff suppressed because it is too large Load Diff

1299
nshlib/nsh_main.c Normal file

File diff suppressed because it is too large Load Diff

95
nshlib/nsh_mmcmds.c Normal file
View File

@ -0,0 +1,95 @@
/****************************************************************************
* apps/nshlib/dbg_mmcmds.c
*
* Copyright (C) 2011 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 NuttX 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 <stdlib.h>
#include "nsh.h"
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: cmd_free
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_FREE
int cmd_free(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
struct mallinfo mem;
#ifdef CONFIG_CAN_PASS_STRUCTS
mem = mallinfo();
#else
(void)mallinfo(&mem);
#endif
nsh_output(vtbl, " total used free largest\n");
nsh_output(vtbl, "Mem: %11d%11d%11d%11d\n",
mem.arena, mem.uordblks, mem.fordblks, mem.mxordblk);
return OK;
}
#endif

815
nshlib/nsh_netcmds.c Normal file
View File

@ -0,0 +1,815 @@
/****************************************************************************
* apps/nshlib/nsh_netcmds.c
*
* Copyright (C) 2007-2011 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 NuttX 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>
#ifdef CONFIG_NET
#include <sys/stat.h> /* Needed for open */
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sched.h>
#include <fcntl.h> /* Needed for open */
#include <libgen.h> /* Needed for basename */
#include <errno.h>
#include <nuttx/net.h>
#include <nuttx/clock.h>
#include <net/ethernet.h>
#include <net/uip/uip.h>
#include <net/uip/uip-arch.h>
#include <netinet/ether.h>
#ifdef CONFIG_NET_STATISTICS
# include <net/uip/uip.h>
#endif
#if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \
!defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS)
# include <net/uip/uip-lib.h>
#endif
#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0
# include <net/uip/uip-lib.h>
# include <net/uip/tftp.h>
#endif
#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0
# ifndef CONFIG_EXAMPLES_NSH_DISABLE_WGET
# include <net/uip/uip-lib.h>
# include <net/uip/webclient.h>
# endif
#endif
#include "nsh.h"
/****************************************************************************
* Definitions
****************************************************************************/
#define DEFAULT_PING_DATALEN 56
/****************************************************************************
* Private Types
****************************************************************************/
#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0
struct tftpc_args_s
{
bool binary; /* true:binary ("octect") false:text ("netascii") */
bool allocated; /* true: destpath is allocated */
char *destpath; /* Path at destination */
const char *srcpath; /* Path at src */
in_addr_t ipaddr; /* Host IP address */
};
#endif
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
#if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \
!defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS)
static uint16_t g_pingid = 0;
#endif
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: ping_newid
****************************************************************************/
#if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \
!defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS)
static inline uint16_t ping_newid(void)
{
irqstate_t save = irqsave();
uint16_t ret = ++g_pingid;
irqrestore(save);
return ret;
}
#endif
/****************************************************************************
* Name: uip_statistics
****************************************************************************/
#if defined(CONFIG_NET_STATISTICS) && !defined(CONFIG_EXAMPLES_NSH_DISABLE_IFCONFIG)
static inline void uip_statistics(FAR struct nsh_vtbl_s *vtbl)
{
nsh_output(vtbl, "uIP IP ");
#ifdef CONFIG_NET_TCP
nsh_output(vtbl, " TCP");
#endif
#ifdef CONFIG_NET_UDP
nsh_output(vtbl, " UDP");
#endif
#ifdef CONFIG_NET_ICMP
nsh_output(vtbl, " ICMP");
#endif
nsh_output(vtbl, "\n");
/* Received packets */
nsh_output(vtbl, "Received %04x",uip_stat.ip.recv);
#ifdef CONFIG_NET_TCP
nsh_output(vtbl, " %04x",uip_stat.tcp.recv);
#endif
#ifdef CONFIG_NET_UDP
nsh_output(vtbl, " %04x",uip_stat.udp.recv);
#endif
#ifdef CONFIG_NET_ICMP
nsh_output(vtbl, " %04x",uip_stat.icmp.recv);
#endif
nsh_output(vtbl, "\n");
/* Dropped packets */
nsh_output(vtbl, "Dropped %04x",uip_stat.ip.drop);
#ifdef CONFIG_NET_TCP
nsh_output(vtbl, " %04x",uip_stat.tcp.drop);
#endif
#ifdef CONFIG_NET_UDP
nsh_output(vtbl, " %04x",uip_stat.udp.drop);
#endif
#ifdef CONFIG_NET_ICMP
nsh_output(vtbl, " %04x",uip_stat.icmp.drop);
#endif
nsh_output(vtbl, "\n");
nsh_output(vtbl, " IP VHL: %04x HBL: %04x\n",
uip_stat.ip.vhlerr, uip_stat.ip.hblenerr);
nsh_output(vtbl, " LBL: %04x Frg: %04x\n",
uip_stat.ip.lblenerr, uip_stat.ip.fragerr);
nsh_output(vtbl, " Checksum %04x",uip_stat.ip.chkerr);
#ifdef CONFIG_NET_TCP
nsh_output(vtbl, " %04x",uip_stat.tcp.chkerr);
#endif
#ifdef CONFIG_NET_UDP
nsh_output(vtbl, " %04x",uip_stat.udp.chkerr);
#endif
#ifdef CONFIG_NET_ICMP
nsh_output(vtbl, " ----");
#endif
nsh_output(vtbl, "\n");
#ifdef CONFIG_NET_TCP
nsh_output(vtbl, " TCP ACK: %04x SYN: %04x\n",
uip_stat.tcp.ackerr, uip_stat.tcp.syndrop);
nsh_output(vtbl, " RST: %04x %04x\n",
uip_stat.tcp.rst, uip_stat.tcp.synrst);
#endif
nsh_output(vtbl, " Type %04x",uip_stat.ip.protoerr);
#ifdef CONFIG_NET_TCP
nsh_output(vtbl, " ----");
#endif
#ifdef CONFIG_NET_UDP
nsh_output(vtbl, " ----");
#endif
#ifdef CONFIG_NET_ICMP
nsh_output(vtbl, " %04x",uip_stat.icmp.typeerr);
#endif
nsh_output(vtbl, "\n");
/* Sent packets */
nsh_output(vtbl, "Sent ----",uip_stat.ip.sent);
#ifdef CONFIG_NET_TCP
nsh_output(vtbl, " %04x",uip_stat.tcp.sent);
#endif
#ifdef CONFIG_NET_UDP
nsh_output(vtbl, " %04x",uip_stat.udp.sent);
#endif
#ifdef CONFIG_NET_ICMP
nsh_output(vtbl, " %04x",uip_stat.icmp.sent);
#endif
nsh_output(vtbl, "\n");
#ifdef CONFIG_NET_TCP
nsh_output(vtbl, " Rexmit ---- %04x",uip_stat.tcp.rexmit);
#ifdef CONFIG_NET_UDP
nsh_output(vtbl, " ----");
#endif
#ifdef CONFIG_NET_ICMP
nsh_output(vtbl, " ----");
#endif
nsh_output(vtbl, "\n");
#endif
nsh_output(vtbl, "\n");
}
#else
# define uip_statistics(vtbl)
#endif
/****************************************************************************
* Name: ifconfig_callback
****************************************************************************/
int ifconfig_callback(FAR struct uip_driver_s *dev, void *arg)
{
struct nsh_vtbl_s *vtbl = (struct nsh_vtbl_s*)arg;
struct in_addr addr;
nsh_output(vtbl, "%s\tHWaddr %s\n", dev->d_ifname, ether_ntoa(&dev->d_mac));
addr.s_addr = dev->d_ipaddr;
nsh_output(vtbl, "\tIPaddr:%s ", inet_ntoa(addr));
addr.s_addr = dev->d_draddr;
nsh_output(vtbl, "DRaddr:%s ", inet_ntoa(addr));
addr.s_addr = dev->d_netmask;
nsh_output(vtbl, "Mask:%s\n\n", inet_ntoa(addr));
return OK;
}
/****************************************************************************
* Name: tftpc_parseargs
****************************************************************************/
#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0
int tftpc_parseargs(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv,
struct tftpc_args_s *args)
{
FAR const char *fmt = g_fmtarginvalid;
bool badarg = false;
int option;
/* Get the ping options */
memset(args, 0, sizeof(struct tftpc_args_s));
while ((option = getopt(argc, argv, ":bnf:h:")) != ERROR)
{
switch (option)
{
case 'b':
args->binary = true;
break;
case 'n':
args->binary = false;
break;
case 'f':
args->destpath = optarg;
break;
case 'h':
if (!uiplib_ipaddrconv(optarg, (FAR unsigned char*)&args->ipaddr))
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
badarg = true;
}
break;
case ':':
nsh_output(vtbl, g_fmtargrequired, argv[0]);
badarg = true;
break;
case '?':
default:
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
badarg = true;
break;
}
}
/* If a bad argument was encountered, then return without processing the command */
if (badarg)
{
return ERROR;
}
/* There should be exactly on parameter left on the command-line */
if (optind == argc-1)
{
args->srcpath = argv[optind];
}
else if (optind >= argc)
{
fmt = g_fmttoomanyargs;
goto errout;
}
else
{
fmt = g_fmtargrequired;
goto errout;
}
/* The HOST IP address is also required */
if (!args->ipaddr)
{
fmt = g_fmtargrequired;
goto errout;
}
/* If the destpath was not provided, then we have do a little work. */
if (!args->destpath)
{
char *tmp1;
char *tmp2;
/* Copy the srcpath... baseanme might modify it */
fmt = g_fmtcmdoutofmemory;
tmp1 = strdup(args->srcpath);
if (!tmp1)
{
goto errout;
}
/* Get the basename of the srcpath */
tmp2 = basename(tmp1);
if (!tmp2)
{
free(tmp1);
goto errout;
}
/* Use that basename as the destpath */
args->destpath = strdup(tmp2);
free(tmp1);
if (!args->destpath)
{
goto errout;
}
args->allocated = true;
}
return OK;
errout:
nsh_output(vtbl, fmt, argv[0]);
return ERROR;
}
#endif
/****************************************************************************
* Name: wget_callback
****************************************************************************/
#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_WGET
static void wget_callback(FAR char **buffer, int offset, int datend,
FAR int *buflen, FAR void *arg)
{
(void)write((int)arg, &((*buffer)[offset]), datend - offset);
}
#endif
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: cmd_get
****************************************************************************/
#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_GET
int cmd_get(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
struct tftpc_args_s args;
char *fullpath;
/* Parse the input parameter list */
if (tftpc_parseargs(vtbl, argc, argv, &args) != OK)
{
return ERROR;
}
/* Get the full path to the local file */
fullpath = nsh_getfullpath(vtbl, args.srcpath);
/* Then perform the TFTP get operation */
if (tftpget(args.srcpath, fullpath, args.ipaddr, args.binary) != OK)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "tftpget", NSH_ERRNO);
}
/* Release any allocated memory */
if (args.allocated)
{
free(args.destpath);
}
free(fullpath);
return OK;
}
#endif
#endif
/****************************************************************************
* Name: cmd_ifconfig
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_IFCONFIG
int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
netdev_foreach(ifconfig_callback, vtbl);
uip_statistics(vtbl);
return OK;
}
#endif
/****************************************************************************
* Name: cmd_ping
****************************************************************************/
#if defined(CONFIG_NET_ICMP) && defined(CONFIG_NET_ICMP_PING) && \
!defined(CONFIG_DISABLE_CLOCK) && !defined(CONFIG_DISABLE_SIGNALS)
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_PING
int cmd_ping(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
FAR const char *fmt = g_fmtarginvalid;
const char *staddr;
uip_ipaddr_t ipaddr;
uint32_t start;
uint32_t next;
uint32_t dsec = 10;
uint16_t id;
bool badarg = false;
int count = 10;
int option;
int seqno;
int replies = 0;
int elapsed;
int tmp;
int i;
/* Get the ping options */
while ((option = getopt(argc, argv, ":c:i:")) != ERROR)
{
switch (option)
{
case 'c':
count = atoi(optarg);
if (count < 1 || count > 10000)
{
nsh_output(vtbl, g_fmtargrange, argv[0]);
badarg = true;
}
break;
case 'i':
tmp = atoi(optarg);
if (tmp < 1 || tmp >= 4294)
{
nsh_output(vtbl, g_fmtargrange, argv[0]);
badarg = true;
}
else
{
dsec = 10 * tmp;
}
break;
case ':':
nsh_output(vtbl, g_fmtargrequired, argv[0]);
badarg = true;
break;
case '?':
default:
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
badarg = true;
break;
}
}
/* If a bad argument was encountered, then return without processing the command */
if (badarg)
{
return ERROR;
}
/* There should be exactly on parameter left on the command-line */
if (optind == argc-1)
{
staddr = argv[optind];
if (!uiplib_ipaddrconv(staddr, (FAR unsigned char*)&ipaddr))
{
goto errout;
}
}
else if (optind >= argc)
{
fmt = g_fmttoomanyargs;
goto errout;
}
else
{
fmt = g_fmtargrequired;
goto errout;
}
/* Get the ID to use */
id = ping_newid();
/* Loop for the specified count */
nsh_output(vtbl, "PING %s %d bytes of data\n", staddr, DEFAULT_PING_DATALEN);
start = g_system_timer;
for (i = 1; i <= count; i++)
{
/* Send the ECHO request and wait for the response */
next = g_system_timer;
seqno = uip_ping(ipaddr, id, i, DEFAULT_PING_DATALEN, dsec);
/* Was any response returned? We can tell if a non-negative sequence
* number was returned.
*/
if (seqno >= 0 && seqno <= i)
{
/* Get the elpased time from the time that the request was
* sent until the response was received. If we got a response
* to an earlier request, then fudge the elpased time.
*/
elapsed = TICK2MSEC(g_system_timer - next);
if (seqno < i)
{
elapsed += 100*dsec*(i - seqno);
}
/* Report the receipt of the reply */
nsh_output(vtbl, "%d bytes from %s: icmp_seq=%d time=%d ms\n",
DEFAULT_PING_DATALEN, staddr, seqno, elapsed);
replies++;
}
/* Wait for the remainder of the interval. If the last seqno<i,
* then this is a bad idea... we will probably lose the response
* to the current request!
*/
elapsed = TICK2DSEC(g_system_timer - next);
if (elapsed < dsec)
{
usleep(100000*dsec);
}
}
/* Get the total elapsed time */
elapsed = TICK2MSEC(g_system_timer - start);
/* Calculate the percentage of lost packets */
tmp = (100*(count - replies) + (count >> 1)) / count;
nsh_output(vtbl, "%d packets transmitted, %d received, %d%% packet loss, time %d ms\n",
count, replies, tmp, elapsed);
return OK;
errout:
nsh_output(vtbl, fmt, argv[0]);
return ERROR;
}
#endif
#endif /* CONFIG_NET_ICMP && CONFIG_NET_ICMP_PING */
/****************************************************************************
* Name: cmd_put
****************************************************************************/
#if defined(CONFIG_NET_UDP) && CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_PUT
int cmd_put(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
struct tftpc_args_s args;
char *fullpath;
/* Parse the input parameter list */
if (tftpc_parseargs(vtbl, argc, argv, &args) != OK)
{
return ERROR;
}
/* Get the full path to the local file */
fullpath = nsh_getfullpath(vtbl, args.srcpath);
/* Then perform the TFTP put operation */
if (tftpput(fullpath, args.destpath, args.ipaddr, args.binary) != OK)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "tftpput", NSH_ERRNO);
}
/* Release any allocated memory */
if (args.allocated)
{
free(args.destpath);
}
free(fullpath);
return OK;
}
#endif
#endif
/****************************************************************************
* Name: cmd_wget
****************************************************************************/
#if defined(CONFIG_NET_TCP) && CONFIG_NFILE_DESCRIPTORS > 0
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_WGET
int cmd_wget(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
char *localfile = NULL;
char *allocfile = NULL;
char *buffer = NULL;
char *fullpath = NULL;
char *url;
const char *fmt;
bool badarg = false;
int option;
int fd = -1;
int ret;
/* Get the wget options */
while ((option = getopt(argc, argv, ":o:")) != ERROR)
{
switch (option)
{
case 'o':
localfile = optarg;
break;
case ':':
nsh_output(vtbl, g_fmtargrequired, argv[0]);
badarg = true;
break;
case '?':
default:
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
badarg = true;
break;
}
}
/* If a bad argument was encountered, then return without processing the command */
if (badarg)
{
return ERROR;
}
/* There should be exactly on parameter left on the command-line */
if (optind == argc-1)
{
url = argv[optind];
}
else if (optind >= argc)
{
fmt = g_fmttoomanyargs;
goto errout;
}
else
{
fmt = g_fmtargrequired;
goto errout;
}
/* Get the local file name */
if (!localfile)
{
allocfile = strdup(url);
localfile = basename(allocfile);
}
/* Get the full path to the local file */
fullpath = nsh_getfullpath(vtbl, localfile);
/* Open the local file for writing */
fd = open(fullpath, O_WRONLY|O_CREAT|O_TRUNC, 0644);
if (fd < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "open", NSH_ERRNO);
ret = ERROR;
goto exit;
}
/* Allocate an I/O buffer */
buffer = malloc(512);
if (!buffer)
{
fmt = g_fmtcmdoutofmemory;
goto errout;
}
/* And perform the wget */
ret = wget(url, buffer, 512, wget_callback, (FAR void *)fd);
if (ret < 0)
{
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "wget", NSH_ERRNO);
goto exit;
}
/* Free allocated resources */
exit:
if (fd >= 0)
{
close(fd);
}
if (allocfile)
{
free(allocfile);
}
if (fullpath)
{
free(fullpath);
}
if (buffer)
{
free(buffer);
}
return ret;
errout:
nsh_output(vtbl, fmt, argv[0]);
ret = ERROR;
goto exit;
}
#endif
#endif
#endif /* CONFIG_NET */

169
nshlib/nsh_netinit.c Normal file
View File

@ -0,0 +1,169 @@
/****************************************************************************
* apps/nshlib/nsh_netinit.c
*
* Copyright (C) 2010-2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* This is influenced by 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 <debug.h>
#include <net/if.h>
#include <net/uip/uip-lib.h>
#if defined(CONFIG_EXAMPLES_NSH_DHCPC)
# include <net/uip/resolv.h>
# include <net/uip/dhcpc.h>
#endif
#include "nsh.h"
#ifdef CONFIG_NET
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nsh_netinit
*
* Description:
* Initialize the network per the selected NuttX configuration
*
****************************************************************************/
int nsh_netinit(void)
{
struct in_addr addr;
#if defined(CONFIG_EXAMPLES_NSH_DHCPC)
FAR void *handle;
#endif
#if defined(CONFIG_EXAMPLES_NSH_DHCPC) || defined(CONFIG_EXAMPLES_NSH_NOMAC)
uint8_t 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. Note that there is no logic for renewing the IP address in this
* example. The address should be renewed in ds.lease_time/2 seconds.
*/
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
return OK;
}
#endif /* CONFIG_NET */

297
nshlib/nsh_proccmds.c Normal file
View File

@ -0,0 +1,297 @@
/****************************************************************************
* apps/nshlib/nsh_proccmds.c
*
* Copyright (C) 2007-2009, 2011 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 NuttX 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sched.h>
#include <errno.h>
#include "nsh.h"
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/* The returned value should be zero for sucess or TRUE or non zero for
* failure or FALSE.
*/
typedef int (*exec_t)(void);
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static const char *g_statenames[] =
{
"INVALID ",
"PENDING ",
"READY ",
"RUNNING ",
"INACTIVE",
"WAITSEM ",
#ifndef CONFIG_DISABLE_MQUEUE
"WAITSIG ",
#endif
#ifndef CONFIG_DISABLE_MQUEUE
"MQNEMPTY",
"MQNFULL "
#endif
};
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: ps_task
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_PS
static void ps_task(FAR _TCB *tcb, FAR void *arg)
{
struct nsh_vtbl_s *vtbl = (struct nsh_vtbl_s*)arg;
int i;
/* Show task status */
nsh_output(vtbl, "%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]);
/* Show task name and arguments */
nsh_output(vtbl, "%s(", tcb->argv[0]);
/* Special case 1st argument (no comma) */
if (tcb->argv[1])
{
nsh_output(vtbl, "%p", tcb->argv[1]);
}
/* Then any additional arguments */
#if CONFIG_MAX_TASK_ARGS > 2
for (i = 2; i <= CONFIG_MAX_TASK_ARGS && tcb->argv[i]; i++)
{
nsh_output(vtbl, ", %p", tcb->argv[i]);
}
#endif
nsh_output(vtbl, ")\n");
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: cmd_exec
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_EXEC
int cmd_exec(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
char *endptr;
long addr;
addr = strtol(argv[1], &endptr, 0);
if (!addr || endptr == argv[1] || *endptr != '\0')
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
nsh_output(vtbl, "Calling %p\n", (exec_t)addr);
return ((exec_t)addr)();
}
#endif
/****************************************************************************
* Name: cmd_ps
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_PS
int cmd_ps(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
nsh_output(vtbl, "PID PRI SCHD TYPE NP STATE NAME\n");
sched_foreach(ps_task, vtbl);
return OK;
}
#endif
/****************************************************************************
* Name: cmd_kill
****************************************************************************/
#ifndef CONFIG_DISABLE_SIGNALS
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_KILL
int cmd_kill(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
char *ptr;
char *endptr;
long signal;
long pid;
/* Check incoming parameters. The first parameter should be "-<signal>" */
ptr = argv[1];
if (*ptr != '-' || ptr[1] < '0' || ptr[1] > '9')
{
goto invalid_arg;
}
/* Extract the signal number */
signal = strtol(&ptr[1], &endptr, 0);
/* The second parameter should be <pid> */
ptr = argv[2];
if (*ptr < '0' || *ptr > '9')
{
goto invalid_arg;
}
/* Extract athe pid */
pid = strtol(ptr, &endptr, 0);
/* Send the signal. Kill return values:
*
* EINVAL An invalid signal was specified.
* EPERM The process does not have permission to send the signal to any
* of the target processes.
* ESRCH The pid or process group does not exist.
* ENOSYS Do not support sending signals to process groups.
*/
if (kill((pid_t)pid, (int)signal) == 0)
{
return OK;
}
switch (errno)
{
case EINVAL:
goto invalid_arg;
case ESRCH:
nsh_output(vtbl, g_fmtnosuch, argv[0], "task", argv[2]);
return ERROR;
case EPERM:
case ENOSYS:
default:
nsh_output(vtbl, g_fmtcmdfailed, argv[0], "kill", NSH_ERRNO);
return ERROR;
}
invalid_arg:
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
#endif
#endif
/****************************************************************************
* Name: cmd_sleep
****************************************************************************/
#ifndef CONFIG_DISABLE_SIGNALS
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_SLEEP
int cmd_sleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
char *endptr;
long secs;
secs = strtol(argv[1], &endptr, 0);
if (!secs || endptr == argv[1] || *endptr != '\0')
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
sleep(secs);
return OK;
}
#endif
#endif
/****************************************************************************
* Name: cmd_usleep
****************************************************************************/
#ifndef CONFIG_DISABLE_SIGNALS
#ifndef CONFIG_EXAMPLES_NSH_DISABLE_USLEEP
int cmd_usleep(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
char *endptr;
long usecs;
usecs = strtol(argv[1], &endptr, 0);
if (!usecs || endptr == argv[1] || *endptr != '\0')
{
nsh_output(vtbl, g_fmtarginvalid, argv[0]);
return ERROR;
}
usleep(usecs);
return OK;
}
#endif
#endif

124
nshlib/nsh_romfsetc.c Normal file
View File

@ -0,0 +1,124 @@
/****************************************************************************
* apps/nshlib/nsh_romfsetc.c
*
* Copyright (C) 2008-2011 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 NuttX 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/mount.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/ramdisk.h>
#include "nsh.h"
#ifdef CONFIG_EXAMPLES_NSH_ROMFSETC
/* Should we use the default ROMFS image? Or a custom, board-specific
* ROMFS image?
*/
#ifdef CONFIG_EXAMPLES_NSH_ARCHROMFS
# include <arch/board/nsh_romfsimg.h>
#else
# include "nsh_romfsimg.h"
#endif
/****************************************************************************
* Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nsh_romfsetc
****************************************************************************/
int nsh_romfsetc(void)
{
int ret;
/* Create a ROM disk for the /etc filesystem */
ret = romdisk_register(CONFIG_EXAMPLES_NSH_ROMFSDEVNO, romfs_img,
NSECTORS(romfs_img_len), CONFIG_EXAMPLES_NSH_ROMFSSECTSIZE);
if (ret < 0)
{
dbg("nsh: romdisk_register failed: %d\n", -ret);
return ERROR;
}
/* Mount the file system */
vdbg("Mounting ROMFS filesystem at target=%s with source=%s\n",
CONFIG_EXAMPLES_NSH_ROMFSMOUNTPT, MOUNT_DEVNAME);
ret = mount(MOUNT_DEVNAME, CONFIG_EXAMPLES_NSH_ROMFSMOUNTPT, "romfs", MS_RDONLY, NULL);
if (ret < 0)
{
dbg("nsh: mount(%s,%s,romfs) failed: %s\n",
MOUNT_DEVNAME, CONFIG_EXAMPLES_NSH_ROMFSMOUNTPT, errno);
return ERROR;
}
return OK;
}
#endif /* CONFIG_EXAMPLES_NSH_ROMFSETC */

89
nshlib/nsh_romfsimg.h Normal file
View File

@ -0,0 +1,89 @@
unsigned char romfs_img[] = {
0x2d, 0x72, 0x6f, 0x6d, 0x31, 0x66, 0x73, 0x2d, 0x00, 0x00, 0x01, 0x50,
0x9f, 0x13, 0x82, 0x87, 0x4e, 0x53, 0x48, 0x49, 0x6e, 0x69, 0x74, 0x56,
0x6f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xff, 0xff, 0x97,
0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0xd1, 0xd1, 0xff, 0x80, 0x2e, 0x2e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
0x68, 0x2d, 0x96, 0x03, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x64, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xff, 0xff, 0x00,
0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3a, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x6e, 0x8d, 0x9c, 0xab, 0x58, 0x72, 0x63, 0x53, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x23, 0x20, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x61, 0x20, 0x52,
0x41, 0x4d, 0x44, 0x49, 0x53, 0x4b, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d,
0x6f, 0x75, 0x6e, 0x74, 0x20, 0x69, 0x74, 0x20, 0x61, 0x74, 0x20, 0x2f,
0x74, 0x6d, 0x70, 0x0a, 0x0a, 0x6d, 0x6b, 0x72, 0x64, 0x20, 0x2d, 0x6d,
0x20, 0x32, 0x20, 0x2d, 0x73, 0x20, 0x35, 0x31, 0x32, 0x20, 0x31, 0x30,
0x32, 0x34, 0x0a, 0x6d, 0x6b, 0x66, 0x61, 0x74, 0x66, 0x73, 0x20, 0x2f,
0x64, 0x65, 0x76, 0x2f, 0x72, 0x61, 0x6d, 0x32, 0x0a, 0x6d, 0x6f, 0x75,
0x6e, 0x74, 0x20, 0x2d, 0x74, 0x20, 0x76, 0x66, 0x61, 0x74, 0x20, 0x2f,
0x64, 0x65, 0x76, 0x2f, 0x72, 0x61, 0x6d, 0x32, 0x20, 0x2f, 0x74, 0x6d,
0x70, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x00, 0x00, 0x00, 0x00, 0xd1, 0xd1, 0xff, 0xe0, 0x2e, 0x2e, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
unsigned int romfs_img_len = 1024;

449
nshlib/nsh_serial.c Normal file
View File

@ -0,0 +1,449 @@
/****************************************************************************
* apps/nshlib/nsh_serial.c
*
* Copyright (C) 2007-2009, 2011 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 <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <debug.h>
#include "nsh.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
struct serial_s
{
struct nsh_vtbl_s ss_vtbl;
int ss_fd; /* Re-direct file descriptor */
FILE *ss_stream; /* Re-direct stream */
char ss_line[CONFIG_EXAMPLES_NSH_LINELEN];
};
struct serialsave_s
{
int ss_fd; /* Re-direct file descriptor */
FILE *ss_stream; /* Re-direct stream */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
static FAR struct nsh_vtbl_s *nsh_consoleclone(FAR struct nsh_vtbl_s *vtbl);
static void nsh_consolerelease(FAR struct nsh_vtbl_s *vtbl);
#endif
static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes);
static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...);
static FAR char *nsh_consolelinebuffer(FAR struct nsh_vtbl_s *vtbl);
static void nsh_consoleredirect(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t *save);
static void nsh_consoleundirect(FAR struct nsh_vtbl_s *vtbl, FAR uint8_t *save);
static void nsh_consoleexit(FAR struct nsh_vtbl_s *vtbl);
/****************************************************************************
* Private Data
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: nsh_allocstruct
****************************************************************************/
static inline FAR struct serial_s *nsh_allocstruct(void)
{
struct serial_s *pstate = (struct serial_s *)zalloc(sizeof(struct serial_s));
if (pstate)
{
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
pstate->ss_vtbl.clone = nsh_consoleclone;
pstate->ss_vtbl.release = nsh_consolerelease;
#endif
pstate->ss_vtbl.write = nsh_consolewrite;
pstate->ss_vtbl.output = nsh_consoleoutput;
pstate->ss_vtbl.linebuffer = nsh_consolelinebuffer;
pstate->ss_vtbl.redirect = nsh_consoleredirect;
pstate->ss_vtbl.undirect = nsh_consoleundirect;
pstate->ss_vtbl.exit = nsh_consoleexit;
pstate->ss_fd = 1;
pstate->ss_stream = stdout;
}
return pstate;
}
/****************************************************************************
* Name: nsh_openifnotopen
****************************************************************************/
static int nsh_openifnotopen(struct serial_s *pstate)
{
/* The stream is open in a lazy fashion. This is done because the file
* descriptor may be opened on a different task than the stream.
*/
if (!pstate->ss_stream)
{
pstate->ss_stream = fdopen(pstate->ss_fd, "w");
if (!pstate->ss_stream)
{
return ERROR;
}
}
return 0;
}
/****************************************************************************
* Name: nsh_closeifnotclosed
****************************************************************************/
static void nsh_closeifnotclosed(struct serial_s *pstate)
{
if (pstate->ss_stream == stdout)
{
fflush(stdout);
pstate->ss_fd = 1;
}
else
{
if (pstate->ss_stream)
{
fflush(pstate->ss_stream);
fclose(pstate->ss_stream);
}
else if (pstate->ss_fd >= 0 && pstate->ss_fd != 1)
{
close(pstate->ss_fd);
}
pstate->ss_fd = -1;
pstate->ss_stream = NULL;
}
}
/****************************************************************************
* Name: nsh_consolewrite
*
* Description:
* write a buffer to the remote shell window.
*
* Currently only used by cat.
*
****************************************************************************/
static ssize_t nsh_consolewrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes)
{
FAR struct serial_s *pstate = (FAR struct serial_s *)vtbl;
ssize_t ret;
/* The stream is open in a lazy fashion. This is done because the file
* descriptor may be opened on a different task than the stream. The
* actual open will then occur with the first output from the new task.
*/
if (nsh_openifnotopen(pstate) != 0)
{
return (ssize_t)ERROR;
}
/* Write the data to the output stream */
ret = fwrite(buffer, 1, nbytes, pstate->ss_stream);
if (ret < 0)
{
dbg("[%d] Failed to send buffer: %d\n", pstate->ss_fd, errno);
}
return ret;
}
/****************************************************************************
* Name: nsh_consoleoutput
*
* Description:
* Print a string to the currently selected stream.
*
****************************************************************************/
static int nsh_consoleoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...)
{
FAR struct serial_s *pstate = (FAR struct serial_s *)vtbl;
va_list ap;
int ret;
/* The stream is open in a lazy fashion. This is done because the file
* descriptor may be opened on a different task than the stream. The
* actual open will then occur with the first output from the new task.
*/
if (nsh_openifnotopen(pstate) != 0)
{
return ERROR;
}
va_start(ap, fmt);
ret = vfprintf(pstate->ss_stream, fmt, ap);
va_end(ap);
return ret;
}
/****************************************************************************
* Name: nsh_consolelinebuffer
*
* Description:
* Return a reference to the current line buffer
*
****************************************************************************/
static FAR char *nsh_consolelinebuffer(FAR struct nsh_vtbl_s *vtbl)
{
FAR struct serial_s *pstate = (FAR struct serial_s *)vtbl;
return pstate->ss_line;
}
/****************************************************************************
* Name: nsh_consoleclone
*
* Description:
* Make an independent copy of the vtbl
*
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
static FAR struct nsh_vtbl_s *nsh_consoleclone(FAR struct nsh_vtbl_s *vtbl)
{
FAR struct serial_s *pstate = (FAR struct serial_s *)vtbl;
FAR struct serial_s *pclone = nsh_allocstruct();
if (pclone->ss_fd == 1)
{
pclone->ss_fd = 1;
pclone->ss_stream = stdout;
}
else
{
pclone->ss_fd = pstate->ss_fd;
pclone->ss_stream = NULL;
}
return &pclone->ss_vtbl;
}
#endif
/****************************************************************************
* Name: nsh_consolerelease
*
* Description:
* Release the cloned instance
*
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
static void nsh_consolerelease(FAR struct nsh_vtbl_s *vtbl)
{
FAR struct serial_s *pstate = (FAR struct serial_s *)vtbl;
nsh_closeifnotclosed(pstate);
free(vtbl);
}
#endif
/****************************************************************************
* Name: nsh_consoleredirect
*
* Description:
* Set up for redirected output. This function is called from nsh_parse()
* in two different contexts:
*
* 1) Redirected background commands of the form: command > xyz.text &
*
* In this case:
* - vtbl: A newly allocated and initialized instance created by
* nsh_consoleclone,
* - fd:- The file descriptor of the redirected output
* - save: NULL
*
* nsh_consolerelease() will perform the clean-up when the clone is
* destroyed.
*
* 2) Redirected foreground commands of the form: command > xyz.txt
*
* In this case:
* - vtbl: The current state structure,
* - fd: The file descriptor of the redirected output
* - save: Where to save the re-directed registers.
*
* nsh_consoleundirect() will perform the clean-up after the redirected
* command completes.
*
****************************************************************************/
static void nsh_consoleredirect(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t *save)
{
FAR struct serial_s *pstate = (FAR struct serial_s *)vtbl;
FAR struct serialsave_s *ssave = (FAR struct serialsave_s *)save;
/* Case 1: Redirected foreground commands */
if (ssave)
{
/* pstate->ss_stream and ss_fd refer refer to the
* currently opened output stream. If the console is open, flush
* any pending output.
*/
if (pstate->ss_stream)
{
fflush(pstate->ss_stream);
}
/* Save the current fd and stream values. These will be restored
* when nsh_consoleundirect() is called.
*/
ssave->ss_fd = pstate->ss_fd;
ssave->ss_stream = pstate->ss_stream;
}
else
{
/* nsh_consoleclone() set pstate->ss_fd and ss_stream to refer
* to standard out. We just want to leave these alone and overwrite
* them with the fd for the re-directed stream.
*/
}
/* In either case, set the fd of the new, re-directed output and nullify
* the output stream (it will be fdopen'ed if it is used).
*/
pstate->ss_fd = fd;
pstate->ss_stream = NULL;
}
/****************************************************************************
* Name: nsh_consoleundirect
*
* Description:
* Set up for redirected output
*
****************************************************************************/
static void nsh_consoleundirect(FAR struct nsh_vtbl_s *vtbl, FAR uint8_t *save)
{
FAR struct serial_s *pstate = (FAR struct serial_s *)vtbl;
FAR struct serialsave_s *ssave = (FAR struct serialsave_s *)save;
nsh_closeifnotclosed(pstate);
pstate->ss_fd = ssave->ss_fd;
pstate->ss_stream = ssave->ss_stream;
}
/****************************************************************************
* Name: nsh_consoleexit
*
* Description:
* Exit the shell task
*
****************************************************************************/
static void nsh_consoleexit(FAR struct nsh_vtbl_s *vtbl)
{
exit(0);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nsh_main
****************************************************************************/
int nsh_consolemain(int argc, char *argv[])
{
FAR struct serial_s *pstate = nsh_allocstruct();
/* Present a greeting */
printf(g_nshgreeting);
fflush(pstate->ss_stream);
/* Execute the startup script */
#ifdef CONFIG_EXAMPLES_NSH_ROMFSETC
(void)nsh_script(&pstate->ss_vtbl, "init", NSH_INITPATH);
#endif
/* Then enter the command line parsing loop */
for (;;)
{
/* Display the prompt string */
fputs(g_nshprompt, pstate->ss_stream);
fflush(pstate->ss_stream);
/* Get the next line of input */
if (fgets(pstate->ss_line, CONFIG_EXAMPLES_NSH_LINELEN, stdin))
{
/* Parse process the command */
(void)nsh_parse(&pstate->ss_vtbl, pstate->ss_line);
fflush(pstate->ss_stream);
}
}
return OK;
}

853
nshlib/nsh_telnetd.c Normal file
View File

@ -0,0 +1,853 @@
/****************************************************************************
* apps/nshlib/nsh_telnetd.c
*
* Copyright (C) 2007-2011 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 <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <net/if.h>
#include <net/uip/uip-lib.h>
#if defined(CONFIG_EXAMPLES_NSH_DHCPC)
# include <net/uip/resolv.h>
# include <net/uip/dhcpc.h>
#endif
#include "nsh.h"
#ifdef CONFIG_EXAMPLES_NSH_TELNET
/****************************************************************************
* 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
#ifdef CONFIG_EXAMPLES_NSH_TELNETD_DUMPBUFFER
# define nsh_telnetdump(vtbl,msg,buf,nb) nsh_dumpbuffer(vtbl,msg,buf,nb)
#else
# define nsh_telnetdump(vtbl,msg,buf,nb)
#endif
/****************************************************************************
* Private Types
****************************************************************************/
struct telnetio_s
{
sem_t tio_sem;
int tio_sockfd;
uint8_t tio_bufndx;
uint8_t tio_state;
char tio_inbuffer[CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE];
};
struct redirect_s
{
int rd_fd; /* Re-direct file descriptor */
FILE *rd_stream; /* Re-direct stream */
};
struct telnetsave_s
{
bool ts_redirected;
union
{
struct telnetio_s *tn;
struct redirect_s rd;
} u;
};
struct telnetd_s
{
struct nsh_vtbl_s tn_vtbl;
uint16_t tn_sndlen;
bool tn_redirected;
union
{
struct telnetio_s *tn;
struct redirect_s rd;
} u;
char tn_outbuffer[CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE];
char tn_cmd[CONFIG_EXAMPLES_NSH_LINELEN];
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
static void tio_semtake(struct telnetio_s *tio);
static FAR struct nsh_vtbl_s *nsh_telnetclone(FAR struct nsh_vtbl_s *vtbl);
#endif
static void nsh_telnetrelease(FAR struct nsh_vtbl_s *vtbl);
static ssize_t nsh_telnetwrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes);
static int nsh_telnetoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...);
static int nsh_redirectoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...);
static FAR char *nsh_telnetlinebuffer(FAR struct nsh_vtbl_s *vtbl);
static void nsh_telnetredirect(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t *save);
static void nsh_telnetundirect(FAR struct nsh_vtbl_s *vtbl, FAR uint8_t *save);
static void nsh_telnetexit(FAR struct nsh_vtbl_s *vtbl);
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: tio_semtake
****************************************************************************/
static void tio_semtake(struct telnetio_s *tio)
{
/* Take the semaphore (perhaps waiting) */
while (sem_wait(&tio->tio_sem) != 0)
{
/* The only case that an error should occur here is if the wait was
* awakened by a signal.
*/
ASSERT(errno == EINTR);
}
}
/****************************************************************************
* Name: tio_semgive
****************************************************************************/
#define tio_semgive(tio) ASSERT(sem_post(&tio->tio_sem) == 0)
/****************************************************************************
* Name: nsh_allocstruct
****************************************************************************/
static FAR struct telnetd_s *nsh_allocstruct(void)
{
struct telnetd_s *pstate = (struct telnetd_s *)zalloc(sizeof(struct telnetd_s));
if (pstate)
{
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
pstate->tn_vtbl.clone = nsh_telnetclone;
pstate->tn_vtbl.release = nsh_telnetrelease;
#endif
pstate->tn_vtbl.write = nsh_telnetwrite;
pstate->tn_vtbl.output = nsh_telnetoutput;
pstate->tn_vtbl.linebuffer = nsh_telnetlinebuffer;
pstate->tn_vtbl.redirect = nsh_telnetredirect;
pstate->tn_vtbl.undirect = nsh_telnetundirect;
pstate->tn_vtbl.exit = nsh_telnetexit;
}
return pstate;
}
/****************************************************************************
* Name: nsh_openifnotopen
****************************************************************************/
static int nsh_openifnotopen(struct telnetd_s *pstate)
{
struct redirect_s *rd = &pstate->u.rd;
/* The stream is open in a lazy fashion. This is done because the file
* descriptor may be opened on a different task than the stream.
*/
if (!rd->rd_stream)
{
rd->rd_stream = fdopen(rd->rd_fd, "w");
if (!rd->rd_stream)
{
return ERROR;
}
}
return 0;
}
/****************************************************************************
* Name: nsh_closeifnotclosed
****************************************************************************/
static void nsh_closeifnotclosed(struct telnetd_s *pstate)
{
struct redirect_s *rd = &pstate->u.rd;
if (rd->rd_stream == stdout)
{
fflush(stdout);
rd->rd_fd = 1;
}
else
{
if (rd->rd_stream)
{
fflush(rd->rd_stream);
fclose(rd->rd_stream);
}
else if (rd->rd_fd >= 0 && rd->rd_fd != 1)
{
close(rd->rd_fd);
}
rd->rd_fd = -1;
rd->rd_stream = NULL;
}
}
/****************************************************************************
* Name: nsh_putchar
*
* Description:
* Add another parsed character to the TELNET command string
*
* Assumption:
* Caller holds TIO semaphore
*
****************************************************************************/
static void nsh_putchar(struct telnetd_s *pstate, uint8_t ch)
{
struct telnetio_s *tio = pstate->u.tn;
/* Ignore carriage returns */
if (ch == ISO_cr)
{
return;
}
/* Add all other characters to the cmd buffer */
pstate->tn_cmd[tio->tio_bufndx] = ch;
/* If a newline was added or if the buffer is full, then process it now */
if (ch == ISO_nl || tio->tio_bufndx == (CONFIG_EXAMPLES_NSH_LINELEN - 1))
{
pstate->tn_cmd[tio->tio_bufndx] = '\0';
nsh_telnetdump(&pstate->tn_vtbl, "TELNET CMD",
(uint8_t*)pstate->tn_cmd, strlen(pstate->tn_cmd));
nsh_parse(&pstate->tn_vtbl, pstate->tn_cmd);
tio->tio_bufndx = 0;
}
else
{
tio->tio_bufndx++;
vdbg("Add '%c', bufndx=%d\n", ch, tio->tio_bufndx);
}
}
/****************************************************************************
* Name: nsh_sendopt
*
* Description:
*
****************************************************************************/
static void nsh_sendopt(struct telnetd_s *pstate, uint8_t option, uint8_t value)
{
struct telnetio_s *tio = pstate->u.tn;
uint8_t optbuf[4];
optbuf[0] = TELNET_IAC;
optbuf[1] = option;
optbuf[2] = value;
optbuf[3] = 0;
nsh_telnetdump(&pstate->tn_vtbl, "Send optbuf", optbuf, 4);
tio_semtake(tio); /* Only one call to send at a time */
if (send(tio->tio_sockfd, optbuf, 4, 0) < 0)
{
dbg("[%d] Failed to send TELNET_IAC: %d\n", tio->tio_sockfd, errno);
}
tio_semgive(tio);
}
/****************************************************************************
* Name: nsh_flush
*
* Description:
* Dump the buffered output info.
*
****************************************************************************/
static void nsh_flush(FAR struct telnetd_s *pstate)
{
struct telnetio_s *tio = pstate->u.tn;
if (pstate->tn_sndlen > 0)
{
nsh_telnetdump(&pstate->tn_vtbl, "Shell output",
(uint8_t*)pstate->tn_outbuffer, pstate->tn_sndlen);
tio_semtake(tio); /* Only one call to send at a time */
if (send(tio->tio_sockfd, pstate->tn_outbuffer, pstate->tn_sndlen, 0) < 0)
{
dbg("[%d] Failed to send response: %d\n", tio->tio_sockfd, errno);
}
tio_semgive(tio);
}
pstate->tn_sndlen = 0;
}
/****************************************************************************
* Name: nsh_receive
*
* Description:
* Process a received TELENET buffer
*
****************************************************************************/
static int nsh_receive(struct telnetd_s *pstate, size_t len)
{
struct telnetio_s *tio = pstate->u.tn;
char *ptr = tio->tio_inbuffer;
uint8_t ch;
while (len > 0)
{
ch = *ptr++;
len--;
vdbg("ch=%02x state=%d\n", ch, tio->tio_state);
switch (tio->tio_state)
{
case STATE_IAC:
if (ch == TELNET_IAC)
{
nsh_putchar(pstate, ch);
tio->tio_state = STATE_NORMAL;
}
else
{
switch (ch)
{
case TELNET_WILL:
tio->tio_state = STATE_WILL;
break;
case TELNET_WONT:
tio->tio_state = STATE_WONT;
break;
case TELNET_DO:
tio->tio_state = STATE_DO;
break;
case TELNET_DONT:
tio->tio_state = STATE_DONT;
break;
default:
tio->tio_state = STATE_NORMAL;
break;
}
}
break;
case STATE_WILL:
/* Reply with a DONT */
nsh_sendopt(pstate, TELNET_DONT, ch);
tio->tio_state = STATE_NORMAL;
break;
case STATE_WONT:
/* Reply with a DONT */
nsh_sendopt(pstate, TELNET_DONT, ch);
tio->tio_state = STATE_NORMAL;
break;
case STATE_DO:
/* Reply with a WONT */
nsh_sendopt(pstate, TELNET_WONT, ch);
tio->tio_state = STATE_NORMAL;
break;
case STATE_DONT:
/* Reply with a WONT */
nsh_sendopt(pstate, TELNET_WONT, ch);
tio->tio_state = STATE_NORMAL;
break;
case STATE_NORMAL:
if (ch == TELNET_IAC)
{
tio->tio_state = STATE_IAC;
}
else
{
nsh_putchar(pstate, ch);
}
break;
}
}
return OK;
}
/****************************************************************************
* 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 = nsh_allocstruct();
struct telnetio_s *tio = (struct telnetio_s *)zalloc(sizeof(struct telnetio_s));
struct nsh_vtbl_s *vtbl = &pstate->tn_vtbl;
int sockfd = (int)arg;
int ret = ERROR;
dbg("[%d] Started\n", sockfd);
/* Verify that the state structure was successfully allocated */
if (pstate && tio)
{
/* Initialize the thread state structure */
sem_init(&tio->tio_sem, 0, 1);
tio->tio_sockfd = sockfd;
tio->tio_state = STATE_NORMAL;
pstate->u.tn = tio;
/* Output a greeting */
nsh_output(vtbl, g_nshgreeting);
/* Execute the startup script */
#if defined(CONFIG_EXAMPLES_NSH_ROMFSETC) && !defined(CONFIG_EXAMPLES_NSH_CONSOLE)
(void)nsh_script(vtbl, "init", NSH_INITPATH);
#endif
/* Loop processing each TELNET command */
do
{
/* Display the prompt string */
nsh_output(vtbl, g_nshprompt);
nsh_flush(pstate);
/* Read a buffer of data from the TELNET client */
ret = recv(tio->tio_sockfd, tio->tio_inbuffer,
CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE, 0);
if (ret > 0)
{
/* Process the received TELNET data */
nsh_telnetdump(vtbl, "Received buffer",
(uint8_t*)tio->tio_inbuffer, ret);
ret = nsh_receive(pstate, ret);
}
}
while (ret >= 0 && tio->tio_state != STATE_CLOSE);
dbg("[%d] ret=%d tn.tio_state=%d\n", sockfd, ret, tio->tio_state);
/* End of command processing -- Clean up and exit */
}
/* Exit the task */
if (pstate)
{
free(pstate);
}
if (tio)
{
sem_destroy(&tio->tio_sem);
free(tio);
}
dbg("[%d] Exitting\n", sockfd);
close(sockfd);
return NULL;
}
/****************************************************************************
* Name: nsh_telnetwrite
*
* Description:
* write a buffer to the remote shell window.
*
* Currently only used by cat.
*
****************************************************************************/
static ssize_t nsh_telnetwrite(FAR struct nsh_vtbl_s *vtbl, FAR const void *buffer, size_t nbytes)
{
struct telnetd_s *pstate = (struct telnetd_s *)vtbl;
struct telnetio_s *tio = pstate->u.tn;
ssize_t ret = nbytes;
/* Flush anything already in the output buffer */
nsh_flush(pstate);
/* Then write the user buffer */
nsh_telnetdump(&pstate->tn_vtbl, "Buffer output",(uint8_t*)buffer, nbytes);
tio_semtake(tio); /* Only one call to send at a time */
ret = send(tio->tio_sockfd, buffer, nbytes, 0);
if (ret < 0)
{
dbg("[%d] Failed to send buffer: %d\n", tio->tio_sockfd, errno);
}
tio_semgive(tio);
return ret;
}
/****************************************************************************
* Name: nsh_telnetoutput
*
* 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.
*
****************************************************************************/
static int nsh_telnetoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...)
{
struct telnetd_s *pstate = (struct telnetd_s *)vtbl;
int nbytes = pstate->tn_sndlen;
int len;
va_list ap;
/* Put the new info into the buffer. Here we are counting on the fact that
* no output strings will exceed CONFIG_EXAMPLES_NSH_LINELEN!
*/
va_start(ap, fmt);
vsnprintf(&pstate->tn_outbuffer[nbytes],
(CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE - 1) - nbytes, fmt, ap);
va_end(ap);
/* Get the size of the new string just added and the total size of
* buffered data
*/
len = strlen(&pstate->tn_outbuffer[nbytes]);
nbytes += len;
/* Expand any terminating \n to \r\n */
if (nbytes < (CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE - 2) &&
pstate->tn_outbuffer[nbytes-1] == '\n')
{
pstate->tn_outbuffer[nbytes-1] = ISO_cr;
pstate->tn_outbuffer[nbytes] = ISO_nl;
pstate->tn_outbuffer[nbytes+1] = '\0';
nbytes++;
}
pstate->tn_sndlen = nbytes;
/* Flush to the network if the buffer does not have room for one more
* maximum length string.
*/
if (nbytes > CONFIG_EXAMPLES_NSH_IOBUFFER_SIZE - CONFIG_EXAMPLES_NSH_LINELEN)
{
nsh_flush(pstate);
}
return len;
}
/****************************************************************************
* Name: nsh_redirectoutput
*
* Description:
* Print a string to the currently selected stream.
*
****************************************************************************/
static int nsh_redirectoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...)
{
FAR struct telnetd_s *pstate = (FAR struct telnetd_s *)vtbl;
va_list ap;
int ret;
/* The stream is open in a lazy fashion. This is done because the file
* descriptor may be opened on a different task than the stream. The
* actual open will then occur with the first output from the new task.
*/
if (nsh_openifnotopen(pstate) != 0)
{
return ERROR;
}
va_start(ap, fmt);
ret = vfprintf(pstate->u.rd.rd_stream, fmt, ap);
va_end(ap);
return ret;
}
/****************************************************************************
* Name: nsh_telnetlinebuffer
*
* Description:
* Return a reference to the current line buffer
*
* ****************************************************************************/
static FAR char *nsh_telnetlinebuffer(FAR struct nsh_vtbl_s *vtbl)
{
struct telnetd_s *pstate = (struct telnetd_s *)vtbl;
return pstate->tn_cmd;
}
/****************************************************************************
* Name: nsh_telnetclone
*
* Description:
* Make an independent copy of the vtbl
*
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
static FAR struct nsh_vtbl_s *nsh_telnetclone(FAR struct nsh_vtbl_s *vtbl)
{
FAR struct telnetd_s *pstate = (FAR struct telnetd_s *)vtbl;
FAR struct telnetd_s *pclone = nsh_allocstruct();
FAR struct nsh_vtbl_s *ret = NULL;
if (pclone)
{
if (pstate->tn_redirected)
{
pclone->tn_redirected = true;
pclone->tn_vtbl.output = nsh_redirectoutput;
pclone->u.rd.rd_fd = pstate->u.rd.rd_fd;
pclone->u.rd.rd_stream = NULL;
}
else
{
pclone->u.tn = pstate->u.tn;
}
ret = &pclone->tn_vtbl;
}
return ret;
}
#endif
/****************************************************************************
* Name: nsh_telnetrelease
*
* Description:
* Release the cloned instance
*
****************************************************************************/
#ifndef CONFIG_EXAMPLES_NSH_DISABLEBG
static void nsh_telnetrelease(FAR struct nsh_vtbl_s *vtbl)
{
FAR struct telnetd_s *pstate = (FAR struct telnetd_s *)vtbl;
if (pstate->tn_redirected)
{
nsh_closeifnotclosed(pstate);
}
else
{
nsh_flush(pstate);
}
free(pstate);
}
#endif
/****************************************************************************
* Name: nsh_telnetredirect
*
* Description:
* Set up for redirected output. This function is called from nsh_parse()
* in two different contexts:
*
* 1) Redirected background commands of the form: command > xyz.text &
*
* In this case:
* - vtbl: A newly allocated and initialized instance created by
* nsh_telnetclone,
* - fd:- The file descriptor of the redirected output
* - save: NULL
*
* nsh_telnetrelease() will perform the clean-up when the clone is
* destroyed.
*
* 2) Redirected foreground commands of the form: command > xyz.txt
*
* In this case:
* - vtbl: The current state structure,
* - fd: The file descriptor of the redirected output
* - save: Where to save the re-directed registers.
*
* nsh_telnetundirect() will perform the clean-up after the redirected
* command completes.
*
****************************************************************************/
static void nsh_telnetredirect(FAR struct nsh_vtbl_s *vtbl, int fd, FAR uint8_t *save)
{
FAR struct telnetd_s *pstate = (FAR struct telnetd_s *)vtbl;
FAR struct telnetsave_s *ssave = (FAR struct telnetsave_s *)save;
if (pstate->tn_redirected)
{
(void)nsh_openifnotopen(pstate);
fflush(pstate->u.rd.rd_stream);
if (!ssave)
{
fclose(pstate->u.rd.rd_stream);
}
}
if (ssave)
{
ssave->ts_redirected = pstate->tn_redirected;
memcpy(&ssave->u.rd, &pstate->u.rd, sizeof(struct redirect_s));
}
pstate->tn_redirected = true;
pstate->u.rd.rd_fd = fd;
pstate->u.rd.rd_stream = NULL;
}
/****************************************************************************
* Name: nsh_telnetundirect
*
* Description:
* Set up for redirected output
*
****************************************************************************/
static void nsh_telnetundirect(FAR struct nsh_vtbl_s *vtbl, FAR uint8_t *save)
{
FAR struct telnetd_s *pstate = (FAR struct telnetd_s *)vtbl;
FAR struct telnetsave_s *ssave = (FAR struct telnetsave_s *)save;
if (pstate->tn_redirected)
{
nsh_closeifnotclosed(pstate);
}
pstate->tn_redirected = ssave->ts_redirected;
memcpy(&pstate->u.rd, &ssave->u.rd, sizeof(struct redirect_s));
}
/****************************************************************************
* Name: nsh_telnetexit
*
* Description:
* Quit the shell instance
*
****************************************************************************/
static void nsh_telnetexit(FAR struct nsh_vtbl_s *vtbl)
{
struct telnetd_s *pstate = (struct telnetd_s *)vtbl;
pstate->u.tn->tio_state = STATE_CLOSE;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: nsh_telnetmain
*
* Description:
* This is the main processing thread for telnetd. It never returns
* unless an error occurs
*
****************************************************************************/
int nsh_telnetmain(int argc, char *argv[])
{
/* Execute nsh_connection() on each connection to port 23 */
uip_server(HTONS(23), nsh_connection, CONFIG_EXAMPLES_NSH_STACKSIZE);
return OK;
}
#endif /* CONFIG_EXAMPLES_NSH_TELNET */

437
nshlib/nsh_test.c Normal file
View File

@ -0,0 +1,437 @@
/****************************************************************************
* apps/nshlib/nsh_test.c
*
* Copyright (C) 2008, 2011 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 NuttX 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.
*
****************************************************************************/
/* Test syntax:
*
* expression = simple-expression | !expression |
* expression -o expression | expression -a expression
*
* simple-expression = unary-expression | binary-expression
*
* unary-expression = string-unary | file-unary
*
* string-unary = -n string | -z string
*
* file-unary = -b file | -c file | -d file | -e file | -f file |
* -r file | -s file | -w file
*
* binary-expression = string-binary | numeric-binary
*
* string-binary = string = string | string == string | string != string
*
* numeric-binary = integer -eq integer | integer -ge integer |
* integer -gt integer | integer -le integer |
* integer -lt integer | integer -ne integer
*
* Note that the smallest expression consists of two strings.
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include "nsh.h"
#if !defined(CONFIG_EXAMPLES_NSH_DISABLESCRIPT) && !defined(CONFIG_EXAMPLES_NSH_DISABLE_TEST)
/****************************************************************************
* Definitions
****************************************************************************/
#define TEST_TRUE OK
#define TEST_FALSE ERROR
#define TEST_ERROR 1
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: binaryexpression
****************************************************************************/
static inline int binaryexpression(FAR struct nsh_vtbl_s *vtbl, char **argv)
{
char *endptr;
long integer1;
long integer2;
/* STRING2 = STRING2 */
if (strcmp(argv[1], "=") == 0 || strcmp(argv[1], "==") == 0)
{
/* Return true if the strings are identical */
return strcmp(argv[0], argv[2]) == 0 ? TEST_TRUE : TEST_FALSE;
}
/* STRING1 != STRING2 */
if (strcmp(argv[1], "!=") == 0)
{
/* Return true if the strings are different */
return strcmp(argv[0], argv[2]) != 0 ? TEST_TRUE : TEST_FALSE;
}
/* The remaining operators assuming that the two values are integers */
integer1 = strtol(argv[0], &endptr, 0);
if (argv[0][0] == '\0' || *endptr != '\0')
{
return TEST_ERROR;
}
integer2 = strtol(argv[2], &endptr, 0);
if (argv[2][0] == '\0' || *endptr != '\0')
{
return TEST_ERROR;
}
/* INTEGER1 -eq INTEGER2 */
if (strcmp(argv[1], "-eq") == 0)
{
/* Return true if the strings are different */
return integer1 == integer2 ? TEST_TRUE : TEST_FALSE;
}
/* INTEGER1 -ge INTEGER2 */
if (strcmp(argv[1], "-ge") == 0)
{
/* Return true if the strings are different */
return integer1 >= integer2 ? TEST_TRUE : TEST_FALSE;
}
/* INTEGER1 -gt INTEGER2 */
if (strcmp(argv[1], "-gt") == 0)
{
/* Return true if the strings are different */
return integer1 > integer2 ? TEST_TRUE : TEST_FALSE;
}
/* INTEGER1 -le INTEGER2 */
if (strcmp(argv[1], "-le") == 0)
{
/* Return true if the strings are different */
return integer1 <= integer2 ? TEST_TRUE : TEST_FALSE;
}
/* INTEGER1 -lt INTEGER2 */
if (strcmp(argv[1], "-lt") == 0)
{
/* Return true if the strings are different */
return integer1 < integer2 ? TEST_TRUE : TEST_FALSE;
}
/* INTEGER1 -ne INTEGER2 */
if (strcmp(argv[1], "-ne") == 0)
{
/* Return true if the strings are different */
return integer1 != integer2 ? TEST_TRUE : TEST_FALSE;
}
return TEST_ERROR;
}
/****************************************************************************
* Name: unaryexpression
****************************************************************************/
static inline int unaryexpression(FAR struct nsh_vtbl_s *vtbl, char **argv)
{
struct stat buf;
char *fullpath;
int ret;
/* -n STRING */
if (strcmp(argv[0], "-n") == 0)
{
/* Return true if the length of the string is non-zero */
return strlen(argv[1]) != 0 ? TEST_TRUE : TEST_FALSE;
}
/* -z STRING */
if (strcmp(argv[0], "-z") == 0)
{
/* Return true if the length of the string is zero */
return strlen(argv[1]) == 0 ? TEST_TRUE : TEST_FALSE;
}
/* All of the remaining assume that the following argument is the
* path to a file.
*/
fullpath = nsh_getfullpath(vtbl, argv[1]);
if (!fullpath)
{
return TEST_FALSE;
}
ret = stat(fullpath, &buf);
nsh_freefullpath(fullpath);
if (ret != 0)
{
/* The file does not exist (or another error occurred) -- return FALSE */
return TEST_FALSE;
}
/* -b FILE */
if (strcmp(argv[0], "-b") == 0)
{
/* Return true if the path is a block device */
return S_ISBLK(buf.st_mode) ? TEST_TRUE : TEST_FALSE;
}
/* -c FILE */
if (strcmp(argv[0], "-c") == 0)
{
/* Return true if the path is a character device */
return S_ISCHR(buf.st_mode) ? TEST_TRUE : TEST_FALSE;
}
/* -d FILE */
if (strcmp(argv[0], "-d") == 0)
{
/* Return true if the path is a directory */
return S_ISDIR(buf.st_mode) ? TEST_TRUE : TEST_FALSE;
}
/* -e FILE */
if (strcmp(argv[0], "-e") == 0)
{
/* Return true if the file exists */
return TEST_TRUE;
}
/* -f FILE */
if (strcmp(argv[0], "-f") == 0)
{
/* Return true if the path refers to a regular file */
return S_ISREG(buf.st_mode) ? TEST_TRUE : TEST_FALSE;
}
/* -r FILE */
if (strcmp(argv[0], "-r") == 0)
{
/* Return true if the file is readable */
return (buf.st_mode & (S_IRUSR|S_IRGRP|S_IROTH)) != 0 ? TEST_TRUE : TEST_FALSE;
}
/* -s FILE */
if (strcmp(argv[0], "-s") == 0)
{
/* Return true if the size of the file is greater than zero */
return buf.st_size > 0 ? TEST_TRUE : TEST_FALSE;
}
/* -w FILE */
if (strcmp(argv[0], "-w") == 0)
{
/* Return true if the file is write-able */
return (buf.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) != 0 ? TEST_TRUE : TEST_FALSE;
}
/* Unrecognized operator */
return TEST_ERROR;
}
/****************************************************************************
* Name: expression
****************************************************************************/
static int expression(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
int value;
int i = 0;
/* Check for unary operations on expressions */
if (strcmp(argv[0], "!") == 0)
{
if (argc < 2)
{
goto errout_syntax;
}
return expression(vtbl, argc-1, &argv[1]) == TEST_TRUE ? TEST_FALSE : TEST_TRUE;
}
/* Check for unary operations on simple, typed arguments */
else if (argv[0][0] == '-')
{
if (argc < 2)
{
goto errout_syntax;
}
i += 2;
value = unaryexpression(vtbl, argv);
}
/* Check for binary operations on simple, typed arguments */
else
{
if (argc < 3)
{
goto errout_syntax;
}
i += 3;
value = binaryexpression(vtbl, argv);
}
/* Test if there any failure */
if (value == TEST_ERROR)
{
goto errout_syntax;
}
/* Is there anything after the simple expression? */
if (i < argc)
{
/* EXPRESSION -a EXPRESSION */
if (strcmp(argv[i], "-a") == 0)
{
if (value != TEST_TRUE)
{
return TEST_FALSE;
}
else
{
i++;
return expression(vtbl, argc-i, &argv[i]);
}
}
/* EXPRESSION -o EXPRESSION */
else if (strcmp(argv[i], "-o") == 0)
{
if (value == TEST_TRUE)
{
return TEST_TRUE;
}
else
{
i++;
return expression(vtbl, argc-i, &argv[i]);
}
}
else
{
goto errout_syntax;
}
}
return value;
errout_syntax:
nsh_output(vtbl, g_nshsyntax, "test");
return TEST_FALSE;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: cmd_test
****************************************************************************/
int cmd_test(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
return expression(vtbl, argc-1, &argv[1]);
}
/****************************************************************************
* Name: cmd_lbracket
****************************************************************************/
int cmd_lbracket(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
if (strcmp(argv[argc-1], "]") != 0)
{
nsh_output(vtbl, g_nshsyntax, argv[0]);
return ERROR;
}
else
{
return expression(vtbl, argc-2, &argv[1]);
}
}
#endif /* !CONFIG_EXAMPLES_NSH_DISABLESCRIPT && !CONFIG_EXAMPLES_NSH_DISABLE_TEST */

5
nshlib/rcS.template Normal file
View File

@ -0,0 +1,5 @@
# Create a RAMDISK and mount it at XXXRDMOUNTPOUNTXXX
mkrd -m XXXMKRDMINORXXX -s XXMKRDSECTORSIZEXXX XXMKRDBLOCKSXXX
mkfatfs /dev/ramXXXMKRDMINORXXX
mount -t vfat /dev/ramXXXMKRDMINORXXX XXXRDMOUNTPOUNTXXX