Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 3264 → Rev 3265

/branches/shell/uspace/app/bdsh/scli.h
0,0 → 1,20
#ifndef SCLI_H
#define SCLI_H
 
#include "config.h"
#include <stdint.h>
 
typedef struct {
char *name;
char *home;
char *line;
char *cwd;
char *prompt;
uint64_t lasterr;
} cliuser_t;
 
extern int cli_set_prompt(cliuser_t *usr);
extern int cli_init(cliuser_t *usr);
extern void cli_finit(cliuser_t *usr);
 
#endif
/branches/shell/uspace/app/bdsh/input.c
0,0 → 1,177
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
* Copyright (c) 2008, Jiri Svoboda - All Rights Reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#ifdef HELENOS
#include <io/stream.h>
#endif
 
#include "config.h"
#include "util.h"
#include "scli.h"
#include "input.h"
#include "errors.h"
#include "exec.h"
 
extern volatile unsigned int cli_interactive;
 
/* More than a macro than anything */
void cli_restricted(char *cmd)
{
cli_verbose("%s is not available in %s mode\n", cmd,
cli_interactive ? "interactive" : "non-interactive");
 
return;
}
 
/* Tokenizes input from console, sees if the first word is a built-in, if so
* invokes the built-in entry point (a[0]) passing all arguments in a[] to
* the handler */
int tok_input(cliuser_t *usr)
{
char *cmd[WORD_MAX];
int n = 0, i = 0;
int rc = 0;
char *tmp = cli_strdup(usr->line);
 
if (NULL == usr->line) {
rc = CL_EFAIL;
goto finit;
}
 
/* Break up what the user typed, space delimited */
cmd[n] = cli_strtok(tmp, " ");
while (cmd[n] && n < WORD_MAX) {
cmd[++n] = cli_strtok(NULL, " ");
}
 
/* We have rubbish */
if (NULL == cmd[0]) {
rc = CL_ENOENT;
goto finit;
}
 
/* Check what kind of command argv[0] might be */
if ((i = (is_builtin(cmd[0]))) > -1) {
/* Its a builtin */
if (builtin_is_restricted(i)) {
/* Try an external command matching argv[0] */
rc = try_exec(cmd[0], cmd);
if (rc)
cli_restricted(cmd[0]);
goto finit;
}
rc = run_builtin(i, cmd, usr);
goto finit;
} else if ((i = (is_module(cmd[0]))) > -1) {
/* Its a module, it can't modify cliuser_t */
if (module_is_restricted(i)) {
rc = try_exec(cmd[0], cmd);
if (rc)
cli_restricted(cmd[0]);
goto finit;
}
rc = run_module(i, cmd);
goto finit;
} else {
/* See what try_exec() thinks of it */
rc = try_exec(cmd[0], cmd);
goto finit;
}
 
finit:
if (NULL != usr->line) {
free(usr->line);
usr->line = (char *) NULL;
}
free(tmp);
return rc;
}
 
#ifdef HELENOS
/* Borrowed from Jiri Svoboda's 'cli' uspace app */
void read_line(char *buffer, int n)
{
char c;
int chars;
 
chars = 0;
while (chars < n - 1) {
c = getchar();
if (c < 0)
return;
if (c == '\n')
break;
if (c == '\b') {
if (chars > 0) {
putchar('\b');
--chars;
}
continue;
}
putchar(c);
buffer[chars++] = c;
}
putchar('\n');
buffer[chars] = '\0';
}
#endif
 
/* This is soupy, fix me */
void get_input(cliuser_t *usr)
{
char line[INPUT_MAX];
size_t len = 0;
 
printf("%s", usr->prompt);
#ifdef HELENOS
read_line(line, INPUT_MAX);
#else
fgets(line, INPUT_MAX, stdin);
#endif
len = strlen(line);
/* Make sure we don't have rubbish or a C/R happy user */
if (len == 0)
return;
if (len == 1 && line[len-1] == '\n')
return;
#ifndef HELENOS
/* Null terminate line */
if (len > 0 && line[len-1] == '\n')
line[len-1] = '\0';
#endif
usr->line = cli_strdup(line);
return;
}
 
/branches/shell/uspace/app/bdsh/LICENSE
0,0 → 1,28
Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
 
Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
 
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.
 
Neither the name of the original program's authors 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.
/branches/shell/uspace/app/bdsh/input.h
0,0 → 1,15
#ifndef INPUT_H
#define INPUT_H
 
#include "cmds/cmds.h"
 
/* prototypes */
extern int tok_input(cliuser_t *);
extern void get_input(cliuser_t *);
extern void cli_restricted(char *);
 
#ifdef HELENOS
extern void read_line(char *, int);
#endif
 
#endif
/branches/shell/uspace/app/bdsh/AUTHORS
0,0 → 1,7
This sample CLI was originally inspired by the HelenOS testing sub system
written by Martin Decky.
 
This program, itself was written by Tim Post (modules, built ins, replacement
libraries, handlers, etc).
 
This program uses the GNU Autoconf program which was developed by the GNU project.
/branches/shell/uspace/app/bdsh/cmds/mknewcmd
0,0 → 1,344
#!/bin/sh
# Copyright (C) 2008 Tim Post - All Rights Reserved
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 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.
#
# Neither the name of the original program's authors 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.
 
# Script to generate skeletal files for a new command
# Uses `getopt', not quite a bash-ism but might be
# lacking on some legacy systems.
 
# If your shell does not support eval, shift (x) or
# here-now documents, sorry :)
 
