%%s 25/13/3440 %%d D 1.14 01-Aug-83 09:49:30 tools 14 13 %%c Restored hshdef to conditionalize the definition of internal commands %%c upon the existence of LARGE_ADDRESS_SPACE. This was changed on RSX %%c when the memory-overlaid version of the history shell was being %%c developed, to the detriment of functionality on non-RSX systems. %%s 50/27/3403 %%d D 1.13 16-Jun-83 10:59:46 sventek 13 12 %%c Replaced runtime calls to `impath' with static declaration of search %%c path using STD_PATH. %%s 37/37/3393 %%d D 1.12 15-Jun-83 15:25:22 sventek 12 11 %%c Removed trailing periods from quoted strings, as they are no longer needed. %%s 3/3/3427 %%d D 1.11 13-Jun-83 12:27:49 sventek 11 10 %%c Converted references to `select' to `switch'. %%s 85/25/3345 %%d D 1.10 04-Feb-83 15:09:52 sventek 10 9 %%c Made appropriate modifications to permit the memory-overlaid version %%c of the history shell (with aliases) to be build for RSX-11M. The modules %%c affected were: %%c %%c 1. hshdef had the conditional on LARGE_ADDRESS_SPACE removed. %%c 2. sh.w`sh.r`dask was modified to call Prompt instead of prompt. This was %%c after much soul searching to determine whether the response to the ask %%c command should be recorded in the history. It was finally decided NOT! %%c 3. hsh.tkb and hsh.odl were added to reflect the current situation. A %%c future update to these files will be necessary to permit these files %%c to be constructed during toolgen from the information contained in the %%c tools.tkb file. %%s 8/8/3362 %%d D 1.9 13-Jan-83 14:57:32 sventek 9 8 %%c Modified routines `shcom', `dask' and `procdf' to reflect the new %%c multi-statement syntax in clauses in the for statement. %%s 24/12/3346 %%d D 1.8 16-Dec-82 18:20:19 sventek 8 7 %%c Modified sh.r`param to conditionally include code to prevent gobbling %%c of the '$' when the token found immediately after the $ is not defined. %%c An expression of the form $ is still replaced by nothing if it %%c is not defined. The code to support this is conditionalized on the %%c symbol KEEP_DOLLARS. A commented define for this symbol was added to %%c sh.r`defns, such that enabling the feature is simple. This is a generalization %%c of a modification made by Dave Martin. This feature has great value on %%c VMS, where many of the system logical names have '$' in them. %%s 525/264/2833 %%d D 1.7 24-Nov-82 15:52:54 sventek 7 6 %%c Added additional support for the following shell commands %%c alias ask param unalias unparam source %%c Also performed quite a bit of general cleanup on the code. %%c Modified documentation to track the source changes. %%s 317/32/2780 %%d D 1.6 23-Nov-82 11:14:51 sventek 6 5 %%c Modified several routines to support the new shell commands param, alias %%c and ask. Added definition file shdef to be used when building sh, and %%c modified hshdef and eshdef to define DO_PARAM to enable these new features. %%c The aliases or parameters are not exported to children, although that is %%c an obvious next step. The files affected are: %%c sh.w`shcmd, sh.w`shflag, sh.w`shdef (new), sh.w`hshdef, sh.w`eshdef, %%c sh.w`sh.r`cmdtyp, sh.w`sh.r`initsh, sh.w`sh.r`shcom and sh.w`sh.r`shellc. %%s 9/4/2803 %%d D 1.5 02-Nov-82 13:32:07 sventek 5 4 %%c Modified sh.w`sh.r`defns to reduce the symbols TREESIZE and MAXTOK if %%c DO_STARTUP is defined. This is to permit hsh to fit on RSX-11M. %%s 7/7/2800 %%d D 1.4 01-Nov-82 19:09:40 sventek 4 3 %%c Made appropriate modifications to convert all occurrences of the string %%c ''' to the string '@''. The previous form is now a syntax error, due to %%c the extension to ratfor to permit "'" to be used as a quoted string %%c delimiter %%s 40/20/2767 %%d D 1.3 25-Oct-82 11:39:15 sventek 3 2 %%c Experienced problems with inheritance of redirection for STDOUT and ERROUT %%c for parenthesized commands. In particular: %%c %%c (first; second) >>file %%c %%c expanded into %%c %%c first >>file %%c second >>>file %%c %%c Also noticed problems with initialization of redirection stuff, such that %%c if a parenthesized command failed in mid-command, the next command could %%c experience incorrect redirection behavior. %%c %%c To fix this, modified the following files: %%c sh.w`stdsub %%c sh.w`sh.r`dosemi %%c sh.w`sh.r`errf %%c sh.w`sh.r`execut %%c sh.w`sh.r`outf %%s 4/4/2783 %%d D 1.2 09-Apr-82 10:46:02 j 2 1 %%c Reordered the statements in sh.w`sh.r`rlogin to conform with normal %%c statement ordering. Moved the string declaration after all other %%c declarations and before the first executable statement. %%s 0/0/0 %%d D 1.1 25-Mar-82 12:13:36 v1.1 1 0 %%c Version 1.1 is the Spring 1982 Distribution of the LBL/Hughes release %%c of the Software Tools Virtual Operating System software and documentation. %%T %%I 1 %%D 6 #-h- eshdef 123 asc 25-mar-82 08:45:05 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%D 7 #-h- eshdef 141 asc 23-nov-82 10:48:46 sventek (joseph sventek) %%E 7 %%E 6 %%I 7 %%D 12 #-h- eshdef 776 asc 24-nov-82 14:09:09 sventek (joseph sventek) %%E 12 %%E 7 %%I 12 #-h- eshdef 775 asc 15-jun-83 15:05:05 sventek (joseph sventek) %%E 12 define(prompt,ledpmt) #define(IMBED_ED,) define(DO_STARTUP,) %%D 12 define(USE_STRING,"usage: esh [-cdnvx] [file [arguments]].") %%E 12 %%D 6 #-h- hshdef 104 asc 25-mar-82 08:45:06 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%I 12 define(USE_STRING,"usage: esh [-cdnvx] [file [arguments]]") %%E 12 define(DO_PARAM,) %%D 7 #-h- hshdef 158 asc 21-nov-82 18:26:43 sventek (joseph sventek) %%E 7 %%E 6 %%I 7 define(INT_COMMANDS,"cd@1ho@2home@3logout@4path@5von@6voff@7xon@10xoff@11#@12_ alias@13param@14ask@15source@16unalias@17unparam@20") define(C_CD,8%1) define(C_HO,8%2) define(C_HOME,8%3) define(C_LOGOUT,8%4) define(C_PATH,8%5) define(C_VON,8%6) define(C_VOFF,8%7) define(C_XON,8%10) define(C_XOFF,8%11) define(C_COMMENT,8%12) define(C_ALIAS,8%13) define(C_PARAM,8%14) define(C_ASK,8%15) define(C_SOURCE,8%16) define(C_UNALIAS,8%17) define(C_UNPARAM,8%20) ifdef(IMBED_ED) define(INT_COMMANDS,"cd@1ho@2home@3logout@4path@5von@6voff@7xon@10xoff@11#@12_ alias@13param@14ask@15source@16unalias@17unparam@20e@21") define(C_E,8%21) enddef %%D 10 #-h- hshdef 646 asc 24-nov-82 14:09:10 sventek (joseph sventek) %%E 10 %%E 7 %%I 10 %%D 12 #-h- hshdef 576 asc 04-feb-83 14:21:20 sventek (joseph sventek) %%E 12 %%E 10 %%I 12 %%D 13 #-h- hshdef 575 asc 15-jun-83 15:05:06 sventek (joseph sventek) %%E 13 %%E 12 %%I 13 %%D 14 #-h- hshdef 375 asc 16-jun-83 10:30:44 sventek (joseph sventek) %%E 14 %%E 13 %%I 14 #-h- hshdef 689 asc 01-aug-83 09:30:42 tools (lblh csam sventek) %%E 14 define(prompt,logpmt) define(DO_STARTUP,) %%D 12 define(USE_STRING,"usage: hsh [-cdnvx] [file [arguments]].") %%E 12 %%I 6 %%D 10 ifdef(LARGE_ADDRESS_SPACE) define(DO_PARAM,) %%E 10 %%I 7 %%D 10 define(INT_COMMANDS,"cd@1ho@2home@3logout@4path@5von@6voff@7xon@10xoff@11#@12_ %%E 10 %%I 10 %%I 12 %%D 14 define(USE_STRING,"usage: hsh [-cdnvx] [file [arguments]]") %%E 14 %%E 12 %%D 13 define(DO_PARAM,) define(INT_COMMANDS,"cd@1ho@2home@3logout@4path@5von@6voff@7xon@10xoff@11#@12_ %%E 13 %%E 10 %%D 13 alias@13param@14ask@15source@16unalias@17unparam@20") %%E 13 %%D 10 define(C_CD,8%1) define(C_HO,8%2) define(C_HOME,8%3) define(C_LOGOUT,8%4) define(C_PATH,8%5) define(C_VON,8%6) define(C_VOFF,8%7) define(C_XON,8%10) define(C_XOFF,8%11) define(C_COMMENT,8%12) define(C_ALIAS,8%13) define(C_PARAM,8%14) define(C_ASK,8%15) define(C_SOURCE,8%16) define(C_UNALIAS,8%17) define(C_UNPARAM,8%20) %%E 10 %%E 7 %%D 10 enddef %%E 10 %%E 6 %%I 10 %%I 13 %%D 14 define(INT_COMMANDS,"cd@1ho@2home@3logout@4path@5von@6voff@7xon@10xoff@11#@12") %%E 14 %%E 13 %%D 14 define(C_CD,8%1) define(C_HO,8%2) define(C_HOME,8%3) define(C_LOGOUT,8%4) define(C_PATH,8%5) define(C_VON,8%6) define(C_VOFF,8%7) define(C_XON,8%10) define(C_XOFF,8%11) define(C_COMMENT,8%12) %%E 14 %%D 13 define(C_ALIAS,8%13) define(C_PARAM,8%14) define(C_ASK,8%15) define(C_SOURCE,8%16) define(C_UNALIAS,8%17) define(C_UNPARAM,8%20) %%E 13 %%E 10 %%I 14 define(USE_STRING,"usage: hsh [-cdnvx] [file [arguments]].") ifdef(LARGE_ADDRESS_SPACE) define(DO_PARAM,) define(INT_COMMANDS,"cd@1ho@2home@3logout@4path@5von@6voff@7xon@10xoff@11#@12_ alias@13param@14ask@15source@16unalias@17unparam@20") define(C_CD,8%1) define(C_HO,8%2) define(C_HOME,8%3) define(C_LOGOUT,8%4) define(C_PATH,8%5) define(C_VON,8%6) define(C_VOFF,8%7) define(C_XON,8%10) define(C_XOFF,8%11) define(C_COMMENT,8%12) define(C_ALIAS,8%13) define(C_PARAM,8%14) define(C_ASK,8%15) define(C_SOURCE,8%16) define(C_UNALIAS,8%17) define(C_UNPARAM,8%20) elsedef # rely upon defaults in sh.r`defns enddef %%E 14 #-h- cpars 537 asc 25-mar-82 08:45:07 v1.1 (sw-tools v1.1) # /cpars/ - holds token and tree info for shell # put on a file called 'cpars' # Used only by the shell common /cpars/ tkbuf(TSIZE, MAXTOK), tree(TREESIZE), stack(MAXSTACK), treend, pp, ibuf(MAXLINE) integer tkbuf #token table for parsing integer tree #parse tree integer stack #push down stack for tokens integer treend #next available tree node; init by parse integer pp #push down counter; init by parse character ibuf #input buffer #-h- csclin 160 asc 25-mar-82 08:45:11 v1.1 (sw-tools v1.1) ## csclin - scratch line for shell # put on a file called 'csclin' common / csclin / lin(MAXLINE) character lin # scratch line for use throughout the shell. %%D 6 #-h- shflag 900 asc 25-mar-82 08:45:12 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%D 7 #-h- shflag 946 asc 21-nov-82 17:51:38 sventek (joseph sventek) %%E 7 %%E 6 %%I 7 #-h- shflag 934 asc 23-nov-82 22:40:10 sventek (joseph sventek) %%E 7 # shflag - common block to hold shell flags # put on a file called 'shflag' # Used only by the shell common /shflag/ exec, prlin, prcom, carg, drop, cargdn, %%D 6 shin, logfd, inunit, %%E 6 %%I 6 %%D 7 shin, logfd, inunit, table, %%E 7 %%E 6 %%I 7 shin, depth, unit(MAX_NEST), table, %%E 7 clin(MAXLINE) integer exec # flag to cause/suppress command execution # init = YES integer prlin # flag to cause printing of lines as read # init = NO integer prcom # flag to cause printing of command as executed # init = NO integer carg # flag to cause execution of shell command line as input # init = NO integer drop # flag to cause drop-through to native CLI upon search # error - init = YES integer cargdn # YES if -c & arguments have been fetched. %%D 7 integer shin # file identifier for shell input (generally STDIN) integer logfd # open unit for reading login.sh integer inunit # input unit for shell %%E 7 %%I 6 %%I 7 integer shin # current input unit == unit(depth) integer depth # depth of open input units filedes unit # array of open input units %%E 7 pointer table # lookup table pointer %%E 6 character clin # buffer to hold shell arg to be used as input %%D 3 #-h- stdsub 1131 asc 25-mar-82 08:45:12 v1.1 (sw-tools v1.1) %%E 3 %%I 3 %%D 13 #-h- stdsub 1218 asc 25-oct-82 10:29:13 sventek (joseph sventek) %%E 13 %%E 3 %%I 13 #-h- stdsub 1124 asc 16-jun-83 10:30:45 sventek (joseph sventek) %%E 13 # /stdsub/ - common block holding file info for shell # put on a file named 'stdsub' # Used only by the shell common /stdsub/ in, cin(MAXSTACK), out, cout(MAXSTACK), er, cerr(MAXSTACK), aout(MAXSTACK), %%I 3 aerr(MAXSTACK), %%E 3 script, pctr, pfile(MAXSTACK), hfile(FILENAMESIZE), input(FILENAMESIZE), sh(FILENAMESIZE), %%D 13 spath(MAXPATHSIZE), %%E 13 olddir(FILENAMESIZE), homedr(FILENAMESIZE) integer in # input stack count integer cin # input substitution stack integer out # output stack count integer cout # output stack integer er # errout stack count integer cerr # errout stack %%D 3 integer aout # append flag %%E 3 %%I 3 integer aout # append flag for standard output integer aerr # append flag for standard error %%E 3 integer script # flag showing if script file being processed integer pctr # running pipe count character pfile # names of pipe files character hfile # names of heredocument files character input # holds name of standard input file for script # init input(1) = EOS character sh # holds name of shell for script and background %%D 13 character spath # search path for loccom calls - initialized by initsh %%E 13 character olddir # name of `previous' directory. character homedr # name of home directory. %%D 6 #-h- shcmd 636 asc 25-mar-82 08:45:16 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%D 7 #-h- shcmd 854 asc 21-nov-82 17:51:40 sventek (joseph sventek) %%E 7 %%E 6 %%D 7 ## ShCmd -- Common block holding shell commands # Put on a file called 'shcmd' # Used only by the shell common /shcmd/ cd(3), e(2), ho(3), home(5), logout(7), von(4), voff(5), xon(4), xoff(5), %%E 7 %%I 6 %%D 7 param(6), alias(6), ask(4), %%E 7 %%E 6 %%D 7 shopth(5) character cd # change working directory character e # Enter embedded editor character ho # change to home directory character home # synonym for ``ho'' character logout # logout from shell character von # equivalent to `-v' in command line character voff # turns off `von' character xon # equivalent to `xon' in command line character xoff # turns off `xon' %%E 7 %%I 6 %%D 7 character param # command to set parameter character alias # command to define an alias character ask # command to ask for parameter value %%E 7 %%E 6 %%D 7 character shopth # command to show search path %%E 7 %%D 2 #-h- sh.r 38879 asc 25-mar-82 08:45:31 v1.1 (sw-tools v1.1) %%E 2 %%I 2 %%D 3 #-h- sh.r 38872 asc 09-apr-82 10:29:32 j (sventek j) %%E 3 %%E 2 %%I 3 %%D 4 #-h- sh.r 39189 asc 25-oct-82 10:29:21 sventek (joseph sventek) %%E 4 %%E 3 %%I 4 %%D 5 #-h- sh.r 39204 asc 01-nov-82 18:15:27 sventek (joseph sventek) %%E 5 %%E 4 %%D 5 #-h- defns 1902 asc 25-mar-82 08:42:12 v1.1 (sw-tools v1.1) %%E 5 %%I 5 %%D 6 #-h- sh.r 39337 asc 02-nov-82 13:16:45 sventek (joseph sventek) #-h- defns 2031 asc 02-nov-82 13:06:13 sventek (joseph sventek) %%E 6 %%E 5 %%I 6 %%D 7 #-h- sh.r 45313 asc 21-nov-82 18:24:44 sventek (joseph sventek) #-h- defns 2101 asc 21-nov-82 14:09:43 sventek (joseph sventek) %%E 7 %%E 6 %%I 7 %%D 8 #-h- sh.r 45857 asc 24-nov-82 15:37:28 sventek (joseph sventek) #-h- defns 2555 asc 24-nov-82 13:41:32 sventek (joseph sventek) %%E 8 %%E 7 %%I 8 %%D 9 #-h- sh.r 46232 asc 16-dec-82 17:54:14 sventek (joseph sventek) %%E 9 %%I 9 %%D 10 #-h- sh.r 46222 asc 13-jan-83 14:40:19 sventek (joseph sventek) %%E 10 %%E 9 %%I 10 %%D 11 #-h- sh.r 46222 asc 04-feb-83 14:21:30 sventek (joseph sventek) %%E 11 %%E 10 %%I 11 %%D 12 #-h- sh.r 46222 asc 13-jun-83 12:07:58 sventek (joseph sventek) %%E 12 %%E 11 %%D 12 #-h- defns 2636 asc 16-dec-82 16:40:14 sventek (joseph sventek) %%E 12 %%E 8 %%I 12 %%D 13 #-h- sh.r 46215 asc 15-jun-83 15:05:16 sventek (joseph sventek) #-h- defns 2635 asc 15-jun-83 15:02:30 sventek (joseph sventek) %%E 13 %%E 12 %%I 13 #-h- sh.r 46287 asc 16-jun-83 10:30:54 sventek (joseph sventek) #-h- defns 2565 asc 16-jun-83 09:35:06 sventek (joseph sventek) %%E 13 # definitions for shell # put on a file named 'defns' # Used only by the shell define(TSIZE,4) define(MAXSHLINE,MAXLINE) # maximum command line length define(SHELL,17) # flag for shell command define(IBPTR,1) # array index for token pointers define(TMARK,2) # array index for token marks define(NODEPTR,3) # array index for node pointers define(ESCAN,4) # array index for end of scan %%D 5 define(MAXTOK,132) # max token size define(TREESIZE,200) # max size of tree %%E 5 %%I 5 ifdef(DO_STARTUP) define(TREESIZE,160) # max size of tree define(MAXTOK,100) # max number of tokens elsedef define(TREESIZE,200) # max size of tree define(MAXTOK,132) # max number of tokens enddef %%E 5 define(ROOT,-1) # flag for beginning of tree define(PARENT,1) define(NTYPE,2) define(LCHILD,3) define(RCHILD,4) define(REDIN,5) define(REDOUT,6) define(REDERR,7) define(NENT,8) define(CMD,9) define(ARGUMENT,10) define(COM,'c') define(PAR,'p') define(SSYNTAX,0) define(SSYN1,1) define(SSYN2,2) define(SSYN3,3) define(MAXSTACK,15) define(PIPE,'|') define(SEPCHAR,';') define(SCRIPT,2) define(OWNER,-1) # flag for receiving message from parent define(BUFSIZE,MAXLINE) define(COMMENTCHAR,'#') %%D 13 define(MAXPATHSIZE,arith(FILENAMESIZE,*,3)) # max size of search path %%E 13 define(PB_SIZE,512) # size of push back buffer %%I 7 define(MAX_NEST,3) # maximum nesting of source files %%E 7 %%I 8 #define(KEEP_DOLLARS,) # if defined, $word is non-special if not # defined. %%E 8 #define(DEBUG,) # if defined, issue debug statements ifdef(DEBUG) # macro definitions when debugging define(debug_int,call putlin($1,ERROUT);call putint($2,5,ERROUT) call putch('@n',ERROUT)) define(debug_str,call putlin($1,ERROUT);call putstr($2,5,ERROUT) call putch('@n',ERROUT)) define(debug_token,call putch('@n',ERROUT);debug_int("token #",$1) debug_int(" TMARK:",tkbuf(TMARK,$1)) debug_int(" NODE:",tkbuf(NODEPTR,$1)) debug_int(" ESCAN:",tkbuf(ESCAN,$1))) define(debug_node,call putch('@n',ERROUT);debug_int("node #",$1) debug_int(" parent:",tree($1+PARENT)) debug_str(" type:",tree($1+NTYPE)) debug_int(" Lchild:",tree($1+LCHILD)) debug_int(" Rchild:",tree($1+RCHILD))) enddef ifnotdef(USE_STRING) %%D 12 define(USE_STRING,"usage: sh [-cdnvx] [file [arguments]].") %%E 12 %%I 12 define(USE_STRING,"usage: sh [-cdnvx] [file [arguments]]") %%E 12 enddef %%I 6 %%I 7 ifnotdef(INT_COMMANDS) define(INT_COMMANDS,"cd@1ho@2home@3logout@4path@5von@6voff@7xon@10xoff@11#@12") define(C_CD,8%1) define(C_HO,8%2) define(C_HOME,8%3) define(C_LOGOUT,8%4) define(C_PATH,8%5) define(C_VON,8%6) define(C_VOFF,8%7) define(C_XON,8%10) define(C_XOFF,8%11) define(C_COMMENT,8%12) enddef %%E 7 ifdef(DO_PARAM) %%D 7 define(MEM_SIZE,500) %%E 7 %%I 7 ifdef(LARGE_ADDRESS_SPACE) define(MEM_SIZE,5000) elsedef define(MEM_SIZE,500) enddef %%E 7 define(COL_WIDTH,-15) enddef %%E 6 %%D 7 #-h- main 569 asc 25-mar-82 08:42:14 v1.1 (sw-tools v1.1) %%E 7 %%I 7 %%D 12 #-h- main 505 asc 24-nov-82 13:41:34 sventek (joseph sventek) %%E 12 %%E 7 %%I 12 #-h- main 503 asc 15-jun-83 15:02:31 sventek (joseph sventek) %%E 12 ## sh - driver subroutine for DEH shell DRIVER(sh) character line(MAXSHLINE) %%D 7 integer parser, shline %%E 7 %%I 7 integer parser, shline, equal %%E 7 %%I 7 string qmark "?@n" %%E 7 call query(USE_STRING) call initsh %%D 7 repeat %%E 7 %%I 7 while (shline(line) != EOF) if (line(1) != '@n') %%E 7 { %%D 7 if (shline(line) == EOF) break if (line(1) == '@n' | line(1) == COMMENTCHAR) next if (line(1) == '?' & line(2) == '@n') { call remark("Type intro for an introduction to the tools.") next } if (parser(line) == ERR) call remark ("syntax error.") %%E 7 %%I 7 if (equal(line, qmark) == YES) %%D 12 call remark("Type intro for an introduction to the tools.") %%E 12 %%I 12 call remark("Type intro for an introduction to the tools") %%E 12 else if (parser(line) == ERR) %%D 12 call remark("syntax error.") %%E 12 %%E 7 %%I 12 call remark("syntax error") %%E 12 else %%D 7 call execut %%E 7 %%I 7 call execut %%E 7 } call endsh(EOF) DRETURN end #-h- arglin 419 asc 25-mar-82 08:42:15 v1.1 (sw-tools v1.1) ## arglin - pick up all arguments starting with i subroutine arglin (buf, i) character buf(ARB) integer i, k, m integer getarg include csclin k = 1 for (j=i; getarg(j, lin, MAXLINE) != EOF; j=j+1) { if (lin(1) == ESCAPE & lin(2) == '<' ) m = 2 else m = 1 call stcopy(lin, m, buf, k) call chcopy( ' ', buf, k) } if (k > 1) k = k - 1 #delete last blank buf(k) = '@n' buf(k+1) = EOS return end %%D 4 #-h- atbeg 350 asc 25-mar-82 08:42:16 v1.1 (sw-tools v1.1) %%E 4 %%I 4 #-h- atbeg 351 asc 01-nov-82 18:14:30 sventek (joseph sventek) %%E 4 ## atbeg - return YES if at beginning of new shell token integer function atbeg(c) character c integer spec if (spec(c) == YES | #special shell character c == '<' | c == '>' | c == '?' | #redirected IO c == ' ' | c == '@t' | #arg separator %%D 4 c == ''' | c == '"') #new quoted string %%E 4 %%I 4 c == '@'' | c == '"') #new quoted string %%E 4 atbeg = YES else atbeg = NO return end %%D 6 #-h- cmdtyp 514 asc 25-mar-82 08:42:18 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%D 7 #-h- cmdtyp 951 asc 21-nov-82 14:09:45 sventek (joseph sventek) %%E 7 %%E 6 %%I 7 %%D 13 #-h- cmdtyp 952 asc 23-nov-82 16:21:52 sventek (joseph sventek) %%E 13 %%E 7 %%I 13 #-h- cmdtyp 976 asc 16-jun-83 09:35:08 sventek (joseph sventek) %%E 13 ## cmdtyp - check command and prepare for appropriate fetching integer function cmdtyp (comand, path) character comand(ARB), path(ARB) integer equal, shcom integer loccom include stdsub %%I 6 ifdef(DO_PARAM) integer i, junk integer ludef include shflag elsedef integer length enddef %%E 6 string local "local" string execut "x" string suffix BOTH_SUFFIX %%I 13 string spath STD_PATH %%E 13 call strcpy(comand, path) %%D 6 if (shcom(comand) == YES) %%E 6 %%I 6 ifdef(DO_PARAM) if (ludef(path, comand, table) == NO) call strcpy(path, comand) for (i=1; comand(i) != EOS; i=i+1) if (comand(i) == ' ' | comand(i) == '@t') break else path(i) = comand(i) path(i) = EOS call skipbl(comand, i) elsedef %%D 7 i = length(comand) %%E 7 %%I 7 i = length(comand) + 1 %%E 7 enddef %%D 7 if (shcom(path) == YES) %%E 7 %%E 6 %%I 7 if (shcom(path) > 0) %%E 7 cmdtyp = SHELL %%D 6 else if (equal(comand, execut) == YES) %%E 6 %%I 6 else if (equal(path, execut) == YES) %%E 6 { call strcpy(local, path) cmdtyp = BINARY } else %%D 6 cmdtyp = loccom(comand, spath, suffix, path) %%E 6 %%I 6 { cmdtyp = loccom(path, spath, suffix, path) i = 1 } call scopy(comand, i, comand, 1) %%E 6 return end %%D 12 #-h- doampr 955 asc 25-mar-82 08:42:19 v1.1 (sw-tools v1.1) %%E 12 %%I 12 %%D 13 #-h- doampr 953 asc 15-jun-83 15:02:33 sventek (joseph sventek) %%E 13 %%E 12 %%I 13 #-h- doampr 977 asc 16-jun-83 09:35:09 sventek (joseph sventek) %%E 13 ## doampr - process ampersand node of parse tree subroutine doampr (node, dir) integer node, dir, i integer spawn, getcl, loccom character desc(PIDSIZE) include stdsub include cpars include shflag string shstr "sh" string suffix IMAGE_SUFFIX string second " -c " %%I 13 string spath STD_PATH %%E 13 if (dir == RCHILD | dir == PARENT) return if ( loccom( shstr, spath, suffix, sh) != BINARY ) { %%D 12 call remark( "? Can't locate shell image file.") %%E 12 %%I 12 call remark( "? Can't locate shell image file") %%E 12 return } i = 1 call stcopy( shstr, 1, clin, i) call stcopy( second, 1, clin, i) if (getcl(node, dir, clin, i) == ERR) return call stripb(clin) # strip trailing blanks if (prcom == YES) #user wishes to see command call dspcom(sh, clin) if (exec == YES) #execute command { if (spawn(sh, clin, desc, BACKGR) == ERR) %%D 12 call remark ("Cannot spawn background process.") %%E 12 %%I 12 call remark ("Cannot spawn background process") %%E 12 else call remark (desc) } return end %%D 6 #-h- docom 1714 asc 25-mar-82 08:42:21 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%D 7 #-h- docom 1680 asc 21-nov-82 14:09:47 sventek (joseph sventek) %%E 7 %%E 6 %%I 7 %%D 12 #-h- docom 1725 asc 23-nov-82 16:50:24 sventek (joseph sventek) %%E 12 %%E 7 %%I 12 #-h- docom 1723 asc 15-jun-83 15:02:34 sventek (joseph sventek) %%E 12 ## docom - process command node of parse tree integer function docom (node, dir) integer dir, i, j, node, type, status integer spawn, shellc %%D 6 integer cmdtyp, equal integer pickup, inf, outf, errf, length %%E 6 %%I 6 integer cmdtyp, equal, length %%D 7 integer pickup, inf, outf, errf %%E 7 %%E 6 %%I 7 integer pickup, inf, outf, errf, scrf %%E 7 character comand(FILENAMESIZE), desc(PIDSIZE) include shflag %%D 7 include shcmd %%E 7 %%I 7 %%E 7 string local "local" string errmsg "? Can't find program or script named `" %%I 7 string xoff "xoff" %%E 7 #pick up command j = 1 junk = pickup(clin, j, node, CMD, junk) call fold(clin) type = cmdtyp( clin, comand) #check task and prepare command call if( type == ERR & drop == NO ) { call putlin(errmsg, ERROUT) call putlin(comand, ERROUT) %%D 12 call remark("'.") %%E 12 %%I 12 call remark("'") %%E 12 return(ERR) } %%D 6 if( equal( comand, local) == YES | type == SHELL ) j = 1 else call chcopy( ' ', clin, j) %%E 6 %%I 6 j = length(clin) + 1 if (j > 1) call chcopy(' ', clin, j) %%E 6 if( type == ASCII ) %%D 7 call scrf(node, comand, clin) %%E 7 %%I 7 { if (scrf(node, comand, clin) == ERR) return(ERR) } %%E 7 else #pick up arguments { if( type == ERR ) call strcpy( local, comand) for( i = 1 ; pickup( clin, j, node, ARGUMENT, i) != ERR ; i = i + 1 ) call chcopy( ' ', clin, j) #pick up file substitutions if( inf(node, clin, j) != ERR ) call chcopy( ' ', clin, j) if( outf(node, clin, j) != ERR ) call chcopy( ' ', clin, j) if( errf(node, clin, j) != ERR ) call chcopy( ' ', clin, j) } call stripb( clin) # strip trailing blanks if( prcom == YES & equal(comand, xoff) == NO ) #user wishes to see command call dspcom(comand, clin) if( exec == YES ) #execute command { if( type == SHELL ) #execute shell commands status = shellc( comand, clin) else { status = spawn( comand, clin, desc, WAIT) if( status == ERR ) %%D 12 call remark( "? Can't spawn process.") %%E 12 %%I 12 call remark( "? Can't spawn process") %%E 12 else if( status != OK ) andif( status != CHILD_ABORTED ) status = ERR } } else status = OK return(status) end %%D 12 #-h- dopar 1132 asc 25-mar-82 08:42:22 v1.1 (sw-tools v1.1) %%E 12 %%I 12 #-h- dopar 1131 asc 15-jun-83 15:02:36 sventek (joseph sventek) %%E 12 ## dopar - handle parenthesized statement integer function dopar (p1,p2) character tok integer p, p1, p2, l, pnode, node, pt, ndx integer setree, mktree include cpars l = 0 for (p=p1; p') { if (setree(node, REDOUT, tkbuf( IBPTR, p)) == ERR) { dopar = ERR return } } else if (tok == '?') { if (setree(node, REDERR, tkbuf( IBPTR, p)) == ERR) { dopar = ERR return } } else { %%D 12 call stxerr("invalid token following parenthesis (dopar).") %%E 12 %%I 12 call stxerr("invalid token following parenthesis (dopar)") %%E 12 dopar = ERR return } } dopar = OK return end %%D 7 #-h- doparn 1129 asc 25-mar-82 08:42:24 v1.1 (sw-tools v1.1) %%E 7 %%I 7 #-h- doparn 1129 asc 23-nov-82 22:26:28 sventek (joseph sventek) %%E 7 ## doparn - process parentheses node of parse tree integer function doparn (node, dir) integer node, dir include cpars include stdsub if (dir == LCHILD) { if (tree(node+REDIN) != 0) #input substitution { if (in == 0 | (in != 0 & cin(in) > 0) ) { in = in + 1 cin(in) = tree(node+REDIN) #flag substitution by setting to negative tree(node+REDIN) = -tree(node+REDIN) } } if (tree(node+REDOUT) != 0) { if (out == 0 | #output substitution (out != 0 & cout(out) > 0)) { out = out + 1 cout(out) = tree(node+REDOUT) #flag substitution tree(node+REDOUT) = -tree(node+REDOUT) } } if (tree(node+REDERR) != 0) { er = er + 1 cerr(er ) = tree(node+REDERR) #flag substitution tree(node+REDERR) = -tree(node+REDERR) } } else { if (tree(node+REDIN) < 0) { in = in - 1 tree(node+REDIN) = abs(tree(node+REDIN)) } if (tree(node+REDOUT) < 0) { out = out - 1 tree(node+REDOUT) = abs(tree(node+REDOUT)) } if (tree(node+REDERR) < 0) { er = er - 1 tree(node+REDERR) = abs(tree(node+REDERR)) } } return(OK) end #-h- dopipe 371 asc 25-mar-82 08:42:26 v1.1 (sw-tools v1.1) ## dopipe - process pipe node of parse tree integer function dopipe (node, dir) integer node, dir include stdsub if (dir == LCHILD) { pctr = pctr + 1 pfile(pctr) = NO out = out + 1 cout(out) = -pctr aout(out) = 0 } else if (dir == RCHILD) { in = in + 1 cin(in) = cout(out) out = out - 1 } else { pctr = pctr - 1 in = in - 1 } return(OK) end %%D 3 #-h- dosemi 285 asc 25-mar-82 08:42:26 v1.1 (sw-tools v1.1) %%E 3 %%I 3 #-h- dosemi 363 asc 25-oct-82 10:28:40 sventek (joseph sventek) %%E 3 ## dosemi - process semicolon node of parse tree integer function dosemi (node, dir) integer node, dir include stdsub if (dir == RCHILD) { if (out > 0) aout(out) = aout(out) + 1 %%I 3 if (er > 0) aerr(er) = aerr(er) + 1 %%E 3 } else if (dir == PARENT) { if (out > 0) aout(out) = aout(out) - 1 %%I 3 if (er > 0) aerr(er) = aerr(er) - 1 %%E 3 } return(OK) end %%D 12 #-h- doverb 1081 asc 25-mar-82 08:42:28 v1.1 (sw-tools v1.1) %%E 12 %%I 12 #-h- doverb 1080 asc 15-jun-83 15:02:37 sventek (joseph sventek) %%E 12 ## doverb - handle final command syntax integer function doverb (p1,p2) character tok integer p, p1, p2, p3, i, node, ndx integer mktree, setree include cpars ndx = tkbuf( IBPTR, p1) tok = ibuf(ndx) #check token if (tok == '<' | tok == '>' | tok == '?') { %%D 12 call stxerr("command must preceed i/o redirection (doverb).") %%E 12 %%I 12 call stxerr("command must preceed i/o redirection (doverb)") %%E 12 return(ERR) } nargs = p2 - p1 -1 if (mktree(tkbuf( NODEPTR, p1), COM, 9+nargs, node) == ERR) #make tree entry return(ERR) i = 0 #enter pointers for (p=p1; p') { if (setree(node, REDOUT, tkbuf( IBPTR, p)) == ERR) return(ERR) nargs = nargs - 1 } else if (tok == '?') { if (setree(node, REDERR, tkbuf( IBPTR, p)) == ERR) return(ERR) nargs = nargs - 1 } else { if (setree(node, CMD+i, tkbuf( IBPTR, p)) == ERR) return(ERR) i = i + 1 } } if (setree(node, NENT, nargs) == ERR) #set nbr args return(ERR) return(OK) end %%D 7 #-h- dspcom 370 asc 25-mar-82 08:42:29 v1.1 (sw-tools v1.1) %%E 7 %%I 7 #-h- dspcom 369 asc 23-nov-82 14:10:35 sventek (joseph sventek) %%E 7 subroutine dspcom(com, arg) integer i integer equal, shcom # function(s) character com(ARB), arg(ARB) string local "local" call putlin(com, ERROUT) i = 1 %%D 7 if( equal( com, local) == NO & shcom(com) == NO) %%E 7 %%I 7 if( equal( com, local) == NO & shcom(com) == 0) %%E 7 while (arg(i) != ' ' & arg(i) != EOS) i = i + 1 else call putch(' ', ERROUT) call putlin(arg(i), ERROUT) call putch('@n', ERROUT) return end %%D 7 #-h- dsppth 328 asc 25-mar-82 08:42:30 v1.1 (sw-tools v1.1) %%E 7 %%I 7 %%D 13 #-h- dsppth 360 asc 23-nov-82 21:59:06 sventek (joseph sventek) %%E 13 %%E 7 %%I 13 #-h- dsppth 513 asc 16-jun-83 10:07:07 sventek (joseph sventek) %%E 13 ## Dsppth - Display search path. %%D 7 subroutine dsppth %%E 7 %%I 7 subroutine dsppth(file) %%E 7 include stdsub integer i %%I 7 character file(ARB) %%E 7 string sepstr " -> " %%I 13 string spath STD_PATH %%E 13 %%D 7 call pwdir(STDOUT, EOS) %%E 7 %%I 7 call pwdir(file, STDOUT, EOS) %%E 7 for( i = 1 ; spath(i) != '@n' ; i = i + 1 ) %%D 13 if( spath(i) == EOS & spath(i+1) != '@n' ) call putlin(sepstr, STDOUT) %%E 13 %%I 13 if( spath(i) == EOS) if (spath(i+1) == '@n') break else call putlin(sepstr, STDOUT) %%E 13 else %%D 13 call putch(spath(i), STDOUT) %%E 13 %%I 13 { call mkpath(spath(i), file) call putlin(file, STDOUT) while (spath(i) != EOS) i = i + 1 i = i - 1 } %%E 13 call putch('@n', STDOUT) return end #-h- endsh 236 asc 25-mar-82 08:42:30 v1.1 (sw-tools v1.1) ## endsh - terminate execution of the shell subroutine endsh(comand) character comand ifdef(prompt) integer junk string null "" enddef ifdef(prompt) if (comand != EOF) call logend(null, junk) enddef call endst(OK) end %%D 3 #-h- errf 494 asc 25-mar-82 08:42:31 v1.1 (sw-tools v1.1) %%E 3 %%I 3 #-h- errf 538 asc 25-oct-82 10:28:42 sventek (joseph sventek) %%E 3 ## errf - pick up errout file substitution for command integer function errf (node, buf, i) %%D 3 integer node, i %%E 3 %%I 3 integer node, i, j %%E 3 integer pickup integer junk character buf(ARB) include cpars include stdsub %%D 3 errf = ERR %%E 3 if( er == 0 & pickup( buf, i, node, REDERR, junk) != ERR ) %%D 3 errf = OK else if (er > 0 & cerr(er) > 0) #check for parens %%E 3 %%I 3 return(OK) else if (er > 0) # check for parens %%E 3 { %%D 3 ### Er may not be properly set if (aout(out) != 0) #append call chcopy( '?', buf, i) call stcopy (ibuf, cerr(er), buf, i) errf = OK %%E 3 %%I 3 if (cerr(er) > 0) # use paren substitution { j = cerr(er) + 1 if (aerr(er) != 0 & ibuf(j) != '?') # append call chcopy('?', buf, i) call stcopy(ibuf, cerr(er), buf, i) } return(OK) %%E 3 } %%D 3 return %%E 3 %%I 3 return(ERR) %%E 3 end %%D 3 #-h- execut 997 asc 25-mar-82 08:42:33 v1.1 (sw-tools v1.1) %%E 3 %%I 3 %%D 12 #-h- execut 1101 asc 25-oct-82 10:28:42 sventek (joseph sventek) %%E 12 %%E 3 %%I 12 #-h- execut 1100 asc 15-jun-83 15:02:39 sventek (joseph sventek) %%E 12 ## execut - process shell parse tree subroutine execut integer node, type, dir, status, i, j, junk integer mvnext, dosemi, doampr, dopipe, doparn, docom, remove include stdsub in = 0 #initialize file substitution stacks out = 0 er = 0 pctr = 0 hfile(1) = EOS %%D 3 for (i=1; i<=MAXSTACK; i=i+1) %%E 3 %%I 3 for (i=1; i<=MAXSTACK; i=i+1) # initialize I/O redirection info { %%E 3 pfile(i) = NO %%I 3 cin(i) = 0 cout(i) = 0 cerr(i) = 0 aout(i) = 0 aerr(i) = 0 } %%E 3 node = ROOT while (mvnext(node, type, dir) != ROOT) #move thru tree { if (type == SEPCHAR) status = dosemi (node, dir) else if (type == '&') status = doampr (node, dir) else if (type == PIPE) status = dopipe (node, dir) else if (type == PAR) status = doparn (node, dir) else if (type == COM) status = docom (node, dir) else { %%D 12 call remark("? Invalid parse tree (execut).") %%E 12 %%I 12 call remark("? Invalid parse tree (execut)") %%E 12 status = ERR } if( status == ERR | status == CHILD_ABORTED ) break } if( hfile(1) != EOS ) junk = remove(hfile) for (i=1; i<=MAXSTACK; i=i+1) #remove scratch files if (pfile(i) == YES) { j = 1 call gpname( i, hfile, j) junk = remove( hfile) } return end #-h- getcl 715 asc 25-mar-82 08:42:34 v1.1 (sw-tools v1.1) ## getcl - get command line for background process integer function getcl(node, dir, buf, k) integer node, junk, snode, type, dir, lastd, k character buf(ARB) integer mvnext, gtask include shflag snode = node repeat { junk = mvnext(node, type, dir) if (node == snode) #back to where we started break if (type == SEPCHAR & dir == RCHILD) call chcopy( SEPCHAR, buf, k) else if (type == '&') { if (dir == RCHILD | (dir == PARENT & lastd == LCHILD)) call chcopy( '&', buf, k) lastd = dir } else if (type == PIPE & dir == RCHILD) call chcopy( '|', buf, k) else if (type == PAR) call gpar(node, dir, buf, k) else if (type == COM) getcl = gtask(node, buf, k) } return end #-h- gpar 563 asc 25-mar-82 08:42:35 v1.1 (sw-tools v1.1) ## gpar - get parentheses info for script file subroutine gpar(node, dir, buf, i) integer node, dir, i, n character buf(ARB) integer pickup, length string rpst ") @@" if (dir == LCHILD) call chcopy( '(', buf, i) else if (dir == PARENT) { n = i call stcopy( rpst, 1, buf, i) if( pickup( buf, i, node, REDIN, junk) != ERR) call chcopy( ' ', buf, i) else i = n + 2 if ( pickup( buf, i, node, REDOUT, junk) != ERR) call chcopy( ' ', buf, i) if ( pickup( buf, i, node, REDERR, junk) != ERR) call chcopy( ' ', buf, i) } return end #-h- gpname 376 asc 25-mar-82 08:42:37 v1.1 (sw-tools v1.1) ## gpname - make unique pipe name for file id n subroutine gpname(n, name, i) character name(ARB) integer itoc, length integer i, junk, n include stdsub string pipef(5) "p" pfile(n) = YES # has been generated junk = itoc( n, pipef(2), 3) # generate scratf seed call scratf( pipef, name(i)) # generate name i = i + length( name(i)) # bump pointer return end %%D 6 #-h- gtask 850 asc 25-mar-82 08:42:38 v1.1 (sw-tools v1.1) %%E 6 %%I 6 #-h- gtask 890 asc 21-nov-82 14:09:51 sventek (joseph sventek) %%E 6 ## gtask - pick up command and arguments for background process integer function gtask(node, buf, j) integer node, junk, type, j, k, n %%D 6 integer pickup, cmdtyp character buf(ARB) %%E 6 %%I 6 integer pickup, cmdtyp, length character buf(ARB), comand(FILENAMESIZE) %%E 6 include shflag n = j junk = pickup( buf, j, node, CMD, junk) %%D 6 k = j + 1 type = cmdtyp( buf(n), buf(k)) %%E 6 %%I 6 type = cmdtyp( buf(n), comand) %%E 6 if( type == ERR & drop == NO ) { call remark ("invalid task") j = n buf(j) = EOS return(ERR) } gtask = OK %%I 6 j = length(buf) + 1 %%E 6 #pick up arguments call chcopy( ' ', buf, j) for (i=1; pickup( buf, j, node, ARGUMENT, i) != ERR; i=i+1) call chcopy( ' ', buf, j) call chcopy( ESCAPE, buf, j) if( pickup( buf, j, node, REDIN, junk) != ERR) call chcopy( ' ', buf, j) else j = j - 1 if ( pickup( buf, j, node, REDOUT, junk) != ERR) call chcopy( ' ', buf, j) if ( pickup( buf, j, node, REDERR, junk) != ERR) call chcopy( ' ', buf, j) buf(j) = EOS return end %%D 7 #-h- herdoc 585 asc 25-mar-82 08:42:39 v1.1 (sw-tools v1.1) %%E 7 %%I 7 %%D 12 #-h- herdoc 585 asc 23-nov-82 17:37:44 sventek (joseph sventek) %%E 12 %%E 7 %%I 12 #-h- herdoc 584 asc 15-jun-83 15:02:41 sventek (joseph sventek) %%E 12 ## herdoc - generate 'here document' for shell subroutine herdoc(char, buf, i) character char, buf(ARB) integer create, getlin integer int, i, n include stdsub include shflag include csclin string doc "doc" n = i call chcopy( '<', buf, i) call scratf(doc, hfile) int = create(hfile, WRITE) if (int == ERR) { %%D 12 call remark("? Can't open file for inline text.") %%E 12 %%I 12 call remark("? Can't open file for inline text") %%E 12 hfile(1) = EOS i = n buf(i) = EOS return } call stcopy( hfile, 1, buf, i) while( getlin( lin, shin) != EOF) { if (lin(1) == char) break call putlin(lin, int) } call close(int) return end #-h- inf 706 asc 25-mar-82 08:42:40 v1.1 (sw-tools v1.1) ## inf - pick up input substitution for command integer function inf(node, buf, i) integer node, i, n integer pickup character buf(ARB), char include stdsub include cpars n = i if (in > 0 & cin(in) < 0) #receive input from pipe { call chcopy( '<', buf, i) call gpname( abs(cin(in)), buf, i) } else if( pickup( buf, i, node, REDIN, junk) == ERR & in > 0 ) call stcopy( ibuf, cin(in), buf, i) else if (script == YES & input(1) != EOS) { call chcopy( '<', buf, i) call stcopy( input, 1, buf, i) } if (buf(n) == '<' & buf(n+1) == '<') #check for 'here document' { char = buf(n+2) i = n call herdoc( char, buf, i) } if (buf(n) != EOS) return(OK) else return(ERR) end %%D 6 #-h- initsh 1937 asc 25-mar-82 08:42:42 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%D 7 #-h- initsh 2752 asc 21-nov-82 15:11:56 sventek (joseph sventek) %%E 7 %%E 6 %%I 7 %%D 13 #-h- initsh 2308 asc 23-nov-82 17:37:46 sventek (joseph sventek) %%E 13 %%E 7 %%I 13 #-h- initsh 2226 asc 16-jun-83 09:35:14 sventek (joseph sventek) %%E 13 ## initsh - initialize shell subroutine initsh integer getarg, open, loccom, length, index integer i include shflag %%D 7 include shcmd %%E 7 include stdsub PB_DECL(PB_SIZE) # declaration for push back buffer %%I 6 ifdef(DO_PARAM) pointer mktabl DS_DECL(Mem,MEM_SIZE) # dynamic storage allocation string argstr "$0" enddef %%E 6 string suffix NO_SUFFIX %%I 13 string spath STD_PATH %%E 13 %%D 7 data cd /'c', 'd', EOS/ ifdef(IMBED_ED) data e /'e', EOS/ enddef data ho /'h', 'o', EOS/ data home /'h', 'o', 'm', 'e', EOS/ data logout /'l', 'o', 'g', 'o', 'u', 't', EOS/ data shopth /'p', 'a', 't', 'h', EOS/ %%E 7 %%I 6 %%D 7 ifdef(DO_PARAM) data param /'p', 'a', 'r', 'a', 'm', EOS/ data alias /'a', 'l', 'i', 'a', 's', EOS/ data ask /'a', 's', 'k', EOS/ enddef %%E 7 %%E 6 %%D 7 data von /'v', 'o', 'n', EOS/ data voff /'v', 'o', 'f', 'f', EOS/ data xon /'x', 'o', 'n', EOS/ data xoff /'x', 'o', 'f', 'f', EOS/ %%E 7 data input(1) /EOS/ %%D 7 # initialize standard input file data shin /STDIN/ %%E 7 %%I 7 depth = 1 # initialize input unit unit(1) = STDIN %%E 7 call pbinit(PB_SIZE) # initialize push-back buffer %%I 6 ifdef(DO_PARAM) call dsinit(MEM_SIZE) # initialize dynamic storage table = mktabl(1) # create lookup table enddef %%E 6 prlin = NO exec = YES prcom = NO carg = NO drop = YES script = NO %%D 13 # initialize search path # search path is :~home/tools~usr:~bin call impath(spath) # fetch search path. %%E 13 call homdir( homedr, LOCAL) # get user's home directory. call gwdir( olddir, LOCAL) # previous directory is current work dir. call enbint # enable software interrupts for( i = 1 ; getarg(i, clin, MAXLINE) != EOF ; i = i + 1 ) { if( i == 1 & clin(1) == '-' ) #shell flag { call fold(clin) if( index( clin, 'v') > 0 ) prlin = YES if( index( clin, 'n') > 0 ) exec = NO if( index( clin, 'x') > 0 ) prcom = YES if( index( clin, 'c') > 0 ) carg = YES if( index( clin, 'd') > 0 ) drop = NO call delarg(i) i = i - 1 } else if( carg == YES ) { call arglin(clin, i) cargdn = NO break } %%D 6 else if( i == 1 ) %%E 6 %%I 6 else if( i == 1 ) # have a script file %%E 6 { %%D 6 if( loccom( clin, spath, suffix, clin) != ASCII ) %%E 6 %%I 6 if( loccom( clin, spath, suffix, input) != ASCII ) %%E 6 call cant(clin) %%D 6 shin = open(clin, READ) %%E 6 %%I 6 %%D 7 shin = open(input, READ) %%E 7 %%E 6 %%D 7 if( shin == ERR ) %%E 7 %%D 6 call cant(clin) %%E 6 %%I 6 %%I 7 unit(depth) = open(input, READ) if( unit(depth) == ERR ) %%E 7 call cant(input) %%E 6 script = YES %%I 6 input(1) = EOS ifdef(DO_PARAM) call entdef(argstr, clin, table) # enter $0 defn for (i=i+1; getarg(i, clin, MAXLINE) != EOF; i=i+1) if ( clin(1) == ESCAPE & clin(2) == '<') call scopy(clin, 3, input, 1) else { argstr(2) = argstr(2) + 1 # rely upon ASCII here call entdef(argstr, clin, table) # install $n } break elsedef %%E 6 } else if( clin(1) == ESCAPE ) { if( clin(2) == '<' ) call scopy(clin, 3, input, 1) else next call delarg (i) i = i - 1 %%I 6 enddef %%E 6 } } %%D 7 call rlogin # set up unit for login.sh %%E 7 %%I 7 ifdef(DO_STARTUP) call rlogin # set up unit for login.sh enddef shin = unit(depth) %%E 7 return end %%D 4 #-h- mktoks 775 asc 25-mar-82 08:42:45 v1.1 (sw-tools v1.1) %%E 4 %%I 4 %%D 12 #-h- mktoks 776 asc 01-nov-82 18:14:38 sventek (joseph sventek) %%E 12 %%E 4 %%I 12 #-h- mktoks 775 asc 15-jun-83 15:02:43 sventek (joseph sventek) %%E 12 ## mktoks - create parse tables for shell parser integer function mktoks (line, k) integer length integer i, paren character line(ARB) integer shtok integer k, l include cpars paren = 0 i = 1 call putbak (EOS) #initialize buffer call pbstr (line) for (k=1; shtok(ibuf(i)) != EOS; k=k+1) { if (ibuf(i) != EOS) { tkbuf(IBPTR,k) = i tkbuf(TMARK,k) = 0 tkbuf(NODEPTR,k) = 0 tkbuf(ESCAN,k) = 0 if (ibuf(i) == '(') paren = paren + 1 else if (ibuf(i) == ')') paren = paren - 1 l = i + length(ibuf(i)) - 1 %%D 4 if ((ibuf(i) == ''' | ibuf(i) == '"') & %%E 4 %%I 4 if ((ibuf(i) == '@'' | ibuf(i) == '"') & %%E 4 ibuf(l) != ibuf(i)) { %%D 12 call remark("? Unbalanced quotes.") %%E 12 %%I 12 call remark("? Unbalanced quotes") %%E 12 return(ERR) } i = l + 2 } } k = k - 1 ibuf(i) = EOS if (paren != 0) return(ERR) else return(OK) end #-h- mktree 866 asc 25-mar-82 08:42:46 v1.1 (sw-tools v1.1) ## mktree - create child node for given parent integer function mktree (pnode, type, size, cnode) integer pnode, type, size, cnode, i include cpars cnode = treend treend = treend + size #next available space if (treend >TREESIZE) { call stxerr("tree buffer size exceeded (mktree)") cnode = ERR return(ERR) } for (i=1; i<=size; i=i+1) #clear entries tree(cnode+i) = 0 tree(cnode+PARENT) = pnode tree(cnode+NTYPE) = type #ifdef(DEBUG) # call putch('@n',ERROUT) # debug_int("child node =",cnode) # debug_int("parent node =",pnode) #enddef if (pnode >= 0) #install back pointer { # ifdef(DEBUG) # debug_node(pnode) # enddef if (tree(pnode+LCHILD) == 0) tree(pnode+LCHILD) = cnode else if (tree(pnode+RCHILD) == 0) tree(pnode+RCHILD) = cnode else { call stxerr("too many children (mktree)") return(ERR) } } return(cnode) end #-h- mvnext 355 asc 25-mar-82 08:42:48 v1.1 (sw-tools v1.1) ## mvnext - move to next node in parse tree integer function mvnext (node, type, dir) integer node, dir, type integer nxtbr include cpars if (node == ROOT) #just starting { mvnext = 0 dir = LCHILD } else mvnext = tree(node+dir) if (mvnext != ROOT) { type = tree(mvnext+NTYPE) dir = nxtbr(mvnext, node) } node = mvnext return end #-h- nextp 187 asc 25-mar-82 08:42:49 v1.1 (sw-tools v1.1) ## nextp - get next pointer from pushdown stack integer function nextp (p) integer p include cpars if (pp == 0) p = EOS else { p = stack(pp) pp = pp - 1 } return(p) end %%D 7 #-h- nodir 236 asc 25-mar-82 08:42:49 v1.1 (sw-tools v1.1) ## NoDir - Print error message for invalid directory spec. subroutine nodir(dir) character dir(ARB) string start "? Can't find directory named `" call putlin( start, ERROUT) call putlin( dir, ERROUT) call remark( "'.") return end %%E 7 #-h- nxtbr 391 asc 25-mar-82 08:42:50 v1.1 (sw-tools v1.1) ## nxtbr - determine next direction for moving in parse tree integer function nxtbr (node, lnode) integer node, lnode include cpars if (lnode == tree(node+PARENT)) #going down { if (tree(node+LCHILD) != 0) return(LCHILD) else return(PARENT) } else if (lnode == tree(node+LCHILD) & #going up tree(node+RCHILD) != 0) return(RCHILD) else return(PARENT) end %%D 3 #-h- outf 588 asc 25-mar-82 08:42:51 v1.1 (sw-tools v1.1) %%E 3 %%I 3 #-h- outf 663 asc 25-oct-82 10:28:47 sventek (joseph sventek) %%E 3 ## outf - pick up output file substitution for command integer function outf (node, buf, i) %%D 3 integer node, i %%E 3 %%I 3 integer node, i, j %%E 3 integer pickup integer junk character buf(ARB) include cpars include stdsub if( out == 0 & pickup( buf, i, node, REDOUT, junk) != ERR ) return(OK) else if (out > 0) #check for pipes and parens { if (aout(out) != 0) #append call chcopy( '>', buf, i) if (cout(out) > 0) #use paren substitution %%D 3 call stcopy( ibuf, cout(out), buf, i) %%E 3 %%I 3 { j = cout(out) + 1 if (aout(out) == 0 | ibuf(j) != '>') j = j - 1 call stcopy( ibuf, j, buf, i) } %%E 3 else #pipe { call chcopy( '>', buf, i) call gpname( abs(cout(out)), buf, i) } return(OK) } return(ERR) end %%D 6 #-h- param 458 asc 25-mar-82 08:42:52 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%D 7 #-h- param 1718 asc 21-nov-82 14:09:57 sventek (joseph sventek) %%E 7 %%I 7 %%D 8 #-h- param 1718 asc 23-nov-82 17:37:50 sventek (joseph sventek) %%E 8 %%E 7 %%I 8 #-h- param 2012 asc 16-dec-82 17:19:52 sventek (joseph sventek) %%E 8 ifdef(DO_PARAM) ## param - handle parameter substitution for the shell integer function param(c) character c, t character ngetch, type integer ludef %%D 8 integer i %%E 8 %%I 8 integer i, found %%E 8 include shflag include csclin string qublqu "@" @"" if (c == '$') #handle param substitution { %%I 8 found = YES # assume it will be found %%E 8 lin(1) = '$' for (i=2; ; i=i+1) { lin(i) = ngetch(lin(i), shin) t = type(lin(i)) if (t != LETTER & t != DIGIT & t != '_') break } if (i == 2 & (t == '*' | t == '@@')) # wants all parameters { i = 4 call putbak('"') # output terminating quote lin(3) = EOS for (lin(2) = '9'; lin(2) > '0'; lin(2) = lin(2) - 1) if (ludef(lin, lin(i), table) == YES) # found one { call pbstr(lin(i)) # push it back on input if (lin(2) == '1') # finish up break if (t == '@@') call pbstr(qublqu) else call putbak(' ') } call putbak('"') # output beginning quote } else { call putbak(lin(i)) lin(i) = EOS i = i + 1 if (ludef(lin, lin(i), table) == YES) call pbstr(lin(i)) %%I 8 ifdef(KEEP_DOLLARS) else if (type(lin(2)) != DIGIT | i > 4) # not $ found = NO enddef %%E 8 } %%I 8 ifdef(KEEP_DOLLARS) if (found == NO) call pbstr(lin) # put back $word enddef %%E 8 c = ngetch(c, shin) %%D 8 return(YES) %%E 8 %%I 8 return(found) %%E 8 } return(NO) end elsedef %%E 6 ## param - handle parameter substitution for the shell integer function param(c) character c, num(2), ngetch integer getarg, ctoi, i, junk include shflag include csclin if (c == '$') #handle param substitution { num(1) = ngetch( num(1), shin) num(2) = EOS i = 1 n = ctoi( num, i) if (n > 0) { if( getarg( n+1, lin, MAXLINE) != EOF) call pbstr(lin) c = ngetch( c, shin) %%I 8 return(YES) %%E 8 } %%D 8 else c = num(1) return(YES) } %%E 8 %%I 8 ifdef(KEEP_DOLLARS) %%E 8 %%D 8 else %%E 8 %%I 8 call putbak(num(1)) %%E 8 %%D 8 return(NO) %%E 8 %%I 8 elsedef c = num(1) enddef } return(NO) %%E 8 end %%I 6 enddef %%E 6 #-h- parser 1280 asc 25-mar-82 08:42:54 v1.1 (sw-tools v1.1) ## parser - parse shell command line # syntax : empty # | syn1 # syn1 : syn2 # | syn2 & syntax # | syn2 ; syntax # syn2 : syn3 # | syn3 | syn2 # syn3 : (syn1) [out] [?errout] # | tok tok* [out] [?errout] integer function parser (line) integer p, p1, p2, mark, i, j integer syntax, syn1, syn2, syn3 integer mktoks, nextp character line(ARB) include cpars include shflag treend = 0 #initialize tree pointer pp = 0 #initialize stack pointer for (i=1; i<=TSIZE; i=i+1) #initialize token table for (j=1; j<=MAXTOK; j=j+1) tkbuf(i,j) = 0 for (i=1; i<=TREESIZE; i=i+1) #initialize parse tree tree(i) = 0 for (i=1; i<=MAXLINE; i=i+1) #initialize input buffer ibuf(i) = EOS if (mktoks(line,p2) == ERR) return(ERR) tkbuf( TMARK, 1) = SSYNTAX tkbuf( NODEPTR, 1) = -1 tkbuf( ESCAN, 1) = p2 call putbac (1) while (nextp(p1) != EOS) #generate parse tree { mark = tkbuf( TMARK, p1) p2 = tkbuf( ESCAN, p1) if (mark == SSYNTAX) parser = syntax(p1, p2) else if (mark == SSYN1) parser = syn1(p1, p2) else if (mark == SSYN2) parser = syn2(p1,p2) else if (mark == SSYN3) parser = syn3(p1,p2) if (parser == ERR) return } parser = OK return end %%D 7 #-h- pastbl 196 asc 25-mar-82 08:42:55 v1.1 (sw-tools v1.1) %%E 7 %%I 7 #-h- pastbl 196 asc 23-nov-82 17:37:52 sventek (joseph sventek) %%E 7 ## pastbl - read past blanks and tabs on input subroutine pastbl (c) character c character ngetch include shflag repeat c = ngetch(c, shin) until (c != ' ' & c != '@t') return end %%D 7 #-h- pickup 667 asc 25-mar-82 08:42:56 v1.1 (sw-tools v1.1) %%E 7 %%I 7 #-h- pickup 666 asc 23-nov-82 22:26:37 sventek (joseph sventek) %%E 7 ## pickup - pick up character string from parse tree integer function pickup( array, i, node, field, arg) integer node, field, arg, i character array(ARB) include cpars pickup = OK %%D 7 %%E 7 if ( (field == REDIN | field == REDOUT | field == REDERR) & (tree(node+NTYPE) == COM | tree(node+NTYPE) == PAR) & tree(node+field) != 0 ) call stcopy( ibuf, tree(node+field), array, i) else if (field == CMD & tree(node+NTYPE) == COM) call stcopy( ibuf, tree(node+CMD), array, i) else if (field == ARGUMENT & tree(node+NTYPE) == COM & arg <= tree(node+NENT) ) call stcopy( ibuf, tree(node+CMD+arg), array, i) else pickup = ERR return end #-h- putbac 209 asc 25-mar-82 08:42:56 v1.1 (sw-tools v1.1) ## putbac - put pointer on pushdown stack subroutine putbac (p) integer p include cpars pp = pp + 1 if (pp > MAXSTACK) call stxerr("stack size exceeded (putbac)") else stack(pp) = p return end %%D 7 #-h- pwdir 215 asc 25-mar-82 08:42:57 v1.1 (sw-tools v1.1) subroutine pwdir( fd, c) %%E 7 %%I 7 #-h- pwdir 220 asc 23-nov-82 21:59:13 sventek (joseph sventek) subroutine pwdir(file, fd, c) %%E 7 character file(FILENAMESIZE), c integer fd call gwdir( file, PATH) if( file(2) == '@@' ) file(2) = '\' call putlin(file, fd) if (c != EOS) call putch(c, fd) return end %%D 6 #-h- qs 364 asc 25-mar-82 08:42:58 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%D 7 #-h- qs 437 asc 21-nov-82 18:10:00 sventek (joseph sventek) %%E 7 %%E 6 %%I 7 #-h- qs 437 asc 23-nov-82 17:37:53 sventek (joseph sventek) %%E 7 ## qs - handle extract quoted string token in shell subroutine qs(char, tok) character c, tok(ARB), char integer j, junk integer param character ngetch include shflag tok(1) = char j = 2 for (c=ngetch(c,shin); c != EOS; c=ngetch(c, shin)) { %%I 6 if (char == '"') # expand parameters inside of "..." junk = param(c) %%E 6 if (c == EOS) break tok(j) = c j = j + 1 if (c == char) #done break } tok(j) = EOS return end %%D 2 #-h- rlogin 282 asc 25-mar-82 08:42:58 v1.1 (sw-tools v1.1) %%E 2 %%I 2 %%D 7 #-h- rlogin 282 asc 09-apr-82 10:28:40 j (sventek j) %%E 7 %%E 2 %%I 7 #-h- rlogin 237 asc 23-nov-82 17:37:54 sventek (joseph sventek) ifdef(DO_STARTUP) %%E 7 subroutine rlogin integer open %%D 2 string lgin "login.sh" %%E 2 include shflag include stdsub %%I 2 string lgin "login.sh" %%E 2 %%D 7 inunit = shin ifdef(DO_STARTUP) call tooldr(sh, LOCAL) call concat(sh, lgin, hfile) logfd = open(hfile, READ) if (logfd != ERR) shin = logfd elsedef logfd = ERR enddef %%E 7 %%I 7 call tooldr(sh, LOCAL) call concat(sh, lgin, hfile) unit(2) = open(hfile, READ) if (unit(2) != ERR) depth = 2 %%E 7 return end %%D 7 #-h- scrf 1409 asc 25-mar-82 08:42:59 v1.1 (sw-tools v1.1) %%E 7 %%I 7 enddef %%D 12 #-h- scrf 1424 asc 23-nov-82 16:50:36 sventek (joseph sventek) %%E 12 %%E 7 %%I 12 %%D 13 #-h- scrf 1423 asc 15-jun-83 15:02:48 sventek (joseph sventek) %%E 13 %%E 12 %%I 13 #-h- scrf 1446 asc 16-jun-83 09:35:18 sventek (joseph sventek) %%E 13 ## scrf - prepare script file for execution by shell %%D 7 subroutine scrf (node, comand, args) %%E 7 %%I 7 integer function scrf (node, comand, args) %%E 7 character comand(ARB), args(ARB) integer pickup, inf, outf, errf, length, loccom integer i, j, type include shflag include stdsub string suffix IMAGE_SUFFIX string prflag "-v " string cmflag "-x " string drflag "-d " string shstr "sh" %%I 13 string spath STD_PATH %%E 13 # handle scripts by spawning the shell with the script as input j = 1 call stcopy( shstr, 1, args, j) call chcopy( ' ', args, j) if (prlin == YES) #pass along shell flags call stcopy( prflag, 1, args, j) if (prcom == YES) call stcopy( cmflag, 1, args, j) if (drop == NO) call stcopy( drflag, 1, args, j) # The shell becomes the main command and the script file name # becomes an argument to the shell call stcopy( comand, 1, args, j) if( loccom( shstr, spath, suffix, comand) != BINARY ) { %%D 12 call remark( "? Can't locate shell image file.") %%E 12 %%D 7 return %%E 7 %%I 7 %%I 12 call remark( "? Can't locate shell image file") %%E 12 return(ERR) %%E 7 } call chcopy( ' ', args, j) for (i=1; pickup(args, j, node, ARGUMENT, i) != ERR; i=i+1) #pick up args call chcopy( ' ', args, j) call chcopy( ESCAPE, args, j) if( inf(node, args, j) != ERR) #pick up STDIN substitution call chcopy( ' ', args, j) else j = j - 1 if( outf(node, args, j) != ERR) #pick up STDOUT substitution call chcopy( ' ', args, j) if( errf(node, args, j) != ERR) #pick up ERROUT substitution call chcopy( ' ', args, j) args(j) = EOS %%D 7 return %%E 7 %%I 7 return(OK) %%E 7 end #-h- setree 290 asc 25-mar-82 08:43:01 v1.1 (sw-tools v1.1) ## setree - put 'value' in given node at given position integer function setree (node, posn, value) integer node, posn, value, i include cpars i = node + posn if (tree(i) != 0) { call stxerr("doubly defined argument (setree)") return(ERR) } tree(i) = value return(OK) end %%D 6 #-h- shcom 548 asc 25-mar-82 08:43:01 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%D 7 #-h- shcom 674 asc 21-nov-82 15:12:02 sventek (joseph sventek) %%E 7 %%E 6 %%I 7 %%D 9 #-h- shcom 409 asc 23-nov-82 14:10:43 sventek (joseph sventek) %%E 9 %%E 7 %%I 9 #-h- shcom 407 asc 13-jan-83 14:24:43 sventek (joseph sventek) %%E 9 ## shcom - see if command is shell command integer function shcom(comand) character comand(ARB) %%D 7 integer equal # function(s) %%E 7 %%I 7 integer i, j %%E 7 %%D 7 include shcmd %%E 7 %%I 7 string intcmd INT_COMMANDS %%E 7 %%D 7 if( equal( comand, cd) == YES | ifdef(IMBED_ED) equal( comand, e) == YES | enddef equal( comand, ho) == YES | equal( comand, home) == YES | equal( comand, logout) == YES | equal( comand, von) == YES | equal( comand, voff) == YES | equal( comand, xon) == YES | equal( comand, xoff) == YES | %%E 7 %%I 6 %%D 7 ifdef(DO_PARAM) equal( comand, param) == YES | equal( comand, alias) == YES | equal( comand, ask) == YES | enddef %%E 7 %%E 6 %%D 7 equal( comand, shopth) == YES ) return(YES) else return(NO) %%E 7 %%I 7 for (i = 1; intcmd(i) != EOS; i = i + 1) { %%D 9 for (j = 1; comand(j) != EOS; [i = i + 1; j = j + 1]) %%E 9 %%I 9 for (j = 1; comand(j) != EOS; i = i + 1, j = j + 1) %%E 9 if (comand(j) != intcmd(i)) break if (comand(j) == EOS & intcmd(i) < ' ') return(intcmd(i)) while (intcmd(i) > ' ') i = i + 1 } return(0) %%E 7 end %%D 6 #-h- shellc 1346 asc 25-mar-82 08:43:03 v1.1 (sw-tools v1.1) %%E 6 %%I 6 %%D 7 #-h- shellc 2359 asc 21-nov-82 15:12:04 sventek (joseph sventek) %%E 7 %%E 6 %%I 7 %%D 11 #-h- shellc 1568 asc 24-nov-82 13:41:45 sventek (joseph sventek) %%E 11 %%E 7 %%I 11 %%D 12 #-h- shellc 1568 asc 13-jun-83 12:07:13 sventek (joseph sventek) %%E 12 %%E 11 %%I 12 #-h- shellc 1565 asc 15-jun-83 15:02:49 sventek (joseph sventek) %%E 12 ## shellc - execute shell command integer function shellc (comand, args) character args(ARB), comand(ARB) %%D 7 integer cwdir, equal # function(s) %%E 7 %%I 6 %%I 7 integer shcom, chgdir # function(s) %%E 7 ifdef(DO_PARAM) integer dask %%I 7 filedes open %%E 7 enddef %%E 6 integer i, status %%D 7 include shcmd %%E 7 %%I 7 %%E 7 include stdsub include shflag status = OK %%D 7 if( equal( comand, cd) == YES) { call gwdir( sh, LOCAL) # fetch current working directory if( args(1) == EOS ) # bare cd => back to previous dir call strcpy( olddir, args) if( cwdir(args) == ERR ) # oops, no such directory %%E 7 %%I 7 %%D 11 select(shcom(comand)) %%E 11 %%E 7 %%I 11 switch(shcom(comand)) %%E 11 { %%D 7 call nodir( args) status = ERR } else { call strcpy( sh, olddir) # store previous directory call pwdir(ERROUT, '@n') # verify change to user } } else if( equal( comand, ho) == YES | equal( comand, home) == YES ) { call gwdir( sh, LOCAL) if( cwdir(homedr) == ERR ) { call nodir( homedr) status = ERR } else { call strcpy( sh, olddir) call pwdir( ERROUT, '@n') } } else if( equal(comand, von) == YES ) prlin = YES else if( equal(comand, voff) == YES ) prlin = NO else if( equal(comand, xon) == YES ) prcom = YES else if( equal(comand, xoff) == YES ) prcom = NO else if( equal(comand, shopth) == YES ) call dsppth else if( equal(comand, logout) == YES ) call endsh('q') %%E 7 %%I 7 case C_CD: status = chgdir(args) case C_HO, C_HOME: status = chgdir(homedr) case C_VON: prlin = YES case C_VOFF: prlin = NO case C_XON: prcom = YES case C_XOFF: prcom = NO case C_PATH: call dsppth(sh) case C_LOGOUT: call endsh('q') case C_COMMENT: ; %%E 7 ifdef(IMBED_ED) %%D 7 else if( equal( comand, e) == YES ) call editor(args) %%E 7 %%I 7 case C_E: call editor(args) %%E 7 enddef %%I 6 ifdef(DO_PARAM) %%D 7 else if (equal(comand, param) == YES) { if (args(1) == EOS) # list known parameters call dsptbl(args, '$') else %%E 7 %%I 7 case C_PARAM: %%E 7 { %%D 7 sh(1) = '$' # start with $ for ([i=1; j=2]; args(i) != EOS; [i=i+1; j=j+1]) if (args(i) == ' ') break else sh(j) = args(i) sh(j) = EOS call skipbl(args, i) call scopy(args, i, args, 1) if (args(1) == EOS) call rmdef(sh, table) %%E 7 %%I 7 if (args(1) == EOS) # list known parameters call dsptbl(args, '$') %%E 7 else %%D 7 call entdef(sh, args, table) %%E 7 %%I 7 call procdf(args, '$') %%E 7 } %%D 7 } else if (equal(comand, alias) == YES) { if (args(1) == EOS) # list known parameters call dsptbl(args, EOS) else %%E 7 %%I 7 case C_ALIAS: %%E 7 { %%D 7 for (i=1; args(i) != EOS; i=i+1) if (args(i) == ' ') break else sh(i) = args(i) sh(i) = EOS call skipbl(args, i) call scopy(args, i, args, 1) if (args(1) == EOS) call rmdef(sh, table) %%E 7 %%I 7 if (args(1) == EOS) # list known aliases call dsptbl(args, EOS) %%E 7 else %%D 7 call entdef(sh, args, table) %%E 7 %%I 7 call procdf(args, EOS) %%E 7 } %%D 7 } else if (equal(comand, ask) == YES) status = dask(args) %%E 7 %%I 7 case C_ASK: status = dask(args) case C_SOURCE: if (depth >= MAX_NEST) %%D 12 call remark("? Source files nested to deeply.") %%E 12 %%I 12 call remark("? Source files nested to deeply") %%E 12 else { depth = depth + 1 unit(depth) = open(args, READ) if (unit(depth) == ERR) { call putlin(args, ERROUT) %%D 12 call remark(" - cannot open.") %%E 12 %%I 12 call remark(" - cannot open") %%E 12 depth = depth - 1 } else shin = unit(depth) } case C_UNALIAS: call killdf(args, EOS) case C_UNPARAM: call killdf(args, '$') %%E 7 enddef %%E 6 %%D 7 else call remark ("? Invalid shell command.") %%E 7 %%I 7 default: { status = ERR %%D 12 call remark ("? Invalid shell command.") %%E 12 %%I 12 call remark ("? Invalid shell command") %%E 12 } } %%E 7 return(status) end %%D 7 #-h- shline 957 asc 25-mar-82 08:43:05 v1.1 (sw-tools v1.1) %%E 7 %%I 7 #-h- shline 1032 asc 23-nov-82 21:52:53 sventek (joseph sventek) %%E 7 ## shline - prompt and get input line for shell integer function shline (line) character line(ARB) integer equal, length, prompt %%I 7 ifdef(prompt) integer Prompt enddef %%E 7 character tmpara(5) integer i, k include shflag %%D 7 include shcmd %%E 7 string pchar "% " %%I 7 string voff "voff" %%E 7 if( carg == YES ) # get input from command line { if( cargdn == YES ) { line(1) = EOS k = EOF } else { call strcpy( clin, line) cargdn = YES k = length(line) } } else repeat { %%D 7 k = prompt( pchar, line, shin) %%E 7 %%I 7 ifdef(prompt) if (depth > 1) k = Prompt(pchar, line, shin) else enddef k = prompt(pchar, line, shin) %%E 7 if (k != EOF) break %%D 7 if( shin == logfd ) # finished login.sh - now input { call close(shin) # close login.sh shin = inunit # restore input unit k = OK # read again on input file } %%E 7 %%I 7 if (depth > 1) # just close and unstack { call close(shin) depth = depth - 1 shin = unit(depth) k = OK } %%E 7 } until (k == EOF) if( k != EOF ) { %%D 7 for( i=1 ; i <= 4 & i <= k ; i = i + 1 ) %%E 7 %%I 7 for( i=1 ; i <= 4; i = i + 1 ) %%E 7 tmpara(i) = line(i) tmpara(i) = EOS call fold(tmpara) if( prlin == YES & equal(tmpara, voff) == NO ) # user wishes to see line call putlin(line, ERROUT) } return(k) end %%D 4 #-h- shtok 1201 asc 25-mar-82 08:43:06 v1.1 (sw-tools v1.1) %%E 4 %%I 4 %%D 7 #-h- shtok 1202 asc 01-nov-82 18:14:44 sventek (joseph sventek) %%E 7 %%E 4 %%I 7 #-h- shtok 1202 asc 23-nov-82 17:37:58 sventek (joseph sventek) %%E 7 ## shtok - extract next shell token integer function shtok (tok) character tok(ARB), c, ngetch integer spec, param, atbeg integer i, j, pstat include shflag pstat = NO #initialize variable repeat #loop until non-null token found { call pastbl(c) #skip leading blanks & tabs j = 1 if (spec(c) == YES) #single shell special character { tok(1) = c tok(2) = EOS shtok = c return } %%D 4 if (c == ''' | c == '"') #quoted string %%E 4 %%I 4 if (c == '@'' | c == '"') #quoted string %%E 4 { call qs(c, tok) shtok = tok(1) return } if (c == '<' | c == '>' | c == '?') #redirected IO for (i=1; i<=2; i=i+1) { tok(j) = c j = j + 1 call pastbl(c) if (c != tok(j-1)) break } for ( ; c != EOS; c=ngetch(c, shin)) { pstat = param(c) if (c == EOS) break if (atbeg(c) == YES) { call putbak(c) break } if (c == ESCAPE) { c = ngetch(c, shin) if (spec(c) == NO & #ignore if not shell char. (c != ESCAPE & c != '$')) { call putbak(c) c = ESCAPE } } tok(j) = c j = j + 1 } tok(j) = EOS shtok = tok(1) if (pstat == NO | j < 1) return #continue if null token produced by empty parameter substitution pstat = NO } end #-h- spec 367 asc 25-mar-82 08:43:08 v1.1 (sw-tools v1.1) ## spec - handle special characters in shell commands integer function spec (c) character c character sp(8) data sp(1), sp(2), sp(3), sp(4), sp(5), sp(6), sp(7), sp(8) /'&', '(', ')', SEPCHAR, '|', '^', '@n', EOS/ if (index(sp, c) != 0) { spec = YES if (c == '^') #allow '^' for PIPE c = '|' } else spec = NO return end #-h- stripb 170 asc 25-mar-82 08:43:09 v1.1 (sw-tools v1.1) subroutine stripb(buf) integer i integer length character buf(ARB) for( i=length(buf) ; i > 0 ; i=i-1 ) if( buf(i) != ' ' ) break buf(i+1) = EOS return end #-h- stxerr 227 asc 25-mar-82 08:43:09 v1.1 (sw-tools v1.1) ## stxerr - report syntax error subroutine stxerr (reason) character reason(ARB) include cpars string first "? Syntax error: " call putlin(first, ERROUT) call putlin (reason, ERROUT) call putch ('@n', ERROUT) return end #-h- syn1 1194 asc 25-mar-82 08:43:10 v1.1 (sw-tools v1.1) ## syn1 - parse shell syntax level 1 # SYN1 -> SYN2 # -> SYN2 ; SYNTAX # -> SYN2 & SYNTAX integer function syn1 (p1,p2) character tok integer p, p1, p2, node, l, pt, ndx integer mktree include cpars l = 0 ifdef(DEBUG) debug_int("p1 =",p1) debug_int("p2 =",p2) enddef for (p=p1; p 0) call stxerr("unbalenced left parentheses (syn1)") else { tkbuf( TMARK, p1) = SSYN2 call putbac (p1) } return(OK) end #-h- syn2 840 asc 25-mar-82 08:43:12 v1.1 (sw-tools v1.1) ## syn2 - parse shell syntax level 2 # SYN2 -> SYN3 # -> SYN3 | SYN2 integer function syn2 (p1,p2) character tok integer p, p1, p2, l, node, pt, ndx integer mktree include cpars l = 0 for (p=p1; p (SYN1) [out] [?errout] # -> word word* [out] [?errout] integer function syn3 (p1,p2) integer p1, p2, ndx integer dopar, doverb include cpars if (p1 >= p2) { call stxerr("empty command (syn3)") return(ERR) } ndx = tkbuf( IBPTR, p1) if (ibuf(ndx) == '(') return( dopar(p1,p2)) else return( doverb(p1,p2)) end #-h- syntax 491 asc 25-mar-82 08:43:14 v1.1 (sw-tools v1.1) ## syntax - parse shell syntax level zero # SYNTAX -> EMPTY # -> SYN1 integer function syntax (p1,p2) integer p, p1, p2, ndx character tok include cpars for (p=p1; p 1) # non-null response { args(j) = EOS # overwrite @n call entdef(sh, args, table)# enter value } } return(status) end enddef %%E 6 %%D 7 #-h- sh.fmt 10590 asc 25-mar-82 08:46:15 v1.1 (sw-tools v1.1) %%E 7 %%I 7 %%D 9 #-h- procdf 793 asc 24-nov-82 15:06:19 sventek (joseph sventek) %%E 9 %%I 9 %%D 12 #-h- procdf 791 asc 13-jan-83 14:24:47 sventek (joseph sventek) %%E 12 %%E 9 %%I 12 #-h- procdf 790 asc 15-jun-83 15:02:54 sventek (joseph sventek) %%E 12 ifdef(DO_PARAM) subroutine procdf(args, c) character args(ARB), c integer i, j, ndx integer ludef, shcom include shflag include stdsub string undef " - not defined" if (c != EOS) { sh(1) = c j = 2 } else j = 1 ndx = j %%D 9 for (i = 1; args(i) != EOS; [i = i + 1; j = j + 1]) %%E 9 %%I 9 for (i = 1; args(i) != EOS; i = i + 1, j = j + 1) %%E 9 if (args(i) == ' ') break else sh(j) = args(i) sh(j) = EOS call skipbl(args, i) call scopy(args, i, args, 1) if (args(1) == EOS) if (ludef(sh, args, table) == YES) { call putstr(sh(ndx), COL_WIDTH, ERROUT) call putch(' ', ERROUT) call putlnl(args, ERROUT) } else { call putlin(sh(ndx), ERROUT) call putlnl(undef, ERROUT) } else if (shcom(sh) > 0) %%D 12 call remark("Attempt to redefine a reserved word.") %%E 12 %%I 12 call remark("Attempt to redefine a reserved word") %%E 12 else call entdef(sh, args, table) return end enddef #-h- chgdir 533 asc 23-nov-82 21:59:21 sventek (joseph sventek) integer function chgdir(args) character args(ARB) integer cwdir include stdsub string finish ": no such directory!" call gwdir(sh, LOCAL) # save current working directory if (args(1) == EOS) # bare cd ==> use saved directory call strcpy(olddir, args) if (cwdir(args) == ERR) # directory does not exist { call putlin(args, ERROUT) call putlnl(finish, ERROUT) return(ERR) } else { call strcpy(sh, olddir) # save last directory for future call pwdir(sh, ERROUT, '@n') # display to user } return(OK) end #-h- killdf 194 asc 23-nov-82 22:56:11 sventek (joseph sventek) ifdef(DO_PARAM) subroutine killdf(args, c) character args(ARB), c include stdsub include shflag i = 1 call chcopy(c, sh, i) call concat(sh, args, sh) call rmdef(sh, table) return end enddef #-h- sh.fmt 15213 asc 24-nov-82 15:37:52 sventek (joseph sventek) %%E 7 .so ~bin/manhdr .hd Sh (1) 27-Jul-81 shell (command line interpreter) .sy sh [-cdnvx] [name [arguments]]. .ds Sh is a command line interpreter: it reads lines typed by you and interprets them as requests to execute other programs. .ti -2 o COMMANDS In simplest form, a command line consists of the command name followed by arguments to the command, all separated by spaces: .ce command arg1 arg2 ... argn The shell splits up the command name and the arguments into separate strings. Then a file with name `command' is sought; `command' may be a path name to specify any file in the system. If `command' is found, it is brought into memory and executed. The arguments collected by the shell are accessible to the command. When the command is finished, the shell resumes its own execution and indicates its readiness to accept another command by typing a prompt character. If file `command' can't be found in the current directory or through its pathname, the shell searches your `home/tools' directory, the site-specific tools directory, and finally the general tools directory. If the file still has not been found, and the `-d' switch has not been specified, the shell passes the entire command line to the local operating system's command line interpreter (DCL for VMS). An example of a simple command is: .ce sort list which would sort the contents of file `list', printing the output at your terminal. Some characters on the command line have special meanings to the shell (these are discussed below). The character `@' may be included anywhere in the command line to cause the following character to lose any special meaning it may have to the shell (to be `escaped'). Sequences of characters enclosed in double (") or single (') quotes are also taken literally. .ti -2 o STANDARD I/O Shell programs in general have three standard files open : `input', `output', and `error output'. All three are assigned to your terminal unless redirected by the special arguments `<', `>', `?', `>>', `??', (and sometimes `-'). An argument of the form `name' causes file `name' to be used as the standard output. An argument of the form `?name' causes the file `name' to be used as the standard error output. Arguments of the form `>>name' or `??name' cause program output to be appended to `name' for standard output or error output respectively. If `name' does not exist, it will be created. Most tools have the capability to read their input from a series of files. In this case, the list of files overrides reading from standard input. However, many of the tools allow you to read from both a list of files and from input by specifying the filename `-' for standard input. For example: .ce format file1 - file2 would read its input from `file1', then from the standard input, then from `file2'. .ti -2 o FILTERS AND PIPES The output from one command may be directed to the input of another. A sequence of commands separated by vertical bars (`|') or carets (`^') causes the shell to arrange that the standard output of each command be delivered to the standard input of the next command in sequence. Thus in the command line: .ce sort list | uniq | crt `Sort' sorts the contents of file `list'; its output is passed to `uniq', which strips out duplicate lines. The output from `uniq' is then input to `crt', which prepares the lines for viewing on your crt terminal. The vertical bar is called a `pipe'. Programs such as `sort', `uniq', and `crt', which copy standard input to standard output (making some changes along the way) are called `filters'. .ti -2 o COMMAND SEPARATORS Commands need not be on different lines; instead they may be separated by semicolons: .ce ar t file; ed The above command will first list the contents of the archived file `file', then enter the editor. The shell also allows commands to be grouped together with parentheses, where the group can then be used as a filter. For example: .ce (date; cat chocolate) | comm vanilla writes first the date and then the file `chocolate' to standard output, which is then read as input by `comm'. This tool compares the results with existing file `vanilla' to see which lines the two files have in common. .ti -2 o MULTITASKING On many systems the shell also allows processes to be executed in the background. If a command is followed by `&', the shell will not wait for the command to finish before prompting again; instead, it is ready immediately to accept a new command. For instance: .ce ratfor ambrose >george & preprocesses the file `ambrose', putting the output on `george'. No matter how long the compilation takes, the shell returns immediately. The identification number of the process running that command is printed. This identification may be used to wait for the completion of the command or to terminate it. The `&' may be used several times in a line. Parentheses and pipes are also allowed (within the same background process). .ti -2 o SCRIPT FILES The shell itself is a command, and may be called recursively, either implicitly or explicitly. This is primarily useful for executing files containing lines of shell commands. For instance, suppose you had a file named `nbrcount.sh' which looked like this: .nf .in +15 echo "Counting strings of digits" tr $4 ar u loveletters $4 .in -15 .fi Then, executing the command: .ce private Dan John Harold fair would merge the files `Dan', `John', and `Harold', encrypt them, and store them away in an archive under the name `fair'. Script files may be used as filters in pipelines just like regular commands. Script files sometimes require in-line data to be available to them. A special input redirection notation `<<' is used to achieve this effect. For example, the editor normally takes its commands from the standard input. However, within a shell procedure commands could be embedded this way: .nf .in +15 ed file < ed "-pWas gibt? " file The user must explicitly ask for a parameter to be expanded. We have already seen examples of the use of parameters, when referencing the positional arguments to scripts as $1, $2, ..., $9. For example, suppose that a particular directory on another machine has a set of files with cooking recipes. A parameter can be used to permit easy reference to the directory param cook /@node/db0/frenchchf Then commands of the form ls $cook; cat $cook/quiche.man .sp will permit you to list the contents of the directory and display one of the recipes. .sp Parameters are expanded inside of quoted strings when they are delimited by a quote character ("), but are not expanded when delimited by an apostrophe ('). In addition to the positional parameters $1, $2, ..., $9, two shorthand parameters are available for causing all positional parameters to be displayed: .sp $@ results in "$1" "$2" ... .br $* results in "$1 $2 ..." %%E 7 .ti -2 o INTERRUPTS There are often occasions when you may wish to interrupt the execution of a process initiated by the shell. This may be achieved by typing the interrupt character at the terminal. Typing the interrupt character will cause the process to be terminated, and the shell will prompt you for your next command. A complete list of system-specific special terminal characters may be had by typing the command `tty' to the shell. `Tty' is a system-dependent tool which displays on standard output all of the special terminal characters interpreted by the local system. For example, the interrupt character for the VAX is ^C (control C). If the following two commands are typed to the shell: .in +15 .nf sort mybigfile ^C .in -15 .fi then the sorter would be aborted. .ti -2 o TERMINATION The shell may be terminated by typing an EndOfFile (`^Z') as a command. .fl .sa The Unix command sh. .br The Bell system Technical Journal, vol. 57, no. 6, part 2, July-Aug 1978. .di The error message `syntax error' appears whenever a command line cannot be understood. .au .br Dennis Hall, Joe Sventek, Debbie Scherrer, Dave Martin. .bu If you want to escape a shell special character that appears as the first character of an argument, you must escape it with quotes rather than an `@' sign. #-h- esh.fmt 11511 asc 25-mar-82 08:46:39 v1.1 (sw-tools v1.1) .so ~bin/manhdr .hd Esh (1) 5-Oct-81 extended shell, with intraline editing and history .sy esh [-cdnvx] [file [arguments]] .ds `esh' is an extended version of `sh' which incorporates several features designed to make it easier to use. L I N E E D I T I N G .in +5 .ti -3 o Both backspace (^H) and RUBOUT (RUB, DEL) may be used to delete the last character typed. .sp .ti -3 o ^U may be used to undo the current line - i.e. delete it and re-prompt for the line. .sp .ti -3 o ^R may be used to re-type the line. This is useful when working on a hard-copy terminal, since character deletes are done with backspaces. .sp .ti -3 o ^W deletes the last word, where words are defined as strings of non-blanks. .sp .ti -3 o ^D causes the current working directory to be listed on the terminal, after which the line is re-displayed and you may continue input on the current line. This is useful when you get part way through a command, and then realize that the critical file name has slipped from recent memory. .sp .ti -3 o ^F (or ESC) causes file recognition to be performed on the current pathname. If the filename can be extended unambiguously, it will be; otherwise, a list of files matching the current pattern are displayed, the line re-displayed, and you may continue input on the line. .sp .ti -3 o ^A causes the previous command line to be retrieved and the cursor to be positioned at the end. This is useful for adding stages to pipelines, for example. ^A may also be used in conjunction with the history mechanism to append to previous commands. .sp .ti -3 o ^E causes the intraline editor to be entered. If the cursor is at the beginning of a line the previous line is retrieved; otherwise the current line is edited. The editing commands are discussed below in the section on intraline editing. .in -5 H I S T O R Y M E C H A N I S M A history of the commands input to `esh' are maintained for each session. You may invoke special history manipulating functions by starting a command line with an exclamation mark (! - also known as a BANG) in column 1. If is is necessary to send a line starting with a BANG to the shell, lines starting with "@!" have the "@" stripped off, and the remainder of the line is given to the shell. Lines starting with BANG enable you to communicate with a miniature version of the editor `ed'. At any time, the last 25 commands are available for recall and manipulation. The current line concept of `ed' is supported, although the current line is ALWAYS the last command in the history. Legal history commands are: .in +5 .ti -3 1. history display !h[istory] [n][l] This is the equivalent of a browse command in `ed'. !h will display the last screenful of commands, along with their line numbers. The screensize, which defaults to 22 lines, may be changed by specifying a BLANK and a number following the !h[istory] string (!h 10, for example). The new screensize is remembered and used in all !h commands as the default screensize. Specifying a screensize larger than 25 has the effect of setting the size to 25. The optional trailing `l' (list) will cause control characters in the commands to be displayed as `^', where is the character one needs to type in conjunction with the CTRL key to generate the control character. !b[rowse] [n][l] This command is a synonym for history. It is included to increase the similiarity of function with the editor. .ti -3 2. history recall ![line_number][;line_number]... This command permits the recall of a command from the history for re-execution. The command so recalled is displayed and then passed on to the shell for execution. This command is then entered at the bottom of the history. Valid line_numbers are the same as those for the editor. For example, a line_number may be the number listed next to the command in the history display, a pattern of the form "\pattern[\]", which indicates a backward search in the 25 line history window, or a pattern of the form "/pattern[/]", indicating a search forward, wrapping to the start of the 25 line window. The trailing '\' or '/' are optional when specifying a single pattern. The semi-colon syntax is the same as that in `ed', indicating that the search for the second pattern is to start at the line where the first pattern was found. If the pattern specified was illegal, or a line matching the pattern could not be found, or an invalid line_number was specified, a comment is displayed # invalid line number and you are prompted for more input. The history is not modified in this case. All sequences of patterns resolve into a single line number. It is not possible to request a range of lines from the history. It should be noted that the line_numbering is completely regular with `ed'. In particular, "!" followed by nothing maps into a fetch of the current line (last command typed). See the writeup on `ed' for more details on the specification of line_numbers. .ti -3 3. history recall and modification ![line_number]s/pat/repl[/[g]] Upon successfully recalling a command from the history, it may be modified before it is passed on to `esh' for execution. This is performed with the 's' command, which is exactly the same as that for `ed'. The delimiters for `pat' and `repl' may be any character, the remembered pattern feature is available, and the trailing delimiter after the replacement pattern is optional. The optional trailing `g' indicates substitution for all occurrences of 'pat' in the line. See the `ed' manual entry for more information on the substitute command. If the substitution fails for any reason, a comment is displayed # illegal substitution and you are prompted for more input. The history is not modified in this case. .ti -3 4. history archiving !w[rite] [>[>]]file This command permits you to archive (save) the entire transcript of activity to a file. It also passes an EOF to `esh', which causes `esh' to terminate execution. The commands !w file .br !w >file both cause `file' to be overwritten with the transcript, while >>file causes the transcript to be appended to `file'. It should be noted that the !w command causes ALL of the input given to `esh' in this session to be saved, not just the current 25 line window. It also passes an EOF to `esh', which will terminate execution. .ti -3 5. history deletion !q[uit] .br ^Z These commands cause an EOF to be sent to `esh' and the deletion of the log of activity. .in -5 Lines consisting solely of a carriage return are NOT logged in the history. If you need to perform several edits on a command before having it executed, you can exploit the fact that lines beginning with a sharp (#) are comments to the shell. For example: .in +5 .nf !\%ed\s/%/#/ !s/pat1/repl1/ .in +6 .cc * . . . . . . *cc . .in -6 !s/patn/repln/ !s/%#// .fi .in -5 All of the intermediate comment lines will be placed in the history, displacing other lines from the window which may possibly be needed. Of course, it may be simpler in such cases to just enter the command by hand. .sp 2 I N T R A L I N E E D I T I N G .sp The intraline editing functions are a subset of those available in the "VI" screen editor from Berkeley. You are referred to the VI documentation for a tutorial introduction. The intraline editing "mode" is entered via ^E. Exactly what happens when the ^E is typed depends on what precedes it on the command line. If the ^E is the first character on a line, the previous command is retrieved and the cursor is positioned at the beginning of the line. If the line is a history reference (i.e. begins with a "!"), the referenced line is retrieved and the cursor is positioned at the beginning of the line. If the line is anything else, the cursor is positioned at the end of the line. Once in the intraline editor the following commands are allowed: .sp Notes: `[n]' indicates an optional integer count input is terminated with ^Z or ESC .nf MOVE cursor: ------------ [n]SPACE -> positions [n]BS <- positions [n]h <- positions % <- to beginning of line (BOL) $ -> to end of line (EOL) [n]w -> (non-alphanumeric) words [n]W -> (non-blank) words [n]b <- (non-alphanumeric) words [n]B <- (non-blank) words [n]e -> to end of th (non-alphanumeric) word [n]E -> to end of th (non-blank) word [n]f -> thru th occurrence of char [n]t -> to th occurrence of char [n]F <- thru th occurrence of char [n]T <- to th occurrence of char [n]; Repeat last `f', `t', `F', or `T' [n], Repeat last `f', `t', `F', or `T' in reverse INSERT or APPEND : ------------------------ [n]i Insert text before cursor [n]I Insert text before beginning of line [n]a Append text after cursor [n]A Append text after end of line REPLACE or SUBSTITUTE for character(s): ---------------------------------------------- R Replace (overlay) text on screen with r Replace current character with [n]s Substitute characters with CHANGE to : ------------------- [n]cw next (non-alphanumeric) words to [n]cW next (non-blank) words to [n]ce thru end of th (non-alphanumeric) word to [n]cE thru end of th (non-blank) word to c% text from BOL thru cursor to c$ text from cursor thru EOL to C Synonym for `c$' DELETE (s): ------------------------ [n]x characters, starting at cursor [n]dSPACE characters, starting at cursor [n]X previous characters [n]dw next (non-alphanumeric) words [n]dW next (non-blank) words [n]db previous (non-alphanumeric) words [n]dB previous (non-blank) words [n]df thru next th occurrence of char [n]dt to next th occurrence of char [n]dF thru prev th occurrence of char [n]dT to prev th occurrence of char dd entire line d% from beginning of line to cursor, inclusive d$ from cursor to end of line, inclusive D Synonym for `d$' [n]. Repeat previous `delete' command UNDO action of previous command(s): ----------------------------------- u Undo the last change to the line U Undo ALL commands; restore line to original state EXIT intra-line editor: ----------------------- ^Z Move cursor to EOL and exit intra-line edit ^E Move cursor to EOL and force RETURN RETURN Delete after cursor to EOL and execute command line .sp .fi The three methods of exiting the intraline editing mode are worthy of special mention. In particular you will usually exit with ^E rather than RETURN or ^Z, since the RETURN will chop off everything to the right of the cursor and ^Z will merely return to the line-gathering routine which invoked the intraline editor. Note that a ^E^E sequence may be used to repeat the previous command line. .fl .sa sh - command line interpreter .di # invalid line number .br # invalid substitution .au Editing features: Dave Martin .br History mechanism: Joe Sventek .bu %%D 7 #-h- hsh.fmt 6206 asc 25-mar-82 08:47:00 v1.1 (sw-tools v1.1) %%E 7 %%I 7 #-h- hsh.fmt 6565 asc 24-nov-82 15:38:05 sventek (joseph sventek) %%E 7 .so ~bin/manhdr .hd Hsh (1) 2-May-81 shell with history and editing functions .sy hsh [-cdnvx] [file [arguments]] .ds `hsh' is identical to `sh' with the exception that a history is kept of commands typed; recall and editing functions on the history are permitted and described below. Consult the manual entry for `sh' for more information on the common functions. A history of the commands input to `hsh' are maintained for each session. The user may invoke special history manipulating functions by starting a command line with an exclamation mark (! - also known as a BANG) in column 1. If is is necessary to send a line starting with a BANG to the shell, lines starting with "@!" have the "@" stripped off, and the remainder of the line is given to the shell. Lines starting with BANG enable the user to communicate with a miniature version of the editor `ed'. At any time, the last 25 commands are available for recall and manipulation. The current line concept of `ed' is supported, although the current line is ALWAYS the last command in the history. Legal history commands are: .in +5 .ti -3 1. history display !h[istory] [n][l] This is the equivalent of a browse command in `ed'. !h will display the last screenful of commands, along with their line numbers. The screensize, which defaults to 22 lines, may be changed by specifying a BLANK and a number following the !h[istory] string (!h 10, for example). The new screensize is remembered and used in all !h commands as the default screensize. Specifying a screensize larger than 25 has the effect of setting the size to 25. The optional trailing `l' (list) will cause control characters in the commands to be displayed as `^', where is the character one needs to type in conjunction with the CTRL key to generate the control character. !b[rowse] [n][l] This command is a synonym for history. It is included to increase the similiarity of function with the editor. .ne 30 .ti -3 2. history recall ![line_number][;line_number]... This command permits the recall of a command from the history for re-execution. The command so recalled is displayed to the user and then passed on to the shell for execution. This command is then entered at the bottom of the history. Valid line_numbers are the same as those for the editor. For example, a line_number may be the number listed next to the command in the history display, a pattern of the form "\pattern[\]", which indicates a backward search in the 25 line history window, or a pattern of the form "/pattern[/]", indicating a search forward, wrapping to the start of the 25 line window. The trailing '\' or '/' are optional when specifying a single pattern. The semi-colon syntax is the same as that in `ed', indicating that the search for the second pattern is to start at the line where the first pattern was found. If the pattern specified was illegal, or a line matching the pattern could not be found, or an invalid line_number was specified, a comment is displayed to the user # invalid line number and the user is prompted for more input. The history is not modified in this case. All sequences of patterns resolve into a single line number. It is not possible to request a range of lines from the history. It should be noted that the line_numbering is completely regular with `ed'. In particular, "!" followed by nothing maps into a fetch of the current line (last command typed). See the writeup on `ed' for more details on the specification of line_numbers. .ti -3 3. history recall and modification ![line_number]s/pat/repl[/[g]] Upon successfully recalling a command from the history, it may be modified before it is passed on to `hsh' for execution. This is performed with the 's' command, which is exactly the same as that for `ed'. The delimiters for `pat' and `repl' may be any character, the remembered pattern feature is available, and the trailing delimiter after the replacement pattern is optional. The optional trailing 'g' indicates substitution for all occurrences of 'pat' in the line. See the `ed' manual entry for more information on the substitute command. If the substitution fails for any reason, a comment is displayed to the user # illegal substitution and the user is prompted for more input. The history is not modified in this case. .ti -3 4. history archiving !w[rite] [>[>]]file This command permits the user to archive (save) the entire transcript of activity to a file. It also passes an EOF to `hsh', which causes `hsh' to terminate execution. The commands !w file .br !w >file both cause `file' to be overwritten with the transcript, while >>file causes the transcript to be appended to `file'. It should be noted that the !w command causes ALL of the input given to `hsh' in this session to be saved, not just the current 25 line window. It also passes an EOF to `hsh', which will terminate execution. .ti -3 5. history deletion !q[uit] .br ^Z These commands cause an EOF to be sent to `hsh' and the deletion of the log of activity. .in -5 .ne 30 Lines consisting solely of a carriage return are NOT logged in the history. If the user needs to perform several edits on a command before having it executed, he can exploit the fact that lines beginning with a sharp (#) are comments to the shell. For example: .in +5 .nf !\%ed\s/%/#/ !s/pat1/repl1/ .in +6 .cc * . . . . . . *cc . .in -6 !s/patn/repln/ !s/%#// .fi .in -5 All of the intermediate comment lines will be placed in the history, displacing other lines from the window which may possibly be needed. Of course, it may be simpler in such cases to just enter the command by hand. .fl Creates a scratch file ~tmp/pid.log for the command transcript. .sa .nf sh - command line interpreter esh - shell with file recognition and RAW tty I/O ed - text editor .fi .di # invalid line number .br # invalid substitution .au Joe Sventek .bu %%I 7 Due to address space limitations on some systems (RSX-11M, for example), the history shell will not have support for the following shell internal commands: .sp alias ask param unalias unparam source %%E 7 %%I 6 %%D 7 #-h- shdef 18 asc 21-nov-82 17:52:17 sventek (joseph sventek) %%E 7 %%I 7 For those systems where the `source' command is supported, commands read from alternate input files (login.sh, `source'ed files) are NOT logged in the history. #-h- shdef 472 asc 24-nov-82 14:09:48 sventek (joseph sventek) %%E 7 define(DO_PARAM,) %%I 7 define(INT_COMMANDS,"cd@1ho@2home@3logout@4path@5von@6voff@7xon@10xoff@11#@12_ alias@13param@14ask@15source@16unalias@17unparam@20") define(C_CD,8%1) define(C_HO,8%2) define(C_HOME,8%3) define(C_LOGOUT,8%4) define(C_PATH,8%5) define(C_VON,8%6) define(C_VOFF,8%7) define(C_XON,8%10) define(C_XOFF,8%11) define(C_COMMENT,8%12) define(C_ALIAS,8%13) define(C_PARAM,8%14) define(C_ASK,8%15) define(C_SOURCE,8%16) define(C_UNALIAS,8%17) define(C_UNPARAM,8%20) %%I 10 #-h- hsh.tkb 64 asc 04-feb-83 14:22:04 sventek (joseph sventek) hsh.tsk/fp/cp,hsh.map=hsh/mp units=8 actfil=7 libr=fcsres:ro // #-h- hsh.odl 2660 asc 04-feb-83 14:22:05 sventek (joseph sventek) .NAME SHROOT .NAME SHINIT .NAME SHINPT .NAME SHPARS .NAME SHEXEC .ROOT SHROOT-MAIN-*!(SHINIT-INIT,SHINPT-INPUT,SHPARS-PARSE,SHEXEC-EXEC) MAIN: .FCTR COMMON-MAIN1-MAIN2-FORTS-FLIB-SLIB COMMON: .FCTR CDSMEM-SHFLAG-STDSUB-CPBACK-CSCLIN-CPARS .PSECT CDSMEM,RW,D,GBL,REL,OVR .PSECT SHFLAG,RW,D,GBL,REL,OVR .PSECT STDSUB,RW,D,GBL,REL,OVR .PSECT CPBACK,RW,D,GBL,REL,OVR .PSECT CSCLIN,RW,D,GBL,REL,OVR .PSECT CPARS,RW,D,GBL,REL,OVR MAIN1: .FCTR MAIN11-MAIN12-MAIN13-MAIN14-MAIN15-MAIN16 MAIN11: .FCTR RLIB/LB:.MAIN.:CLOWER:CONCAT:DSFREE:DSGET:ENTDEF:ENTER:ERROR MAIN12: .FCTR RLIB/LB:FDEL:FGENR8:FLFIND:FXLATE:GETCH:GETDIR:GETLIN:GETPNM MAIN13: .FCTR RLIB/LB:GETTYP:GLOCNM:GWDIR:HOMDIR:ITOC:LOCCOM:LOOKUP:LUDEF MAIN14: .FCTR RLIB/LB:MINLIB:MINPRM:MKPATH:PUTSTR:QUERY:R$CVTF:R$GUIC MAIN15: .FCTR RLIB/LB:REALDV:REMARK:REMOVE:RESDEF:RESTIL:SCOPY:SCRATF MAIN16: .FCTR RLIB/LB:SDUPL:SKIPBL:STLU:PROMPT MAIN2: .FCTR SH/LB:ENDSH:MAIN INIT: .FCTR INIT1-INIT2-FLIB INIT1: .FCTR RLIB/LB:DELARG:DSINIT:ENBINT:GETARG:IMPATH:MKTABL:PBINIT:TOOLDR INIT2: .FCTR SH/LB:ARGLIN:INITSH:RLOGIN INPUT: .FCTR INPUT1-INPUT2-FLIB INPUT1: .FCTR INP11-INP12-INP13-INP14-INP15-INP16 INP11: .FCTR RLIB/LB:ADDINT:ADDSET:AMATCH:CATSUB:CTOI:DODASH:EDLINE:ESC INP12: .FCTR RLIB/LB:FILSET:GETCCL:LOCATE:LOGEND:LOGPMT:MAKPAT:MAKSUB:MATCH INP13: .FCTR RLIB/LB:NOTE:OMATCH:PATSIZ:PLOG00:PLOG01:PLOG03:PLOG04:PLOG06 INP14: .FCTR RLIB/LB:PLOG07:PLOG08:PLOG09:PLOG10:PLOG11:PLOG12:PLOG13:PLOG14 INP15: .FCTR RLIB/LB:PLOG15:PLOG16:PLOG17:PLOG18:PLOG19:PLOG20:PLOG21:PLOG22 INP16: .FCTR RLIB/LB:PUTINT:SEEK:STCLOS INPUT2: .FCTR SH/LB:SHLINE PARSE: .FCTR PARSE1-PARSE2-FLIB PARSE1: .FCTR RLIB/LB:NGETCH:PBSTR:PUTBAK PARSE2: .FCTR PAR21-PAR22-PAR23 PAR21: .FCTR SH/LB:ATBEG:DOPAR:DOVERB:MKTOKS:MKTREE:NEXTP:PARAM:PARSER PAR22: .FCTR SH/LB:PASTBL:PUTBAC:QS:SETREE:SHTOK:SPEC:STXERR:SYN1 PAR23: .FCTR SH/LB:SYN2:SYN3:SYNTAX EXEC: .FCTR EXEC1-EXEC2-FLIB EXEC1: .FCTR EXEC11-EXEC12-EXEC13-EXEC14 EXEC11: .FCTR RLIB/LB:APPRED:ASSNGI:BCKSPN:CLOSDR:CWDIR:DELETE:DOPEN:EXTPNM EXEC12: .FCTR RLIB/LB:FILNFO:GENPNM:GETPRI:GTMODE:INDEXS:OPENDR:RCVDAT:RMDEF EXEC13: .FCTR RLIB/LB:SCTABL:SDAT:SNDARG:SPWSUB:SRDA:SRESET:SSPAWN:STDDEV EXEC14: .FCTR RLIB/LB:STDDIR:STMODE:STSPWN:UPPER EXEC2: .FCTR EXEC21-EXEC22-EXEC23-EXEC24 EXEC21: .FCTR SH/LB:CHGDIR:CMDTYP:DOAMPR:DOCOM:DOPARN:DOPIPE:DOSEMI:DSPCOM EXEC22: .FCTR SH/LB:DSPPTH:DSPTBL:ERRF:EXECUT:GETCL:GPAR:GPNAME:GTASK EXEC23: .FCTR SH/LB:HERDOC:INF:KILLDF:MVNEXT:NXTBR:OUTF:PICKUP:PROCDF EXEC24: .FCTR SH/LB:PWDIR:SCRF:SHCOM:SHELLC:STRIPB:DASK FORTS: .FCTR LB:[1,1]F77NER-LB:[1,1]F77OTS/LB:$SHORT FLIB: .FCTR LB:[1,1]F77OTS/LB SLIB: .FCTR LB:[1,1]SYSLIB/LB .END %%I 13 #-h- movhshdef 575 asc 16-jun-83 10:31:28 sventek (joseph sventek) define(prompt,logpmt) define(DO_STARTUP,) define(USE_STRING,"usage: hsh [-cdnvx] [file [arguments]]") define(DO_PARAM,) define(INT_COMMANDS,"cd@1ho@2home@3logout@4path@5von@6voff@7xon@10xoff@11#@12_ alias@13param@14ask@15source@16unalias@17unparam@20") define(C_CD,8%1) define(C_HO,8%2) define(C_HOME,8%3) define(C_LOGOUT,8%4) define(C_PATH,8%5) define(C_VON,8%6) define(C_VOFF,8%7) define(C_XON,8%10) define(C_XOFF,8%11) define(C_COMMENT,8%12) define(C_ALIAS,8%13) define(C_PARAM,8%14) define(C_ASK,8%15) define(C_SOURCE,8%16) define(C_UNALIAS,8%17) define(C_UNPARAM,8%20) %%E 13 %%E 10 %%E 7 %%E 6 %%E 1