amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (04/17/91)
Submitted-by: umueller@iiic.ethz.ch Posting-number: Volume 91, Issue 093 Archive-name: shells/cshell-5.10/part06 #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 6 (of 6)." # Contents: execom.c # Wrapped by tadguy@ab20 on Tue Apr 16 15:34:35 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'execom.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'execom.c'\" else echo shar: Extracting \"'execom.c'\" \(37168 characters\) sed "s/^X//" >'execom.c' <<'END_OF_FILE' X/* X * EXECOM.C X * X * Matthew Dillon, 10 August 1986 X * Version 2.07M by Steve Drew 10-Sep-87 X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90 X * Version 5.00L by Urban Mueller 17-Feb-91 X * X */ X X#include "shell.h" X X#define DEFAULTFRAME 1024 X X Xtypedef struct StackFrame { X struct StackFrame *next; X int bytesleft; X char *ptr; X char mem[1]; X} FRAME; X X/* execom.c */ Xstatic char *compile_avf(FRAME **frame,char **av,int start,int end,char delim,int quote); Xstatic int hasspace( char *s ); Xstatic void preformat(char *s, char *d); Xstatic void backtrans(char *str); Xstatic int fcomm(char *str,FRAME **frame,char *from); Xstatic char *exarg(char **ptr, char *elast); Xstatic char *format_insert_string(FRAME **frameptr, char *str, char *from); Xstatic int find_command(char *str); Xstatic void exec_every(void); Xstatic void show_usage(char *str); Xstatic void get_opt(char **av, int *ac, int ccno); Xstatic int checkav( FRAME **frame,int n ); Xstatic char *tempname( int which ); Xstatic char *skipword( char *strskip ); Xstatic int myfgets( char *buf, FILE *in ); X Xstatic void newframe( FRAME **frame, int bytes); Xstatic char *falloc( FRAME **frame, int bytes ); Xstatic char *frealloc( FRAME **frame, char *oldstring, int morebytes ); Xstatic void funalloc( FRAME **frame, int bytes ); Xstatic char *push_cpy( FRAME **frame, char *s); Xstatic void deleteframe( FRAME *frame); X Xint do_nothing(void); X Xstruct COMMAND { X int (*func)(); X short minargs; X short stat; X int val; X char *name; X char *options; X char *usage; X}; X X#define ST_COND 0x01 X#define ST_NORED 0x02 X#define ST_NOEXP 0x04 X#define ST_AV 0x08 /* delimit args within a variable */ X#define ST_FUNC 0x10 X#define ST_EQUAL 0x20 X X#define COND ST_COND X#define NORED ST_NORED X#define NOEXP ST_NOEXP X#define AV ST_AV X#define FUNC ST_FUNC X#define EQUAL ST_EQUAL X X#define ALIAS LEVEL_ALIAS X#define SET LEVEL_SET X#define LOCAL LEVEL_LOCAL X Xstruct COMMAND Command[] = { X do_run, 0, AV, 0, "\001", NULL, NULL, /* may call do_source, do_cd */ X do_nothing, 0, 0, 0, "\002", NULL, NULL, /* dummy for aliases */ X do_nothing, 0, 0, 0, "\003", NULL, NULL, /* dummy for aliases with args */ X do_abortline, 0, 0, 0, "abortline", NULL, "", X do_action, 2, 0, 9, "action", "av", "action file [args]", X do_addbuffers,2, 0, 0, "addbuffers", NULL, "{drive bufs}", X do_set_var, 0, 0, ALIAS, "alias", NULL, "[name [string] ]",/* uses avline */ X do_ascii, 0, 0, 0, "ascii", "oh", "-oh [string]", X do_aset, 1, 0, 0, "aset", NULL, "name value", X do_assign, 0, 0, 0, "assign", "lnp",",logical,-lnp {logical physical}", X do_basename, 2, FUNC, 0, "basename", NULL, "var path", X do_cat, 0, 0, 0, "cat", "n", "-n [file file...]", X do_cd, 0, 0, 0, "cd", "g", "[path],-g path...path", X do_class, 0, AV, 0, "class", "n", "-n name {type=param} \"actions\" {action=command}", X do_close, 0, 0, 0, "close", NULL, "filenumber", X do_copy, 1, 0, 0, "copy", "rudpfm","-dfmpru file file,-ud file...file dir,-ud dir...dir dir", X do_copy, 1, 0, 0, "cp", "rudpfm","-dfmpru file file,-ud file...file dir,-ud dir...dir dir", X do_date, 0, 0, 0, "date", "sr", "-sr [date/time]", X do_inc, 1, 0, -1, "dec", NULL, "varname [step]", X do_rm, 0, 0, 0, "delete", "rp", "-pr file...file", X do_dir, 0,NOEXP, 0, "dir", "sfdcnhltbuikqavopzeg","-abcdefghiklnopqstuv [-z lformat] [path...path]", X do_diskchange,1, 0, 0, "diskchange", NULL, "drive", X do_echo, 0, AV, 0, "echo", "ne", "-ne string", X do_if, 0, COND, 1, "else", NULL, "", X do_if, 0, COND, 2, "endif", NULL, "", X do_error, 1, 0, 0, "error", NULL, "num", X do_exec, 1, 0, 0, "exec", NULL, "command", X do_fault, 1, 0, 0, "fault", NULL, "error", X do_filenote, 1, 0, 0, "filenote", "s", "file...file note,-s file...file", X do_fileslist, 0, 0, 0, "flist", NULL, "", X do_fltlower, 0, 0, 0, "fltlower", NULL, "<in >out", X do_fltupper, 0, 0, 0, "fltupper", NULL, "<in >out", X do_foreach, 3, 0, 0, "foreach", "v", "-v varname ( string ) command", X do_forever, 1, 0, 0, "forever", NULL, "command", X do_forline, 3, 0, 0, "forline", NULL, "var filename command", X do_fornum, 4, 0, 0, "fornum", "vs", "-vs var n1 n2 command", X do_getenv, 1, FUNC, 0, "getenv", NULL, "shellvar envvar", X do_goto, 1, 0, 0, "goto", NULL, "label", X do_head, 1, 0, 0, "head", NULL, "filename [num]", X do_help, 0, 0, 0, "help", NULL, "", X do_history, 0, 0, 0, "history", NULL, "[partial_string]", X do_howmany, 0, 0, 0, "howmany", NULL, "", X do_htype, 1, 0, 0, "htype", "r", "-r file...file", X do_if, 1,COND|NORED,0, "if", "rftmdvn","-n arg cond arg,-n arg,-nf file,-nd dir -nm,-nt file...file,-nr rpn_expr,-v varname", X do_inc, 1, 0, 1, "inc", NULL, "varname [step]", X do_info, 0, 0, 0, "info", NULL, "[drive...drive]", X do_input, 1, 0, 0, "input", "sr", "-rs var...var", X do_join, 2, 0, 1, "join", "r", "-r file...file", X do_keymap, 1, 0, 0, "keymap", "n", "-n number {key=function}", X do_label, 1, COND, 0, "label", NULL, "name", X do_local, 0, 0, 0, "local", NULL, "[var...var]", X do_linecnt, 0, 0, 0, "linecnt", NULL, "<in >out", X do_dir, 0,NOEXP, 0, "ls", "sfdcnhltbuikqavopzeg","-abcdefghiklnopqstuv [-z format] [path...path]", X do_man, 0, 0, 0, "man", NULL, "command...command", X do_mkdir, 0, 0, 0, "md", NULL, "name...name", X do_mem, 0, 0, 0, "mem", "cfqsr","-cfqsr", X do_menu, 0, 0, 0, "menu", "n", "-n [title item...item]", X do_mkdir, 0, 0, 0, "mkdir", NULL, "name...name", X do_mv, 2, 0, 0, "mv", NULL, "from to,from...from todir", X do_open, 3, 0, 0, "open", NULL, "file mode number", X do_path, 0, 0, 0, "path", "r", "-r [dir...dir]", X do_pri, 2, 0, 0, "pri", NULL, "clinumber pri,0 pri", X do_protect, 2, 0, 0, "protect", NULL, "file...file flags", X do_ps, 0, 0, 0, "ps", "le", "-el [commandname...commandname]", X do_pwd, 0, 0, 0, "pwd", NULL, "", X do_qsort, 0, 0, 0, "qsort", "r", "-r <in >out", X do_quit, 0,NORED, 0, "quit", NULL, "", X do_truerun, 1,NORED, 1, "rback", NULL, "command", X do_mv, 2, 0, 0, "rename", NULL, "from to,from...from todir", X do_readfile, 1, 0, 0, "readfile", NULL, "varname [filename]", X do_relabel, 2, 0, 0, "relabel", NULL, "drive name", X do_resident, 0, 0, 0, "resident", "ard",",-ard file...file", X do_return, 0, 0, 0, "return", NULL, "[n]", X do_rm, 0, 0, 0, "rm", "rp", "-rp file...file", X do_rpn, 0,NOEXP, 0, "rpn", NULL, "expression", X do_rxrec, 0, 0, 0, "rxrec", NULL, "[portname]", X do_rxsend, 2, 0, 0, "rxsend", "rl", "-lc portname string", X do_truerun, 1,NORED, 0, "run", NULL, "command", X do_search, 2, 0, 0, "search", "rcwneqvbfalo","-abceflnoqrvw file...file string", X do_set_var, 0, AV, SET, "set", NULL, "[name [string] ]", X do_setenv, 2, 0, 0, "setenv", NULL, "var value", X do_sleep, 0, 0, 0, "sleep", NULL, "timeout", X do_split, 1, 0, 0, "split", NULL, "srcvar dstvar...dstvar", X do_source, 1, AV, 0, "source", NULL, "file", /* uses avline */ X do_stack, 0, 0, 0, "stack", NULL, "[bytes]", X do_strhead, 3, FUNC, 0, "strhead", NULL, "varname breakchar string", X do_strings, 1, 0, 0, "strings", "r", "-r file...file minlength", X do_strleft, 3, FUNC, 0, "strleft", NULL, "varname string n", X do_strlen, 2, FUNC, 0, "strlen", NULL, "varname string", X do_strmid, 3, FUNC, 0, "strmid", NULL, "varname string n1 [n2]", X do_strright, 3, FUNC, 0, "strright", NULL, "varname string n", X do_strtail, 3, FUNC, 0, "strtail", NULL, "varname breakchar string", X do_tackon, 3, FUNC, 0, "tackon", NULL, "var pathname filename", X do_head, 1, 0, 1, "tail", NULL, "filename [num]", X do_tee, 0, 0, 0, "tee", NULL, "<in >out", X do_touch, 0, 0, 0, "touch", NULL, "file...file", X do_truncate, 0, 0, 0, "truncate", NULL, "<in >out", X do_cat, 0, 0, 0, "type", NULL, "-n [file...file]", X do_unset_var, 0, 0, ALIAS, "unalias", NULL, "name...name", X do_uniq, 0, 0, 0, "uniq", NULL, "<in >out", X do_unset_var, 0, 0, LOCAL, "unlocal", NULL, "var...var", X do_unset_var, 0, 0, SET, "unset", NULL, "name...name", X do_usage, 0, 0, 0, "usage", NULL, "[command...command]", X do_ver, 0, 0, 0, "version", NULL, "", X do_waitport, 1, 0, 0, "waitforport",NULL, "portname [seconds]", X do_whereis, 1,NOEXP, 0, "whereis", "r", "-r file [path...path]", X do_window, 0,NOEXP, 0, "window", "slfbaq","-slfbaq", X NULL, 0, 0, 0, NULL, NULL, NULL, X}; X X X/* do_which, 1, 0, 0, "which", NULL, "command", */ X X#ifdef isalphanum Xchar isalph[256]; X#endif X Xint Xexec_command( char *base ) X{ X FRAME *frame=NULL; X char *scr, buf[6]; X int len, ret; X X if (!H_stack && S_histlen>1) { X add_history(base); X sprintf(buf, "%d", H_tail_base + H_len); X set_var(LEVEL_SET, v_histnum, buf); X } X X len=strlen(base)*3+20; X newframe( &frame, len+DEFAULTFRAME ); X X scr = falloc(&frame,len); X preformat( base,scr ); X X funalloc( &frame, len-strlen(scr)-2 ); X ret=fcomm(scr,&frame,NULL); X X deleteframe( frame ); X X return ret; X} X X#ifndef isalphanum Xisalphanum( char c ) X{ X return ( X (c >= 'a' && c <= 'z') || X (c >= 'A' && c <= 'Z') || X (c >= '0' && c <= '9') || X (c == '_') X ); X} X#endif X X#define HOT_GAP 0x80 X#define HOT_BLANK 0x81 X#define HOT_STAR 0x82 X#define HOT_QUES 0x83 X#define HOT_EXCL 0x84 X#define HOT_SEMI 0x85 X#define HOT_PIPE 0x86 X#define HOT_DOLLAR 0x87 X#define HOT_IN 0x88 X#define HOT_OUT 0x89 X#define HOT_BSLASH 0x8a X#define HOT_LASTCD 0x8b X#define HOT_BACKG 0x8c X#define HOT_CURLL 0x8d X#define HOT_CURLR 0x8e X#define HOT_CURDIR 0x8f X#define HOT_PARDIR 0x90 X#define HOT_BEGOUT 0x91 X#define HOT_ENDOUT 0x92 X#define HOT_EQUAL 0x93 X#define HOT_BEGIN 0x94 X#define HOT_APOSTR 0x95 X X X X Xvoid Xpreformat( char *s, char *d ) X{ X static char termchar[]={ 0, '}', ')', '`' }; X static char hotchar []={ 0, HOT_CURLR, HOT_ENDOUT, HOT_APOSTR }; X int qm=0, i, level, curmode, argc=0, beg=1; X char mode[100], c; X X while (*s) { X if (qm ) { X while( *s && *s != '\"' && *s != '\\') X *d++ = *s++; X if( !*s ) break; X } X if( beg ) c=HOT_BEGIN,beg=0; else c=*s; X switch (c) { X case ' ': X case 9: X *d++ = HOT_BLANK; Xargstart: X while (*s == ' ' || *s == 9) ++s; X if( *s == '\\' && !argc ) { *d++=HOT_BSLASH; if( *d++=*++s ) ++s; } X if( *s == '~' ) { *d++=HOT_LASTCD; s++; } X else if( *s=='.'&&s[1]=='.') { *d++=HOT_PARDIR; *d++='.'; s+=2; } X else if( *s=='.' ) { *d++=HOT_CURDIR; s++; } X else if( argc && (!*s || *s == '|' || *s == ';' || *s=='#')) --d; X argc++; X break; X case '*': X *d++ = HOT_GAP; X *d++ = HOT_STAR; X ++s; X break; X case '?': X *d++ = HOT_GAP; X *d++ = HOT_QUES; X ++s; X break; X case '!': X *d++ = HOT_EXCL; X ++s; X break; X case '#': X *d++ = '\0'; X while (*s) ++s; X break; X case HOT_BEGIN: X argc=0; X goto argstart; X case ';': X *d++= HOT_SEMI, argc=0, s++; X goto argstart; X case '|': X *d++= HOT_PIPE, argc=0, s++; X goto argstart; X case '\\': X if( (i=*++s-'0')>=0 && i<=7 ) { X if( *++s>='0' && *s<='7' ) { X i= 8*i + *s++-'0'; X if( *s>='0' && *s<='7' ) X i= 8*i + *s++-'0'; X } X *d++ = i; X } else { X *d++ = *s; X if (*s) ++s; X } X break; X case '\"': X qm = 1 - qm; X ++s; X break; X case '^': X *d++ = *++s & 0x1F; X if (*s) ++s; X break; X case '<': X *d++ = HOT_IN; X ++s; X break; X case '>': X *d++ = HOT_OUT; X ++s; X break; X case '&': X *d++ = HOT_BACKG; X ++s; X break; X case '$': /* search end of var name */ X if( s[1]=='(' ) { X curmode=2; X *d++=HOT_BEGOUT; X *d++=*++s; X goto brace; X } X *d++ = HOT_GAP; X *d++ = HOT_DOLLAR; X ++s; X while (isalphanum(*s)) *d++ = *s++; X *d++ = HOT_GAP; X break; X case '`': X curmode=3; X *d++=HOT_APOSTR; X goto brace; X case '{': X curmode=1; X *d++ = HOT_CURLL; Xbrace: X level=0; s++; X mode[level++]=curmode; X while( *s && level ) { X switch( *s ) { X case '\"': *d++=*s++; X while( *s && *s!='\"' ) X if( *s=='\\' ) { *d++=*s++; if( *s ) *d++=*s++; } X else *d++=*s++; X if( *s ) *d++=*s++; X break; X case '\\': *d++=*s++; if( *s ) *d++=*s++; X break; X case '{' : mode[level++]=1; s++; X break; X case '}' : X case ')' : X case '`' : for( i=level-1; i>=0 && termchar[mode[i]]!=*s;--i ) ; X if( i==0 ) *d++=hotchar [mode[i]]; X if( i>=0 ) level=i; X s++; X break; X default : *d++=*s++; X break; X } X } X break; X default: X *d++ = *s++; X while( *s>=65 && (*s&31)<=26 ) X *d++=*s++; X break; X } X } X *d++=0; X *d=0; X if (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d); X return; X} X Xstatic void Xbacktrans( char *str ) X{ X while( *str ) { X while( *(signed char *)str>0 ) str++; X if( !*str ) break; X switch( *str) { X case HOT_GAP : *str++=0; break; X case HOT_BLANK : *str++=' '; break; X case HOT_STAR : *str++='*'; break; X case HOT_QUES : *str++='?'; break; X case HOT_EXCL : *str++='!'; break; X case HOT_SEMI : *str++=';'; break; X case HOT_PIPE : *str++='|'; break; X case HOT_DOLLAR: *str++='$'; break; X case HOT_IN : *str++='<'; break; X case HOT_OUT : *str++='>'; break; X case HOT_BSLASH: *str++='\\'; break; X case HOT_LASTCD: *str++='~'; break; X case HOT_BACKG : *str++='&'; break; X case HOT_CURLL : *str++='{'; break; X case HOT_CURLR : *str++='}'; break; X case HOT_CURDIR: *str++='.'; break; X case HOT_PARDIR: *str++='.'; break; X case HOT_BEGOUT: *str++='$'; break; X case HOT_ENDOUT: *str++=')'; break; X case HOT_EQUAL : *str++='='; break; X case HOT_APOSTR: *str++='`'; break; X default : str++; break; X } X } X} X X/* X * process formatted string. ' ' is the delimeter. X * X * 0: check '\0': no more, stop, done. X * 1: check $. if so, extract, format, insert X * 2: check alias. if so, extract, format, insert. goto 1 X * 3: check history or substitution, extract, format, insert. goto 1 X * X * 4: assume first element now internal or disk based command. X * X * 5: extract each ' ' or 0x80 delimited argument and process, placing X * in av[] list (except 0x80 args appended). check in order: X * X * '$' insert string straight X * '>' setup stdout X * '>>' setup stdout flag for append X * '<' setup stdin X * '*' or '?' do directory search and insert as separate args. X * X * ';' 0 '|' end of command. if '|' setup stdout X * -execute command, fix stdin and out (|) sets X * up stdin for next guy. X */ X Xint alias_count; Xint has_wild; /* set if any arg has wild card */ Xchar *LastCommand; XBPTR OldCin; X X#define MAXACDEF 32 X Xint Xfcomm( char *str, FRAME **frameptr, char *from ) X{ X char *nextstr, *command; X char *pend_alias; X char cout_ispipe=0, cin_ispipe=0, cout_append=0, elast; X char backg, firstrun, override, block; X char *cin_name=NULL, *cout_name=NULL; X char **oldav=av; X int oldac=ac, oldmax=max_ac, err, ccno, cstat; X X max_ac= MAXACDEF; X av=(char **)falloc( frameptr, max_ac*sizeof(char *)); X ac=0; X X if (++alias_count >= MAXALIAS) { /* Recursion getting too deep? */ X fprintf(stderr,"Alias Loop\n"); X err = 20; X goto done1; X } X Xnextcommand: X command = NULL; X pend_alias= NULL; X err = 0; X has_wild = 0; X firstrun = 1; X ccno=cstat= 0; X elast = 1; X block = 0; X X if (*str == 0) X goto done1; X X if (*str == HOT_EXCL) { X char *p, c, *istr; /* fix to allow !cmd1;!cmd2 */ X for(p = str; *p && *p != HOT_SEMI ; ++p); X c = *p; X *p = 0; X if( str[1]==HOT_EXCL ) str[1]='!'; X istr = get_history(str,1); X *p = c; X replace_head(istr); X str = format_insert_string( frameptr, str, istr ); X } X X /******************************************************* X * Part one of the parser: X * The argument line is generated as an array of strings X */ X X nextstr = str; X ac = 0; X do { /* outer loop: each pass typically generates one av[ac] */ X char *arg, *ptr; X short redir; X short doexpand; X short cont; X short inc; X X av[ac] = NULL; X cont = 1; X doexpand = redir = inc = 0; X X while (cont && elast) { /* inner loop: adds one piece to av[ac] */ X ptr = exarg(&nextstr,&elast); X inc = 1; X cont = (elast == 0x80); X switch (*ptr) { /* arg must be set in every case */ X case HOT_IN: X redir = -2; X case HOT_OUT: X if (cstat & (ST_NORED | ST_COND)) { /* don't extract */ X redir = 0; /* <> stuff if its */ X arg = ptr; /* external cmd. */ X break; X } X ++redir; X arg = ptr + 1; X if (*arg == HOT_OUT) { X redir = 2; /* append >> */ X ++arg; X } X cont = 1; X break; X case HOT_DOLLAR: X /* restore args if from set command or pend_alias */ X if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) { X char *pe, sv; X while (pe = index(arg,0xA0)) { X sv = *pe; X *pe = '\0'; X checkav(frameptr,1); X X if (av[ac]) { X av[ac] = frealloc( frameptr,av[ac],strlen(arg)); X strcat(av[ac++], arg); X } else X av[ac++] = push_cpy(frameptr,arg); X X *pe = sv; X av[ac] = NULL; X arg = pe+1; X } X } else X arg = ptr; X break; X case HOT_LASTCD: X if ((!ptr[1] || ptr[1]=='/')&&(arg=get_var(LEVEL_SET, v_lcd))) { X if( ptr[1] ) { X strcpy(Buf,arg); X strcat(Buf,ptr+1); X arg=Buf; X } X } else X arg = ptr; X break; X case HOT_CURDIR: X arg=ptr; X if( !ptr[1] || ptr[1]=='/' ) X arg= ptr[1] ? ptr+2 : ptr+1; X break; X case HOT_PARDIR: X arg=ptr; X if( !ptr[2] || ptr[2]=='/' ) X arg= ptr[2] ? ptr+2 : "/"; X break; X X case HOT_STAR: X case HOT_QUES: X if( !(cstat & ST_NOEXP) && !(pend_alias && *pend_alias=='*')) X if( ac!=1 || av[1]&&*av[1] || *ptr!=HOT_QUES || ptr[1] ) X doexpand = 1; X arg = ptr; X break; X default: X arg = ptr; X break; X } X X /* Append arg to av[ac] */ X X if (av[ac]) { X av[ac] = frealloc( frameptr,av[ac],strlen(arg)); X strcat(av[ac], arg); X } else X av[ac] = push_cpy(frameptr,arg); X X if (elast != 0x80) X break; X } X X /* one argument is now complete */ X X backg = *av[ac] && av[ac][strlen(av[ac])-1]==HOT_BACKG; X override= *av[ac] == HOT_BSLASH; X X if( firstrun && *av[0] == HOT_CURLL ) { X char *end; X av[0]++; X if( end=index(av[0],HOT_CURLR)) *end=0; X block=1; X } X X if( *av[ac]==HOT_BEGOUT || *av[ac]==HOT_APOSTR ) { X BPTR cout, oldcout= Myprocess->pr_COS; X FILE *in; X char *t, *val; X int apo; X X apo= *av[ac]==HOT_APOSTR; X inc=0; X if( t=index(av[ac]+1, apo ? HOT_APOSTR : HOT_ENDOUT )) X *t=0; X X if(!(cout = Open(tempname(2),MODE_NEWFILE))) { X err= 20; X ierror (NULL, 504); X } else { X Myprocess->pr_COS = DEVTAB(stdout) = cout; X execute(av[ac]+2-apo); X Close(cout); X X if(!(in=fopen(tempname(2),"r"))) { X err= 1; X ierror (NULL, 504); X } else { X while( myfgets(Buf,in)) X if( apo ) { X for( val=Buf; t=index(val,' '); val=t+1) X *t=0, av[ac++]=push_cpy(frameptr,val); X av[ac++]= push_cpy(frameptr,val); X } else X av[ac++]= push_cpy(frameptr,Buf); X fclose(in); X DeleteFile(tempname(2)); X } X } X X Myprocess->pr_COS = DEVTAB(stdout) = oldcout; X } X X backtrans( av[ac] ); X X if (doexpand) { /* process expansion */ X char **eav, **ebase; X int eac; X has_wild = 1; X eav = ebase = expand(av[ac], &eac); X inc = 0; X if (eav) { X if( checkav( frameptr, eac ) ) { X ierror (NULL, 506); X err = 1; X } else { X QuickSort(eav, eac); X for (; eac; --eac, ++eav) X av[ac++] = push_cpy(frameptr,*eav); X } X free_expand (ebase); X } X } else if( av[ac][0]==')' ) { X int i; X char *pe, sv; X for( i=ac-1; i>0; i-- ) X if( *av[i]=='@' ) X break; X if( i>0 && av[i][strlen(av[i])-1]=='(' ) { X extern int exec_fn_err; X char *exec_function(); X char *avi=av[i], *last=av[ac]; X av[i]=v_value; av[ac]=NULL; X arg=exec_function( avi+1, av+i, ac-i ); X av[i]=avi; av[ac]=last; X inc=0; X if( exec_fn_err<0 ) X ac++; X else if( exec_fn_err>0 || !arg ) X ac=i, av[ac]=NULL; X else { X ac=i; X while (pe = index(arg,0xA0)) { X sv = *pe; X *pe = '\0'; X checkav( frameptr, 1 ); X av[ac++] = push_cpy(frameptr,arg); X *pe = sv; X arg= pe+1; X } X av[ac] = falloc(frameptr,strlen(arg)+strlen(last+1)+4); X strcpy(av[ac],arg); X strcat(av[ac++], last+1 ); X } X } X } X X /******************************* X * special handling of first arg X */ X X if( firstrun ) { /* we just found out the command */ X firstrun=0; X command=av[0]; X X if (*command == 0) X goto done0; X X if( block ) X pend_alias=command; X else if ( override ) X memmove( command, command+1, strlen(command)); X else { X pend_alias=get_var(LEVEL_ALIAS,command); /* if not \command */ X if( pend_alias && pend_alias==from ) X pend_alias=NULL; X } X X if( pend_alias ) X ccno=*pend_alias=='%' || *pend_alias=='*' ? 2 : 1; X else X ccno=find_command(command); X cstat=Command[ccno].stat; X X if ( !(cstat & ST_COND) && (disable || forward_goto) ) { X while (elast && elast != HOT_SEMI && elast != HOT_PIPE) X exarg(&nextstr,&elast); X goto done0; X } X } X X if (redir && !err) { /* store redirection */ X char *file = (doexpand) ? av[--ac] : av[ac]; X X if (redir < 0) X cin_name = file; X else { X cout_name = file; X cout_append = (redir == 2); X } X inc = 0; X } X X if (inc) { /* check elast for space */ X ++ac; X if( checkav(frameptr,1) ) { X ierror (NULL, 506); X err = 1; /* error condition */ X elast = 0; /* don't process any more arguemnts */ X } X } X } while( elast==HOT_BLANK ); X av[ac] = NULL; X X X /****************************************************************** X * Part two: X * The argument line is processed (pipes, commands, recursive calls X */ X X /* process pipes via files */ X X if (elast == HOT_PIPE && !err) { X static int which; /* 0 or 1 in case of multiple pipes */ X which = 1 - which; X cout_name = tempname( which ); X cout_ispipe = 1; X } X X X if (err) X goto done0; X X { X char *avline; X char delim = ' '; X BPTR oldcin = Myprocess->pr_CIS, cin=NULL; X BPTR oldcout = Myprocess->pr_COS, cout=NULL; X char *cin_buf=NULL; X struct FileHandle *ci=NULL; X long oldbuf=NULL; X X if( backg ) { X char *larg=av[ac-1]; X memmove( av+1, av, ac*sizeof(*av)); X command=av[0]="rback"; X ccno=find_command(command); X cstat=Command[ccno].stat; X if( strlen(larg)>1 ) X larg[strlen(larg)-1]=0, ac++; X } X if( ccno==2 || (cstat & ST_AV)) /* alias with argument */ X delim = 0xA0; X avline = compile_avf(frameptr,av,(pend_alias?1:0), ac, delim, ccno==1); X X OldCin=oldcin; X fflush(stdout); X LastCommand=command; X if ( !(cstat & (ST_NORED | ST_COND))) { /* redirection not disabled */ X if (cin_name) { X if (!(cin = extOpen(cin_name,MODE_OLDFILE))) { X ierror (NULL, 504); X err = 20; X cin_name = NULL; X } else { X Myprocess->pr_CIS = DEVTAB(stdin) = cin; X ci = (struct FileHandle *)(cin<<2); X cin_buf = SAllocMem(202L, MEMF_PUBLIC); X oldbuf = ci->fh_Buf; X if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */ X ci->fh_Buf = (long)cin_buf>>2; X } X } X if (cout_name) { X if (cout_append && (cout =extOpen(cout_name,1005L))) { X Seek(cout, 0L, OFFSET_END ); X } else { X cout = extOpen(cout_name,MODE_NEWFILE); X } X if (cout == NULL) { X err = 20; X ierror (NULL, 504); X cout_name = NULL; X cout_append = 0; X } else { X Myprocess->pr_COS = DEVTAB(stdout) = cout; X } X } X } X X if( Verbose&VERBOSE_ALIAS ) { X if( Verbose&VERBOSE_HILITE ) fprintf(stderr,"%s",o_hilite); X if( pend_alias ) X fprintf(stderr,"%-*s%s %s\n",alias_count,">",av[0],avline); X else X fprintf(stderr,"%-*s%s\n",alias_count,">",avline); X if( Verbose&VERBOSE_HILITE ) fprintf(stderr,"%s",o_lolite); X } X X if( pend_alias ) { X char *scr; X FRAME *subframe=NULL; X X if( ccno==2 ) { /* has arguments */ X char *ptr=pend_alias, *val=avline; X int clen; X X clen=strlen(ptr)*2+20; X newframe( &subframe, clen+DEFAULTFRAME ); X push_locals( (ROOT *)falloc( &subframe, sizeof(ROOT) )); X do { /* set all args */ X char *varname, *gap=NULL; X for( varname= ++ptr; *ptr && *ptr!=' ' && *ptr!='%'; ++ptr); X if( *ptr=='%' && (gap=index(val,0xA0 )) ) *gap=0; X set_var( LEVEL_LOCAL, varname, val ); X val= gap ? gap+1 : ""; X } while( *ptr=='%' ); X scr = falloc(&subframe,clen); X preformat (ptr, scr); X } else { X char *scr2; X int clen=strlen(pend_alias)+strlen(avline)+20; X X newframe( &subframe,3*clen+DEFAULTFRAME ); X push_locals( (ROOT *)falloc( &subframe, sizeof(ROOT) )); X scr2= falloc( &subframe,clen ); X sprintf(scr2,"%s %s",pend_alias,avline); X scr = falloc( &subframe, 2*clen ); X preformat( scr2,scr); X } X fcomm (scr,&subframe,pend_alias); X pop_locals(); X deleteframe(subframe); X } else { X if (ac < Command[ccno].minargs + 1) { X show_usage( NULL ); X err = 20; X if (E_stack == 0 ) X seterr(err); X } else if (!err) { X int (*func)(char*,int)=Command[ccno].func, i; X get_opt( av, &ac, ccno ); X i=0; X if( ccno>0 && ac==2 && !strcmp(av[1],"?") ) X show_usage(avline); X else X i = (*func)(avline, Command[ccno].val); /* do the call */ X if (i < 0) X i = 20; X err = i; X if (E_stack == 0 ) X seterr(err); X fflush(stderr); X } X } X if (!(cstat & (ST_NORED | ST_COND))) { X if (cin_name) { X ci->fh_Buf = oldbuf; X fflush(stdin); X clearerr(stdin); X#ifdef AZTEC_C X stdin->_bp=stdin->_bend; X#else X stdin->_rcnt=stdin->_wcnt; X#endif X extClose(cin); X FreeMem(cin_buf, 202L); X } X if (cout_name) { X fflush(stdout); X clearerr(stdout); X#ifdef AZTEC_C X stdout->_flags &= ~_IODIRTY; /* because of nil: device */ X#endif X extClose(cout); X cout_append = 0; X } X } X Myprocess->pr_CIS = DEVTAB(stdin) = oldcin; X Myprocess->pr_COS = DEVTAB(stdout) = oldcout; X X if (cin_ispipe && cin_name) X DeleteFile(cin_name); X if (cout_ispipe) { X cin_name = cout_name; /* ok to assign.. static name */ X cin_ispipe = 1; X } else { X cin_name = NULL; X } X cout_name = NULL; X cout_ispipe = 0; X } X Xdone0: X { X char *exc; X if (err && E_stack==0) { X exc = get_var(LEVEL_SET, v_except); X if (err >= ((exc)?atoi(exc):1)) { X if (exc) { X ++H_stack, ++E_stack; X a0tospace(exc); X exec_command(exc); X --E_stack, --H_stack; X } else { X Exec_abortline = 1; X } X } X seterr(err); X } X if (elast != 0 && Exec_abortline == 0) { X memmove( str, nextstr, strlen(nextstr)+1 ); X goto nextcommand; X } X Exec_abortline = 0; X if (cin_name) X DeleteFile(cin_name); X } Xdone1: X X av=oldav; ac=oldac; max_ac=oldmax; X --alias_count; X return err; /* TRUE = error occured */ X} X X Xstatic char * Xexarg(char **ptr, char *elast) X{ X char *end, *start; X X start = end = *ptr; X while ( *(signed char *)end>0 || *end && *end != 0x80 && X *end != HOT_SEMI && *end != HOT_PIPE && *end != HOT_BLANK) X ++end; X *elast = *end; X *end = '\0'; X *ptr = end + 1; X return start; X} X X Xstatic void Xnewframe(FRAME **frameptr, int bytes) X{ X FRAME *new; X X new=salloc( bytes + 4 + sizeof(FRAME) ); X new->next= *frameptr; X X new->bytesleft = bytes; X new->ptr = new->mem; X *frameptr=new; X} X Xstatic char * Xfalloc( FRAME **frameptr, int bytes ) X{ X char *mem,inc; X X bytes+=2; /* 2 extra bytes for do_run */ X X if( (*frameptr)->bytesleft <= bytes ) X newframe( frameptr, bytes+DEFAULTFRAME ); X X inc=4-((long)(*frameptr)->ptr&3); /* 1 extra byte and longword alignment */ X mem=(*frameptr)->ptr+inc; X (*frameptr)->bytesleft-=bytes+inc; X (*frameptr)->ptr +=bytes+inc; X return mem; X} X Xstatic char * Xfrealloc( FRAME **frameptr, char *oldstring, int morebytes ) X{ X char *mem=oldstring; X X if( (*frameptr)->bytesleft <= morebytes ) { X int oldlen=(*frameptr)->ptr-oldstring; X newframe( frameptr, oldlen+morebytes+DEFAULTFRAME ); X mem= (*frameptr)->ptr; X strcpy((*frameptr)->ptr,oldstring); X oldlen+=morebytes; X (*frameptr)->ptr +=oldlen; X (*frameptr)->bytesleft-=oldlen; X } X (*frameptr)->bytesleft-=morebytes; X (*frameptr)->ptr +=morebytes; X return mem; X} X Xstatic void Xfunalloc( FRAME **frameptr, int bytes ) X{ X (*frameptr)->bytesleft+=bytes; X (*frameptr)->ptr -=bytes; X} X X X Xvoid Xdeleteframe(FRAME *frame) X{ X FRAME *nxt; X X for( ; frame; frame=nxt ) { X nxt=frame->next; X free(frame); X } X} X X/* X * Insert 'from' string in front of 'str' while deleting the X * first entry in 'str'. if freeok is set, then 'str' will be X * free'd X */ X Xstatic char * Xformat_insert_string(FRAME **frameptr, char *str, char *from) X{ X char *new, *strskip; X int len; X X strskip=skipword( str ); X len = strlen(from)*3+20; X new = falloc( frameptr, len); X preformat(from, new); X funalloc( frameptr, len -strlen(new) - 2 ); X frealloc( frameptr, new, strlen(strskip)+2); X strcat(new, strskip); X new[strlen(new)+1] = 0; X return new; X} X Xstatic char * Xskipword( char *strskip ) X{ X for ( ; *(signed char *)strskip>0 X || *strskip && *strskip != HOT_BLANK X && *strskip != HOT_SEMI && *strskip != HOT_PIPE X && *strskip != 0x80; ++strskip); X return strskip; X} X Xchar * Xfind_internal( char *str ) X{ X return Command[find_command(str)].name; X} X Xstatic int Xfind_command( char *str ) X{ X int i, len = strlen(str); X struct COMMAND *com; X char c=*str; X X for( com=Command, i=0; com->func; com++, i++ ) X if ( c==*com->name && !strncmp(str, com->name, len)) X if(o_abbrev || len==strlen(com->name)) X return i; X return 0; X} X Xint exec_fn_err; X Xextern struct FUNCTION { X short id, minargs, maxargs; X char *name; X} Function[]; X X Xchar *gotfunc( int i, char **fav, int fac ); X Xchar * Xexec_function( char *str, char **fav, int fac) X{ X int len=strlen(str)-1, i; X X exec_fn_err=0; X for (i = 0; Command[i].func; ++i) X if ( Command[i].stat&ST_FUNC && !strncmp(str,Command[i].name,len)) { X if( fac<Command[i].minargs ) { X exec_fn_err=20; X return NULL; X } else { X int (*func)( void )=Command[i].func; X char **oldav=av; X int oldac=ac; X av=fav-1, ac=fac+1; X exec_fn_err=(*func)(); X av=oldav, ac=oldac; X return get_var( LEVEL_SET, fav[0] ); X } X } X for (i = 0; Function[i].id; ++i) X if ( len==strlen(Function[i].name)&&!strncmp(str,Function[i].name,len)) X return gotfunc( i,fav,fac ); X X exec_fn_err=-1; X return NULL; X} X Xint Xechofunc(void) X{ X int i; X char *str; X X if( !strlen(av[0]) ) return -1; X exec_fn_err=0; X for (i = 0; Function[i].id; ++i) X if ( !strcmp(av[0],Function[i].name)) { X if(str=gotfunc( i,av,ac )) X printf("%s\n",str); X return exec_fn_err; X } X return -1; X} X X Xchar * Xgotfunc( int i, char **fav, int fac ) X{ X fac--; fav++; X if( fac<Function[i].minargs ) { X fprintf( stderr, "Not enough arguments for @%s\n", X Function[i].name ); X exec_fn_err=20; X return NULL; X } else if( fac>Function[i].maxargs ) { X if( ac > Function[i].maxargs ) X fprintf( stderr, "Too many arguments for @%s\n", X Function[i].name ); X exec_fn_err=20; X return NULL; X } else { X exec_fn_err=dofunc( Function[i].id, fav, fac); X return get_var( LEVEL_SET, v_value ); X } X return NULL; X} X X X Xdo_help() X{ X struct COMMAND *com; X int i=0; X X for (com = &Command[3]; com->func; ++com) { X printf ("%-12s", com->name); X if (++i % 6 == 0) printf("\n"); X } X printf("\n\nUse man <command> for more information\n"); X return 0; X} X Xdo_nothing() X{ X return 0; X} X Xstatic char * Xpush_cpy(FRAME **frameptr, char *s) X{ X return strcpy(falloc(frameptr,strlen(s)+1), s); X} X Xvoid Xexec_every(void) X{ X char *str = get_var(LEVEL_SET, v_every); X X if (str) { X ++H_stack, ++E_stack; X a0tospace( str ); X exec_command(str); X --E_stack, --H_stack; X } X} X Xchar * Xa0tospace( str ) X char *str; X{ X char *get=str, *put=str; X X while( *get ) X if( *get==0xA0 ) X *put++=' ', get++; X else X *put++=*get++; X return str; X} X Xvoid Xshow_usage( str ) X char *str; X{ X int ccno, first=0, err=0; X char *get, *put, buf[300]; X X if( !str ) X str=LastCommand, err=1; X for( put=str; *put && (*put&127)!=32; put++ ) ; X *put=0; X X put=buf; X ccno = find_command (str); X if( get= Command[ccno].usage ) { X do { X put+=sprintf(put, first++?" %s ":"Usage: %s ", X Command[ccno].name ); X if( *get=='-' ) { X *put++='['; *put++='-'; X get++; X while( *get && *get!=' ' && *get!=',' ) X *put++=*get++; X *put++=']'; X } X while( *get && *get!=',' ) X *put++=*get++; X *put++='\n'; X } while( *get++ ); X *put=0; X fprintf( err ? stderr : stdout, "%s", buf ); X } X} X Xint Xexecute( char *str ) X{ X ULONG toptions=options; X BPTR toldcin=OldCin; X int ret, oldac=ac, oldmax=max_ac; X char **oldav=av; X X if( !str ) return -1; X X ++H_stack; X ret=exec_command(str); X --H_stack; X X av=oldav; max_ac=oldmax; ac=oldac; X options=toptions; OldCin=toldcin; X X return ret; X} X Xdo_exec( char *str ) X{ X return execute( next_word( str ) ); X} X Xint Xinteractive( void ) X{ X return IsInteractive(Output()); X} X Xstatic int Xcheckav( FRAME **frameptr, int n ) X{ X char **tmp; X int newac; X X if( ac+n+10>=max_ac ) { X newac=max_ac+n+40; X tmp=(char **)falloc(frameptr,newac*sizeof(char *)); X memcpy(tmp,av,max_ac*sizeof(char *)); X av=tmp; max_ac=newac; X } X return 0; X} X X/* Parse the options specified in sw[] X Setting a bit in global variable options X for each one found X*/ X Xstatic void Xget_opt( char **av, int *ac, int ccno ) X{ X char **get=av+1,**put=av+1, *c, *s; X int i=1, l, usage=0, nac; X long oldopts; X X options=0; X if( !ccno ) X return; X X for( ; i<*ac && *av[i]=='-'; i++, get++ ) { X if( !*(c=*get+1) ) X goto stop; X oldopts=options; X for ( ; *c ; c++) { X if( *c<'a' || *c>'z' ) X { options=oldopts; goto stop; } X for( l=0, s=Command[ccno].options; *s && *s != *c; ++s ) X ++l; X if ( *s ) X options |= (1 << l); X else if( !usage ) { X usage=1; X show_usage(NULL); X } X } X } Xstop: X for( nac=1; i<*ac; i++ ) X *put++=*get++, nac++; X *put=NULL; X *ac=nac; X} X X#if 0 XUSHORT Options[160]; X Xint Xdo_options() X{ X for( i=1; i<ac; i+=2 ) { X if( ac-i<=1 ) X { ierror( av[i], 500 ); return 20; } X if( *av[i+1]!='-' ) X { ierror( av[i+1], 500 ); return 20; } X options=0; X parseopts( av[i+1]+1 ); X } X} X#endif X Xextern char *MyMem; Xstatic char Pipe[2][32]; X Xchar * Xtempname( int which ) X{ X sprintf(Pipe[which],"%spipe%c%d_%lx",o_pipe,'A'+which,alias_count,MyMem); X return Pipe[which]; X} X X#define ISSPACE(c) ((c)==' ' || (c)==9 || (c)==0xA0) X Xstatic int Xhasspace( char *s ) X{ X if( !*s ) X return 1; X for ( ; *s; s++) X if (ISSPACE(*s)) return 1; X return 0; X} X Xchar * Xcompile_avf(FRAME **framep,char **av, int start, int end, char delim, int quote) X{ X char *cstr, *p; X int len, i; X X len = 3; X for (i = start; i < end; ++i) len += strlen(av[i]) + 3; X if( framep ) X p = cstr = falloc(framep,len); X else X p = cstr = salloc(len); X *cstr = '\0'; X for (i = start; i < end; ++i) { X if (debug) fprintf (stderr, "AV[%2d] :%s:\n", i, av[i]); X if (quote && hasspace(av[i])) X p += sprintf(p, "\"%s\"", av[i]); X else X p += sprintf(p, "%s", av[i]); X if (i+1 < end) *p++=delim; X } X *p='\0'; X return cstr; X} X Xchar * Xcompile_av(char **av, int start, int end, char delim, int quote) X{ X return compile_avf(NULL,av, start, end, delim, quote); X} X Xstatic int Xmyfgets( char *buf, FILE *in ) X{ X int l; X char *ret; X if( ret=fgets(buf,253,in) ) { X l=strlen(buf); X if( buf[l-1]=='\n' ) X buf[l-1]=0; X } X return ret!=NULL && !dobreak(); X} END_OF_FILE if test 37168 -ne `wc -c <'execom.c'`; then echo shar: \"'execom.c'\" unpacked with wrong size! fi # end of 'execom.c' fi echo shar: End of archive 6 \(of 6\). cp /dev/null ark6isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>. Mail comments to the moderator at <amiga-request@uunet.uu.net>. Post requests for sources, and general discussion to comp.sys.amiga.misc.