usage()
{
def="$DEFAULT_COMMAND"
cat << EOF
\`$PROGNAME' generates skeletal command files to simplify adding commands
Usage: $PROGNAME [options] <location>
Options:
-n, --name Name of the command (default: ${def})
-d, --desc Short (20 30 chars) description of the command
(def: "The $def command")
-e, --entry Entry function of the command (def: cmd_${def})
-h, --help-entry Entry function for command help (def: help_cmd_${def})
-a, --alias Alias (nickname) for this command (def: none)
-r, --restrict Restriction level (interactive, non-interactive, both)
(def: module is both, builtin is interactive only)
-t, --type Type of command (module or builtin) (def: module)
-H, --help This help summary
-V, --version Print $PROGNAME version and exit normally
 
Notes:
You must supply at least the name of the command.
 
If you do not specify a location (i.e. modules/foo), the command will be
created in modules/command_name or builtins/command_name depending on your
selection.
 
This script will only create skeletal files and inform you what headers
need to be modified to incorporate the command. You will also have to
manually update the main Makefile.
 
This script is intended only to be a convenience for developers. Example use:
$PROGNAME -n foo -d "Foo power" -a bar -r both -t module modules/foo
 
The example would generate a modular command named 'foo', which is also
reached by typing 'bar' and available in either interactive or noninteractive
mode.
 
Skeletal files do *not* depend on the autoconf generated "config.h" unless you
include it. This may or may not be desirable depending on your use.
 
Report bugs to $PROGMAINT
 
EOF
}
 
# Convert a string to all uppercase
toupper()
{
local str="$1"
 
echo "${str}" | tr 'a-z' 'A-Z'
}
 
# Template stored `here-now' style, this generates all files needed
# for a new command according to arguments passed.
generate_code()
{
echo "Creating ${OUTDIR}/${CMDNAME}.def ..."
cat << EOF > ${OUTDIR}/${CMDNAME}.def
{
"${CMDNAME}",
"${CMDDESC}",
&${CMDENTRY},
&${HELPENTRY},
${CMDRESTRICT}
},
 
EOF
[ -n "${CMDALIAS}" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}.def
{
"${CMDALIAS}",
NULL,
&${CMDENTRY},
&${HELPENTRY},
${CMDRESTRICT}
},
 
EOF
local defname=$(toupper "${CMDNAME}")
echo "Creating ${OUTDIR}/entry.h ..."
cat << EOF > ${OUTDIR}/entry.h
#ifndef ${defname}_ENTRY_H
#define ${defname}_ENTRY_H
 
EOF
[ "${CMDTYPE}" = "module" ] && cat << EOF >> ${OUTDIR}/entry.h
/* Entry points for the ${CMDNAME} command */
extern int * ${CMDENTRY}(char **);
extern void * ${HELPENTRY}(unsigned int);
 
#endif /* ${defname}_ENTRY_H */
 
EOF
[ "${CMDTYPE}" = "builtin" ] && cat << EOF >> ${OUTDIR}/entry.h
/* Pick up cliuser_t */
#include "scli.h"
 
/* Entry points for the ${CMDNAME} command */
extern int * ${CMDENTRY}(char **, cliuser_t *);
extern void * ${HELPENTRY}(unsigned int);
 
#endif /* ${defname}_ENTRY_H */
 
EOF
echo "Creating ${OUTDIR}/${CMDNAME}.h ..."
cat << EOF > ${OUTDIR}/${CMDNAME}.h
#ifndef ${defname}_H
#define ${defname}_H
 
/* Prototypes for the ${CMDNAME} command, excluding entry points */
 
 
#endif /* ${defname}_H */
 
EOF
echo "Creating ${OUTDIR}/${CMDNAME}.c ..."
cat << EOF > ${OUTDIR}/${CMDNAME}.c
/* Automatically generated by ${PROGNAME} on ${TIMESTAMP}
* This is machine generated output. The author of ${PROGNAME} claims no
* copyright over the contents of this file. Where legally permitted, the
* contents herein are donated to the public domain.
*
* You should apply any license and copyright that you wish to this file,
* replacing this header in its entirety. */
 
#include <stdio.h>
#include <stdlib.h>
#include "entry.h"
#include "${CMDNAME}.h"
#include "cmds.h"
 
static char *cmdname = "${CMDNAME}";
 
/* Dispays help for ${CMDNAME} in various levels */
void * ${HELPENTRY}(unsigned int level)
{
printf("This is the %s help for '%s'.\n",
level ? EXT_HELP : SHORT_HELP, cmdname);
return 0;
}
 
EOF
[ "${CMDTYPE}" = "module" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}.c
/* Main entry point for ${CMDNAME}, accepts an array of arguments */
int * ${CMDENTRY}(char **argv)
EOF
[ "${CMDTYPE}" = "builtin" ] && cat << EOF >> ${OUTDIR}/${CMDNAME}.c
/* Main entry point for ${CMDNAME}, accepts an array of arguments and a
* pointer to the cliuser_t structure */
int * ${CMDENTRY}(char **argv, cliuser_t *usr)
EOF
cat << EOF >> ${OUTDIR}/${CMDNAME}.c
{
unsigned int argc;
unsigned int i;
 
/* Count the arguments */
for (argc = 0; argv[argc] != NULL; argc ++);
 
printf("%s %s\n", TEST_ANNOUNCE, cmdname);
printf("%d arguments passed to %s", argc - 1, cmdname);
 
if (argc < 2) {
printf("\n");
return 0;
}
 
printf(":\n");
for (i = 1; i < argc; i++)
printf("[%d] -> %s\n", i, argv[i]);
 
return 0;
}
 
EOF
printf "Done.\n\nYou should now modify %ss/%ss.h and ../Makefile.in" \
"${CMDTYPE}" "${CMDTYPE}"
printf " to include your new command.\n"
[ -n "$CMDALIAS" ] && {
printf "\nYou should also modify %ss/%s_aliases.h and " \
"${CMDTYPE}" "${CMDTYPE}"
printf "add %s as an alias for %s\n" \
"${CMDALIAS}" "${CMDNAME}"
}
printf "\nOnce completed, re-run configure or configure.sub and make\n\n"
}
 
# Main program
 
TIMESTAMP="$(date)"
PROGNAME=$(basename $0)
PROGVER="0.0.1"
PROGMAINT="Tim Post <echo@echoreply.us>"
DEFAULT_COMMAND="cmdname"
 
# We need at least one
[ $# = 0 ] && usage && exit 1;
 
TEMP=$(getopt -o n:d:e:h:a:r:t:HV \
--long name:,desc:,entry:,help-entry:,alias:,restrict:,type:,help,version \
-- "$@") || {
echo "Try $PROGNAME --help for help"
}
 
eval set -- "$TEMP"
 
while true; do
case "$1" in
-n | --name)
CMDNAME="$2"
shift 2
continue
;;
-d | --desc)
CMDDESC="$2"
shift 2
continue
;;
-e | --entry)
CMDENTRY="$2"
shift 2
continue
;;
-h | --help-entry)
HELPENTRY="$2"
shift 2
continue
;;
-a | --alias)
CMDALIAS="$2"
shift 2
continue
;;
-r | --restrict)
CMDRESTRICT="$2"
shift 2
continue
;;
-t | --type)
CMDTYPE="$2"
shift 2
continue
;;
-H | --help)
usage
exit 0
;;
-V | --version)
echo "$PROGVER"
exit 0
;;
--)
break
;;
esac
done
 
# Pick up a location if one was specified
eval set -- "$*"
[ -n "$2" ] && OUTDIR="$2"
 
# Fill in defaults for whatever was not specified
[ -n "$CMDNAME" ] || CMDNAME="$DEFAULT_COMMAND"
[ -n "$CMDDESC" ] || CMDDESC="The $CMDNAME command"
[ -n "$CMDENTRY" ] || CMDENTRY="cmd_${CMDNAME}"
[ -n "$HELPENTRY" ] || HELPENTRY="help_cmd_${CMDNAME}"
[ -n "$CMDTYPE" ] || CMDTYPE="module"
[ -n "$OUTDIR" ] || OUTDIR="${CMDTYPE}s/${CMDNAME}"
 
# Builtins typically only need to be available in interactive mode,
# set the default accordingly.
[ -n "$CMDRESTRICT" ] || {
[ "$CMDTYPE" = "module" ] && CMDRESTRICT="both"
[ "$CMDTYPE" = "builtin" ] && CMDRESTRICT="interactive"
}
 
# Set the restriction level as the structure expects to see it
case "$CMDRESTRICT" in
0 | both)
CMDRESTRICT="0"
;;
1 | non-interactive)
CMDRESTRICT="1"
;;
-1 | interactive)
CMDRESTRICT="-1"
;;
*)
usage
exit 1
;;
esac
 
