Index: uspace/app/bdsh/cmds/builtin_cmds.c
===================================================================
--- uspace/app/bdsh/cmds/builtin_cmds.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtin_cmds.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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;
+}
Index: uspace/app/bdsh/cmds/builtins/README
===================================================================
--- uspace/app/bdsh/cmds/builtins/README	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/README	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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.
Index: uspace/app/bdsh/cmds/builtins/builtin_aliases.h
===================================================================
--- uspace/app/bdsh/cmds/builtins/builtin_aliases.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/builtin_aliases.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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
Index: uspace/app/bdsh/cmds/builtins/builtins.h
===================================================================
--- uspace/app/bdsh/cmds/builtins/builtins.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/builtins.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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
Index: uspace/app/bdsh/cmds/builtins/cd/cd.c
===================================================================
--- uspace/app/bdsh/cmds/builtins/cd/cd.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/cd/cd.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <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 <directory>\n"
+		"  Change directory to <directory>, e.g `%s /sbin'\n",
+			cmdname, 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;
+
+	for (argc = 0; argv[argc] != NULL; argc ++);
+
+	/* 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;
+	}
+
+	if (argc < 2) {
+		printf("%s - no directory specified. Try `help %s extended'\n",
+			cmdname, cmdname);
+		return CMD_FAILURE;
+	}
+
+	/* We have the correct # of arguments
+     * TODO: handle tidle (~) expansion? */
+
+	rc = chdir(argv[1]);
+
+	if (rc == 0) {
+		return CMD_SUCCESS;
+	} else {
+		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;
+}
Index: uspace/app/bdsh/cmds/builtins/cd/cd.def
===================================================================
--- uspace/app/bdsh/cmds/builtins/cd/cd.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/cd/cd.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,14 @@
+{
+	"cd",
+	"Change the current working directory",
+	&cmd_cd,
+	&help_cmd_cd,
+	-1
+},
+{
+	"chdir",
+	NULL,
+	&cmd_cd,
+	&help_cmd_cd,
+	-1
+},
Index: uspace/app/bdsh/cmds/builtins/cd/cd.h
===================================================================
--- uspace/app/bdsh/cmds/builtins/cd/cd.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/cd/cd.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,7 @@
+#ifndef CD_H
+#define CD_H
+
+/* Prototypes for the cd command (excluding entry points) */
+
+
+#endif
Index: uspace/app/bdsh/cmds/builtins/cd/entry.h
===================================================================
--- uspace/app/bdsh/cmds/builtins/cd/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/cd/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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
+
+
Index: uspace/app/bdsh/cmds/builtins/pwd/entry.h
===================================================================
--- uspace/app/bdsh/cmds/builtins/pwd/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/pwd/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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
+
+
Index: uspace/app/bdsh/cmds/builtins/pwd/pwd.c
===================================================================
--- uspace/app/bdsh/cmds/builtins/pwd/pwd.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/pwd/pwd.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,71 @@
+/* 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 "config.h"
+#include "errors.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)
+{
+	char *buff;
+
+	buff = (char *) malloc(PATH_MAX);
+	if (NULL == buff) {
+		cli_error(CL_ENOMEM, "%s:", cmdname);
+		return CMD_FAILURE;
+	}
+
+	memset(buff, 0, sizeof(buff));
+	getcwd(buff, PATH_MAX);
+
+	if (! buff) {
+		cli_error(CL_EFAIL,
+			"Unable to determine the current working directory");
+		free(buff);
+		return CMD_FAILURE;
+	} else {
+		printf("%s\n", buff);
+		free(buff);
+		return CMD_SUCCESS;
+	}
+}
Index: uspace/app/bdsh/cmds/builtins/pwd/pwd.def
===================================================================
--- uspace/app/bdsh/cmds/builtins/pwd/pwd.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/pwd/pwd.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,7 @@
+{
+	"pwd",
+	"Prints the current working directory",
+	&cmd_pwd,
+	&help_cmd_pwd,
+	-1
+},
Index: uspace/app/bdsh/cmds/builtins/pwd/pwd.h
===================================================================
--- uspace/app/bdsh/cmds/builtins/pwd/pwd.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/builtins/pwd/pwd.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,6 @@
+#ifndef PWD_H_
+#define PWD_H_
+
+/* Prototypes for the pwd command (excluding entry points) */
+
+#endif
Index: uspace/app/bdsh/cmds/cmds.h
===================================================================
--- uspace/app/bdsh/cmds/cmds.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/cmds.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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
Index: uspace/app/bdsh/cmds/mknewcmd
===================================================================
--- uspace/app/bdsh/cmds/mknewcmd	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/mknewcmd	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,347 @@
+#!/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 "config.h"
+#include "util.h"
+#include "errors.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 CMD_VOID;
+}
+
+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 CMD_SUCCESS;
+	}
+
+	printf(":\n");
+	for (i = 1; i < argc; i++)
+		printf("[%d] -> %s\n", i, argv[i]);
+
+	return CMD_SUCCESS;
+}
+
+EOF
+	printf "Done.\n\nYou should now modify %ss/%ss.h and ../Makefile" \
+		"${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 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
+
Index: uspace/app/bdsh/cmds/mod_cmds.c
===================================================================
--- uspace/app/bdsh/cmds/mod_cmds.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/mod_cmds.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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;
+}
Index: uspace/app/bdsh/cmds/modules/README
===================================================================
--- uspace/app/bdsh/cmds/modules/README	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/README	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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.
+
+
Index: uspace/app/bdsh/cmds/modules/cat/cat.c
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/cat/cat.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,72 @@
+/* Automatically generated by mknewcmd on Wed Aug 13 15:41:09 PHT 2008
+ * This is machine generated output. The author of mknewcmd 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 <getopt.h>
+
+#include "config.h"
+#include "util.h"
+#include "errors.h"
+#include "entry.h"
+#include "cat.h"
+#include "cmds.h"
+
+static char *cmdname = "cat";
+
+static struct option long_options[] = {
+	{ "help",		no_argument,		0,	'h' },
+	{ "version",	no_argument,		0,	'v' },
+	{ "file",		required_argument,	0,	'f' },
+	{ 0, 0, 0, 0 }
+};
+
+/* Dispays help for cat in various levels */
+void * help_cmd_cat(unsigned int level)
+{
+	printf("This is the %s help for '%s'.\n",
+		level ? EXT_HELP : SHORT_HELP, cmdname);
+	return CMD_VOID;
+}
+
+/* Main entry point for cat, accepts an array of arguments */
+int * cmd_cat(char **argv)
+{
+	unsigned int argc;
+	unsigned int i;
+	int c, opt_ind;
+
+	/* Count the arguments */
+	for (argc = 0; argv[argc] != NULL; argc ++);
+
+	printf("%s %s\n", TEST_ANNOUNCE, cmdname);
+	printf("%d arguments passed to %s\n", argc - 1, cmdname);
+
+	for (i = 1; i < argc; i++)
+		printf("[%d] -> %s\n", i, argv[i]);
+
+	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
+		c = getopt_long(argc, argv, "f:hv", long_options, &opt_ind);
+		switch (c) {
+		case 'h':
+			help_cmd_cat(HELP_SHORT);
+			break;
+		case 'v':
+			printf("I have no version, sorry.\n");
+			break;
+		case 'f':
+			printf("File : %s\n", optarg);
+			break;
+		}
+	}
+
+	printf("argc = %d, optind = %d\n", argc, optind);
+
+	return CMD_SUCCESS;
+}
+
Index: uspace/app/bdsh/cmds/modules/cat/cat.def
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/cat/cat.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,8 @@
+{
+	"cat",
+	"The cat command",
+	&cmd_cat,
+	&help_cmd_cat,
+	0
+},
+
Index: uspace/app/bdsh/cmds/modules/cat/cat.h
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/cat.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/cat/cat.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,8 @@
+#ifndef CAT_H
+#define CAT_H
+
+/* Prototypes for the cat command, excluding entry points */
+
+
+#endif /* CAT_H */
+
Index: uspace/app/bdsh/cmds/modules/cat/entry.h
===================================================================
--- uspace/app/bdsh/cmds/modules/cat/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/cat/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,9 @@
+#ifndef CAT_ENTRY_H
+#define CAT_ENTRY_H
+
+/* Entry points for the cat command */
+extern int * cmd_cat(char **);
+extern void * help_cmd_cat(unsigned int);
+
+#endif /* CAT_ENTRY_H */
+
Index: uspace/app/bdsh/cmds/modules/help/entry.h
===================================================================
--- uspace/app/bdsh/cmds/modules/help/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/help/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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
Index: uspace/app/bdsh/cmds/modules/help/help.c
===================================================================
--- uspace/app/bdsh/cmds/modules/help/help.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/help/help.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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"
+
+static 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;
+}
Index: uspace/app/bdsh/cmds/modules/help/help.def
===================================================================
--- uspace/app/bdsh/cmds/modules/help/help.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/help/help.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,7 @@
+{
+	"help",
+	"Show help for commands",
+	&cmd_help,
+	&help_cmd_help,
+	0
+},
Index: uspace/app/bdsh/cmds/modules/help/help.h
===================================================================
--- uspace/app/bdsh/cmds/modules/help/help.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/help/help.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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
Index: uspace/app/bdsh/cmds/modules/ls/entry.h
===================================================================
--- uspace/app/bdsh/cmds/modules/ls/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/ls/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,9 @@
+#ifndef LS_ENTRY_H
+#define LS_ENTRY_H
+
+/* Entry points for the ls command */
+extern int * cmd_ls(char **);
+extern void * help_cmd_ls(unsigned int);
+
+#endif /* LS_ENTRY_H */
+
Index: uspace/app/bdsh/cmds/modules/ls/ls.c
===================================================================
--- uspace/app/bdsh/cmds/modules/ls/ls.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/ls/ls.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,197 @@
+/* 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.
+ */
+
+/* NOTE:
+ * This is a bit of an ugly hack, working around the absence of fstat / etc.
+ * As more stuff is completed and exposed in libc, this will improve */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#include "errors.h"
+#include "config.h"
+#include "util.h"
+#include "entry.h"
+#include "ls.h"
+#include "cmds.h"
+
+static char *cmdname = "ls";
+
+unsigned int ls_scope(const char *path)
+{
+	int fd;
+	DIR *dirp;
+
+	dirp = opendir(path);
+	if (dirp) {
+		closedir(dirp);
+		return LS_DIR;
+	}
+
+	fd = open(path, O_RDONLY);
+	if (fd > 0) {
+		close(fd);
+		return LS_FILE;
+	}
+
+	return LS_BOGUS;
+}
+
+void ls_scan_dir(const char *d, DIR *dirp)
+{
+	struct dirent *dp;
+	unsigned int scope;
+	char *buff;
+
+	if (! dirp)
+		return;
+
+	buff = (char *)malloc(PATH_MAX);
+	if (NULL == buff) {
+		cli_error(CL_ENOMEM, "ls: failed to scan %s", d);
+		return;
+	}
+
+	while ((dp = readdir(dirp))) {
+		memset(buff, 0, sizeof(buff));
+		/* Don't worry if inserting a double slash, this will be fixed by
+		 * absolutize() later with subsequent calls to open() or readdir() */
+		snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name);
+		scope = ls_scope(buff);
+		switch (scope) {
+		case LS_DIR:
+			ls_print_dir(dp->d_name);
+			break;
+		case LS_FILE:
+			ls_print_file(dp->d_name);
+			break;
+		case LS_BOGUS:
+			/* Odd chance it was deleted from the time readdir() found
+			 * it and the time that it was scoped */
+			printf("ls: skipping bogus node %s\n", dp->d_name);
+			break;
+		}
+	}
+
+	free(buff);
+
+	return;
+}
+
+/* ls_print_* currently does nothing more than print the entry.
+ * in the future, we will likely pass the absolute path, and
+ * some sort of ls_options structure that controls how each
+ * entry is printed and what is printed about it.
+ *
+ * Now we just print basic DOS style lists */
+
+void ls_print_dir(const char *d)
+{
+	printf("%-40s\t<DIR>\n", d);
+
+	return;
+}
+
+void ls_print_file(const char *f)
+{
+	printf("%-40s\n", f);
+
+	return;
+}
+
+void * help_cmd_ls(unsigned int level)
+{
+	if (level == HELP_SHORT) {
+		printf("`%s' lists files and directories.\n", cmdname);
+	} else {
+		help_cmd_ls(HELP_SHORT);
+		printf("  `%s' [path], if no path is given the current "
+				"working directory is used.\n", cmdname);
+	}
+
+	return CMD_VOID;
+}
+
+int * cmd_ls(char **argv)
+{
+	unsigned int argc;
+	unsigned int scope;
+	char *buff;
+	DIR *dirp;
+
+	/* Count the arguments */
+	for (argc = 0; argv[argc] != NULL; argc ++);
+
+	buff = (char *) malloc(PATH_MAX);
+	if (NULL == buff) {
+		cli_error(CL_ENOMEM, "%s: ", cmdname);
+		return CMD_FAILURE;
+	}
+	memset(buff, 0, sizeof(buff));
+
+	if (argc == 1)
+		getcwd(buff, PATH_MAX);
+	else
+		strncpy(buff, argv[1], PATH_MAX);
+
+	scope = ls_scope(buff);
+
+	switch (scope) {
+	case LS_BOGUS:
+		cli_error(CL_ENOENT, buff);
+		free(buff);
+		return CMD_FAILURE;
+	case LS_FILE:
+		ls_print_file(buff);
+		break;
+	case LS_DIR:
+		dirp = opendir(buff);
+		if (! dirp) {
+			/* May have been deleted between scoping it and opening it */
+			cli_error(CL_EFAIL, "Could not stat %s", buff);
+			free(buff);
+			return CMD_FAILURE;
+		}
+		ls_scan_dir(buff, dirp);
+		closedir(dirp);
+		break;
+	}
+
+	free(buff);
+
+	return CMD_SUCCESS;
+}
+
Index: uspace/app/bdsh/cmds/modules/ls/ls.def
===================================================================
--- uspace/app/bdsh/cmds/modules/ls/ls.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/ls/ls.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,16 @@
+{
+	"ls",
+	"The ls command",
+	&cmd_ls,
+	&help_cmd_ls,
+	0
+},
+
+{
+	"dir",
+	NULL,
+	&cmd_ls,
+	&help_cmd_ls,
+	0
+},
+
Index: uspace/app/bdsh/cmds/modules/ls/ls.h
===================================================================
--- uspace/app/bdsh/cmds/modules/ls/ls.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/ls/ls.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,18 @@
+#ifndef LS_H
+#define LS_H
+
+/* Various values that can be returned by ls_scope() */
+#define LS_BOGUS 0
+#define LS_FILE  1
+#define LS_DIR   2
+
+/* Protoypes for non entry points, intrinsic to ls. Stuff like ls_scope()
+ * is also duplicated in rm, while rm sort of duplicates ls_scan_dir().
+ * TODO make some more shared functions and don't expose the stuff below */
+extern unsigned int ls_scope(const char *);
+extern void ls_scan_dir(const char *, DIR *);
+extern void ls_print_dir(const char *);
+extern void ls_print_file(const char *);
+
+#endif /* LS_H */
+
Index: uspace/app/bdsh/cmds/modules/mkdir/entry.h
===================================================================
--- uspace/app/bdsh/cmds/modules/mkdir/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/mkdir/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,9 @@
+#ifndef MKDIR_ENTRY_H
+#define MKDIR_ENTRY_H
+
+/* Entry points for the mkdir command */
+extern int * cmd_mkdir(char **);
+extern void * help_cmd_mkdir(unsigned int);
+
+#endif /* MKDIR_ENTRY_H */
+
Index: uspace/app/bdsh/cmds/modules/mkdir/mkdir.c
===================================================================
--- uspace/app/bdsh/cmds/modules/mkdir/mkdir.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/mkdir/mkdir.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,91 @@
+/* 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.
+ */
+
+/* TODO:
+ * Implement -p option when some type of getopt is ported */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "config.h"
+#include "errors.h"
+#include "entry.h"
+#include "mkdir.h"
+#include "cmds.h"
+
+static char *cmdname = "mkdir";
+
+/* Dispays help for mkdir in various levels */
+void * help_cmd_mkdir(unsigned int level)
+{
+	if (level == HELP_SHORT) {
+		printf("`%s' creates a new directory\n", cmdname);
+	} else {
+		help_cmd_mkdir(HELP_SHORT);
+		printf("  `%s' <directory>\n", cmdname);
+	}
+
+	return CMD_VOID;
+}
+
+/* Main entry point for mkdir, accepts an array of arguments */
+int * cmd_mkdir(char **argv)
+{
+	unsigned int argc;
+	DIR *dirp;
+
+	/* Count the arguments */
+	for (argc = 0; argv[argc] != NULL; argc ++);
+
+	if (argc != 2) {
+		printf("%s - incorrect number of arguments. Try `help %s extended'\n",
+			cmdname, cmdname);
+		return CMD_FAILURE;
+	}
+
+	dirp = opendir(argv[1]);
+	if (dirp) {
+		closedir(dirp);
+		cli_error(CL_EEXISTS, "Can not create directory %s", argv[1]);
+		return CMD_FAILURE;
+	}
+
+	if (mkdir(argv[1], 0) != 0) {
+		cli_error(CL_EFAIL, "Could not create %s", argv[1]);
+		return CMD_FAILURE;
+	}
+
+	return CMD_SUCCESS;
+}
+
Index: uspace/app/bdsh/cmds/modules/mkdir/mkdir.def
===================================================================
--- uspace/app/bdsh/cmds/modules/mkdir/mkdir.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/mkdir/mkdir.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,16 @@
+{
+	"mkdir",
+	"The mkdir command",
+	&cmd_mkdir,
+	&help_cmd_mkdir,
+	0
+},
+
+{
+	"md",
+	NULL,
+	&cmd_mkdir,
+	&help_cmd_mkdir,
+	0
+},
+
Index: uspace/app/bdsh/cmds/modules/mkdir/mkdir.h
===================================================================
--- uspace/app/bdsh/cmds/modules/mkdir/mkdir.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/mkdir/mkdir.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,8 @@
+#ifndef MKDIR_H
+#define MKDIR_H
+
+/* Prototypes for the mkdir command, excluding entry points */
+
+
+#endif /* MKDIR_H */
+
Index: uspace/app/bdsh/cmds/modules/module_aliases.h
===================================================================
--- uspace/app/bdsh/cmds/modules/module_aliases.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/module_aliases.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,22 @@
+#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",
+	"md", "mkdir",
+	"del", "rm",
+	"dir", "ls",
+	NULL, NULL
+};
+
+#endif
Index: uspace/app/bdsh/cmds/modules/modules.h
===================================================================
--- uspace/app/bdsh/cmds/modules/modules.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/modules.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,45 @@
+#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"
+#include "mkdir/entry.h"
+#include "rm/entry.h"
+#include "cat/entry.h"
+#include "touch/entry.h"
+#include "ls/entry.h"
+#include "mount/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"
+#include "mkdir/mkdir.def"
+#include "rm/rm.def"
+#include "cat/cat.def"
+#include "touch/touch.def"
+#include "ls/ls.def"
+#include "mount/mount.def"
+	{NULL, NULL, NULL, NULL}
+};
+
+#endif
Index: uspace/app/bdsh/cmds/modules/mount/entry.h
===================================================================
--- uspace/app/bdsh/cmds/modules/mount/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/mount/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,9 @@
+#ifndef MOUNT_ENTRY_H
+#define MOUNT_ENTRY_H
+
+/* Entry points for the mount command */
+extern int * cmd_mount(char **);
+extern void * help_cmd_mount(unsigned int);
+
+#endif /* MOUNT_ENTRY_H */
+
Index: uspace/app/bdsh/cmds/modules/mount/mount.c
===================================================================
--- uspace/app/bdsh/cmds/modules/mount/mount.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/mount/mount.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,51 @@
+/* Automatically generated by mknewcmd on Wed Aug 13 16:08:34 PHT 2008
+ * This is machine generated output. The author of mknewcmd 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 "config.h"
+#include "util.h"
+#include "errors.h"
+#include "entry.h"
+#include "mount.h"
+#include "cmds.h"
+
+static char *cmdname = "mount";
+
+/* Dispays help for mount in various levels */
+void * help_cmd_mount(unsigned int level)
+{
+	printf("This is the %s help for '%s'.\n",
+		level ? EXT_HELP : SHORT_HELP, cmdname);
+	return CMD_VOID;
+}
+
+/* Main entry point for mount, accepts an array of arguments */
+int * cmd_mount(char **argv)
+{
+	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 CMD_SUCCESS;
+	}
+
+	printf(":\n");
+	for (i = 1; i < argc; i++)
+		printf("[%d] -> %s\n", i, argv[i]);
+
+	return CMD_SUCCESS;
+}
+
Index: uspace/app/bdsh/cmds/modules/mount/mount.def
===================================================================
--- uspace/app/bdsh/cmds/modules/mount/mount.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/mount/mount.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,8 @@
+{
+	"mount",
+	"The mount command",
+	&cmd_mount,
+	&help_cmd_mount,
+	0
+},
+
Index: uspace/app/bdsh/cmds/modules/mount/mount.h
===================================================================
--- uspace/app/bdsh/cmds/modules/mount/mount.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/mount/mount.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,8 @@
+#ifndef MOUNT_H
+#define MOUNT_H
+
+/* Prototypes for the mount command, excluding entry points */
+
+
+#endif /* MOUNT_H */
+
Index: uspace/app/bdsh/cmds/modules/quit/entry.h
===================================================================
--- uspace/app/bdsh/cmds/modules/quit/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/quit/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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
+
+
Index: uspace/app/bdsh/cmds/modules/quit/quit.c
===================================================================
--- uspace/app/bdsh/cmds/modules/quit/quit.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/quit/quit.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -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;
+}
Index: uspace/app/bdsh/cmds/modules/quit/quit.def
===================================================================
--- uspace/app/bdsh/cmds/modules/quit/quit.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/quit/quit.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,14 @@
+{
+	"quit",
+	"Exit the console",
+	&cmd_quit,
+	&help_cmd_quit,
+	-1
+},
+{
+	"exit",
+	NULL,
+	&cmd_quit,
+	&help_cmd_quit,
+	-1
+},
Index: uspace/app/bdsh/cmds/modules/quit/quit.h
===================================================================
--- uspace/app/bdsh/cmds/modules/quit/quit.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/quit/quit.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,6 @@
+#ifndef QUIT_H
+#define QUIT_H
+
+/* Prototypes for the quit command (excluding entry points) */
+
+#endif
Index: uspace/app/bdsh/cmds/modules/rm/entry.h
===================================================================
--- uspace/app/bdsh/cmds/modules/rm/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/rm/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,9 @@
+#ifndef RM_ENTRY_H
+#define RM_ENTRY_H
+
+/* Entry points for the rm command */
+extern int * cmd_rm(char **);
+extern void * help_cmd_rm(unsigned int);
+
+#endif /* RM_ENTRY_H */
+
Index: uspace/app/bdsh/cmds/modules/rm/rm.c
===================================================================
--- uspace/app/bdsh/cmds/modules/rm/rm.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/rm/rm.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,253 @@
+/* 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 <fcntl.h>
+#include <dirent.h>
+#include <assert.h>
+#include <getopt.h>
+
+#include "config.h"
+#include "errors.h"
+#include "util.h"
+#include "entry.h"
+#include "rm.h"
+#include "cmds.h"
+
+static char *cmdname = "rm";
+#define RM_VERSION "0.0.1"
+
+static rm_job_t rm;
+
+static struct option long_options[] = {
+	{ "help", no_argument, 0, 'h' },
+	{ "version", no_argument, 0, 'v' },
+	{ "recursive", no_argument, 0, 'r' },
+	{ "force", no_argument, 0, 'f' },
+	{ "safe", no_argument, 0, 's' },
+	{ 0, 0, 0, 0 }
+};
+
+unsigned int rm_start(rm_job_t *rm)
+{
+	rm->recursive = 0;
+	rm->force = 0;
+	rm->safe = 0;
+
+	/* Make sure we can allocate enough memory to store
+	 * what is needed in the job structure */
+	if (NULL == (rm->nwd = (char *) malloc(PATH_MAX)))
+		return 0;
+	memset(rm->nwd, 0, sizeof(rm->nwd));
+
+	if (NULL == (rm->owd = (char *) malloc(PATH_MAX)))
+		return 0;
+	memset(rm->owd, 0, sizeof(rm->owd));
+
+	if (NULL == (rm->cwd = (char *) malloc(PATH_MAX)))
+		return 0;
+	memset(rm->cwd, 0, sizeof(rm->cwd));
+
+	chdir(".");
+
+	if (NULL == (getcwd(rm->owd, PATH_MAX)))
+		return 0;
+
+	return 1;
+}
+
+void rm_end(rm_job_t *rm)
+{
+	if (NULL != rm->nwd)
+		free(rm->nwd);
+
+	if (NULL != rm->owd)
+		free(rm->owd);
+
+	if (NULL != rm->cwd)
+		free(rm->cwd);
+
+	return;
+}
+
+unsigned int rm_recursive(const char *path)
+{
+	int rc;
+
+	/* First see if it will just go away */
+	rc = rmdir(path);
+	if (rc == 0)
+		return 0;
+
+	/* Its not empty, recursively scan it */
+	cli_error(CL_ENOTSUP,
+		"Can not remove %s, directory not empty", path);
+	return 1;
+}
+
+unsigned int rm_single(const char *path)
+{
+	if (unlink(path)) {
+		cli_error(CL_EFAIL, "rm: could not remove file %s", path);
+		return 1;
+	}
+	return 0;
+}
+
+unsigned int rm_scope(const char *path)
+{
+	int fd;
+	DIR *dirp;
+
+	dirp = opendir(path);
+	if (dirp) {
+		closedir(dirp);
+		return RM_DIR;
+	}
+
+	fd = open(path, O_RDONLY);
+	if (fd > 0) {
+		close(fd);
+		return RM_FILE;
+	}
+
+	return RM_BOGUS;
+}
+
+/* Dispays help for rm in various levels */
+void * help_cmd_rm(unsigned int level)
+{
+	if (level == HELP_SHORT) {
+		printf("`%s' removes files and directories.\n", cmdname);
+	} else {
+		help_cmd_rm(HELP_SHORT);
+		printf(
+		"Usage:  %s [options] <path>\n"
+		"Options:\n"
+		"  -h, --help       A short option summary\n"
+		"  -v, --version    Print version information and exit\n"
+		"  -r, --recursive  Recursively remove sub directories\n"
+		"  -f, --force      Do not prompt prior to removing files\n"
+		"  -s, --safe       Stop if directories change during removal\n\n"
+		"Currently, %s is under development, some options don't work.\n",
+		cmdname, cmdname);
+	}
+	return CMD_VOID;
+}
+
+/* Main entry point for rm, accepts an array of arguments */
+int * cmd_rm(char **argv)
+{
+	unsigned int argc;
+	unsigned int i, scope, ret = 0;
+	int c, opt_ind;
+	size_t len;
+	char *buff = NULL;
+
+	for (argc = 0; argv[argc] != NULL; argc ++);
+	if (argc < 2) {
+		cli_error(CL_EFAIL,
+			"%s: insufficient arguments. Try %s --help", cmdname, cmdname);
+		return CMD_FAILURE;
+	}
+
+	if (!rm_start(&rm)) {
+		cli_error(CL_ENOMEM, "%s: could not initialize", cmdname);
+		rm_end(&rm);
+		return CMD_FAILURE;
+	}
+
+	for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
+		c = getopt_long(argc, argv, "hvrfs", long_options, &opt_ind);
+		switch (c) {
+		case 'h':
+			help_cmd_rm(HELP_LONG);
+			return CMD_SUCCESS;
+		case 'v':
+			printf("%s\n", RM_VERSION);
+			return CMD_SUCCESS;
+		case 'r':
+			rm.recursive = 1;
+			break;
+		case 'f':
+			rm.force = 1;
+			break;
+		case 's':
+			rm.safe = 1;
+			break;
+		}
+	}
+
+	if (optind == argc) {
+		cli_error(CL_EFAIL,
+			"%s: insufficient arguments. Try %s --help", cmdname, cmdname);
+		rm_end(&rm);
+		return CMD_FAILURE;
+	}
+
+	i = optind;
+	while (NULL != argv[i]) {
+		len = strlen(argv[i]) + 2;
+		buff = (char *) realloc(buff, len);
+		assert(buff != NULL);
+		memset(buff, 0, sizeof(buff));
+		snprintf(buff, len, argv[i]);
+
+		scope = rm_scope(buff);
+		switch (scope) {
+		case RM_BOGUS: /* FIXME */
+		case RM_FILE:
+			ret += rm_single(buff);
+			break;
+		case RM_DIR:
+			if (! rm.recursive) {
+				printf("%s is a directory, use -r to remove it.\n", buff);
+				ret ++;
+			} else {
+				ret += rm_recursive(buff);
+			}
+			break;
+		}
+		i++;
+	}
+
+	if (NULL != buff)
+		free(buff);
+
+	rm_end(&rm);
+
+	if (ret)
+		return CMD_FAILURE;
+	else
+		return CMD_SUCCESS;
+}
+
Index: uspace/app/bdsh/cmds/modules/rm/rm.def
===================================================================
--- uspace/app/bdsh/cmds/modules/rm/rm.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/rm/rm.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,16 @@
+{
+	"rm",
+	"The rm command",
+	&cmd_rm,
+	&help_cmd_rm,
+	0
+},
+
+{
+	"del",
+	NULL,
+	&cmd_rm,
+	&help_cmd_rm,
+	0
+},
+
Index: uspace/app/bdsh/cmds/modules/rm/rm.h
===================================================================
--- uspace/app/bdsh/cmds/modules/rm/rm.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/rm/rm.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,43 @@
+#ifndef RM_H
+#define RM_H
+
+/* Return values for rm_scope() */
+#define RM_BOGUS 0
+#define RM_FILE  1
+#define RM_DIR   2
+
+/* Flags for rm_update() */
+#define _RM_ENTRY   0
+#define _RM_ADVANCE 1
+#define _RM_REWIND  2
+#define _RM_EXIT    3
+
+/* A simple job structure */
+typedef struct {
+	/* Options set at run time */
+	unsigned int force;      /* -f option */
+	unsigned int recursive;  /* -r option */
+	unsigned int safe;       /* -s option */
+
+	/* Keeps track of the job in progress */
+	int advance; /* How far deep we've gone since entering */
+	DIR *entry;  /* Entry point to the tree being removed */
+	char *owd;   /* Where we were when we invoked rm */
+	char *cwd;   /* Current directory being transversed */
+	char *nwd;   /* Next directory to be transversed */
+
+	/* Counters */
+	int f_removed; /* Number of files unlinked */
+	int d_removed; /* Number of directories unlinked */
+} rm_job_t;
+
+
+/* Prototypes for the rm command, excluding entry points */
+extern unsigned int rm_start(rm_job_t *);
+extern void rm_end(rm_job_t *rm);
+extern unsigned int rm_recursive(const char *);
+extern unsigned int rm_single(const char *);
+extern unsigned int rm_scope(const char *);
+
+#endif /* RM_H */
+
Index: uspace/app/bdsh/cmds/modules/touch/entry.h
===================================================================
--- uspace/app/bdsh/cmds/modules/touch/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/touch/entry.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,9 @@
+#ifndef TOUCH_ENTRY_H
+#define TOUCH_ENTRY_H
+
+/* Entry points for the touch command */
+extern int * cmd_touch(char **);
+extern void * help_cmd_touch(unsigned int);
+
+#endif /* TOUCH_ENTRY_H */
+
Index: uspace/app/bdsh/cmds/modules/touch/touch.c
===================================================================
--- uspace/app/bdsh/cmds/modules/touch/touch.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/touch/touch.c	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,108 @@
+/* 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.
+ */
+
+/* TODO: Options that people would expect, such as not creating the file if
+ * it doesn't exist, specifying the access time, etc */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/types.h>
+
+#include "config.h"
+#include "errors.h"
+#include "util.h"
+#include "entry.h"
+#include "touch.h"
+#include "cmds.h"
+
+static char *cmdname = "touch";
+
+/* Dispays help for touch in various levels */
+void * help_cmd_touch(unsigned int level)
+{
+	if (level == HELP_SHORT) {
+		printf("`%s' updates access times for files\n", cmdname);
+	} else {
+		help_cmd_touch(HELP_SHORT);
+		printf("  `%s' <file>, if the file does not exist it will be "
+				"created\n", cmdname);
+	}
+
+	return CMD_VOID;
+}
+
+/* Main entry point for touch, accepts an array of arguments */
+int * cmd_touch(char **argv)
+{
+	unsigned int argc, i = 0, ret = 0;
+	int fd;
+	char *buff = NULL;
+
+	DIR *dirp;
+
+	/* Count the arguments */
+	for (argc = 0; argv[argc] != NULL; argc ++);
+
+	if (argc == 1) {
+		printf("%s - incorrect number of arguments. Try `help %s extended'\n",
+			cmdname, cmdname);
+		return CMD_FAILURE;
+	}
+
+	for (i = 1; i < argc; i ++) {
+		buff = cli_strdup(argv[i]);
+		dirp = opendir(buff);
+		if (dirp) {
+			cli_error(CL_ENOTSUP, "%s is a directory", buff);
+			closedir(dirp);
+			ret ++;
+			continue;
+		}
+
+		fd = open(buff, O_RDWR | O_CREAT);
+		if (fd < 0) {
+			cli_error(CL_EFAIL, "Could not update / create %s ", buff);
+			ret ++;
+			continue;
+		} else
+			close(fd);
+
+		free(buff);
+	}
+
+	if (ret)
+		return CMD_FAILURE;
+	else
+		return CMD_SUCCESS;
+}
+
Index: uspace/app/bdsh/cmds/modules/touch/touch.def
===================================================================
--- uspace/app/bdsh/cmds/modules/touch/touch.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/touch/touch.def	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,8 @@
+{
+	"touch",
+	"The touch command",
+	&cmd_touch,
+	&help_cmd_touch,
+	0
+},
+
Index: uspace/app/bdsh/cmds/modules/touch/touch.h
===================================================================
--- uspace/app/bdsh/cmds/modules/touch/touch.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
+++ uspace/app/bdsh/cmds/modules/touch/touch.h	(revision 216d6fc606ae06cb619154c1ca9763af0f2c1978)
@@ -0,0 +1,8 @@
+#ifndef TOUCH_H
+#define TOUCH_H
+
+/* Prototypes for the touch command, excluding entry points */
+
+
+#endif /* TOUCH_H */
+
