diff options
author | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-02-02 16:04:09 +0000 |
---|---|---|
committer | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-02-02 16:04:09 +0000 |
commit | 7a586daed8a1ae7de992a35dac2e1b835ae746be (patch) | |
tree | 1642619d0c60b8a67c98baaca85e372bf524d8e4 /apps | |
parent | a52f3af00a22c9f423afad12d623f0d3d7f5994c (diff) | |
download | px4-firmware-7a586daed8a1ae7de992a35dac2e1b835ae746be.tar.gz px4-firmware-7a586daed8a1ae7de992a35dac2e1b835ae746be.tar.bz2 px4-firmware-7a586daed8a1ae7de992a35dac2e1b835ae746be.zip |
NSH now uses the new Telnet daemon and built-in tasks started by NSH can be used over Telnet
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4361 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'apps')
-rw-r--r-- | apps/examples/nsh/nsh_main.c | 56 | ||||
-rw-r--r-- | apps/examples/telnetd/shell.h | 1 | ||||
-rw-r--r-- | apps/include/nsh.h | 50 | ||||
-rw-r--r-- | apps/nshlib/Makefile | 10 | ||||
-rw-r--r-- | apps/nshlib/README.txt | 23 | ||||
-rw-r--r-- | apps/nshlib/nsh.h | 104 | ||||
-rw-r--r-- | apps/nshlib/nsh_apps.c | 39 | ||||
-rw-r--r-- | apps/nshlib/nsh_consolemain.c | 163 | ||||
-rw-r--r-- | apps/nshlib/nsh_dbgcmds.c | 125 | ||||
-rw-r--r-- | apps/nshlib/nsh_ddcmd.c | 7 | ||||
-rw-r--r-- | apps/nshlib/nsh_envcmds.c | 5 | ||||
-rw-r--r-- | apps/nshlib/nsh_fscmds.c | 1 | ||||
-rw-r--r-- | apps/nshlib/nsh_mmcmds.c | 1 | ||||
-rw-r--r-- | apps/nshlib/nsh_netcmds.c | 5 | ||||
-rw-r--r-- | apps/nshlib/nsh_netinit.c | 4 | ||||
-rw-r--r-- | apps/nshlib/nsh_parse.c | 19 | ||||
-rw-r--r-- | apps/nshlib/nsh_proccmds.c | 5 | ||||
-rw-r--r-- | apps/nshlib/nsh_romfsetc.c | 4 | ||||
-rw-r--r-- | apps/nshlib/nsh_serial.c | 534 | ||||
-rw-r--r-- | apps/nshlib/nsh_telnetd.c | 833 | ||||
-rw-r--r-- | apps/nshlib/nsh_test.c | 5 | ||||
-rw-r--r-- | apps/nshlib/nsh_timcmds.c | 5 | ||||
-rw-r--r-- | apps/nshlib/nsh_usbdev.c | 2 | ||||
-rw-r--r-- | apps/system/free/Makefile | 6 | ||||
-rw-r--r-- | apps/system/i2c/Makefile | 5 | ||||
-rw-r--r-- | apps/system/readline/Makefile | 6 |
26 files changed, 509 insertions, 1509 deletions
diff --git a/apps/examples/nsh/nsh_main.c b/apps/examples/nsh/nsh_main.c index 53235a835..5d302e397 100644 --- a/apps/examples/nsh/nsh_main.c +++ b/apps/examples/nsh/nsh_main.c @@ -1,8 +1,8 @@ /**************************************************************************** * examples/nsh/nsh_main.c * - * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -81,56 +81,42 @@ int user_start(int argc, char *argv[]) { - int mid_priority; -#if defined(CONFIG_NSH_CONSOLE) && defined(CONFIG_NSH_TELNET) + int exitval = 0; int ret; -#endif /* Initialize the NSH library */ nsh_initialize(); - /* Set the priority of this task to something in the middle so that 'nice' - * can both raise and lower the priority. + /* If the Telnet console is selected as a front-end, then start the + * Telnet daemon. */ - mid_priority = (sched_get_priority_max(SCHED_NSH) + sched_get_priority_min(SCHED_NSH)) >> 1; - { - struct sched_param param; - - param.sched_priority = mid_priority; - (void)sched_setscheduler(0, SCHED_NSH, ¶m); - } - - /* If both the console and telnet are selected as front-ends, then run - * the telnet front end on another thread. - */ - -#if defined(CONFIG_NSH_CONSOLE) && defined(CONFIG_NSH_TELNET) -# ifndef CONFIG_CUSTOM_STACK - ret = task_create("nsh_telnetmain", mid_priority, CONFIG_NSH_STACKSIZE, - nsh_telnetmain, NULL); -# else - ret = task_create("nsh_telnetmain", mid_priority, nsh_telnetmain, NULL); -# endif +#ifdef CONFIG_NSH_TELNET + ret = nsh_telnetstart(); if (ret < 0) - { + { /* The daemon is NOT running. Report the the error then fail... * either with the serial console up or just exiting. */ - fprintf(stderr, "ERROR: Failed to start TELNET daemon: %d\n", errno); + fprintf(stderr, "ERROR: Failed to start TELNET daemon: %d\n", ret); + exitval = 1; } - - /* If only the telnet front-end is selected, run it on this thread */ - -#elif defined(CONFIG_NSH_TELNET) - return nsh_telnetmain(0, NULL); #endif -/* If the serial console front end is selected, then run it on this thread */ + /* If the serial console front end is selected, then run it on this thread */ #ifdef CONFIG_NSH_CONSOLE - return nsh_consolemain(0, NULL); + ret = nsh_consolemain(0, NULL); + + /* nsh_consolemain() should not return. So if we get here, something + * is wrong. + */ + + fprintf(stderr, "ERROR: nsh_consolemain() returned: %d\n", ret); + exitval = 1; #endif + + return exitval; } diff --git a/apps/examples/telnetd/shell.h b/apps/examples/telnetd/shell.h index 96aab1319..23b30fda7 100644 --- a/apps/examples/telnetd/shell.h +++ b/apps/examples/telnetd/shell.h @@ -91,7 +91,6 @@ # define MAIN_STRING "user_start: " #endif - /* Other definitions ********************************************************/ #define SHELL_PROMPT "uIP 1.0> " diff --git a/apps/include/nsh.h b/apps/include/nsh.h index 6977e44bd..15f35963c 100644 --- a/apps/include/nsh.h +++ b/apps/include/nsh.h @@ -67,27 +67,51 @@ extern "C" { * Public Function Prototypes ****************************************************************************/ -/* Interfaces needed to initialize and execute the NuttShell (NSH). +/**************************************************************************** + * Name: nsh_initialize * - * nsh_initialize() - This function function should be called one during - * application start-up prior to executing nsh_consolemain() or - * nsh_telnetmain(). - */ + * Description: + * This nterfaces is used to initialize the NuttShell (NSH). + * nsh_initialize() should be called one during application start-up prior + * to executing either nsh_consolemain() or nsh_telnetstart(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ EXTERN void nsh_initialize(void); -/* The following interfaces maybe to called or started with task_start to - * start an NSH instance. +/**************************************************************************** + * Name: nsh_consolemain * - * nsh_consolemain() starts NSH on the console (/dev/console). - * nsh_telnetmain() starts a telnet daemon that will allow multiple - * connections via telnet. + * Description: + * This interfaces maybe to called or started with task_start to start a + * single an NSH instance that operates on stdin and stdout (/dev/console). + * This function does not return. * - * These functions do not return. - */ + * Input Parameters: + * Standard task start-up arguements. These are not used. argc may be + * zero and argv may be NULL. + * + * Returned Values: + * This function does not normally return. exit() is usually called to + * terminate the NSH session. This function will return in the event of + * an error. In that case, a nonzero value is returned (1). + * + ****************************************************************************/ EXTERN int nsh_consolemain(int argc, char *argv[]); -EXTERN int nsh_telnetmain(int argc, char *argv[]); + +/* nsh_telnetstart() starts a telnet daemon that will allow multiple + * NSH connections via telnet. This function returns immediately after + * the daemon has been started. + */ + +EXTERN int nsh_telnetstart(void); #undef EXTERN #ifdef __cplusplus diff --git a/apps/nshlib/Makefile b/apps/nshlib/Makefile index 70c27a414..853d24baf 100644 --- a/apps/nshlib/Makefile +++ b/apps/nshlib/Makefile @@ -1,8 +1,8 @@ ############################################################################ # apps/nshlib/Makefile # -# Copyright (C) 2011 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt <spudmonkey@racsa.co.cr> +# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt <gnutt@nuttx.org> # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -40,8 +40,8 @@ include $(APPDIR)/Make.defs # NSH Library ASRCS = -CSRCS = nsh_parse.c nsh_fscmds.c nsh_ddcmd.c nsh_proccmds.c nsh_mmcmds.c \ - nsh_envcmds.c nsh_dbgcmds.c +CSRCS = nsh_parse.c nsh_console.c nsh_fscmds.c nsh_ddcmd.c nsh_proccmds.c \ + nsh_mmcmds.c nsh_envcmds.c nsh_dbgcmds.c ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) CSRCS += nsh_apps.c @@ -60,7 +60,7 @@ CSRCS += nsh_timcmds.c endif ifeq ($(CONFIG_NSH_CONSOLE),y) -CSRCS += nsh_serial.c +CSRCS += nsh_consolemain.c endif ifeq ($(CONFIG_NSH_TELNET),y) diff --git a/apps/nshlib/README.txt b/apps/nshlib/README.txt index fbdf9178a..bc496135d 100644 --- a/apps/nshlib/README.txt +++ b/apps/nshlib/README.txt @@ -870,11 +870,6 @@ NSH-Specific Configuration Settings The maximum length of one command line and of one output line. Default: 80 - * CONFIG_NSH_STACKSIZE - The stack size to use when spawning new threads or tasks. Such - new threads are generated when a command is executed in background - or as new TELNET connections are established. - * CONFIG_NSH_NESTDEPTH The maximum number of nested if-then[-else]-fi sequences that are permissable. Default: 3 @@ -936,6 +931,24 @@ NSH-Specific Configuration Settings function will be called early in NSH initialization to allow board logic to do such things as configure MMC/SD slots. + If Telnet is selected for the NSH console, then we must configure + the resources used by the Telnet daemon and by the Telnet clients. + + * CONFIG_NSH_TELNETD_PORT - The telnet daemon will listen on this + TCP port number for connections. Default: 23 + + * CONFIG_NSH_TELNETD_DAEMONPRIO - Priority of the Telnet daemon. + Default: SCHED_PRIORITY_DEFAULT + + * CONFIG_NSH_TELNETD_DAEMONSTACKSIZE - Stack size allocated for the + Telnet daemon. Default: 2048 + + * CONFIG_NSH_TELNETD_CLIENTPRIO- Priority of the Telnet client. + Default: SCHED_PRIORITY_DEFAULT + + * CONFIG_NSH_TELNETD_CLIENTSTACKSIZE - Stack size allocated for the + Telnet client. Default: 2048 + One or both of CONFIG_NSH_CONSOLE and CONFIG_NSH_TELNET must be defined. If CONFIG_NSH_TELNET is selected, then there some other configuration settings that apply: diff --git a/apps/nshlib/nsh.h b/apps/nshlib/nsh.h index 9a5a49d42..90d02bb7f 100644 --- a/apps/nshlib/nsh.h +++ b/apps/nshlib/nsh.h @@ -1,8 +1,8 @@ /**************************************************************************** * apps/nshlib/nsh.h * - * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,22 +43,19 @@ #include <nuttx/config.h> #include <sys/types.h> + +#include <stdio.h> #include <stdint.h> #include <stdbool.h> #include <errno.h> -#ifdef CONFIG_NSH_CONSOLE -# include <stdio.h> -#endif - /**************************************************************************** * Definitions ****************************************************************************/ - -/* The telnetd interface and background commands require pthread support */ +/* Configuration ************************************************************/ +/* The background commands require pthread support */ #ifdef CONFIG_DISABLE_PTHREAD -# undef CONFIG_NSH_TELNET # ifndef CONFIG_NSH_DISABLEBG # define CONFIG_NSH_DISABLEBG 1 # endif @@ -89,6 +86,41 @@ # endif #endif +/* If Telnet is selected for the NSH console, then we must configure + * the resources used by the Telnet daemon and by the Telnet clients. + * + * CONFIG_NSH_TELNETD_PORT - The telnet daemon will listen on this. + * port. Default: 23 + * CONFIG_NSH_TELNETD_DAEMONPRIO - Priority of the Telnet daemon. + * Default: SCHED_PRIORITY_DEFAULT + * CONFIG_NSH_TELNETD_DAEMONSTACKSIZE - Stack size allocated for the + * Telnet daemon. Default: 2048 + * CONFIG_NSH_TELNETD_CLIENTPRIO- Priority of the Telnet client. + * Default: SCHED_PRIORITY_DEFAULT + * CONFIG_NSH_TELNETD_CLIENTSTACKSIZE - Stack size allocated for the + * Telnet client. Default: 2048 + */ + +#ifndef CONFIG_NSH_TELNETD_PORT +# define CONFIG_NSH_TELNETD_PORT 23 +#endif + +#ifndef CONFIG_NSH_TELNETD_DAEMONPRIO +# define CONFIG_NSH_TELNETD_DAEMONPRIO SCHED_PRIORITY_DEFAULT +#endif + +#ifndef CONFIG_NSH_TELNETD_DAEMONSTACKSIZE +# define CONFIG_NSH_TELNETD_DAEMONSTACKSIZE 2048 +#endif + +#ifndef CONFIG_NSH_TELNETD_CLIENTPRIO +# define CONFIG_NSH_TELNETD_CLIENTPRIO SCHED_PRIORITY_DEFAULT +#endif + +#ifndef CONFIG_NSH_TELNETD_CLIENTSTACKSIZE +# define CONFIG_NSH_TELNETD_CLIENTSTACKSIZE 2048 +#endif + /* Verify support for ROMFS /etc directory support options */ #ifdef CONFIG_NSH_ROMFSETC @@ -160,14 +192,6 @@ # define CONFIG_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_NSH_STACKSIZE -# define CONFIG_NSH_STACKSIZE 4096 -#endif - /* The maximum number of nested if-then[-else]-fi sequences that * are permissable. */ @@ -187,26 +211,6 @@ # 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) @@ -257,31 +261,7 @@ struct nsh_parser_s #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_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; -}; - +struct nsh_vtbl_s; /* Defined in nsh_console.h */ typedef int (*cmd_t)(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); /**************************************************************************** diff --git a/apps/nshlib/nsh_apps.c b/apps/nshlib/nsh_apps.c index d70c0d10f..c6f750948 100644 --- a/apps/nshlib/nsh_apps.c +++ b/apps/nshlib/nsh_apps.c @@ -1,7 +1,7 @@ /**************************************************************************** * apps/nshlib/nsh_apps.c * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. * Copyright (C) 2011 Uros Platise. All rights reserved. * Author: Uros Platise <uros.platise@isotel.eu> * @@ -51,6 +51,7 @@ #include <apps/apps.h> #include "nsh.h" +#include "nsh_console.h" #ifdef CONFIG_NSH_BUILTIN_APPS @@ -89,30 +90,30 @@ int nsh_execapp(FAR struct nsh_vtbl_s *vtbl, FAR const char *cmd, FAR char **argv) { - int ret = OK; + int ret = OK; - /* Try to find command within pre-built application list. */ + /* Try to find command within pre-built application list. */ - ret = exec_namedapp(cmd, (FAR const char **)argv); - if (ret < 0) - { - return -errno; - } + ret = exec_namedapp(cmd, (FAR const char **)argv); + if (ret < 0) + { + return -errno; + } #ifdef CONFIG_SCHED_WAITPID - if (vtbl->np.np_bg == false) - { - waitpid(ret, NULL, 0); - } - else + if (vtbl->np.np_bg == false) + { + waitpid(ret, NULL, 0); + } + else #endif - { - struct sched_param param; - sched_getparam(0, ¶m); - nsh_output(vtbl, "%s [%d:%d]\n", cmd, ret, param.sched_priority); - } + { + struct sched_param param; + sched_getparam(0, ¶m); + nsh_output(vtbl, "%s [%d:%d]\n", cmd, ret, param.sched_priority); + } - return OK; + return OK; } #endif /* CONFIG_NSH_BUILTIN_APPS */ diff --git a/apps/nshlib/nsh_consolemain.c b/apps/nshlib/nsh_consolemain.c new file mode 100644 index 000000000..372ef5a1f --- /dev/null +++ b/apps/nshlib/nsh_consolemain.c @@ -0,0 +1,163 @@ +/**************************************************************************** + * apps/nshlib/nsh_consolemain.c + * + * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> + * + * 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 <stdio.h> +#include <assert.h> + +#include <apps/readline.h> + +#include "nsh.h" +#include "nsh_console.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: nsh_consolemain + * + * Description: + * This interfaces maybe to called or started with task_start to start a + * single an NSH instance that operates on stdin and stdout (/dev/console). + * This function does not return. + * + * Input Parameters: + * Standard task start-up arguements. These are not used. argc may be + * zero and argv may be NULL. + * + * Returned Values: + * This function does not normally return. exit() is usually called to + * terminate the NSH session. This function will return in the event of + * an error. In that case, a nonzero value is returned (1). + * + ****************************************************************************/ + +int nsh_consolemain(int argc, char *argv[]) +{ + FAR struct console_stdio_s *pstate = nsh_newconsole(); + DEBUGASSERT(pstate); + int ret; + + /* If we are using a USB serial console, then we will have to wait for the + * USB to be connected to the host. + */ + +#ifdef HAVE_USB_CONSOLE + DEBUGASSERT(nsh_usbconsole() == OK); +#endif + + /* Present a greeting */ + + fputs(g_nshgreeting, pstate->cn_outstream); + fflush(pstate->cn_outstream); + + /* Execute the startup script */ + +#ifdef CONFIG_NSH_ROMFSETC + (void)nsh_script(&pstate->cn_vtbl, "init", NSH_INITPATH); +#endif + + /* Then enter the command line parsing loop */ + + for (;;) + { + /* Display the prompt string */ + + fputs(g_nshprompt, pstate->cn_outstream); + fflush(pstate->cn_outstream); + + /* Get the next line of input */ + + ret = readline(pstate->cn_line, CONFIG_NSH_LINELEN, + INSTREAM(pstate), OUTSTREAM(pstate)); + if (ret > 0) + { + /* Parse process the command */ + + (void)nsh_parse(&pstate->cn_vtbl, pstate->cn_line); + fflush(pstate->cn_outstream); + } + + /* Readline normally returns the number of characters read, + * but will return 0 on end of file or a negative value + * if an error occurs. Either will cause the session to + * terminate. + */ + + else + { + fprintf(pstate->cn_outstream, g_fmtcmdfailed, "readline", NSH_ERRNO_OF(-ret)); + nsh_exit(&pstate->cn_vtbl, 1); + } + } + + /* Clean up */ + + nsh_exit(&pstate->cn_vtbl, 0); + + /* We do not get here, but this is necessary to keep some compilers happy */ + + return OK; +} diff --git a/apps/nshlib/nsh_dbgcmds.c b/apps/nshlib/nsh_dbgcmds.c index e9d6d9dab..31199db3e 100644 --- a/apps/nshlib/nsh_dbgcmds.c +++ b/apps/nshlib/nsh_dbgcmds.c @@ -1,8 +1,8 @@ /**************************************************************************** * apps/nshlib/dbg_dbgcmds.c * - * Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -47,6 +47,7 @@ #include <errno.h> #include "nsh.h" +#include "nsh_console.h" /**************************************************************************** * Definitions @@ -151,36 +152,36 @@ int cmd_mb(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) /* 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 */ + { + /* Print the value at the address */ - nsh_output(vtbl, " %p = 0x%02x", ptr, *ptr); + nsh_output(vtbl, " %p = 0x%02x", ptr, *ptr); - /* Are we supposed to write a value to this address? */ + /* Are we supposed to write a value to this address? */ - if (mem.dm_write) - { - /* Yes, was the supplied value within range? */ + 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; - } + 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). - */ + /* 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); - } + *ptr = (uint8_t)mem.dm_value; + nsh_output(vtbl, " -> 0x%02x", *ptr); + } - /* Make sure we end it with a newline */ + /* Make sure we end it with a newline */ - nsh_output(vtbl, "\n", *ptr); - } + nsh_output(vtbl, "\n", *ptr); + } } return ret; } @@ -204,36 +205,36 @@ int cmd_mh(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) /* 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 */ + { + /* Print the value at the address */ - nsh_output(vtbl, " %p = 0x%04x", ptr, *ptr); + nsh_output(vtbl, " %p = 0x%04x", ptr, *ptr); - /* Are we supposed to write a value to this address? */ + /* Are we supposed to write a value to this address? */ - if (mem.dm_write) - { - /* Yes, was the supplied value within range? */ + 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; - } + 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). - */ + /* 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); - } + *ptr = (uint16_t)mem.dm_value; + nsh_output(vtbl, " -> 0x%04x", *ptr); + } - /* Make sure we end it with a newline */ + /* Make sure we end it with a newline */ - nsh_output(vtbl, "\n", *ptr); - } + nsh_output(vtbl, "\n", *ptr); + } } return ret; } @@ -257,28 +258,28 @@ int cmd_mw(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) /* 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 */ + { + /* Print the value at the address */ - nsh_output(vtbl, " %p = 0x%08x", ptr, *ptr); + nsh_output(vtbl, " %p = 0x%08x", ptr, *ptr); - /* Are we supposed to write a value to this address? */ + /* 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). - */ + 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); - } + *ptr = mem.dm_value; + nsh_output(vtbl, " -> 0x%08x", *ptr); + } - /* Make sure we end it with a newline */ + /* Make sure we end it with a newline */ - nsh_output(vtbl, "\n", *ptr); - } + nsh_output(vtbl, "\n", *ptr); + } } return ret; } diff --git a/apps/nshlib/nsh_ddcmd.c b/apps/nshlib/nsh_ddcmd.c index 11652fe7e..5b03cbd2f 100644 --- a/apps/nshlib/nsh_ddcmd.c +++ b/apps/nshlib/nsh_ddcmd.c @@ -1,8 +1,8 @@ /**************************************************************************** * apps/nshlib/nsh_ddcmd.c * - * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -41,6 +41,7 @@ #include <sys/types.h> #include <sys/stat.h> + #include <stdint.h> #include <stdbool.h> #include <stdlib.h> @@ -51,7 +52,9 @@ #include <errno.h> #include <nuttx/fs.h> + #include "nsh.h" +#include "nsh_console.h" #if CONFIG_NFILE_DESCRIPTORS > 0 && !defined(CONFIG_NSH_DISABLE_DD) diff --git a/apps/nshlib/nsh_envcmds.c b/apps/nshlib/nsh_envcmds.c index 520dd76e7..7603bf779 100644 --- a/apps/nshlib/nsh_envcmds.c +++ b/apps/nshlib/nsh_envcmds.c @@ -1,8 +1,8 @@ /**************************************************************************** * apps/nshlib/nsh_envcmds.c * - * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -47,6 +47,7 @@ #include <errno.h> #include "nsh.h" +#include "nsh_console.h" /**************************************************************************** * Definitions diff --git a/apps/nshlib/nsh_fscmds.c b/apps/nshlib/nsh_fscmds.c index 350055fae..e478ddefb 100644 --- a/apps/nshlib/nsh_fscmds.c +++ b/apps/nshlib/nsh_fscmds.c @@ -68,6 +68,7 @@ #include <debug.h> #include "nsh.h" +#include "nsh_console.h" /**************************************************************************** * Definitions diff --git a/apps/nshlib/nsh_mmcmds.c b/apps/nshlib/nsh_mmcmds.c index fd37df168..545ae60ad 100644 --- a/apps/nshlib/nsh_mmcmds.c +++ b/apps/nshlib/nsh_mmcmds.c @@ -42,6 +42,7 @@ #include <stdlib.h> #include "nsh.h" +#include "nsh_console.h" /**************************************************************************** * Definitions diff --git a/apps/nshlib/nsh_netcmds.c b/apps/nshlib/nsh_netcmds.c index 8285da295..04d10b1e1 100644 --- a/apps/nshlib/nsh_netcmds.c +++ b/apps/nshlib/nsh_netcmds.c @@ -1,8 +1,8 @@ /**************************************************************************** * apps/nshlib/nsh_netcmds.c * - * Copyright (C) 2007-2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -81,6 +81,7 @@ #endif #include "nsh.h" +#include "nsh_console.h" /**************************************************************************** * Definitions diff --git a/apps/nshlib/nsh_netinit.c b/apps/nshlib/nsh_netinit.c index 245d50380..12286cf84 100644 --- a/apps/nshlib/nsh_netinit.c +++ b/apps/nshlib/nsh_netinit.c @@ -1,8 +1,8 @@ /**************************************************************************** * apps/nshlib/nsh_netinit.c * - * Copyright (C) 2010-2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2010-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * This is influenced by similar logic from uIP: * diff --git a/apps/nshlib/nsh_parse.c b/apps/nshlib/nsh_parse.c index cc0443258..cec167f05 100644 --- a/apps/nshlib/nsh_parse.c +++ b/apps/nshlib/nsh_parse.c @@ -64,6 +64,7 @@ #include <apps/nsh.h> #include "nsh.h" +#include "nsh_console.h" /**************************************************************************** * Definitions @@ -463,7 +464,7 @@ static int cmd_unrecognized(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) #ifndef CONFIG_NSH_DISABLE_EXIT static int cmd_exit(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { - nsh_exit(vtbl); + nsh_exit(vtbl, 0); return OK; } #endif @@ -1018,6 +1019,18 @@ static inline int nsh_nice(FAR struct nsh_vtbl_s *vtbl, FAR char **ppcmd, FAR ch /**************************************************************************** * Name: nsh_initialize + * + * Description: + * This nterfaces is used to initialize the NuttShell (NSH). + * nsh_initialize() should be called one during application start-up prior + * to executing either nsh_consolemain() or nsh_telnetstart(). + * + * Input Parameters: + * None + * + * Returned Value: + * None + * ****************************************************************************/ void nsh_initialize(void) @@ -1037,6 +1050,10 @@ void nsh_initialize(void) /**************************************************************************** * Name: nsh_parse + * + * Description: + * This function parses and executes one NSH command. + * ****************************************************************************/ int nsh_parse(FAR struct nsh_vtbl_s *vtbl, char *cmdline) diff --git a/apps/nshlib/nsh_proccmds.c b/apps/nshlib/nsh_proccmds.c index c0dc1713f..487214501 100644 --- a/apps/nshlib/nsh_proccmds.c +++ b/apps/nshlib/nsh_proccmds.c @@ -1,8 +1,8 @@ /**************************************************************************** * apps/nshlib/nsh_proccmds.c * - * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -46,6 +46,7 @@ #include <errno.h> #include "nsh.h" +#include "nsh_console.h" /**************************************************************************** * Definitions diff --git a/apps/nshlib/nsh_romfsetc.c b/apps/nshlib/nsh_romfsetc.c index d97e6591a..4134b45a3 100644 --- a/apps/nshlib/nsh_romfsetc.c +++ b/apps/nshlib/nsh_romfsetc.c @@ -1,8 +1,8 @@ /**************************************************************************** * apps/nshlib/nsh_romfsetc.c * - * Copyright (C) 2008-2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2008-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/apps/nshlib/nsh_serial.c b/apps/nshlib/nsh_serial.c deleted file mode 100644 index 57cb1b1c1..000000000 --- a/apps/nshlib/nsh_serial.c +++ /dev/null @@ -1,534 +0,0 @@ -/**************************************************************************** - * apps/nshlib/nsh_serial.c - * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <gnutt@nuttx.org> - * - * 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 <fcntl.h> -#include <string.h> -#include <stdarg.h> -#include <assert.h> -#include <errno.h> -#include <debug.h> - -#include <apps/readline.h> - -#include "nsh.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Are we using the NuttX console for I/O? Or some other character device? */ - -#ifdef CONFIG_NSH_CONDEV -# define INFD(p) ((p)->ss_confd) -# define INSTREAM(p) ((p)->ss_constream) -# define OUTFD(p) ((p)->ss_confd) -# define OUTSTREAM(p) ((p)->ss_constream) -#else -# define INFD(p) 0 -# define INSTREAM(p) stdin -# define OUTFD(p) 1 -# define OUTSTREAM(p) stdout -#endif - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -struct serial_s -{ - /* NSH front-end call table */ - - struct nsh_vtbl_s ss_vtbl; - - /* NSH input/output streams */ - -#ifdef CONFIG_NSH_CONDEV - int ss_confd; /* Console I/O file descriptor */ -#endif - int ss_outfd; /* Output file descriptor (possibly redirected) */ -#ifdef CONFIG_NSH_CONDEV - FILE *ss_constream; /* Console I/O stream (possibly redirected) */ -#endif - FILE *ss_outstream; /* Output stream */ - - /* Line input buffer */ - - char ss_line[CONFIG_NSH_LINELEN]; -}; - -struct serialsave_s -{ - int ss_outfd; /* Re-directed output file descriptor */ - FILE *ss_outstream; /* Re-directed output stream */ -}; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -#ifndef CONFIG_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) - { - /* Initialize the call table */ - -#ifndef CONFIG_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; - - /* (Re-) open the console input device */ - -#ifdef CONFIG_NSH_CONDEV - pstate->ss_confd = open(CONFIG_NSH_CONDEV, O_RDWR); - if (pstate->ss_confd < 0) - { - free(pstate); - return NULL; - } - - /* Create a standard C stream on the console device */ - - pstate->ss_constream = fdopen(pstate->ss_confd, "r+"); - if (!pstate->ss_constream) - { - close(pstate->ss_confd); - free(pstate); - return NULL; - } -#endif - - /* Initialize the output stream */ - - pstate->ss_outfd = OUTFD(pstate); - pstate->ss_outstream = OUTSTREAM(pstate); - } - 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_outstream) - { - pstate->ss_outstream = fdopen(pstate->ss_outfd, "w"); - if (!pstate->ss_outstream) - { - return ERROR; - } - } - return 0; -} - -/**************************************************************************** - * Name: nsh_closeifnotclosed - * - * Description: - * Close the output stream if it is not the standard output stream. - * - ****************************************************************************/ - -static void nsh_closeifnotclosed(struct serial_s *pstate) -{ - if (pstate->ss_outstream == OUTSTREAM(pstate)) - { - fflush(OUTSTREAM(pstate)); - pstate->ss_outfd = OUTFD(pstate); - } - else - { - if (pstate->ss_outstream) - { - fflush(pstate->ss_outstream); - fclose(pstate->ss_outstream); - } - else if (pstate->ss_outfd >= 0 && pstate->ss_outfd != OUTFD(pstate)) - { - close(pstate->ss_outfd); - } - - pstate->ss_outfd = -1; - pstate->ss_outstream = 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_outstream); - if (ret < 0) - { - dbg("[%d] Failed to send buffer: %d\n", pstate->ss_outfd, 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_outstream, 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_NSH_DISABLEBG -static FAR struct nsh_vtbl_s *nsh_consoleclone(FAR struct nsh_vtbl_s *vtbl) -{ - FAR struct serial_s *pclone = nsh_allocstruct(); - return &pclone->ss_vtbl; -} -#endif - -/**************************************************************************** - * Name: nsh_consolerelease - * - * Description: - * Release the cloned instance - * - ****************************************************************************/ - -#ifndef CONFIG_NSH_DISABLEBG -static void nsh_consolerelease(FAR struct nsh_vtbl_s *vtbl) -{ - FAR struct serial_s *pstate = (FAR struct serial_s *)vtbl; - - /* Close the output stream */ - - nsh_closeifnotclosed(pstate); - - /* Close the console stream */ - -#ifdef CONFIG_NSH_CONDEV - (void)fclose(pstate->ss_constream); -#endif - - /* Then release the vtable container */ - - free(pstate); -} -#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_outstream and ss_outfd refer refer to the - * currently opened output stream. If the output stream is open, flush - * any pending output. - */ - - if (pstate->ss_outstream) - { - fflush(pstate->ss_outstream); - } - - /* Save the current fd and stream values. These will be restored - * when nsh_consoleundirect() is called. - */ - - ssave->ss_outfd = pstate->ss_outfd; - ssave->ss_outstream = pstate->ss_outstream; - } - else - { - /* nsh_consoleclone() set pstate->ss_outfd and ss_outstream 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_outfd = fd; - pstate->ss_outstream = 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_outfd = ssave->ss_outfd; - pstate->ss_outstream = ssave->ss_outstream; -} - -/**************************************************************************** - * Name: nsh_consoleexit - * - * Description: - * Exit the shell task - * - ****************************************************************************/ - -static void nsh_consoleexit(FAR struct nsh_vtbl_s *vtbl) -{ - exit(0); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: nsh_consolemain - ****************************************************************************/ - -int nsh_consolemain(int argc, char *argv[]) -{ - FAR struct serial_s *pstate = nsh_allocstruct(); - DEBUGASSERT(pstate); - int ret; - - /* If we are using a USB console, then we will have to wait for the USB to - * be connected/ - */ - -#ifdef HAVE_USB_CONSOLE - DEBUGASSERT(nsh_usbconsole() == OK); -#endif - - /* Present a greeting */ - - fputs(g_nshgreeting, pstate->ss_outstream); - fflush(pstate->ss_outstream); - - /* Execute the startup script */ - -#ifdef CONFIG_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_outstream); - fflush(pstate->ss_outstream); - - /* Get the next line of input */ - - ret = readline(pstate->ss_line, CONFIG_NSH_LINELEN, - INSTREAM(pstate), OUTSTREAM(pstate)); - if (ret > 0) - { - /* Parse process the command */ - - (void)nsh_parse(&pstate->ss_vtbl, pstate->ss_line); - fflush(pstate->ss_outstream); - } - - /* Readline normally returns the number of characters read, - * but will return 0 on end of file or a negative value - * if an error occurs. Either will cause the session to - * terminate. - */ - - else - { - fprintf(pstate->ss_outstream, g_fmtcmdfailed, "readline", NSH_ERRNO_OF(-ret)); - return 1; - } - } - - return OK; -} diff --git a/apps/nshlib/nsh_telnetd.c b/apps/nshlib/nsh_telnetd.c index 0670c9a05..66923deb2 100644 --- a/apps/nshlib/nsh_telnetd.c +++ b/apps/nshlib/nsh_telnetd.c @@ -1,14 +1,8 @@ /**************************************************************************** * 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. + * Copyright (C) 2007-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -17,23 +11,26 @@ * 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 + * 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 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. + * 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. + * ****************************************************************************/ /**************************************************************************** @@ -42,812 +39,148 @@ #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 <apps/netutils/uiplib.h> -#if defined(CONFIG_NSH_DHCPC) -# include <apps/netutils/resolv.h> -# include <apps/netutils/dhcpc.h> -#endif +#include <apps/netutils/telnetd.h> #include "nsh.h" +#include "nsh_console.h" #ifdef CONFIG_NSH_TELNET /**************************************************************************** - * Definitions + * Pre-processor 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_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_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_NSH_IOBUFFER_SIZE]; - char tn_cmd[CONFIG_NSH_LINELEN]; -}; - /**************************************************************************** * Private Function Prototypes ****************************************************************************/ -#ifndef CONFIG_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 + * Private Data ****************************************************************************/ -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 + * Public Data ****************************************************************************/ -#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_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 + * Private Functions ****************************************************************************/ -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 + * Public Functions ****************************************************************************/ -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 - * + * Name: nsh_telnetmain ****************************************************************************/ -static void nsh_putchar(struct telnetd_s *pstate, uint8_t ch) +int nsh_telnetmain(int argc, char *argv[]) { - struct telnetio_s *tio = pstate->u.tn; - - /* Ignore carriage returns */ + FAR struct console_stdio_s *pstate = nsh_newconsole(); + DEBUGASSERT(pstate != NULL); - if (ch == ISO_cr) - { - return; - } + dbg("Session [%d] Started\n", getpid()); - /* Add all other characters to the cmd buffer */ + /* Present a greeting */ - pstate->tn_cmd[tio->tio_bufndx] = ch; + fputs(g_nshgreeting, pstate->cn_outstream); + fflush(pstate->cn_outstream); - /* If a newline was added or if the buffer is full, then process it now */ + /* Execute the startup script */ - if (ch == ISO_nl || tio->tio_bufndx == (CONFIG_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); - } -} +#if defined(CONFIG_NSH_ROMFSETC) && !defined(CONFIG_NSH_CONSOLE) + (void)nsh_script(&pstate->cn_vtbl, "init", NSH_INITPATH); +#endif -/**************************************************************************** - * Name: nsh_sendopt - * - * Description: - * - ****************************************************************************/ + /* Then enter the command line parsing loop */ -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) + for (;;) { - dbg("[%d] Failed to send TELNET_IAC: %d\n", tio->tio_sockfd, errno); - } - tio_semgive(tio); -} + /* Display the prompt string */ -/**************************************************************************** - * Name: nsh_flush - * - * Description: - * Dump the buffered output info. - * - ****************************************************************************/ + fputs(g_nshprompt, pstate->cn_outstream); + fflush(pstate->cn_outstream); -static void nsh_flush(FAR struct telnetd_s *pstate) -{ - struct telnetio_s *tio = pstate->u.tn; + /* Get the next line of input from the Telnet client */ - 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) + if (fgets(pstate->cn_line, CONFIG_NSH_LINELEN, INSTREAM(pstate)) != NULL) { - dbg("[%d] Failed to send response: %d\n", tio->tio_sockfd, errno); - } - tio_semgive(tio); - } - pstate->tn_sndlen = 0; -} + /* Parse process the received Telnet command */ -/**************************************************************************** - * 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; + (void)nsh_parse(&pstate->cn_vtbl, pstate->cn_line); + fflush(pstate->cn_outstream); } - } - 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_NSH_ROMFSETC) && !defined(CONFIG_NSH_CONSOLE) - (void)nsh_script(vtbl, "init", NSH_INITPATH); -#endif - - /* Loop processing each TELNET command */ - - do + else { - /* 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_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); - } + fprintf(pstate->cn_outstream, g_fmtcmdfailed, "fgets", NSH_ERRNO); + nsh_exit(&pstate->cn_vtbl, 1); } - 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 */ + /* Clean up */ - if (pstate) - { - free(pstate); - } + nsh_exit(&pstate->cn_vtbl, 0); - if (tio) - { - sem_destroy(&tio->tio_sem); - free(tio); - } + /* We do not get here, but this is necessary to keep some compilers happy */ - dbg("[%d] Exitting\n", sockfd); - close(sockfd); - return NULL; + return OK; } /**************************************************************************** - * Name: nsh_telnetwrite - * - * Description: - * write a buffer to the remote shell window. - * - * Currently only used by cat. - * + * Public Functions ****************************************************************************/ -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 + * Name: nsh_telnetstart * * Description: - * Print a string to the remote shell window. + * nsh_telnetstart() starts the Telnet daemon that will allow multiple + * NSH connections via Telnet. This function returns immediately after + * the daemon has been started. * - * 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. + * Input Parameters: + * None. All of the properties of the Telnet daemon are controlled by + * NuttX configuration setting. * + * Returned Values: + * Zero if the Telnet daemon was successfully started. A negated errno + * value will be returned on failure. + * ****************************************************************************/ -static int nsh_telnetoutput(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...) +int nsh_telnetstart(void) { - struct telnetd_s *pstate = (struct telnetd_s *)vtbl; - int nbytes = pstate->tn_sndlen; - int len; - va_list ap; + struct telnetd_config_s config; + int ret; - /* Put the new info into the buffer. Here we are counting on the fact that - * no output strings will exceed CONFIG_NSH_LINELEN! - */ + /* Configure the telnet daemon */ - va_start(ap, fmt); - vsnprintf(&pstate->tn_outbuffer[nbytes], - (CONFIG_NSH_IOBUFFER_SIZE - 1) - nbytes, fmt, ap); - va_end(ap); + config.d_port = HTONS(CONFIG_NSH_TELNETD_PORT); + config.d_priority = CONFIG_NSH_TELNETD_DAEMONPRIO; + config.d_stacksize = CONFIG_NSH_TELNETD_DAEMONSTACKSIZE; + config.t_priority = CONFIG_NSH_TELNETD_CLIENTPRIO; + config.t_stacksize = CONFIG_NSH_TELNETD_CLIENTSTACKSIZE; + config.t_entry = nsh_telnetmain; - /* Get the size of the new string just added and the total size of - * buffered data - */ + /* Start the telnet daemon */ - len = strlen(&pstate->tn_outbuffer[nbytes]); - nbytes += len; - - /* Expand any terminating \n to \r\n */ - - if (nbytes < (CONFIG_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_NSH_IOBUFFER_SIZE - CONFIG_NSH_LINELEN) + vdbg("Starting the Telnet daemon\n"); + ret = telnetd_start(&config); + if (ret < 0) { - nsh_flush(pstate); + dbg("Failed to tart the Telnet daemon: %d\n", ret); } - 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_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_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_NSH_STACKSIZE); - return OK; -} - #endif /* CONFIG_NSH_TELNET */ diff --git a/apps/nshlib/nsh_test.c b/apps/nshlib/nsh_test.c index dd63d6796..6e1b65e5f 100644 --- a/apps/nshlib/nsh_test.c +++ b/apps/nshlib/nsh_test.c @@ -1,8 +1,8 @@ /**************************************************************************** * apps/nshlib/nsh_test.c * - * Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2008, 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -69,6 +69,7 @@ #include <string.h> #include "nsh.h" +#include "nsh_console.h" #if !defined(CONFIG_NSH_DISABLESCRIPT) && !defined(CONFIG_NSH_DISABLE_TEST) diff --git a/apps/nshlib/nsh_timcmds.c b/apps/nshlib/nsh_timcmds.c index 04a79e77d..bc2bda6f4 100644 --- a/apps/nshlib/nsh_timcmds.c +++ b/apps/nshlib/nsh_timcmds.c @@ -1,8 +1,8 @@ /**************************************************************************** * apps/nshlib/dbg_timcmds.c * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -45,6 +45,7 @@ #include <time.h> #include "nsh.h" +#include "nsh_console.h" /**************************************************************************** * Definitions diff --git a/apps/nshlib/nsh_usbdev.c b/apps/nshlib/nsh_usbdev.c index bb17244c1..c8115bfc7 100644 --- a/apps/nshlib/nsh_usbdev.c +++ b/apps/nshlib/nsh_usbdev.c @@ -146,4 +146,4 @@ int nsh_usbconsole(void) } #endif /* HAVE_USB_CONSOLE */ -#endif /* CONFIG_USBDEV */
\ No newline at end of file +#endif /* CONFIG_USBDEV */ diff --git a/apps/system/free/Makefile b/apps/system/free/Makefile index 51bd9a6e3..974c98913 100644 --- a/apps/system/free/Makefile +++ b/apps/system/free/Makefile @@ -61,7 +61,11 @@ COBJS = $(CSRCS:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) OBJS = $(AOBJS) $(COBJS) -BIN = $(APPDIR)/libapps$(LIBEXT) +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}" +else + BIN = "$(APPDIR)/libapps$(LIBEXT)" +endif ROOTDEPPATH = --dep-path . diff --git a/apps/system/i2c/Makefile b/apps/system/i2c/Makefile index 5ea974452..845c149f6 100644 --- a/apps/system/i2c/Makefile +++ b/apps/system/i2c/Makefile @@ -1,8 +1,8 @@ ############################################################################ # apps/system/i2c # -# Copyright (C) 2011 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt <spudmonkey@racsa.co.cr> +# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt <gnutt@nuttx.org> # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -42,7 +42,6 @@ include $(APPDIR)/Make.defs ASRCS = CSRCS = i2c_bus.c i2c_common.c i2c_dev.c i2c_get.c i2c_main.c i2c_set.c i2c_verf.c - AOBJS = $(ASRCS:.S=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT)) diff --git a/apps/system/readline/Makefile b/apps/system/readline/Makefile index 3d9503cea..34fab7e81 100644 --- a/apps/system/readline/Makefile +++ b/apps/system/readline/Makefile @@ -52,7 +52,11 @@ COBJS = $(CSRCS:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) OBJS = $(AOBJS) $(COBJS) -BIN = $(APPDIR)/libapps$(LIBEXT) +ifeq ($(WINTOOL),y) + BIN = "${shell cygpath -w $(APPDIR)/libapps$(LIBEXT)}" +else + BIN = "$(APPDIR)/libapps$(LIBEXT)" +endif ROOTDEPPATH = --dep-path . |