# Do a little sanity
[ -d $OUTDIR ] && {
echo "$OUTDIR already exists, remove it to proceed."
exit 1
}
 
mkdir -p ${OUTDIR} >/dev/null 2>&1 || {
echo "Could not create ${OUTDIR}, aborting!"
exit 1
}
 
# Generate the files and inform on how to include them based on options
generate_code
 
exit 0
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/branches/shell/uspace/app/bdsh/cmds/mod_cmds.c
0,0 → 1,156
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
/* NOTES:
* module_* functions are pretty much identical to builtin_* functions at this
* point. On the surface, it would appear that making each function dual purpose
* would be economical.
*
* These are kept separate because the structures (module_t and builtin_t) may
* grow apart and become rather different, even though they're identical at this
* point.
*
* To keep things easy to hack, everything is separated. In reality this only adds
* 6 - 8 extra functions, but keeps each function very easy to read and modify. */
 
/* TODO:
* Many of these could be unsigned, provided the modules and builtins themselves
* can follow suit. Long term goal. */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "errors.h"
#include "cmds.h"
#include "module_aliases.h"
 
extern volatile unsigned int cli_interactive;
 
int module_is_restricted(int pos)
{
/* Restriction Levels:
* -1 -> Available only in interactive mode
* 0 -> Available in any mode
* 1 -> Available only in non-interactive mode */
 
module_t *mod = modules;
mod += pos;
/* We're interactive, and the module is OK to run */
if (cli_interactive && mod->restricted <= 0)
return 0;
/* We're not interactive, and the module is OK to run */
if (!cli_interactive && mod->restricted >= 0)
return 0;
 
/* Anything else is just a big fat no :) */
return 1;
}
 
/* Checks if an entry function matching command exists in modules[], if so
* its position in the array is returned */
int is_module(const char *command)
{
module_t *mod;
unsigned int i = 0;
 
if (NULL == command)
return -2;
 
for (mod = modules; mod->name != NULL; mod++, i++) {
if (!strcmp(mod->name, command))
return i;
}
 
return -1;
}
 
/* Checks if a module is an alias (sharing an entry point with another
* module). Returns 1 if so */
int is_module_alias(const char *command)
{
unsigned int i = 0;
 
if (NULL == command)
return -1;
 
for(i=0; mod_aliases[i] != NULL; i+=2) {
if (!strcmp(mod_aliases[i], command))
return 1;
}
 
return 0;
}
 
/* Returns the name of the module that an alias points to */
char *alias_for_module(const char *command)
{
unsigned int i = 0;
 
if (NULL == command)
return (char *)NULL;
 
for(i=0; mod_aliases[i] != NULL; i++) {
if (!strcmp(mod_aliases[i], command))
return (char *)mod_aliases[++i];
i++;
}
 
return (char *)NULL;
}
 
 
/* Invokes the 'help' entry function for the module at position (int) module,
* which wants an unsigned int to determine brief or extended display. */
int help_module(int module, unsigned int extended)
{
module_t *mod = modules;
 
mod += module;
 
if (NULL != mod->help) {
mod->help(extended);
return CL_EOK;
} else
return CL_ENOENT;
}
 
/* Invokes the module entry point modules[module], passing argv[] as an argument
* stack. */
int run_module(int module, char *argv[])
{
module_t *mod = modules;
 
mod += module;
 
if (NULL != mod->entry)
return ((int)mod->entry(argv));
 
return CL_ENOENT;
}
/branches/shell/uspace/app/bdsh/cmds/modules/quit/quit.def
0,0 → 1,14
{
"quit",
"Exit the console",
&cmd_quit,
&help_cmd_quit,
-1
},
{
"exit",
NULL,
&cmd_quit,
&help_cmd_quit,
-1
},
/branches/shell/uspace/app/bdsh/cmds/modules/quit/quit.c
0,0 → 1,56
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include "entry.h"
#include "quit.h"
#include "cmds.h"
 
static char *cmdname = "quit";
unsigned int cli_quit = 0;
 
extern volatile int cli_lasterror;
extern const char *progname;
 
void * help_cmd_quit(unsigned int level)
{
printf("Type `%s' to exit %s\n", cmdname, progname);
return CMD_VOID;
}
 
/* Quits the program and returns the status of whatever command
* came before invoking 'quit' */
int * cmd_quit(char *argv[])
{
/* Inform that we're outta here */
cli_quit = 1;
return CMD_SUCCESS;
}
/branches/shell/uspace/app/bdsh/cmds/modules/quit/entry.h
0,0 → 1,10
#ifndef QUIT_ENTRY_H_
#define QUIT_ENTRY_H_
 
/* Entry points for the quit command */
extern void * help_cmd_quit(unsigned int);
extern int * cmd_quit(char *[]);
 
#endif
 
 
/branches/shell/uspace/app/bdsh/cmds/modules/quit/quit.h
0,0 → 1,6
#ifndef QUIT_H
#define QUIT_H
 
/* Prototypes for the quit command (excluding entry points) */
 
#endif
/branches/shell/uspace/app/bdsh/cmds/modules/help/help.def
0,0 → 1,7
{
"help",
"Show help for commands",
&cmd_help,
&help_cmd_help,
0
},
/branches/shell/uspace/app/bdsh/cmds/modules/help/entry.h
0,0 → 1,8
#ifndef HELP_ENTRY_H_
#define HELP_ENTRY_H_
 
/* Entry points for the help command */
extern void * help_cmd_help(unsigned int);
extern int * cmd_help(char *[]);
 
#endif
/branches/shell/uspace/app/bdsh/cmds/modules/help/help.c
0,0 → 1,165
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "entry.h"
#include "help.h"
#include "cmds.h"
#include "modules.h"
#include "builtins.h"
#include "errors.h"
 
const char *cmdname = "help";
extern const char *progname;
extern unsigned int cli_interactive;
 
#define HELP_IS_MODULE 1
#define HELP_IS_BUILTIN 0
#define HELP_IS_RUBBISH -1
 
volatile int mod_switch = -1;
 
/* Just use a pointer here, no need for mod_switch */
int is_mod_or_builtin(char *cmd)
{
int rc = HELP_IS_RUBBISH;
 
rc = is_builtin(cmd);
if (rc > -1) {
mod_switch = rc;
return HELP_IS_BUILTIN;
}
rc = is_module(cmd);
if (rc > -1) {
mod_switch = rc;
return HELP_IS_MODULE;
}
 
return HELP_IS_RUBBISH;
}
 
void *help_cmd_help(unsigned int level)
{
if (level == HELP_SHORT) {
printf(
"\n %s [command] <extended>\n"
" Use help [command] extended for detailed help on [command] "
", even `help'\n\n", cmdname);
} else {
printf(
"\n `%s' - shows help for commands\n"
" Examples:\n"
" %s [command] Show help for [command]\n"
" %s [command] extended Show extended help for [command]\n"
"\n If no argument is given to %s, a list of commands are shown\n\n",
cmdname, cmdname, cmdname, cmdname);
}
 
return CMD_VOID;
}
 
