                    -= NOTES TO PROGRAMMERS/HACKERS =-

Wishing to see the shell developed and not die a quick and dirty death, I
submit some pointers to would be developers:

Status switches can easily be added in `stat.c' by adding new entries in
the switch statement. Shell builtins are defined in the files `shcmds.c',
`alias.c', `vars.c', `assign.c' and `file.c'.  They are defined much like
a C-program in and of themselves, with the number of arguments, the argument
array and the input and output descriptors being passed to the function. Use
of the global variables is not recommended unless you are knowledgeable in the
operation of the shell.  Care should be taken with the use of the global
variables `buf' and `path', as many of ssh's functions use them.

To add builtins, a define should be added to the enum in `cmds.h' and the
NUM_CMDS should be incremented. Also an entry in the command list found at
the start of `parse.c' needs to be inserted in the correct alphabetic
location, then a case statement in shcmds.c which will allow the new command
function to be invoked. One should be able to gleam the calling mechanisms
from the given functions. Someone may want to take the time to remove the
switch altogether and simply put the address of the function to call in the
table in `parse.c' and remove the need for the defines and switch all
together.  If I only had the time, I'd re-write the whole damn thing.

Anyways, for the wretched undergrad with too much time on his hands, here's
a rundown of files and functions in brief:

alias.c
	All of the alias stuff, including the alias and unalias commands.

assign.c
	All of the assign stuff, including the assign and unassign commands.

eval.c
	The expression parser and tokenizer.  Needs to have the order of
	precedence of operators made the same as with C.  The parser is
	recursive decent and pretty easy to follow.  Might also want to
	integrate getnext() into the evaluator.

exe.c
	Where all the fun stuff happens. This is where shell redirection,
	piping, and execution happens.  It's a major chunk of the real
	shell.  I don't think this stuff could be improved dramatically.

file.c
	This is where all the file commands are defined.

init.c
	All the initialization functions.

key.c
	The command line input routines.  Serious improvement possible
	here.  Too much time is wasted checking if a key belongs to a macro
	in my humble opinion.  Just typing shouldn't eat up so much CPU
	time.  A hash table lookup perhaps?

parse.c
	Functions to split up a line into little words the shell can deal
	with. Command strings `...` are parsed and executed here as well.

shcmds.c
	The builtin-invoker and most of the builtin commands are defined
	here.

shell.c
	The other big chunk of the real shell. Command line args are parsed
	here. Sourcing and command execution is overseen here as well as
	the all-important SIGCHLD handler.

stat.c
	The routines to parse the status switches.

vars.c
	The routines to parse variables and the set and unset commands.

wc.c
	Toms wildcard routines, these are fine, don't touch them unless you
	know what you are doing.  Lots of useful routines in here if you
	can figure out how to extract them.  Feel free to import them into
	your own programs, but remember to give credit where credit is due.

cmds.h
	Defines for all the commands.

shell.h
	Pretty much all the structures that the shell uses are defined
	here.  Not all of them, but a good lot of 'em.


Here's a few things I think that should be done straight away:

Tokenize everything and keep it that way until it's time to execute the
command.  Would cut down tremendously on the number of strlen()'s and
strcmp()'s done (profile it sometime, you'll be amazed!). Or maybe just
figure out how to malloc less.  Exe.c is about the only file I feel is
truly optimized in the scope of the current shell, although I think I
could probably remove mallocing in exe.c altogether.  Even simple
tokenization (like remembering that a word is really a string, but have the
quotes stripped off already, this would eliminate quite a few mallocs when it
comes time to execute the command).

key.c could stand to be re-written entirely, but keep the macro support
similar to what it is, I don't like the idea of making your shell emulate
emacs or vi, for crying out loud, you don't need a freaking editor built
into your shell, it just makes the shell much larger for very little gain.
Besides, I don't think emacs or vi is as intuitive as my macro setup.

Speed and size are essential.  A special printf should be made for the
shell.  I don't need all the features of printf, just %s, %d and %c.
Formatting options can be gotten around.  Many printf's can probably be
exchanged for puts()'s and fputs()'s.

Some alias behavior needs to be fixed with reguards to alias substitution
of words in a pipeline while enclosed in parens.  It shouldn't do it.  By
the same token, perhaps it would be best to recursive alias parse, like csh.

The variable stuff could stand to be made more "robust" and the set command
should be made to set individual words in a string var and maybe even
individual characters.  Should probably figure out a way to keep the
recursive stuff from recursing too much.  Perhaps a maximum of 10-20 levels
of recursion.

The command substitution (`...`) needs to be moved out of the split-line()
function and into it's own section, so that it will work properly in shell
scripts without a lot of paren and eval hokus-pokus.  Also since shell level
pipes are a reality in this final version, the way `...` works should
probably be made more along those lines. i.e. remove `...` altogether and
make something like:

	pwd >% xx &! set wd = $<% xx

Where $<% places the output of pwd on the command line for the set command.
Which I would think would be far less kludgy and certainly would work in a
script file. As far as I'm concerned, I don't care about csh compatibility
anymore.  You can do more in ssh...

The secondary password support is far to easily circumvented on machines
with ftp access.  Should be encrypted at least.  Perhaps the secondary
password could be put in a root write only file with a setuid program to
set the password, like passwd works.  Could be made fairly simply.  A
secondary password is perhaps pointless anyway.

Amazing as it may seem, I'm not entirely unhappy with the shell as it is,
in fact I'm fairly pleased with it. One is just never really done with these
projects you know, and who knows, maybe somehow I'll manage to find a way to
update all of this stuff myself.

Well, if you have questions and/or ideas, by all means drop me a line. I can
be reached for the time being at ice@judy.indstate.edu... If I've moved on
try contacting dark@judy.indstate.edu.  If all else fails figure it out
yourself.

Have fun!

							- Steve Baker
