Script started on Fri Apr 26 19:17:35 2002
ws12% car [Kt README

README for CSCI-e215

Russell J Lowke

Assignment 5: "smsh"

______

files: smsh.h          // header file for smsh
       smsh.c          // smsh main .c code
       splitline.h     // header file for splitline
       splitline.c     // splitline .c code
       varlib.h        // header file for varlib
       varlib.c        // varlib .c code
       Makefile        // makefile to compile smsh
       Plan            // general plan for smsh
       typescript      // typescript for smsh
       README          // this file
______

Notes: The   ~lib215/hw/smsh/test.smsh  adds some extra output
only when running in script (typescript) mode on Test 4 - it
still passes the test fine though.

ws12% touch *.c

ws12% make

gcc -g -Wall -c smsh.c
gcc -g -Wall -c varlib.c
gcc -g -Wall -c splitline.c
gcc -g -Wall smsh.o varlib.o splitline.o -o smsh
ws12% maketouch *.c[9Dcat README[10Dexit[K~lib215/hw/smsh/test.smsh

  Testing ./smsh as of Fri Apr 26 19:18:10 EDT 2002
-rwx------   1 lowke    extdeg      73728 Apr 26 19:18 ./smsh

        Test 1: Does the program read commands from a script? 
                OK
        Test 2: Does cd work correctly? 
                /tmp
/tmp
cd works when the directory exists
                /bad.directory: No such file or directory
cd detects bad directories
        Test 3: Does the shell do variable substitution correctly?
                and ignore dollar signs when asked?
                OK
        Test 4: Does the shell read in variables correctly?
                DISPLAY=:0.0
EDITOR=pico
EXINIT=set exrc showmode redraw ic ai |map g 1G
GROUP=extdeg
HOME=/home/l/o/lowke
HOST=ws12
HOSTNAME=ws12
HOSTTYPE=alpha
IFS=    

ISTYPE=ws
LOGNAME=lowke
MACHTYPE=alpha
MAIL=/home/l/o/lowke/.inbox
MAILCAPS=/usr/local/etc/Xmailcap
MAILCHECK=600
MANPATH=/usr/local/man:/usr/share/man:/usr/local/lib/perl5/man
MOZILLA_HOME=/usr/local/navigator
NEXINIT=set ruler escapetime=2 |map g 1G
OSTYPE=osf1
PATH=/usr/local/bin/X11:/usr/bin/X11:/usr/local/bin:/usr/local/stata:/usr/bin:/usr/sbin:/sbin:/bin:/usr/ucb:/usr/etc:/usr/ccs/bin
PROG=./smsh
PWD=/home/l/o/lowke/215/smsh
SHELL=/shells/tcsh
SHLVL=2
TERM=xterm
TERMINFO=/usr/local/share/terminfo
TETEXDIR=/usr/local/lib/teTeX
TMPDIR=/tmp
USER=lowke
VENDOR=dec
VISUAL=pico
WINDOWID=20971534
mailbox=/home/l/o/lowke/.inbox
OK
        Test 5a: Does the if command work?
                OK
        Test 5b: Does the if detect missing thens ?
                unexpected error: IF structure without THEN
OK
        Test 5c: Does the if command find unexpected EOFS?
                root:*:0:1:system PRIVILEGED account:/:/bin/sh
this system has a root login
that is a good thing
unexpected error: IF structure without FI
OK
        Test 5d: Does the if catch missing ifs?
                root:*:0:1:system PRIVILEGED account:/:/bin/sh
unexpected error: THEN without an IF
OK
        Test 6: Does the shell process the exit built-in ok?
                OK
        Test 7: A manual test
                
        Does your shell reject assignment statements of the
        form   
                9xyz=tuna  
        or      x.y=fun
        
         That is, assignments to names that are not legal
        variable identifiers
ws12% 

ws12% ./smsh

> 9xyz=tuna
9xyz: is not an identifier
> x.y=fun
x.y: is not an identifier
> exit
ws12% cat Plan

DESIGN OUTLINE for CSCI-e215 Assignment 5
Russell J Lowke

    smsh.c
    
      AUTHOR: Russell Lowke
   CSCIE-215: Assignment Five

       Usage: smsh [script file name]

  [var]=[value]  Assigns an internal var to a value
            set  prints a list of all saved values
         export  exports a value
   exit [value]  exits smsh with [value]
     read [var]  reads into [var] an assignment input from the keyboard
  cd [pathname]  changes the current working directory
  if [list ;then list ... [;else list] ;fi]
                 Executes the list following if and, if it returns a 0
                 (zero)exit status, executes the list following the first
                 then. Otherwise, the else list is executed.

 Description: Create a Unix shell that allows users to manage processes
              such as running programs and controlling input.
              The shell has its own scripting language with variables and
              if statements.

      Method: Main reads from file or stdin, taking input and sending it to
              splitline (splitline.c) to have variables substituted and to
              be parsed into arguments.  varlib (varlib.c) is used to keep 
              track of all variables added by the user, and to 
              get unix environment vars.
              Once arguments have been isolated they are sent to
              handleCommand to be processed by an appropriate function,
              in most cases a command is external, in which case it is
              handled by execute(), who forks and exec's the command.
              handleCommand also deals with IF related statements, keeping
              careful track of their progress and only allowing the
              correct then/else blocks to be processed.

              
              smsh.c methods:

                main - main checks for a script file for input, otherwise
                       uses stdin input. the loop reads input line by line.  
                       Each line has variables ($VAR)subsititued, then
                       is split into its individual arguments.
                       Finally, the arg count and all args are pased into
                       handleCommand() which returns a state. If this state
                       is != NORMAL on exit then there is a
                       scripting bug ("no fi")
               setup - All initialization goes here.
       handleCommand - Works out where to pass the args to.
                       Internal commands are set to their own specific
                       function, external commands are delt with by execute().
                       More importantly, handleCommand deals with the 
                       possibility of if statements, by use of an 'ifState'
                       var.  This var keeps track of the progress of the
                       if statement.  HandleCommand returns the ifState,
                       which main needs, in case it reaches EOF without
                       a concludeing fi.
               fatal - Fatal error message to stderr then exit (never returns)
        gracefulExit - cleanup smsh before exiting
    get_next_command - read next line from input_stream.  Return FALSE on EOF
             execute - execute commands in argv.
                       Uses fork to make a child duplicate to exe
                       if sucessful exe will exit itself. information of
                       child is held in child_info
             readCmd - Assigns internal var [varname] equal to keyboard input
         getKeyInput - Reads input from the keyboard, placing it in buffer
               cdCmd - cd command, calls chdir with a path.
              report - Report of important vars in info from child
                       Good for debugging, this function is not used by smsh


              splitline.c methods:
              
              splitline contains fuctions to parse strings and general string
              handling, also has fuctions to check for valid variable names.

              
           splitline - parse line [cmdline] into an array of strings
                       cmdline has a string of white-space separated tokens
                       put the addresses of the tokens in the array argv[]
                       put their number in *argcp and do not put more than max
                       in argv or suffer dire consequences!
                       NOTE: this modifies cmdline
                       returns FALSE on too many args or zero args.
                       TRUE for ok stuff
      substituteVars - search through original string [orgStr] looking for
                       embeded vars ('$') and backslash ('\\').  
                       In case of backslash read the next char 'as is',
                       otherwise, in case of viarable, substitute in the
                       variables value.
                       Put the result into new string [newStr].
        validVarName - Test string [varName] to see if it is a legal variable
                       name. Done primarily using isValidVarChar - but also
                       tests for 1st char not being a number
      isValidVarChar - Check if a char [c] is considered legal when in a
                       variable name.
                       Legal values are: numbers from 0 through 9
                                        A - Z, a - z, and underscore.

       Notes: VLtable2environ in execute() calls malloc, but memory is
              free()d with exec
ws12% exit

exit

script done on Fri Apr 26 19:20:05 2002