int *cmd_help(char *argv[])
{
module_t *mod;
builtin_t *cmd;
unsigned int i = 0;
int rc = 0;
int argc;
int level = HELP_SHORT;
 
for (argc = 0; argv[argc] != NULL; argc ++);
 
if (argc > 3) {
printf("\nToo many arguments to `%s', try:\n", cmdname);
help_cmd_help(HELP_SHORT);
return CMD_FAILURE;
}
 
if (argc == 3) {
if (!strcmp("extended", argv[2]))
level = HELP_LONG;
else
level = HELP_SHORT;
}
 
if (argc > 1) {
rc = is_mod_or_builtin(argv[1]);
switch (rc) {
case HELP_IS_RUBBISH:
printf("Invalid command %s\n", argv[1]);
return CMD_FAILURE;
case HELP_IS_MODULE:
help_module(mod_switch, level);
return CMD_SUCCESS;
case HELP_IS_BUILTIN:
help_builtin(mod_switch, level);
return CMD_SUCCESS;
}
}
 
printf("%sAvailable commands are:\n", cli_interactive ? "\n " : "");
if (cli_interactive)
printf(
" ------------------------------------------------------------\n");
 
/* First, show a list of built in commands that are available in this mode */
for (cmd = builtins; cmd->name != NULL; cmd++, i++) {
if (!builtin_is_restricted(i)) {
if (is_builtin_alias(cmd->name))
printf(" %-16s\tAlias for `%s'\n", cmd->name,
alias_for_builtin(cmd->name));
else
printf(" %-16s\t%s\n", cmd->name, cmd->desc);
}
}
 
i = 0;
 
/* Now, show a list of module commands that are available in this mode */
for (mod = modules; mod->name != NULL; mod++, i++) {
if (!module_is_restricted(i)) {
if (is_module_alias(mod->name))
printf(" %-16s\tAlias for `%s'\n", mod->name,
alias_for_module(mod->name));
else
printf(" %-16s\t%s\n", mod->name, mod->desc);
}
}
 
/* Provide a little more information and inform them of history / line
* editing features if they are present */
if (cli_interactive)
printf("\n Try %s %s for more information on how `%s' works.\n\n",
cmdname, cmdname, cmdname);
 
return CMD_SUCCESS;
}
/branches/shell/uspace/app/bdsh/cmds/modules/help/help.h
0,0 → 1,7
#ifndef HELP_H
#define HELP_H
 
/* Prototypes for the help command (excluding entry points) */
extern int is_mod_or_builtin(char *);
 
#endif
/branches/shell/uspace/app/bdsh/cmds/modules/module_aliases.h
0,0 → 1,19
#ifndef MODULE_ALIASES_H
#define MODULE_ALIASES_H
 
/* Modules that declare multiple names for themselves but use the
* same entry functions are aliases. This array helps to determine if
* a module is an alias, as such it can be invoked differently.
* format is alias , real_name */
 
/* So far, this is only used in the help display but could be used to
* handle a module differently even prior to reaching its entry code.
* For instance, 'exit' could behave differently than 'quit', prior to
* the entry point being reached. */
 
char *mod_aliases[] = {
"exit", "quit",
NULL, NULL
};
 
#endif
/branches/shell/uspace/app/bdsh/cmds/modules/README
0,0 → 1,8
Modules are commands or full programs (anything can be made into a module that can return
int type) should go here. Note, modules do not update the structures containing user info
such as the working directory, euid, etc.
 
Stuff that needs to write to the user structures contained in scli.h should be made as
built-in commands, not modules.
 
 
/branches/shell/uspace/app/bdsh/cmds/modules/modules.h
0,0 → 1,33
#ifndef MODULES_H
#define MODULES_H
 
/* Each built in function has two files, one being an entry.h file which
* prototypes the run/help entry functions, the other being a .def file
* which fills the modules[] array according to the cmd_t structure
* defined in cmds.h.
*
* To add or remove a module, just make a new directory in cmds/modules
* for it and copy the 'show' example for basics, then include it here.
* (or reverse the process to remove one)
*
* NOTE: See module_ aliases.h as well, this is where aliases (commands that
* share an entry point with others) are indexed */
 
#include "config.h"
 
/* Prototypes for each module's entry (help/exec) points */
 
#include "help/entry.h"
#include "quit/entry.h"
 
/* Each .def function fills the module_t struct with the individual name, entry
* point, help entry point, etc. You can use config.h to control what modules
* are loaded based on what libraries exist on the system. */
 
module_t modules[] = {
#include "help/help.def"
#include "quit/quit.def"
{NULL, NULL, NULL, NULL}
};
 
#endif
/branches/shell/uspace/app/bdsh/cmds/builtins/builtins.h
0,0 → 1,15
#ifndef BUILTINS_H
#define BUILTINS_H
 
#include "config.h"
 
#include "pwd/entry.h"
#include "cd/entry.h"
 
builtin_t builtins[] = {
#include "pwd/pwd.def"
#include "cd/cd.def"
{NULL, NULL, NULL, NULL}
};
 
#endif
/branches/shell/uspace/app/bdsh/cmds/builtins/cd/cd.def
0,0 → 1,14
{
"cd",
"Change the current working directory",
&cmd_cd,
&help_cmd_cd,
-1
},
{
"chdir",
NULL,
&cmd_cd,
&help_cmd_cd,
-1
},
/branches/shell/uspace/app/bdsh/cmds/builtins/cd/cd.c
0,0 → 1,111
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/errno.h>
#include "util.h"
#include "errors.h"
#include "entry.h"
#include "cmds.h"
#include "cd.h"
 
static char * cmdname = "cd";
 
void * help_cmd_cd(unsigned int level)
{
if (level == HELP_SHORT) {
printf("`%s' changes the current working directory.\n", cmdname);
} else {
printf(
" %s [-L|-P] [dir]\n"
" Your home directory is the default if [dir] is not provided.\n"
" The -P option specifies to always use the physical directory\n"
" structure instead of following symbolic links. The -L option\n"
" is the exact reverse of -P, symbolic links will be forced.\n"
" Note: -L|-P are not yet implemented\n", cmdname);
}
 
return CMD_VOID;
}
 
/* This is a very rudamentary 'cd' command. It is not 'link smart' (yet) */
 
int * cmd_cd(char *argv[], cliuser_t *usr)
{
int argc, rc = 0;
char *dest = NULL;
 
for (argc = 0; argv[argc] != NULL; argc ++);
 
/* Someone just typed 'cd' , send them home */
 
if (argc < 2)
dest = cli_strdup(usr->home);
 
/* We don't yet play nice with whitespace, a getopt implementation should
* protect "quoted\ destination" as a single argument. Its not our job to
* look for && || or redirection as the tokenizer should have done that
* (currently, it does not) */
 
if (argc > 2) {
cli_error(CL_EFAIL, "Too many arguments to `%s'", cmdname);
return CMD_FAILURE;
}
 
/* We have the correct # of arguments
* TODO: handle tidle (~) expansion? */
 
if (argc == 2)
dest = cli_strdup(argv[1]);
 
rc = chdir(dest);
if (rc == 0) {
free(dest);
return CMD_SUCCESS;
} else {
free(dest);
switch (rc) {
case ENOMEM:
cli_error(CL_EFAIL, "Destination path too long");
break;
case ENOENT:
cli_error(CL_ENOENT, "Invalid directory `%s'", argv[1]);
break;
default:
cli_error(CL_EFAIL, "Unable to change to `%s'", argv[1]);
break;
}
}
 
return CMD_FAILURE;
}
/branches/shell/uspace/app/bdsh/cmds/builtins/cd/entry.h
0,0 → 1,12
#ifndef CD_ENTRY_H_
#define CD_ENTRY_H_
 
