Index: uspace/app/bdsh/README
===================================================================
--- uspace/app/bdsh/README	(revision 79872cd42e49e046628c77564cd57e01dec61da6)
+++ uspace/app/bdsh/README	(revision 79872cd42e49e046628c77564cd57e01dec61da6)
@@ -0,0 +1,268 @@
+BDSH - The Brain Dead Shell | Design Documentation
+--------------------------------------------------
+
+Overview:
+=========
+
+BDSH was written as a drop in command line interface for HelenOS to permit
+interactive access to persistent file systems in development. BDSH was
+written from scratch with a very limited userspace standard C library in
+mind. Much like the popular Busybox program, BDSH provides a very limited
+shell with limited common UNIX creature comforts built in.
+
+Porting Busybox (and by extension ASH) would have taken much longer to
+complete, much less make stable due to stark differences between Linux and
+Spartan with regards to IPC, term I/O and process creation. BDSH was written
+and made stable within the space of less than 30 days.
+
+BDSH will eventually evolve and be refined into the HelenOS equivalent
+of Busybox. While BDSH is now very intrinsic to HelenOS, its structure and
+use of strictly lower level functions makes it extremely easy to port.
+
+Design:
+=======
+
+BDSH is made up of three basic components:
+
+ 1. Main i/o, error handling and task management
+ 2. The builtin sub system
+ 3. The module sub system
+
+The main part handles user input, reports errors, spawns external tasks and
+provides a convenient entry point for built-in and modular commands. A simple
+structure, cliuser_t keeps track of the user's vitals, such as their current
+working directory (and eventually uid, home directory, etc if they apply).
+
+This part defines and exposes all functions that are not intrinsic to a
+certain built in or modular command. For instance: string handlers,
+module/builtin search and launch functions, error handlers and other things
+can be found here.
+
+Builtin commands are commands that must have access to cliuser_t, which is
+not exposed to modular commands. For instance, the 'cd' command must update
+the current working directory, which is stored in cliuser_t. As such, the
+entry types for builtin commands are slightly different.
+
+Modular commands do not need anything more than the basic functions that are
+exposed by default. They do not need to modify cliuser_t, they are just self
+contained. A modular command could very easily be made into a stand alone
+program, likewise any stand alone program could easily become a modular
+command.
+
+Both modular and builtin commands share two things in common. Both must have
+two entry points, one to invoke the command and one to invoke a help display
+for the command. Exec (main()) entry points are int * and are expected to
+return a value. Help entry points are void *, no return value is expected.
+
+They are typed as such (from cmds.h):
+
+/* 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);
+
+As you can see, both modular and builtin commands expect an array of
+arguments, however bulitins also expect to be pointed to cliuser_t.
+
+Both are defined with the same simple structure:
+
+/* 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;
+
+NOTE: Builtin commands may grow in this respect, that is why they are
+defined separately.
+
+Builtins, of course, would use the builtin_entry_t type. The name of the
+command is used to associate user input to a possible entry point. The
+description is a short (40 - 60 chars) summary of what the command does. Both
+entry points are then defined, and the restrict value is used to determine a
+commands availability.
+
+Restriction levels are easy, a command is either available exclusively within
+interactive mode, exclusively within non-interactive mode or both. If you are
+looking at a prompt, you are in interactive mode. If you issue a command like
+this:
+
+/sbin/bdsh command [arg1] [arg2]
+
+... you are in non interactive mode. This is done when you need to force the
+parent shell to be the one who actually handles the command, or ensure that
+/sbin/ls was used in lieu of the built in 'ls' when in non-interactive mode.
+
+The values are:
+  0 : Unrestricted
+ -1 : Interactive only
+  1 : Non-interactive only
+
+A script to generate skeletal files for a new command is included, it can be
+found in cmds/mknewcmd. To generate a new modular command named 'foo', which
+should also be reachable by typing 'f00', you would issue this command:
+
+./mknewcmd -n foo -a f00 -t module
+
+This generates all needed files and instructs you on how to include your new
+command in the build and make it accessible. By default, the command will be
+unrestricted. Builtin commands can be created by changing 'module' to
+'builtin'
+
+There are more options to mknewcmd, which allow you to specify the
+description, entry point, help entry point, or restriction. By default, names
+just follow the command such as cmd_foo(), help_cmd_foo(), 'The foo command',
+etc. If you want to see the options and explanations in detail, use
+./mknewcmd --help.
+
+When working with commands, keep in mind that only the main and help entry
+points need to be exposed. If commands share the same functions, put them
+where they are exposed to all commands, without the potential oops of those
+functions going away if the command is eliminated in favor of a stand alone
+external program.
+
+The util.c file is a great place to put those types of functions.
+
+Also, be careful with globals, option structures, etc. The compiler will
+generally tell you if you've made a mistake, however declaring:
+
+volatile int foo
+
+... in a command will allow for anything else to pick it up. Sometimes
+this could be desirable .. other times not. When communicating between
+builtins and the main system, try to use cliuser_t. The one exception
+for this is the cli_quit global, since everything may at some point
+need to check it. Modules should only communicate their return value.
+
+Symbolic constants that everything needs should go in the config.h file,
+however this is not the place to define shared macros.
+
+Making a program into a module
+==============================
+
+If you have some neat program that would be useful as a modular command,
+converting it is not very hard. The following steps should get you through
+the process easily (assuming your program is named 'foo'):
+
+1: Use mknewcmd to generate the skeletal files.
+
+2: Change your "usage()" command as shown:
+     -- void usage(...)
+     ++ void * help_cmd_foo(unsigned int level)
+     -- return;
+     ++ retrn CMD_VOID;
+
+     'level' is either 0 or 1, indicating the level of help requested.
+     If the help / usage function currently exits based on how it is
+     called, you'll need to change it.
+
+3: Change the programs "main()" as shown:
+     -- int main(int argc, char **argv)
+     ++ int * cmd_foo(char **argv)
+     -- return 1;
+     ++ return CMD_FAILURE;
+     -- return 0;
+     ++ return CMD_SUCCESS;
+
+     If main() returns an int that is not 1 or 0 (e.g. 127), cast it as
+     such:
+
+     -- return 127;
+     ++ return (int *) 127;
+
+     NOTE: _ONLY_ the main and help entry points need to return int * or
+     void *, respectively. Also take note that argc has changed. The type
+     for entry points may soon change.
+
+     NOTE: If main is void, you'll need to change it and ensure that its
+     expecting an array of arguments, even if they'll never be read or
+     used. I.e.:
+
+     -- void main(void)
+     ++ int * cmd_foo(char **argv)
+
+     Similararly, do not try to return CMD_VOID within the modules main
+     entry point. If somehow you escape the compiler yelling at you, you
+     will surely see pretty blue and yellow fireworks once its reached.
+
+4: Don't expose more than the entry and help points:
+     -- void my_function(int n)
+     ++ static void my_function(int n)
+
+5: Copy/paste to the stub generated by mknewcmd then add your files to the
+   Makefile. Be sure to add any directories that you made to the SUBDIRS so
+   that a 'make clean' will clean them.
+
+Provided that all functions that your calling are available in the
+userspace C library, your program should compile just fine and appear
+as a modular command.
+
+Overcoming userspace libc obstacles
+===================================
+
+A quick glance through the util.c file will reveal functions like
+cli_strdup(), cli_strtok(), cli_strtok_r() and more. Those are functions
+that were missing from userspace libc when BDSH was born. Later, after
+porting what was needed from FBSD/NBSD, the real functions appeared in
+the userspace libc after being tested in their cli_* implementations.
+
+Those functions remain because they guarantee that bdsh will work even
+on systems that lack them. Additionally, more BDSH specific stuff can
+go into them, such as error handling and reporting when malloc() fails.
+
+You will also notice that FILE, fopen() (and all friends), ato*() and
+other common things might be missing. The HelenOS userspace C library is
+still very young, you are sure to run into something that you want/need
+which is missing.
+
+When that happens, you have three options:
+
+1 - Implement it internally in util.c , when its tested and stable send a
+patch to HelenOS asking for your function to be included in libc. This is
+the best option, as you not only improve BDSH .. but HelenOS as a whole.
+
+2 - Work around it. Not everyone can implement / port fopen() and all of
+its friends. Make open(), read(), write() (etc) work if at all possible.
+
+3 - Send an e-mail to the HelenOS development mailing list. Explain why you
+need the function and what its absence is holding up.
+
+If what you need is part of a library that is typically a shared object, try
+to implement a 'mini' version of it. Currently, all userspace applications
+are statically linked. Giving up creature comforts for size while avoiding
+temporary 'band aids' is never frowned upon.
+
+Most of all, don't get discouraged .. ask for some help prior to giving up
+if you just can't accomplish something with the limited means provided.
+
+Contributing
+============
+
+I will take any well written patch that sanely improves or expands BDSH. Send
+me a patch against the trunk revision, or, if you like a Mercurial repository
+is also maintained at http://echoreply.us/hg/bdsh.hg and kept in sync with
+the trunk.
+
+Please be sure to follow the simple coding standards outlined at
+http://www.helenos.eu/cstyle (mostly just regarding formatting), test your
+changes and make sure your patch applies cleanly against the latest revision.
+
+All patches submitted must be your original code, or a derivative work of
+something licensed under the same 3 clause BSD license as BDSH. See LICENSE
+for more information.
+
+When sending patches, you agree that your work will be published under the
+same 3 clause BSD license as BDSH itself. Failure to ensure that anything
+you used is not under the same or less restrictive license could cause major
+issues for BDSH in the future .. please be sure. Also, please don't forget
+to add yourself in the AUTHORS file, as I am horrible about keeping such
+things up to date.
+
+
+
+
