diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2008-03-05 02:49:35 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2008-03-05 02:49:35 +0000 |
commit | a3ddb08bec11871f6e83bb7aaa53a17a4ea5309c (patch) | |
tree | 7a77642c272052b03260156dc5062d23f16e3a35 | |
parent | New. (diff) | |
download | rtems-a3ddb08bec11871f6e83bb7aaa53a17a4ea5309c.tar.bz2 |
2008-03-04 Joel Sherrill <joel.sherrill@oarcorp.com>
* libmisc/Makefile.am, libmisc/shell/main_cp.c,
libmisc/shell/main_cpuuse.c, libmisc/shell/main_date.c,
libmisc/shell/main_mallocinfo.c, libmisc/shell/main_netstats.c,
libmisc/shell/main_perioduse.c, libmisc/shell/main_stackuse.c,
libmisc/shell/main_wkspaceinfo.c, libmisc/shell/print_heapinfo.c,
libmisc/shell/shell.c, libmisc/shell/shell.h,
libmisc/shell/shell_makeargs.c, libmisc/shell/shellconfig.c,
libmisc/shell/shellconfig.h, libmisc/shell/write_file.c: Add initial
capability to automatically execute a script from the filesystem. Add
echo command from NetBSD and sleep command.
* libmisc/shell/main_echo.c, libmisc/shell/main_sleep.c,
libmisc/shell/shell_script.c: New files.
Diffstat (limited to '')
-rw-r--r-- | cpukit/ChangeLog | 15 | ||||
-rw-r--r-- | cpukit/libmisc/Makefile.am | 13 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_cp.c | 12 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_cpuuse.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_date.c | 4 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_echo.c | 142 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_mallocinfo.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_netstats.c | 76 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_perioduse.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_sleep.c | 57 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_stackuse.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/main_wkspaceinfo.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/print_heapinfo.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/shell.c | 18 | ||||
-rw-r--r-- | cpukit/libmisc/shell/shell.h | 24 | ||||
-rw-r--r-- | cpukit/libmisc/shell/shell_makeargs.c | 2 | ||||
-rw-r--r-- | cpukit/libmisc/shell/shell_script.c | 327 | ||||
-rw-r--r-- | cpukit/libmisc/shell/shellconfig.c | 3 | ||||
-rw-r--r-- | cpukit/libmisc/shell/shellconfig.h | 18 | ||||
-rw-r--r-- | cpukit/libmisc/shell/write_file.c | 8 |
20 files changed, 683 insertions, 48 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index fc2f77746b..4f10e55932 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,18 @@ +2008-03-04 Joel Sherrill <joel.sherrill@oarcorp.com> + + * libmisc/Makefile.am, libmisc/shell/main_cp.c, + libmisc/shell/main_cpuuse.c, libmisc/shell/main_date.c, + libmisc/shell/main_mallocinfo.c, libmisc/shell/main_netstats.c, + libmisc/shell/main_perioduse.c, libmisc/shell/main_stackuse.c, + libmisc/shell/main_wkspaceinfo.c, libmisc/shell/print_heapinfo.c, + libmisc/shell/shell.c, libmisc/shell/shell.h, + libmisc/shell/shell_makeargs.c, libmisc/shell/shellconfig.c, + libmisc/shell/shellconfig.h, libmisc/shell/write_file.c: Add initial + capability to automatically execute a script from the filesystem. Add + echo command from NetBSD and sleep command. + * libmisc/shell/main_echo.c, libmisc/shell/main_sleep.c, + libmisc/shell/shell_script.c: New files. + 2008-02-28 Joel Sherrill <joel.sherrill@oarcorp.com> * itron/include/rtems/itron/task.h, itron/src/cre_tsk.c, diff --git a/cpukit/libmisc/Makefile.am b/cpukit/libmisc/Makefile.am index 9428bc4f7a..6103e3c56d 100644 --- a/cpukit/libmisc/Makefile.am +++ b/cpukit/libmisc/Makefile.am @@ -68,20 +68,21 @@ libshell_a_SOURCES = shell/cat_file.c shell/cmds.c shell/internal.h \ shell/main_alias.c shell/main_cat.c shell/main_cd.c \ shell/main_chdir.c shell/main_chmod.c shell/main_chroot.c \ shell/main_cp.c shell/main_cpuuse.c shell/main_date.c shell/main_dir.c \ - shell/main_exit.c shell/main_help.c shell/main_id.c \ + shell/main_echo.c shell/main_exit.c shell/main_help.c shell/main_id.c \ shell/main_logoff.c shell/main_ls.c shell/main_mallocinfo.c \ shell/main_mdump.c shell/main_medit.c shell/main_mfill.c \ shell/main_mkdir.c shell/main_mount.c $(shell_mount_fs) \ shell/main_mount_msdos.c shell/main_mmove.c shell/main_msdosfmt.c \ shell/main_mwdump.c shell/main_perioduse.c shell/main_pwd.c \ - shell/main_rm.c shell/main_rmdir.c shell/main_stackuse.c \ - shell/main_tty.c shell/main_umask.c shell/main_unmount.c \ - shell/main_blksync.c shell/main_whoami.c shell/shell.c \ - shell/shell_cmdset.c shell/shellconfig.c shell/shellconfig.h \ + shell/main_rm.c shell/main_rmdir.c shell/main_sleep.c \ + shell/main_stackuse.c shell/main_tty.c shell/main_umask.c \ + shell/main_unmount.c shell/main_blksync.c shell/main_whoami.c \ + shell/shell.c shell/shell_cmdset.c shell/shellconfig.c shell/shellconfig.h \ shell/shell.h shell/shell_makeargs.c shell/str2int.c shell/write_file.c \ shell/utils-cp.c shell/err.c shell/errx.c shell/verr.c shell/verrx.c \ shell/vwarn.c shell/vwarnx.c shell/warn.c shell/warnx.c \ - shell/fts.c shell/print_heapinfo.c shell/main_wkspaceinfo.c + shell/fts.c shell/print_heapinfo.c shell/main_wkspaceinfo.c \ + shell/shell_script.c if LIBNETWORKING libshell_a_SOURCES += shell/main_mount_ftp.c shell/main_mount_tftp.c \ shell/main_ifconfig.c shell/main_route.c shell/main_netstats.c \ diff --git a/cpukit/libmisc/shell/main_cp.c b/cpukit/libmisc/shell/main_cp.c index f7e7347b66..3812c3caac 100644 --- a/cpukit/libmisc/shell/main_cp.c +++ b/cpukit/libmisc/shell/main_cp.c @@ -522,10 +522,10 @@ mastercmp(const FTSENT **a, const FTSENT **b) } rtems_shell_cmd_t rtems_shell_CP_Command = { - "cp", /* name */ - "cp [-R [-H | -L | -P]] [-f | -i] [-pv] src target # copy", /* usage */ - "files", /* topic */ - rtems_shell_main_cp, /* command */ - NULL, /* alias */ - NULL /* next */ + "cp", /* name */ + "cp [-R [-H | -L | -P]] [-f | -i] [-pv] src target", /* usage */ + "files", /* topic */ + rtems_shell_main_cp, /* command */ + NULL, /* alias */ + NULL /* next */ }; diff --git a/cpukit/libmisc/shell/main_cpuuse.c b/cpukit/libmisc/shell/main_cpuuse.c index 492997cd8f..b2329934bd 100644 --- a/cpukit/libmisc/shell/main_cpuuse.c +++ b/cpukit/libmisc/shell/main_cpuuse.c @@ -1,7 +1,7 @@ /* * CPUUSE Command Implementation * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be diff --git a/cpukit/libmisc/shell/main_date.c b/cpukit/libmisc/shell/main_date.c index 4d3f4fa94f..4ddbc118b8 100644 --- a/cpukit/libmisc/shell/main_date.c +++ b/cpukit/libmisc/shell/main_date.c @@ -1,10 +1,12 @@ /* * DATE Shell Command Implmentation * - * Author: Fernando RUIZ CASAS + * OAuthor: Fernando RUIZ CASAS * Work: fernando.ruiz@ctv.es * Home: correo@fernando-ruiz.com * + * Significantly rewritten by Joel Sherrill <joel.sherrill@oarcorp.com>. + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. diff --git a/cpukit/libmisc/shell/main_echo.c b/cpukit/libmisc/shell/main_echo.c new file mode 100644 index 0000000000..8f868a2f29 --- /dev/null +++ b/cpukit/libmisc/shell/main_echo.c @@ -0,0 +1,142 @@ +/* $NetBSD: echo.c,v 1.12 2005/02/06 04:43:43 perry Exp $ */ + +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Kenneth Almquist. + * + * 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 University 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 REGENTS 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 REGENTS 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. + * + * @(#)echo.c 8.1 (Berkeley) 5/31/93 + */ + +/* + * Echo command. + * + * echo is steeped in tradition - several of them! + * netbsd has supported 'echo [-n | -e] args' in spite of -e not being + * documented anywhere. + * Posix requires that -n be supported, output from strings containing + * \ is implementation defined + * The Single Unix Spec requires that \ escapes be treated as if -e + * were set, but that -n not be treated as an option. + * (ksh supports 'echo [-eEn] args', but not -- so that it is actually + * impossible to actually output '-n') + * + * It is suggested that 'printf "%b" "string"' be used to get \ sequences + * expanded. printf is now a builtin of netbsd's sh and csh. + */ + +/* + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <rtems.h> +#include <rtems/shell.h> +#include "internal.h" + + + +int rtems_shell_main_echo( + int argc, + char *argv[] +) +{ + char **ap; + char *p; + char c; + int count; + int nflag = 0; + int eflag = 0; + + ap = argv; + if (argc) + ap++; + + if ((p = *ap) != NULL) { + if (!strcmp(p, "-n")) { + nflag = 1; + ap++; + } else if (!strcmp(p, "-e")) { + eflag = 1; + ap++; + } + } + + while ((p = *ap++) != NULL) { + while ((c = *p++) != '\0') { + if (c == '\\' && eflag) { + switch (*p++) { + case 'a': c = '\a'; break; /* bell */ + case 'b': c = '\b'; break; + case 'c': return 0; /* exit */ + case 'e': c = 033; break; /* escape */ + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + case '\\': break; /* c = '\\' */ + case '0': + c = 0; + count = 3; + while (--count >= 0 && (unsigned)(*p - '0') < 8) + c = (c << 3) + (*p++ - '0'); + break; + default: + /* Output the '/' and char following */ + p--; + break; + } + } + putchar(c); + } + if (*ap) + putchar(' '); + } + if (! nflag) + putchar('\n'); + return 0; +} + +rtems_shell_cmd_t rtems_shell_ECHO_Command = { + "echo", /* name */ + "echo [args]", /* usage */ + "misc", /* topic */ + rtems_shell_main_echo, /* command */ + NULL, /* alias */ + NULL /* next */ +}; diff --git a/cpukit/libmisc/shell/main_mallocinfo.c b/cpukit/libmisc/shell/main_mallocinfo.c index 1f459270ee..109dbc3dd3 100644 --- a/cpukit/libmisc/shell/main_mallocinfo.c +++ b/cpukit/libmisc/shell/main_mallocinfo.c @@ -1,7 +1,7 @@ /* * MALLOC_INFO Shell Command Implmentation * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be diff --git a/cpukit/libmisc/shell/main_netstats.c b/cpukit/libmisc/shell/main_netstats.c index 09dea65694..a86b7afa35 100644 --- a/cpukit/libmisc/shell/main_netstats.c +++ b/cpukit/libmisc/shell/main_netstats.c @@ -1,7 +1,7 @@ /* * Network Statistics Shell Command Implmentation * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -52,17 +52,21 @@ int rtems_shell_main_netstats( /* command */ int doICMPStats = 0; int doUDPStats = 0; int doTCPStats = 0; + int verbose = 0; + struct getopt_data getopt_reent; - while ( (option = getopt( argc, argv, "Aimfpcutv")) != -1 ) { - switch (option) { - case 'A': doAll = 1; break; - case 'i': doInetRoutes = 1; break; - case 'm': doMBUFStats = 1; break; - case 'f': doIFStats = 1; break; - case 'p': doIPStats = 1; break; - case 'c': doICMPStats = 1; break; - case 'u': doUDPStats = 1; break; - case 't': doTCPStats = 1; break; + while ( (option = getopt_r( argc, argv, "Aimfpcutv", &getopt_reent)) != -1 ) { + + switch ((char)option) { + case 'A': doAll = 1; break; + case 'i': doInetRoutes = 1; break; + case 'm': doMBUFStats = 1; break; + case 'f': doIFStats = 1; break; + case 'p': doIPStats = 1; break; + case 'c': doICMPStats = 1; break; + case 'u': doUDPStats = 1; break; + case 't': doTCPStats = 1; break; + case 'v': verbose = 1; break; case '?': default: netstats_usage(); @@ -70,21 +74,57 @@ int rtems_shell_main_netstats( /* command */ } } - if ( doInetRoutes == 1 || doAll == 1 ) + if ( verbose ) { + printf( + "doAll=%d\n" + "doInetRoutes=%d\n" + "doMBUFStats=%d\n" + "doIFStats=%d\n" + "doIPStats=%d\n" + "doICMPStats=%d\n" + "doUDPStats=%d\n" + "doTCPStats=%d\n", + doAll, + doInetRoutes, + doMBUFStats, + doIFStats, + doIPStats, + doICMPStats, + doUDPStats, + doTCPStats + ); + } + +#if 0 + if ( doInetRoutes == 1 || doAll == 1 ) { rtems_bsdnet_show_inet_routes(); - if ( doMBUFStats == 1 || doAll == 1 ) + } + + if ( doMBUFStats == 1 || doAll == 1 ) { rtems_bsdnet_show_mbuf_stats(); - if ( doIFStats == 1 || doAll == 1 ) + } + + if ( doIFStats == 1 || doAll == 1 ) { rtems_bsdnet_show_if_stats(); - if ( doIPStats == 1 || doAll == 1 ) + } + + if ( doIPStats == 1 || doAll == 1 ) { rtems_bsdnet_show_ip_stats(); - if ( doICMPStats == 1 || doAll == 1 ) + } + + if ( doICMPStats == 1 || doAll == 1 ) { rtems_bsdnet_show_icmp_stats(); - if ( doUDPStats == 1 || doAll == 1 ) + } + + if ( doUDPStats == 1 || doAll == 1 ) { rtems_bsdnet_show_udp_stats(); - if ( doTCPStats == 1 || doAll == 1 ) + } + + if ( doTCPStats == 1 || doAll == 1 ) { rtems_bsdnet_show_tcp_stats(); + } +#endif return 0; } diff --git a/cpukit/libmisc/shell/main_perioduse.c b/cpukit/libmisc/shell/main_perioduse.c index 9ad18d76de..d0f123af1c 100644 --- a/cpukit/libmisc/shell/main_perioduse.c +++ b/cpukit/libmisc/shell/main_perioduse.c @@ -1,7 +1,7 @@ /* * perioduse Command Implementation * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be diff --git a/cpukit/libmisc/shell/main_sleep.c b/cpukit/libmisc/shell/main_sleep.c new file mode 100644 index 0000000000..6ee4cef614 --- /dev/null +++ b/cpukit/libmisc/shell/main_sleep.c @@ -0,0 +1,57 @@ +/* + * Sleep Shell Command Implmentation + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <time.h> + +#include <rtems.h> +#include <rtems/shell.h> +#include "internal.h" + +int rtems_shell_main_sleep( + int argc, + char *argv[] +) +{ + struct timespec delay; + + if (argc == 2) { + delay.tv_sec = rtems_shell_str2int(argv[1]); + delay.tv_nsec = 0; + nanosleep( &delay, NULL ); + return 0; + } + + if (argc == 3) { + delay.tv_sec = rtems_shell_str2int(argv[1]); + delay.tv_nsec = rtems_shell_str2int(argv[2]); + nanosleep( &delay, NULL ); + return 0; + } + + fprintf( stderr, "%s: Usage seconds [nanoseconds]\n", argv[0] ); + return -1; +} + +rtems_shell_cmd_t rtems_shell_SLEEP_Command = { + "sleep", /* name */ + "sleep seconds [nanoseconds]", /* usage */ + "misc", /* topic */ + rtems_shell_main_sleep, /* command */ + NULL, /* alias */ + NULL /* next */ +}; diff --git a/cpukit/libmisc/shell/main_stackuse.c b/cpukit/libmisc/shell/main_stackuse.c index 6c6c9251ae..3179f3670b 100644 --- a/cpukit/libmisc/shell/main_stackuse.c +++ b/cpukit/libmisc/shell/main_stackuse.c @@ -1,7 +1,7 @@ /* * stackuse Command Implementation * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be diff --git a/cpukit/libmisc/shell/main_wkspaceinfo.c b/cpukit/libmisc/shell/main_wkspaceinfo.c index b5df7a4b42..41a3664330 100644 --- a/cpukit/libmisc/shell/main_wkspaceinfo.c +++ b/cpukit/libmisc/shell/main_wkspaceinfo.c @@ -1,7 +1,7 @@ /* * MALLOC_INFO Shell Command Implmentation * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be diff --git a/cpukit/libmisc/shell/print_heapinfo.c b/cpukit/libmisc/shell/print_heapinfo.c index 9110c97a76..ad6db121d2 100644 --- a/cpukit/libmisc/shell/print_heapinfo.c +++ b/cpukit/libmisc/shell/print_heapinfo.c @@ -1,7 +1,7 @@ /* * Print Heap Information Structure * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c index eca05f19e8..264742a246 100644 --- a/cpukit/libmisc/shell/shell.c +++ b/cpukit/libmisc/shell/shell.c @@ -208,7 +208,7 @@ int rtems_shell_login(FILE * in,FILE * out) { fprintf(out,"RTEMS"); break; case 'V': - fprintf(out,"%s\n%s",_RTEMS_version,_Copyright_Notice); + fprintf(out,"%s\n%s",_RTEMS_version, _Copyright_Notice); break; case '@': fprintf(out,"@"); @@ -371,6 +371,8 @@ rtems_boolean rtems_shell_main_loop( rtems_boolean result = TRUE; rtems_boolean input_file = FALSE; int line = 0; + FILE *stdinToClose = NULL; + FILE *stdoutToClose = NULL; rtems_shell_initialize_command_set(); @@ -397,8 +399,9 @@ rtems_boolean rtems_shell_main_loop( fileno(stdout); -fprintf( stderr, - "-%s-%s-\n", shell_env->input, shell_env->output ); + /* fprintf( stderr, + "-%s-%s-\n", shell_env->input, shell_env->output ); + */ if (shell_env->output && strcmp(shell_env->output, "stdout") != 0) { if (strcmp(shell_env->output, "stderr") == 0) { @@ -414,6 +417,7 @@ fprintf( stderr, return FALSE; } stdout = output; + stdoutToClose = output; } } @@ -425,6 +429,7 @@ fprintf( stderr, return FALSE; } stdin = input; + stdinToClose = input; shell_env->forever = FALSE; input_file = TRUE; } @@ -534,8 +539,7 @@ fprintf( stderr, if ( argv[0] == NULL ) { shell_env->errorlevel = -1; } else if ( shell_cmd == NULL ) { - fprintf(stdout, "shell:%s command not found\n", argv[0]); - shell_env->errorlevel = -1; + shell_env->errorlevel = rtems_shell_script_file( argc, argv ); } else { shell_env->errorlevel = shell_cmd->command(argc, argv); } @@ -551,6 +555,10 @@ fprintf( stderr, fflush( stderr ); } } while (result && shell_env->forever); + if ( stdinToClose ) + fclose( stdinToClose ); + if ( stdoutToClose ) + fclose( stdoutToClose ); return result; } diff --git a/cpukit/libmisc/shell/shell.h b/cpukit/libmisc/shell/shell.h index 9415c5940f..2aca183138 100644 --- a/cpukit/libmisc/shell/shell.h +++ b/cpukit/libmisc/shell/shell.h @@ -73,9 +73,27 @@ int rtems_shell_make_args( int max_args ); -int rtems_shell_scanline(char * line,int size,FILE * in,FILE * out) ; -int rtems_shell_cat_file(FILE * out,char *name); -void rtems_shell_write_file(char *name,char * content); +int rtems_shell_scanline( + char *line, + int size, + FILE *in, + FILE *out +); + +int rtems_shell_cat_file( + FILE *out, + char *name +); + +void rtems_shell_write_file( + const char *name, + const char *content +); + +int rtems_shell_script_file( + int argc, + char *argv[] +); /** * Initialise the shell creating tasks to login and run the shell diff --git a/cpukit/libmisc/shell/shell_makeargs.c b/cpukit/libmisc/shell/shell_makeargs.c index 9359a634d3..35d1cf475d 100644 --- a/cpukit/libmisc/shell/shell_makeargs.c +++ b/cpukit/libmisc/shell/shell_makeargs.c @@ -1,7 +1,7 @@ /* * Split string into argc/argv style argument list * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be diff --git a/cpukit/libmisc/shell/shell_script.c b/cpukit/libmisc/shell/shell_script.c new file mode 100644 index 0000000000..a38d2aa72d --- /dev/null +++ b/cpukit/libmisc/shell/shell_script.c @@ -0,0 +1,327 @@ +/* + * Shell Script Invocation + * + * Pseudo-code from Chris Johns, implemented and debugged + * by Joel Sherrill. + * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <inttypes.h> +#include <sys/types.h> +#include <unistd.h> +#include <getopt.h> + +#include <rtems.h> +#include <rtems/shell.h> +#include "internal.h" + +static void rtems_shell_joel_usage() +{ + printf( + "joel [args] where args may be:\n" + " -o FILE output file (default=stdout)\n" + " -p PRIORITY task priority\n" + " -s SIZE task stack size\n" + " -t NAME task name\n" + ); +} + +int rtems_shell_main_decho( + int argc, + char **argv +) +{ + int i; + + for (i=0 ; i<argc ; i++ ) + printf( "argv[%d] = -%s-\n", i, argv[i] ); + return 0; +} + +static int findOnPATH( + const char *userScriptName, + char *scriptFile +) +{ + /* + * If the user script name starts with a / assume it is a fully + * qualified path name and just use it. + */ + if ( userScriptName[0] == '/' ) { + strcpy( scriptFile, userScriptName ); + return 0; + } + + /* + * For now, the provided name is just turned into a fully + * qualified path name and used. There is no attempt to + * search along a path for it. + */ + + getcwd( scriptFile, PATH_MAX ); + /* XXX should use strncat but what is the limit? */ + strcat( scriptFile, "/" ); + strcat( scriptFile, userScriptName ); + return 0; + +#if 0 + /* + * Does the command (argv[0]) contain a path ?, i.e. starts with + * '.' or contains a '/'? + */ + /* TODO: Add concept of PATH */ + if (!contains_path) { + /* check PATH environment variable */ + for (path_part = PATH; path_part; skip to ':') + { + } + if (not found) + return -1; + } +#endif +} + +int rtems_shell_main_joel( + int argc, + char **argv +) +{ + int option; + int sc; + int verbose = 0; + char *taskName = "JOEL"; + uint32_t stackSize = RTEMS_MINIMUM_STACK_SIZE * 10; + rtems_task_priority taskPriority = 20; + char *outputFile = "stdout"; + rtems_status_code result; + char scriptFile[PATH_MAX]; + struct getopt_data getopt_reent; + + while ( (option = getopt_r( argc, argv, "o:p:s:t:v", &getopt_reent)) != -1 ) { + switch ((char)option) { + case 'o': + outputFile = getopt_reent.optarg; + break; + case 'p': + taskPriority = rtems_shell_str2int(getopt_reent.optarg); + break; + case 's': + stackSize = rtems_shell_str2int(getopt_reent.optarg); + break; + case 't': + taskName = getopt_reent.optarg; + break; + case 'v': + verbose = 1; + break; + case '?': + default: + rtems_shell_joel_usage(); + return -1; + } + } + + if ( verbose ) { + fprintf( stderr, + "outputFile: %s\n" + "taskPriority: %" PRId32 "\n" + "stackSize: %" PRId32 "\n" + "taskName: %s\n", + outputFile, + taskPriority, + stackSize, + taskName + ); + } + + /* + * Verify there is a script name past the end of the arguments. + * Preincrement to skip program name. + */ + if ( getopt_reent.optind >= argc ) { + fprintf( stderr, "Shell: No script to execute\n" ); + return -1; + } + + /* + * Find script on the path. + * + * NOTE: It is terrible that this is done twice but it + * seems to be the most expedient thing. + */ + sc = findOnPATH( argv[getopt_reent.optind], scriptFile ); + if ( sc ) { + fprintf( stderr, "%s not found on PATH\n", argv[0] ); + return -1; + } + + /* fprintf( stderr, "SCRIPT: -%s-\n", scriptFile ); */ + + /* + * I assume that argv[optind...] will have the arguments to + * the shell script. But that remains to be implemented. + */ + + /* + * Run the script + */ + result = rtems_shell_script( + taskName, /* the name of the task */ + stackSize, /* stack size */ + taskPriority, /* task priority */ + scriptFile, /* the script file */ + outputFile, /* where to redirect the script */ + 0, /* run once and exit */ + 1 /* we will wait */ + ); + if (result) + return -1; + return 0; +} + +rtems_shell_cmd_t rtems_shell_JOEL_Command = { + "joel", /* name */ + "joel [args] SCRIPT", /* usage */ + "misc", /* topic */ + rtems_shell_main_joel, /* command */ + NULL, /* alias */ + NULL /* next */ +}; + +/* + * This is a helper function which takes a command as arguments + * which has not been located as a built-in command and attempts + * to find something in the filesystem with the same name that + * appears to be a shell script. + */ +int rtems_shell_script_file( + int argc, + char *argv[] +) +{ + #define FIRST_LINE_LENGTH 128 + #define SCRIPT_ARGV_LIMIT 32 + char scriptFile[PATH_MAX]; + char *scriptHead; + char scriptHeadBuffer[FIRST_LINE_LENGTH]; + int sc; + FILE *script; + size_t length; + int scriptArgc; + char *scriptArgv[SCRIPT_ARGV_LIMIT]; + + /* + * Clear argv pointer array + */ + for ( scriptArgc=0 ; scriptArgc<SCRIPT_ARGV_LIMIT ; scriptArgc++ ) + scriptArgv[scriptArgc] = NULL; + + /* + * Find argv[0] on the path + */ + sc = findOnPATH( argv[0], scriptFile ); + if ( sc ) { + fprintf( stderr, "%s not found on PATH\n", argv[0] ); + return -1; + } + + /* + * Open the file so we can see if it looks like a script. + */ + script = fopen( scriptFile, "r" ); + if ( !script ) { + fprintf( stderr, "%s: Unable to open %s\n", argv[0], scriptFile ); + return -1; + } + + /* + * Is the script OK to run? + * Verify the current user has permission to execute it. + * + * NOTE: May not work on all file systems + */ + sc = access( scriptFile, X_OK ); + if ( sc ) { + fprintf( stderr, "Unable to execute %s\n", scriptFile ); + fclose( script ); + return -1; + } + + /* + * Try to read the first line from the potential script file + */ + scriptHead = fgets(scriptHeadBuffer, FIRST_LINE_LENGTH, script); + if ( !scriptHead ) { + fprintf( + stderr, "%s: Unable to read first line of %s\n", argv[0], scriptFile ); + fclose( script ); + return -1; + } + + fclose(script); + + length = strnlen(scriptHead, FIRST_LINE_LENGTH); + scriptHead[length - 1] = '\0'; + + /* fprintf( stderr, "FIRST LINE: -%s-\n", scriptHead ); */ + + /* + * Verify the name of the "shell" is joel. This means + * the line starts with "#! joel". + */ + if (strncmp("#! joel", scriptHead, 7) != 0) { + fprintf( stderr, "%s: Not a joel script %s\n", argv[0], scriptFile ); + return -1; + } + + /* + * Do not worry about search path further. We have found the + * script, it is executable, and we have successfully read the + * first line and found out it is a script. + */ + + /* + * Check for arguments in fist line of the script. This changes + * how the shell task is run. + */ + + sc = rtems_shell_make_args( + &scriptHead[3], + &scriptArgc, + scriptArgv, + SCRIPT_ARGV_LIMIT - 1 + ); + if ( sc ) { + fprintf( + stderr, "%s: Error parsing joel arguments %s\n", argv[0], scriptFile ); + return -1; + } + + scriptArgv[ scriptArgc++ ] = scriptFile; + + /* + * TODO: How do we pass arguments from here to the script? + * At this point, it doesn't matter because we don't + * have any way for a shell script to access them. + */ + return rtems_shell_main_joel( scriptArgc, scriptArgv ); + + return 0; +} + diff --git a/cpukit/libmisc/shell/shellconfig.c b/cpukit/libmisc/shell/shellconfig.c index f3448ee693..1272ae8380 100644 --- a/cpukit/libmisc/shell/shellconfig.c +++ b/cpukit/libmisc/shell/shellconfig.c @@ -1,6 +1,9 @@ /* * RTEMS Shell Command Set -- DEFAULT Configuration * + * COPYRIGHT (c) 1989-2008. + * On-Line Applications Research Corporation (OAR). + * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at * http://www.rtems.com/license/LICENSE. diff --git a/cpukit/libmisc/shell/shellconfig.h b/cpukit/libmisc/shell/shellconfig.h index 33d60f7e28..3cde53ffc4 100644 --- a/cpukit/libmisc/shell/shellconfig.h +++ b/cpukit/libmisc/shell/shellconfig.h @@ -29,7 +29,10 @@ extern rtems_shell_cmd_t rtems_shell_MEDIT_Command; extern rtems_shell_cmd_t rtems_shell_MFILL_Command; extern rtems_shell_cmd_t rtems_shell_MMOVE_Command; +extern rtems_shell_cmd_t rtems_shell_JOEL_Command; extern rtems_shell_cmd_t rtems_shell_DATE_Command; +extern rtems_shell_cmd_t rtems_shell_ECHO_Command; +extern rtems_shell_cmd_t rtems_shell_SLEEP_Command; extern rtems_shell_cmd_t rtems_shell_ID_Command; extern rtems_shell_cmd_t rtems_shell_TTY_Command; extern rtems_shell_cmd_t rtems_shell_WHOAMI_Command; @@ -144,11 +147,26 @@ extern rtems_shell_filesystems_t *rtems_shell_Mount_filesystems[]; * Common commands that can be optional */ #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \ + !defined(CONFIGURE_SHELL_NO_COMMAND_JOEL)) || \ + defined(CONFIGURE_SHELL_COMMAND_JOEL) + &rtems_shell_JOEL_Command, + #endif + #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \ !defined(CONFIGURE_SHELL_NO_COMMAND_DATE)) || \ defined(CONFIGURE_SHELL_COMMAND_DATE) &rtems_shell_DATE_Command, #endif #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \ + !defined(CONFIGURE_SHELL_NO_COMMAND_ECHO)) || \ + defined(CONFIGURE_SHELL_COMMAND_ECHO) + &rtems_shell_ECHO_Command, + #endif + #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \ + !defined(CONFIGURE_SHELL_NO_COMMAND_SLEEP)) || \ + defined(CONFIGURE_SHELL_COMMAND_SLEEP) + &rtems_shell_SLEEP_Command, + #endif + #if (defined(CONFIGURE_SHELL_COMMANDS_ALL) && \ !defined(CONFIGURE_SHELL_NO_COMMAND_ID)) || \ defined(CONFIGURE_SHELL_COMMAND_ID) &rtems_shell_ID_Command, diff --git a/cpukit/libmisc/shell/write_file.c b/cpukit/libmisc/shell/write_file.c index e294ad99b6..f9e72f4645 100644 --- a/cpukit/libmisc/shell/write_file.c +++ b/cpukit/libmisc/shell/write_file.c @@ -23,13 +23,17 @@ #include <string.h> void rtems_shell_write_file( - char *name, - char * content + const char *name, + const char *content ) { FILE * fd; fd = fopen(name,"w"); + if ( !fd ) { + fprintf( stderr, "Unable to write %s\n", name ); + } + if (fd) { fwrite(content,1,strlen(content),fd); fclose(fd); |