#include "scli.h"
 
/* Entry points for the cd command */
extern void * help_cmd_cd(unsigned int);
extern int * cmd_cd(char *[], cliuser_t *);
 
#endif
 
 
/branches/shell/uspace/app/bdsh/cmds/builtins/cd/cd.h
0,0 → 1,7
#ifndef CD_H
#define CD_H
 
/* Prototypes for the cd command (excluding entry points) */
 
 
#endif
/branches/shell/uspace/app/bdsh/cmds/builtins/pwd/pwd.h
0,0 → 1,6
#ifndef PWD_H_
#define PWD_H_
 
/* Prototypes for the pwd command (excluding entry points) */
 
#endif
/branches/shell/uspace/app/bdsh/cmds/builtins/pwd/entry.h
0,0 → 1,12
#ifndef PWD_ENTRY_H
#define PWD_ENTRY_H
 
#include "scli.h"
 
/* Entry points for the pwd command */
extern void * help_cmd_pwd(unsigned int);
extern int * cmd_pwd(char *[], cliuser_t *);
 
#endif
 
 
/branches/shell/uspace/app/bdsh/cmds/builtins/pwd/pwd.def
0,0 → 1,7
{
"pwd",
"Prints the current working directory",
&cmd_pwd,
&help_cmd_pwd,
-1
},
/branches/shell/uspace/app/bdsh/cmds/builtins/pwd/pwd.c
0,0 → 1,54
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include "entry.h"
#include "cmds.h"
#include "pwd.h"
 
static char * cmdname = "pwd";
 
void * help_cmd_pwd(unsigned int level)
{
printf("`%s' prints your current working directory.\n", cmdname);
return CMD_VOID;
}
int * cmd_pwd(char *argv[], cliuser_t *usr)
{
if (usr->cwd) {
printf("%s\n", usr->cwd);
return CMD_SUCCESS;
} else
printf("/twilight/zone\n");
 
return CMD_FAILURE;
}
/branches/shell/uspace/app/bdsh/cmds/builtins/README
0,0 → 1,16
Commands that need to modify the running user structure defined in scli.h
should reside here. They (will) have a slightly different prototype that
allows passing the user structure to them for ease of modifications.
 
Examples of what should be a built-in and not a module would be:
 
cd (the cwd needs to be updated)
prompt (the prompt needs to be updated)
enable (the euid needs to be updated)
 
.... etc.
 
Anything that does _not_ need to write to this structure should be included
as a module, not a built in.
 
For now, a skeleton directory of stuff that will exist lives here.
/branches/shell/uspace/app/bdsh/cmds/builtins/builtin_aliases.h
0,0 → 1,11
#ifndef BUILTIN_ALIASES_H
#define BUILTIN_ALIASES_H
 
/* See modules/module_aliases.h for an explanation of this file */
 
char *builtin_aliases[] = {
"chdir", "cd",
NULL, NULL
};
 
#endif
/branches/shell/uspace/app/bdsh/cmds/cmds.h
0,0 → 1,73
#ifndef CMDS_H
#define CMDS_H
 
#include "config.h"
#include "scli.h"
 
/* Temporary to store strings */
#define EXT_HELP "extended"
#define SHORT_HELP "short"
#define TEST_ANNOUNCE "Hello, this is :"
 
/* Simple levels of help displays */
#define HELP_SHORT 0
#define HELP_LONG 1
 
/* Acceptable buffer sizes (for strn functions) */
/* TODO: Move me, other files duplicate these needlessly */
#define BUFF_LARGE 1024
#define BUFF_SMALL 255
 
/* Return macros for int type entry points */
#define CMD_FAILURE (int*)1
#define CMD_SUCCESS 0
#define CMD_VOID (void *)NULL
 
/* Types for module command entry and help */
typedef int * (* mod_entry_t)(char **);
typedef void * (* mod_help_t)(unsigned int);
 
/* Built-in commands need to be able to modify cliuser_t */
typedef int * (* builtin_entry_t)(char **, cliuser_t *);
typedef void * (* builtin_help_t)(unsigned int);
 
/* Module structure */
typedef struct {
char *name; /* Name of the command */
char *desc; /* Description of the command */
mod_entry_t entry; /* Command (exec) entry function */
mod_help_t help; /* Command (help) entry function */
int restricted; /* Restricts to interactive/non-interactive only */
} module_t;
 
/* Builtin structure, same as modules except different types of entry points */
typedef struct {
char *name;
char *desc;
builtin_entry_t entry;
builtin_help_t help;
int restricted;
} builtin_t;
 
/* Declared in cmds/modules/modules.h and cmds/builtins/builtins.h
* respectively */
extern module_t modules[];
extern builtin_t builtins[];
 
/* Prototypes for module launchers */
extern int module_is_restricted(int);
extern int is_module(const char *);
extern int is_module_alias(const char *);
extern char * alias_for_module(const char *);
extern int help_module(int, unsigned int);
extern int run_module(int, char *[]);
 
/* Prototypes for builtin launchers */
extern int builtin_is_restricted(int);
extern int is_builtin(const char *);
extern int is_builtin_alias(const char *);
extern char * alias_for_builtin(const char *);
extern int help_builtin(int, unsigned int);
extern int run_builtin(int, char *[], cliuser_t *);
 
#endif
/branches/shell/uspace/app/bdsh/cmds/builtin_cmds.c
0,0 → 1,126
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
/* Almost identical (for now) to mod_cmds.c , however this will not be the case
* soon as builtin_t is going to grow way beyond module_t */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "errors.h"
#include "cmds.h"
#include "builtin_aliases.h"
 
extern volatile unsigned int cli_interactive;
 
int builtin_is_restricted(int pos)
{
builtin_t *cmd = builtins;
cmd += pos;
 
if (cli_interactive && cmd->restricted <= 0)
return 0;
if (!cli_interactive && cmd->restricted >= 0)
return 0;
 
return 1;
}
 
int is_builtin(const char *command)
{
builtin_t *cmd;
unsigned int i = 0;
 
if (NULL == command)
return -2;
 
for (cmd = builtins; cmd->name != NULL; cmd++, i++) {
if (!strcmp(cmd->name, command))
return i;
}
 
return -1;
}
 
int is_builtin_alias(const char *command)
{
unsigned int i = 0;
 
if (NULL == command)
return -1;
 
for(i=0; builtin_aliases[i] != NULL; i+=2) {
if (!strcmp(builtin_aliases[i], command))
return 1;
}
 
return 0;
}
 
char *alias_for_builtin(const char *command)
{
unsigned int i = 0;
 
if (NULL == command)
return (char *)NULL;
 
for(i=0; builtin_aliases[i] != NULL; i++) {
if (!strcmp(builtin_aliases[i], command))
return (char *)builtin_aliases[++i];
i++;
}
 
return (char *)NULL;
}
 
int help_builtin(int builtin, unsigned int extended)
{
builtin_t *cmd = builtins;
 
cmd += builtin;
 
if (NULL != cmd->help) {
cmd->help(extended);
return CL_EOK;
} else
return CL_ENOENT;
}
 
int run_builtin(int builtin, char *argv[], cliuser_t *usr)
{
builtin_t *cmd = builtins;
 
cmd += builtin;
 
if (NULL != cmd->entry)
return((int)cmd->entry(argv, usr));
 
return CL_ENOENT;
}
/branches/shell/uspace/app/bdsh/config.h
0,0 → 1,35
/* Various things that are used in many files
* Various temporary port work-arounds are addressed in __HELENOS__ , this
* serves as a convenience and later as a guide to make "phony.h" for future
* ports */
 
/* Specific port work-arounds : */
#ifdef HELENOS
#define PATH_MAX 255
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 0
#endif
 
/* Work around for getenv() */
#define PATH "/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
#define PATH_DELIM ":"
 
/* Used in many places */
#define SMALL_BUFLEN 256
#define LARGE_BUFLEN 1024
 
/* How many words (arguments) are permitted, how big can a whole
* sentence be? Similar to ARG_MAX */
#define WORD_MAX 255
#define INPUT_MAX 1024
 
/* Leftovers from Autoconf */
#define PACKAGE_MAINTAINER "Tim Post"
#define PACKAGE_BUGREPORT "tinkertim@gmail.com"
#define PACKAGE_NAME "scli"
#define PACKAGE_STRING "scli 0.0.1"
#define PACKAGE_TARNAME "scli"
#define PACKAGE_VERSION "0.0.1"
 
 
 
/branches/shell/uspace/app/bdsh/errors.c
0,0 → 1,95
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
 
#include "config.h"
#include "errors.h"
#include "errstr.h"
 
/* Error printing, translation and handling functions */
 
volatile int cli_lasterr = 0;
extern volatile unsigned int cli_verbocity;
 
/* Look up errno in cl_errors and return the corresponding string.
* Return NULL if not found */
char *err2str(int errno)
{
 
if (NULL != cl_errors[errno])
return cl_errors[errno];
 
return (char *)NULL;
}
 
/* Print an error report signifying errno, which is translated to
* its corresponding human readable string. If errno > 0, raise the
* cli_quit int that tells the main program loop to exit immediately */
 
void cli_error(int errno, const char *fmt, ...)
{
va_list vargs;
va_start(vargs, fmt);
vprintf(fmt, vargs);
va_end(vargs);
 
if (NULL != err2str(errno))
printf(" (%s)\n", err2str(errno));
else
printf(" (Unknown Error %d)\n", errno);
 
if (errno < 0)
exit(EXIT_FAILURE);
 
}
 
/* Just a smart printf(), print the string only if cli_verbocity is high */
void cli_verbose(const char *fmt, ...)
{
if (cli_verbocity) {
va_list vargs;
 
printf("[*] ");
va_start(vargs, fmt);
vprintf(fmt, vargs);
va_end(vargs);
printf("\n");
}
return;
}
 
 
 
 
/branches/shell/uspace/app/bdsh/util.c
0,0 → 1,154
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* Copyright (C) 1998 by Wes Peters <wes@softweyr.com>
* Copyright (c) 1988, 1993 The Regents of the University of California.
* All rights reserved by all copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
/* NOTES:
* 1 - Various functions were adapted from FreeBSD (copyright holders noted above)
* these functions are identified with comments.
*
* 2 - Some of these have since appeared in libc. They remain here for various
* reasons, such as the eventual integration of garbage collection for things
* that allocate memory and don't automatically free it.
*
* 3 - Things that expect a pointer to an allocated string do _no_ sanity checking
* if developing on a simulator with no debugger, take care :)
*/
 
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
 
#include "config.h"
#include "errors.h"
#include "util.h"
 
/* Functions that just have no other home */
 
/* Tests if string is an --option/-option */
unsigned int is_option(char *string)
{
size_t i;
 
/* We have rubbish */
if (NULL == string)
return 0;
 
/* - or -- means an option (or end of options) */
for (i=0; i < strlen(string); i++) {
if (string[i] == '-' && i <= 1)
return 1;
}
 
return 0;
}
 
/* Returns the option count in an array of arguments */
unsigned int count_options(char *argv[])
{
unsigned int i;
unsigned int n = 0;
 
for (i=0; argv[i] != NULL; i++) {
if (is_option((char *)argv[i]))
n++;
}
 
return n;
}
 
/* some platforms do not have strdup, implement it here */
char * cli_strdup(const char *s1)
{
size_t len = strlen(s1) + 1;
void *ret = malloc(len);
 
if (ret == NULL)
return (char *) NULL;
 
return (char *) memcpy(ret, s1, len);
}
 
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */
char * cli_strtok_r(char *s, const char *delim, char **last)
{
char *spanp, *tok;
int c, sc;
 
if (s == NULL && (s = *last) == NULL)
return (NULL);
 
cont:
c = *s++;
for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
if (c == sc)
goto cont;
}
 
if (c == 0) { /* no non-delimiter characters */
*last = NULL;
return (NULL);
}
tok = s - 1;
 
for (;;) {
c = *s++;
spanp = (char *)delim;
do {
if ((sc = *spanp++) == c) {
if (c == 0)
s = NULL;
else
s[-1] = '\0';
*last = s;
return (tok);
}
} while (sc != 0);
}
}
 
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */
char * cli_strtok(char *s, const char *delim)
{
static char *last;
 
return (cli_strtok_r(s, delim, &last));
}
 
/* for debugging, not really used */
void cli_free(void **pointer)
{
if (*pointer != NULL) {
free(*pointer);
*pointer = NULL;
}
}
 
/branches/shell/uspace/app/bdsh/errors.h
0,0 → 1,18
#ifndef ERRORS_H
#define ERRORS_H
 
/* Various error levels */
#define CL_EFATAL -1
#define CL_EOK 0
#define CL_EFAIL 1
#define CL_EBUSY 2
#define CL_ENOENT 3
#define CL_ENOMEM 4
#define CL_EPERM 5
#define CL_ENOTSUP 6
#define CL_EEXEC 7
 
extern char *err2str(int);
extern void cli_error(int, const char *, ...);
extern void cli_verbose(const char *, ...);
#endif
/branches/shell/uspace/app/bdsh/util.h
0,0 → 1,13
#ifndef UTIL_H
#define UTIL_H
 
/* For internal getopt-like stuff */
extern unsigned int is_option(char *);
extern unsigned int count_options(char *[]);
 
/* String functions not yet present in HelenOS uspace libc */
extern char * cli_strdup(const char *s1);
extern char * cli_strtok_r(char *, const char *, char **);
extern char * cli_strtok(char *, const char *);
extern void cli_free(void **);
#endif
/branches/shell/uspace/app/bdsh/exec.c
0,0 → 1,225
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
/* The VERY basics of execute in place support. These are buggy, leaky
* and not nearly done. Only here for beta testing!! You were warned!!
* TODO:
* Hash command lookups to save time
* Create a running pointer to **path and advance/rewind it as we go */
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
 
#ifndef HELENOS
#include <linux/limits.h>
#include <sys/errno.h>
#include <sys/wait.h>
#endif
 
#include "config.h"
#include "util.h"
#include "exec.h"
#include "errors.h"
 
/* Easiest way to handle a shared + allocated string, a structure with
* one member is sort of silly :) */
char *found;
 
/* work-around for access() */
unsigned int try_access(const char *f)
{
int fd;
 
fd = open(f, O_RDONLY);
if (fd > 0) {
close(fd);
return 1;
} else
return 0;
}
 
/* Returns the full path of "cmd" if cmd is found, else just hand back
* cmd as it was presented */
char *find_command(char *cmd)
{
char *path_orig, *path_tok;
char *path[PATH_MAX];
int rc, n = 0, i = 0;
size_t x = strlen(cmd) + 2;
 
found = (char *)malloc(PATH_MAX);
 
/* The user has specified the full path, just give it back. Don't test it,
* they seem to know what they're doing. */
if (cmd[0] == '/' || cmd [0] == '.')
return (char *)cmd;
 
#ifdef HELENOS
path_orig = PATH;
#else
path_orig = getenv("PATH");
if (NULL == path_orig)
path_orig = PATH;
#endif
 
path_tok = cli_strdup(path_orig);
 
/* Extract the PATH env to a path[] array */
path[n] = cli_strtok(path_tok, PATH_DELIM);
while (NULL != path[n]) {
if ((strlen(path[n]) + x ) > PATH_MAX) {
cli_error(CL_ENOTSUP,
"Segment %d of path is too large, search ends at segment %d",
n, n-1);
break;
}
path[++n] = cli_strtok(NULL, PATH_DELIM);
}
 
/* We now have n places to look for the command */
for (i=0; path[i]; i++) {
memset(found, 0, sizeof(found));
snprintf(found, PATH_MAX, "%s/%s", path[i], cmd);
#ifdef HELENOS
rc = try_access(found);
#else
rc = access(found, F_OK);
#endif
if (rc >= 0) {
/* We found it */
free(path_tok);
return (char *) found;
}
}
 
/* We didn't find it, just give it back as-is. Could be an alias
* set in the parent shell */
free(path_tok);
return (char *) cmd;
}
 
#ifdef HELENOS
task_id_t try_exec(char *cmd, char **argv)
{
task_id_t tid;
char *tmp;
 
tmp = cli_strdup(find_command(cmd));
free(found);
 
tid = task_spawn((const char *)tmp, (const char **)argv);
free(tmp);
 
if (tid == 0)
/* HelenOS does not set errno, so all we can do is report
* a task ID of 0 as a generic failure. */
cli_error(CL_EEXEC, "Can not spawn %s", cmd);
 
return tid;
}
 
#else
int try_exec(char *cmd, char **argv)
{
char *tmp;
pid_t pid;
int status;
 
/* Copy the result of allocated 'found' */
tmp = cli_strdup(find_command(cmd));
/* free the pointer, no longer needed */
free(found);
 
if (-1 == (access(tmp, F_OK))) {
cli_error(CL_EFAIL,
"%s : No such external, modular or builtin command", tmp);
free(tmp);
return CL_EFAIL;
}
 
/* Create a child to run the program */
pid = fork();
if (pid == 0) {
execv(tmp, argv);
exit(errno);
} else if (pid > 0) {
/* Block until we get a PID (and result) */
wait(&status);
status = status / 256;
} else {
/* Could not fork, ulimit or out of memory */
cli_error(CL_ENOMEM, "Could not fork");
free(tmp);
return CL_ENOMEM;
}
 
free(tmp);
 
/* No need to go any further if status == 0 */
/*
if (status == 0)
return status;
*/
/* Decode any errors from execv() (these explain themselves) */
switch (status) {
case ENOTDIR:
cli_error(CL_EFAIL, "%s : No such file or directory", tmp);
status = CL_EFAIL;
break;
case EISDIR:
cli_error(CL_EFAIL, "%s : Command is a directory", tmp);
status = CL_EFAIL;
break;
case EACCES:
cli_error(CL_EPERM, "%s :", tmp);
status = CL_EFAIL;
break;
case ENOMEM:
cli_error(CL_ENOMEM, "%s :", tmp);
status = CL_EFAIL;
break;
case ENAMETOOLONG:
cli_error(CL_EFAIL, "Argument list too long");
status = CL_EFAIL;
break;
case EFAULT:
cli_error(CL_EFAIL, "Invalid argument pointer\n(please report "
"this to %s)", PACKAGE_BUGREPORT);
status = CL_EFAIL;
break;
}
 
return status;
}
 
#endif /* HELENOS */
/branches/shell/uspace/app/bdsh/Makefile.gnu
0,0 → 1,105
# Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 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.
#
# Neither the name of the original program's authors 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.
 
CC = gcc
CFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -fno-strict-aliasing
PROGRAM = scli
 
# Any directory that cleaning targets should know about
SUBDIRS = \
./ \
cmds/ \
cmds/modules/ \
cmds/modules/help/ \
cmds/modules/quit/ \
cmds/builtins/ \
cmds/builtins/pwd/ \
cmds/builtins/cd/ \
lib/
 
# Commands
MODULES = \
cmds/modules/help/help.c \
cmds/modules/quit/quit.c
 
BUILTINS = \
cmds/builtins/pwd/pwd.c \
cmds/builtins/cd/cd.c
 
# Non-commands and command loaders
SOURCES = \
cmds/mod_cmds.c \
cmds/builtin_cmds.c \
errors.c \
input.c \
util.c \
exec.c \
scli.c
 
# Included Libs, stuff we build and include (not link against)
LIBS =
 
# Add included libs to include path
INC = -I. -Icmds/ -Icmds/builtins -Icmds/modules -Ilib -Ilib/ustr
 
# All your sources are belong to us, !!! Order Matters Here !!!
SRC = $(LIBS) $(MODULES) $(BUILTINS) $(SOURCES)
 
# Every .c file in $(SRC) will be built to file.o
OBJECTS = $(SRC:.c=.o)
 
# For easy cleaning, *.o is already handled
CLEANDIRS := $(addsuffix *~,$(SUBDIRS))
CLEANDIRS += $(addsuffix *.bak,$(SUBDIRS))
CLEANDIRS += $(addsuffix *.tmp,$(SUBDIRS))
CLEANDIRS += $(addsuffix *.out,$(SUBDIRS))
CLEANDIRS += $(addsuffix *.d,$(SUBDIRS))
CLEANDIRS += $(addsuffix *.gch,$(SUBDIRS))
 
%.o: %.c
$(CC) $(CFLAGS) $(INC) -c $< -o $@
@$(CC) -M $(CFLAGS) $(INC) $*.c > $*.d
 
$(PROGRAM): $(OBJECTS)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) -o $@
 
# Everything else is a phony target
.PHONY: all clean distclean
 
all: $(PROGRAM)
 
clean:
@-rm -f $(OBJECTS)
@-rm -f $(PROGRAM)
@-rm -f $(CLEANDIRS)
 
distclean: clean
 
# Do not delete - header dependencies
-include $(OBJECTS:.o=.d)
/branches/shell/uspace/app/bdsh/errstr.h
0,0 → 1,19
#ifndef ERRSTR_H
#define ERRSTR_H
 
/* Simple array to translate error codes to meaningful strings */
 
static char *cl_errors[] = {
"Success",
"Failure",
"Busy",
"No Such Entry",
"Not Enough Memory",
"Permission Denied",
"Method Not Supported",
"Bad command or file name",
NULL
};
 
#endif
 
/branches/shell/uspace/app/bdsh/exec.h
0,0 → 1,13
#ifndef EXEC_H
#define EXEC_H
 
extern char *find_command(char *);
#ifdef HELENOS
#include <task.h>
extern task_id_t try_exec(char *, char **);
#else
extern int try_exec(char *, char **);
#endif
extern unsigned int try_access(const char *);
 
#endif
/branches/shell/uspace/app/bdsh/scli.c
0,0 → 1,142
/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of the original program's authors 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.
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "scli.h"
#include "input.h"
#include "util.h"
#include "errors.h"
#include "cmds/cmds.h"
 
#ifndef HELENOS
#include <linux/limits.h>
#endif
 
/* See scli.h */
static cliuser_t usr;
 
/* Modified by the 'quit' module, which is compiled before this */
extern unsigned int cli_quit;
 
/* Globals that are modified during start-up that modules/builtins should
* be aware of. */
volatile unsigned int cli_interactive = 1;
volatile unsigned int cli_verbocity = 1;
 
/* The official name of this program
* (change to your liking in configure.ac and re-run autoconf) */
const char *progname = PACKAGE_NAME;
 
/* (re)allocates memory to store the current working directory, gets
* and updates the current working directory, formats the prompt string */
int cli_set_prompt(cliuser_t *usr)
{
usr->prompt = (char *) realloc(usr->prompt, PATH_MAX);
if (NULL == usr->prompt) {
cli_error(CL_ENOMEM, "Can not allocate prompt");
return 1;
}
memset(usr->prompt, 0, sizeof(usr->prompt));
 
usr->cwd = (char *) realloc(usr->cwd, PATH_MAX);
if (NULL == usr->cwd) {
cli_error(CL_ENOMEM, "Can not allocate cwd");
return 1;
}
memset(usr->cwd, 0, sizeof(usr->cwd));
 
usr->cwd = getcwd(usr->cwd, PATH_MAX - 1);
if (NULL == usr->cwd)
snprintf(usr->cwd, PATH_MAX, "(unknown)");
 
if (usr->lasterr != 0)
snprintf(usr->prompt,
PATH_MAX,
"[%lld] %s # ",
usr->lasterr, usr->cwd);
else
snprintf(usr->prompt,
PATH_MAX,
"%s # ",
usr->cwd);
 
return 0;
}
 
int cli_init(cliuser_t *usr)
{
usr->line = (char *) NULL;
usr->name = "root";
usr->home = "/";
usr->cwd = (char *) NULL;
usr->prompt = (char *) NULL;
chdir(usr->home);
usr->lasterr = 0;
return (int) cli_set_prompt(usr);
}
 
/* Destructor */
void cli_finit(cliuser_t *usr)
{
if (NULL != usr->line)
free(usr->line);
if (NULL != usr->prompt)
free(usr->prompt);
if (NULL != usr->cwd)
free(usr->cwd);
}
 
int main(int argc, char *argv[])
{
int ret = 0;
int i = 0;
 
if (cli_init(&usr))
exit(EXIT_FAILURE);
 
while (!cli_quit) {
cli_set_prompt(&usr);
get_input(&usr);
if (NULL != usr.line) {
ret = tok_input(&usr);
usr.lasterr = ret;
}
i++;
}
goto finit;
 
finit:
cli_finit(&usr);
return ret;
}
/branches/shell/uspace/app/bdsh/Makefile
0,0 → 1,125
# Copyright (c) 2005, Martin Decky
# All rights reserved.
# Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 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.
#
# Neither the name of the original program's authors 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.
 
include ../../../version
include ../../Makefile.config
 
LIBC_PREFIX = ../../lib/libc
SOFTINT_PREFIX = ../../lib/softint
include $(LIBC_PREFIX)/Makefile.toolchain
 
CFLAGS += -I../../srv/kbd/include -DHELENOS -fno-strict-aliasing
 
LIBS = $(LIBC_PREFIX)/libc.a
DEFS += -DRELEASE=\"$(RELEASE)\"
 
ifdef REVISION
DEFS += "-DREVISION=\"$(TIMESTAMP)\""
endif
 
ifdef TIMESTAMP
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
PROGRAM = bdsh
 
# Any directory that cleaning targets should know about
SUBDIRS = \
./ \
cmds/ \
cmds/modules/ \
cmds/modules/help/ \
cmds/modules/quit/ \
cmds/builtins/ \
cmds/builtins/pwd/ \
cmds/builtins/cd/ \
lib/
 
SOURCES = \
cmds/modules/help/help.c \
cmds/modules/quit/quit.c \
cmds/builtins/pwd/pwd.c \
cmds/builtins/cd/cd.c \
cmds/mod_cmds.c \
cmds/builtin_cmds.c \
errors.c \
input.c \
util.c \
exec.c \
scli.c
 
CFLAGS += -I. -Icmds/ -Icmds/builtins -Icmds/modules -Ilib -Ilib/ustr
 
OBJECTS = $(SOURCES:.c=.o)
 
# For easy cleaning, *.o is already handled
CLEANDIRS := $(addsuffix *~,$(SUBDIRS))
CLEANDIRS += $(addsuffix *.bak,$(SUBDIRS))
CLEANDIRS += $(addsuffix *.tmp,$(SUBDIRS))
CLEANDIRS += $(addsuffix *.out,$(SUBDIRS))
CLEANDIRS += $(addsuffix *.d,$(SUBDIRS))
CLEANDIRS += $(addsuffix *.gch,$(SUBDIRS) )
 
%.o: %.S
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
 
%.o: %.s
$(AS) $(AFLAGS) $< -o $@
 
%.o: %.c
$(CC) $(CFLAGS) $(INC) -c $< -o $@
$(CC) -M $(CFLAGS) $(INC) $*.c > $*.d
 
$(PROGRAM): $(OBJECTS) $(LIBS)
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
 
# Everything else is a phony target
.PHONY: all clean distclean depend disasm
 
all: $(PROGRAM) disasm
 
clean:
@-rm -f $(OBJECTS)
@-rm -f $(PROGRAM)
@-rm -f $(PROGRAM).map
@-rm -f $(PROGRAM).disasm
@-rm -f $(CLEANDIRS)
 
depend:
@echo ''
 
disasm:
$(OBJDUMP) -d $(PROGRAM) >$(PROGRAM).disasm
 
distclean: clean
 
# Do not delete - dependencies
-include $(OBJECTS:.o=.d)