home *** CD-ROM | disk | FTP | other *** search
- /*
- * EXECOM.C
- *
- * Matthew Dillon, 10 August 1986
- * Version 2.07M by Steve Drew 10-Sep-87
- * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
- * Version 5.00L by Urban Mueller 17-Feb-91
- * Version 5.20L by Andreas M. Kirchwitz (Fri, 13 Mar 1992)
- *
- */
-
- #include "shell.h"
-
- #define DEFAULTFRAME 1024
- #define Strlen(x) strlen((char*)x)
- #define Strcpy(x,y) strcpy((char*)x,(char*)y)
- #define Strcat(x,y) strcat((char*)x,(char*)y)
- #define Index(x,y) ((UBYTE*)index((char*)x,y))
- #define CHECKAV(num) { if( ac+num+10>max_ac ) checkav( frameptr, num ); }
-
- typedef struct StackFrame {
- struct StackFrame *next;
- int bytesleft;
- char *ptr;
- char mem[1];
- } FRAME;
-
- /* execom.c */
- int fcomm(UBYTE *str,FRAME **frame,char *from );
- int hasspace( char *s );
- int myfgets( char *buf, FILE *in );
-
- static char *compile_avf(FRAME **frame,char **av,int start,int end,char delim,int quote);
- static int preformat(char *s, UBYTE *d);
- static void backtrans(UBYTE *str);
- static UBYTE *exarg(UBYTE **ptr, UBYTE *elast);
- static UBYTE *format_insert_string(FRAME **frameptr, UBYTE *str, char *from);
- static int find_command(char *str);
- static int checkav( FRAME **frame,int n );
- static char *tempname( int which );
- static UBYTE *skipword( UBYTE *strskip );
-
- static void newframe( FRAME **frame, int bytes);
- static void *falloc( FRAME **frame, int bytes );
- static void *frealloc( FRAME **frame, char *oldstring, int morebytes );
- static void funalloc( FRAME **frame, int bytes );
- static char *push_cpy( FRAME **frame, void *s);
- static void deleteframe( FRAME *frame);
-
- void exec_every(void);
-
- int do_nothing(void);
-
- struct COMMAND {
- int (*func)();
- short minargs;
- short stat;
- int val;
- char *name;
- char *options;
- char *usage;
- };
-
- #define ST_COND 0x01 /* this is an 'if' type command, no redirection */
- #define ST_NORED 0x02 /* this command can't be redirected */
- #define ST_NOEXP 0x04 /* no wild card expansion for this command */
- #define ST_A0 0x08 /* delimit args with 0xA0 instead of ' ' */
- #define ST_FUNC 0x10 /* can be used as a function */
- #define ST_STORED 0x20 /* stores redirection instead of execuing it */
- #define ST_AVLINE 0x40 /* needs avline */
-
- #define COND ST_COND
- #define NORED ST_NORED
- #define STRED ST_STORED
- #define NOEXP ST_NOEXP
- #define A0 (ST_A0|ST_AVLINE)
- #define AV ST_AVLINE
- #define FUNC ST_FUNC
-
- #define ALIAS LEVEL_ALIAS
- #define SET LEVEL_SET
-
- #define FIRSTCOMMAND 4
- #define COM_EXEC 3
-
- static struct COMMAND Command[] = {
- do_run, 0, A0, 0, "\001", NULL, NULL, /* may call do_source, do_cd */
- do_nothing, 0, 0, 0, "\002", NULL, NULL, /* dummy for aliases */
- do_nothing, 0, 0, 0, "\003", NULL, NULL, /* dummy for aliases with args */
- do_run, 0,NORED|A0, 1, "\004", NULL, NULL, /* external that needs to be Execute()d */
- do_abortline, 0, 0, 0, "abortline", NULL, "",
- do_action, 2, AV, 9, "action", "av", "action file [args]",
- do_addbuffers,1, 0, 0, "addbuffers", NULL, "{drive [bufs]}",
- do_tackon, 3, FUNC, 0, "addpart", NULL, "var pathname filename",
- do_set_var, 0, 0, ALIAS, "alias", NULL, "[name [string] ]",
- do_ascii, 0, 0, 0, "ascii", "oh", "-oh [string]",
- do_assign, 0, 0, 0, "assign", "adpln",",logical,-adp {logical physical}",
- do_basename, 2, FUNC, 0, "basename", NULL, "var path",
- do_cat, 0, 0, 0, "cat", "n", "-n [file file...]",
- do_cd, 0, 0, 0, "cd", "g", "[path],-g path...path",
- do_chmod, 2, 0, 0, "chmod", NULL, "flags file...file",
- do_class, 0, A0, 0, "class", "n", "-n name {type=param} \"actions\" {action=command}",
- do_close, 0, 0, 0, "close", NULL, "filenumber",
- do_copy, 1, 0, 0, "copy", "rudpfmqo","-dfmopqru file file,-ud file...file dir,-ud dir...dir dir",
- do_copy, 1, 0, 0, "cp", "rudpfmqo","-dfmopqru file file,-ud file...file dir,-ud dir...dir dir",
- do_date, 0, 0, 0, "date", "sr", "-sr [date/time]",
- do_inc, 1, 0, -1, "dec", NULL, "varname [step]",
- do_rm, 0, 0, 0, "delete", "rfpqv","-fpqrv file...file",
- do_dir, 0,NOEXP, 0, "dir", "sfdcnhltbuikqavopzegL","-abcdefghiklnopqstuvL [-z lformat] [path...path]",
- do_diskchange,1, 0, 0, "diskchange", NULL, "drive",
- do_echo, 0, 0, 0, "echo", "ne", "-ne string",
- do_if, 0, COND, 1, "else", NULL, "",
- do_if, 0, COND, 2, "endif", NULL, "",
- do_error, 1, 0, 0, "error", NULL, "num",
- do_exec, 1, AV, 0, "exec", "i", "-i command",
- do_fault, 1, 0, 0, "fault", NULL, "error",
- do_filenote, 1, 0, 0, "filenote", "s", "file...file note,-s file...file",
- do_fileslist, 0, 0, 0, "flist", NULL, "",
- do_fltlower, 0, 0, 0, "fltlower", NULL, "<in >out",
- do_fltupper, 0, 0, 0, "fltupper", NULL, "<in >out",
- do_foreach, 3, 0, 0, "foreach", "v", "-v varname ( string ) command",
- do_forever, 1, AV, 0, "forever", NULL, "command",
- do_forline, 3, 0, 0, "forline", NULL, "var filename command",
- do_fornum, 4, 0, 0, "fornum", "vs", "-vs var n1 n2 command",
- do_getenv, 1, FUNC, 0, "getenv", NULL, "shellvar envvar",
- do_goto, 1, 0, 0, "goto", NULL, "label",
- do_head, 0, 0, 0, "head", NULL, "[filename] [num]",
- do_help, 0, 0, 0, "help", "f", "help -f",
- do_history, 0, 0, 0, "history", "nr", "-nr [partial_string]",
- do_howmany, 0, 0, 0, "howmany", NULL, "",
- do_htype, 0, 0, 0, "htype", "r", "-r [file...file]",
- do_if, 1,COND|NORED,0, "if", "rftmdvone","-n arg cond arg,-n arg,-nf file,-nd dir,-nm,-nt file...file,-nr rpn_expr,-no opt args,-v varname",
- do_inc, 1, 0, 1, "inc", NULL, "varname [step]",
- do_info, 0, 0, 0, "info", "pt", "-pt [drive...drive]",
- do_input, 1, 0, 0, "input", "sr", "-rs var...var",
- do_join, 2, 0, 1, "join", "r", "-r file...file",
- do_keymap, 1, 0, 0, "keymap", "n", "-n number {key=function}",
- do_label, 1, COND, 0, "label", NULL, "name",
- do_local, 0, 0, 0, "local", NULL, "[var...var]",
- do_linecnt, 0, 0, 0, "linecnt", NULL, "<in >out",
- do_ln, 1, 0, 0, "ln", "s", "-s original [link]",
- do_dir, 0,NOEXP, 0, "ls", "sfdcnhltbuikqavopzegL","-abcdefghiklnopqstuvL [-z format] [path...path]",
- do_ln, 1, 0, 0, "makelink", "s", "-s original [link]",
- do_man, 0, 0, 0, "man", NULL, "command...command",
- do_mkdir, 1, 0, 0, "md", "p", "-p name...name",
- do_mem, 0, 0, 0, "mem", "cfqsrl","-cflqsr",
- do_menu, 0, 0, 0, "menu", "nm", "-nm [title item...item]",
- do_mkdir, 1, 0, 0, "mkdir", "p", "-p name...name",
- do_mv, 2, 0, 0, "mv", "fv", "-fv from to,from...from todir",
- do_open, 3, 0, 0, "open", NULL, "file mode number",
- do_path, 0, 0, 0, "path", "rg", "-gr [dir...dir]",
- do_pri, 2, 0, 0, "pri", NULL, "clinumber pri,0 pri",
- do_protect, 2, 0, 0, "protect", NULL, "file...file flags",
- do_ps, 0, 0, 0, "ps", "les","-els [commandname...commandname]",
- do_pwd, 0, 0, 0, "pwd", NULL, "",
- do_qsort, 0, 0, 0, "qsort", "r", "-r <in >out",
- do_quit, 0,NORED, 0, "quit", NULL, "",
- do_truerun, 1,NORED|AV, 1, "rback", NULL, "command",
- do_mv, 2, 0, 0, "rename", "fv", "-fv from to,from...from todir",
- do_readfile, 1, 0, 0, "readfile", NULL, "varname [filename]",
- do_relabel, 2, 0, 0, "relabel", NULL, "drive name",
- do_resident, 0, 0, 0, "resident", "ard",",-ard file...file",
- do_return, 0, 0, 0, "return", NULL, "[n]",
- do_rm, 0, 0, 0, "rm", "rfpqv","-fpqrv file...file",
- do_rpn, 0,NOEXP, 0, "rpn", NULL, "expression",
- do_rxrec, 0, 0, 0, "rxrec", NULL, "[portname]",
- do_rxsend, 2, AV, 0, "rxsend", "rl", "-lc portname string",
- do_truerun, 1,STRED|AV, 0, "run", NULL, "command",
- do_search, 2, 0, 0, "search", "rcwneqvbfalo","-abceflnoqrvw file...file string",
- do_set_var, 0, 0, SET, "set", NULL, "[name [string] ]",
- do_setenv, 2, 0, 0, "setenv", NULL, "var value",
- do_sleep, 0, 0, 0, "sleep", NULL, "timeout",
- do_split, 1, 0, 0, "split", NULL, "srcvar dstvar...dstvar",
- do_source, 1, A0, 0, "source", NULL, "file",
- do_stack, 0, 0, 0, "stack", "s", "-s [bytes]",
- do_strhead, 3, FUNC, 0, "strhead", NULL, "varname breakchar string",
- do_strings, 0, 0, 0, "strings", "rb", "-br [file...file] [minlength]",
- do_strleft, 3, FUNC, 0, "strleft", NULL, "varname string n",
- do_strlen, 2, FUNC, 0, "strlen", NULL, "varname string",
- do_strmid, 3, FUNC, 0, "strmid", NULL, "varname string n1 [n2]",
- do_strright, 3, FUNC, 0, "strright", NULL, "varname string n",
- do_strtail, 3, FUNC, 0, "strtail", NULL, "varname breakchar string",
- do_tackon, 3, FUNC, 0, "tackon", NULL, "var pathname filename",
- do_head, 0, 0, 1, "tail", NULL, "[filename] [num]",
- do_tee, 0, 0, 0, "tee", NULL, "<in >out",
- do_touch, 1, 0, 0, "touch", NULL, "file...file",
- do_truncate, 0, 0, 0, "truncate", NULL, "<in >out",
- do_cat, 0, 0, 0, "type", "n", "-n [file...file]",
- do_unset_var, 0, AV, ALIAS, "unalias", NULL, "name...name",
- do_uniq, 0, 0, 0, "uniq", NULL, "<in >out",
- do_unset_var, 0, 0, SET, "unset", NULL, "name...name",
- do_usage, 0, 0, 0, "usage", NULL, "[command...command]",
- do_ver, 0, 0, 0, "version", NULL, "",
- do_waitport, 1, 0, 0, "waitforport",NULL, "portname [seconds]",
- do_whereis, 1,NOEXP, 0, "whereis", "r", "-r file [path...path]",
- do_window, 0,NOEXP, 0, "window", "slfbaq","-slfbaq",
- do_writefile, 1, 0, 0, "writefile", NULL, "var >out",
- NULL, 0, 0, 0, NULL, NULL, NULL,
- };
-
-
- /* do_which, 1, 0, 0, "which", NULL, "command", */
-
- #ifdef isalphanum
- char isalph[256];
- #endif
-
- int
- execute( char *str )
- {
- ULONG toptions=options;
- int ret, oldac=ac, oldmax=max_ac;
- char **oldav=av;
-
- if( !str ) return -1;
-
- ++H_stack;
- ret=exec_command(str);
- --H_stack;
-
- av=oldav; max_ac=oldmax; ac=oldac;
- options=toptions;
-
- return ret;
- }
-
- int
- exec_command( char *base )
- {
- FRAME *frame=NULL;
- UBYTE *scr;
- char buf[6];
- int len, newlen, ret;
-
- if (!H_stack && S_histlen>1) {
- add_history(base);
- sprintf(buf, "%d", H_tail_base + H_len);
- set_var(LEVEL_SET, v_histnum, buf);
- }
-
- len=Strlen(base)*3+20;
- newframe( &frame, len+DEFAULTFRAME );
-
- scr = falloc(&frame,len);
- newlen= preformat( base,scr );
-
- funalloc( &frame, len-newlen-2 );
- ret=fcomm(scr,&frame,NULL);
-
- deleteframe( frame );
-
- return ret;
- }
-
- #ifndef isalphanum
- isalphanum( char c )
- {
- return (
- (c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z') ||
- (c >= '0' && c <= '9') ||
- (c == '_')
- );
- }
- #endif
-
- int isnum(char *s)
- {
- int num = 0;
- if (s) {
- while(isspace(*s)) /* skip spaces */
- s++;
- if (*s=='-' || *s=='+') /* skip sign */
- s++;
- num = isdigit(*s); /* must be a digit */
- while(isdigit(*s)) /* skip digits */
- s++;
- if (!(*s=='\0' || isspace(*s)))
- num = 0;
- }
- return(num);
- }
-
- #define HOT_GAP 0x80
- #define HOT_BLANK 0x81
- #define HOT_STAR 0x82
- #define HOT_QUES 0x83
- #define HOT_EXCL 0x84
- #define HOT_SEMI 0x85
- #define HOT_PIPE 0x86
- #define HOT_DOLLAR 0x87
- #define HOT_IN 0x88
- #define HOT_OUT 0x89
- #define HOT_BSLASH 0x8a
- #define HOT_LASTCD 0x8b
- #define HOT_BACKG 0x8c
- #define HOT_CURLL 0x8d
- #define HOT_CURLR 0x8e
- #define HOT_CURDIR 0x8f
- #define HOT_PARDIR 0x90
- #define HOT_BEGOUT 0x91
- #define HOT_ENDOUT 0x92
- #define HOT_EQUAL 0x93
- #define HOT_BEGIN 0x94
- #define HOT_APOSTR 0x95
- #if 0
- /* AMK: detect DOS patterns */
- #define HOT_PM1 0x96
- #define HOT_PM2 0x97
- #endif
-
- /* USHORT ArgPos[256]; */
-
- static UBYTE termchar[]={ 0, '}', ')', '`' };
- static UBYTE hotchar []={ 0, HOT_CURLR, HOT_ENDOUT, HOT_APOSTR };
-
- static int
- preformat( char *src, UBYTE *d )
- {
- int qm=0, i, level, curmode, argc=0, beg=1;
- UBYTE mode[100], c, *s=(UBYTE*)src, *start=d;
-
- while (*s) {
- if (qm ) {
- while( isalphanum( *s ) || (*s && *s!='\"' && *s!='\\' && *s!='\n'))
- *d++ = *s++;
- if( !*s ) break;
- if( *s=='\n' ) qm=0, *s=';';
- }
- if( beg ) c=HOT_BEGIN,beg=0; else c=*s;
- switch (c) {
- case ' ':
- case 9:
- *d++ = HOT_BLANK;
- argstart:
- while (*s==' ' || *s==9) ++s;
- if( argc && (!*s || *s=='|' || *s==';' || *s=='#' || *s=='\n' ))--d;
- if( *s=='\\' && !argc ) { *d++=HOT_BSLASH; if( *d++=*++s ) ++s; }
- else if( *s=='~' ) { *d++=HOT_LASTCD; s++; }
- else if( *s=='.' )
- for( ;; ) {
- if( s[0]=='.' && issep(s[1]))
- s+=1+(s[1]=='/');
- else if( s[0]=='.' && s[1]=='.' && issep(s[2]))
- *d++='/', s+=2+(s[2]=='/');
- else
- break;
- }
- argc++;
- break;
- case '*':
- *d++ = HOT_GAP;
- *d++ = HOT_STAR;
- ++s;
- break;
- case '?':
- *d++ = HOT_GAP;
- *d++ = HOT_QUES;
- ++s;
- break;
- #if 0
- /* AMK --> detect DOS patterns */
- case '(':
- *d++ = HOT_GAP;
- *d++ = HOT_PM1;
- ++s;
- break;
- case '[':
- *d++ = HOT_GAP;
- *d++ = HOT_PM2;
- ++s;
- break;
- /* <-- AMK */
- #endif
- case '!':
- *d++ = HOT_EXCL;
- ++s;
- break;
- case HOT_BEGIN:
- argc=0;
- goto argstart;
- case '#':
- while (*s && *s!='\n') ++s;
- if( !*s ) break;
- case '\n':
- case ';':
- *d++= HOT_SEMI, argc=0, s++;
- goto argstart;
- case '|':
- *d++= HOT_PIPE, argc=0, s++;
- goto argstart;
- case '\\':
- if( (i=*++s-'0')>=0 && i<=7 ) {
- if( *++s>='0' && *s<='7' ) {
- i= 8*i + *s++-'0';
- if( *s>='0' && *s<='7' )
- i= 8*i + *s++-'0';
- }
- *d++ = i;
- } else {
- *d++ = *s;
- if (*s) ++s;
- }
- break;
- case '\"':
- qm = 1 - qm;
- ++s;
- break;
- case '^':
- *d++ = *++s & 0x1F;
- if (*s) ++s;
- break;
- case '<':
- *d++ = HOT_IN;
- ++s;
- break;
- case '>':
- *d++ = HOT_OUT;
- ++s;
- break;
- case '&':
- *d++ = HOT_BACKG;
- ++s;
- break;
- case '$': /* search end of var name */
- if( s[1]=='(' ) {
- curmode=2;
- *d++=HOT_BEGOUT;
- *d++=*++s;
- goto brace;
- }
- *d++ = HOT_GAP;
- *d++ = HOT_DOLLAR;
- ++s;
- while (isalphanum(*s)) *d++ = *s++;
- *d++ = HOT_GAP;
- break;
- case '`':
- curmode=3;
- *d++=HOT_APOSTR;
- goto brace;
- case '{':
- curmode=1;
- *d++ = HOT_CURLL;
- brace:
- level=0; s++;
- mode[level++]=curmode;
- while( *s && level ) {
- switch( *s ) {
- case '\"': *d++=*s++;
- while( *s && *s!='\"' && *s!='\n')
- if( *s=='\\' ) { *d++=*s++; if( *s ) *d++=*s++; }
- else *d++=*s++;
- if( *s ) *d++=*s++;
- break;
- case '\\': *d++=*s++; if( *s ) *d++=*s++;
- break;
- case '{' : mode[level++]=1; *d++=*s++;
- break;
- case '}' :
- case ')' :
- case '`' : for( i=level-1; i>=0 && termchar[mode[i]]!=*s;--i ) ;
- if( i==0 ) *d++=hotchar [mode[i]];
- else *d++=*s;
- if( i>=0 ) level=i;
- s++;
- break;
- default : *d++=*s++;
- break;
- }
- }
- break;
- default:
- *d++ = *s++;
- while( *s>=65 && (*s&31)<=26 )
- *d++=*s++;
- break;
- }
- }
- endwhile:
- *d++=0;
- *d=0;
- if (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", Strlen(start), start);
- return d-start;
- }
-
- static void
- backtrans( UBYTE *str )
- {
- if( !str )
- return;
-
- while( *str ) {
- while( *(signed char *)str>0 ) str++;
- if( !*str ) break;
- switch( *str) {
- case HOT_GAP : *str++=0; break;
- case HOT_BLANK : *str++=' '; break;
- case HOT_STAR : *str++='*'; break;
- case HOT_QUES : *str++='?'; break;
- case HOT_EXCL : *str++='!'; break;
- case HOT_SEMI : *str++=';'; break;
- case HOT_PIPE : *str++='|'; break;
- case HOT_DOLLAR: *str++='$'; break;
- case HOT_IN : *str++='<'; break;
- case HOT_OUT : *str++='>'; break;
- case HOT_BSLASH: *str++='\\'; break;
- case HOT_LASTCD: *str++='~'; break;
- case HOT_BACKG : *str++='&'; break;
- case HOT_CURLL : *str++='{'; break;
- case HOT_CURLR : *str++='}'; break;
- case HOT_CURDIR: *str++='.'; break;
- case HOT_PARDIR: *str++='.'; break;
- case HOT_BEGOUT: *str++='$'; break;
- case HOT_ENDOUT: *str++=')'; break;
- case HOT_EQUAL : *str++='='; break;
- case HOT_APOSTR: *str++='`'; break;
- #if 0
- /* AMK --> detect DOS patterns */
- case HOT_PM1 : *str++='('; break;
- case HOT_PM2 : *str++='['; break;
- /* <-- AMK */
- #endif
- default : str++; break;
- }
- }
- }
-
- /*
- * process formatted string. ' ' is the delimeter.
- *
- * 0: check '\0': no more, stop, done.
- * 1: check $. if so, extract, format, insert
- * 2: check alias. if so, extract, format, insert. goto 1
- * 3: check history or substitution, extract, format, insert. goto 1
- *
- * 4: assume first element now internal or disk based command.
- *
- * 5: extract each ' ' or 0x80 delimited argument and process, placing
- * in av[] list (except 0x80 args appended). check in order:
- *
- * '$' insert string straight
- * '>' setup stdout
- * '>>' setup stdout flag for append
- * '<' setup stdin
- * '*' or '?' do directory search and insert as separate args.
- *
- * ';' 0 '|' end of command. if '|' setup stdout
- * -execute command, fix stdin and out (|) sets
- * up stdin for next guy.
- */
-
- int alias_count;
- int has_wild; /* set if any arg has wild card */
- char *LastCommand;
- BPTR redir_out, redir_in;
-
- #define MAXACDEF 32
-
- int
- fcomm( UBYTE *str, FRAME **frameptr, char *from )
- {
- UBYTE *nextstr, elast;
- char *pend_alias, *command;
- char cout_ispipe=0, cin_ispipe=0, cout_append=0;
- char backg, firstrun, override, block, nobuiltin;
- char *cin_name=NULL, *cout_name=NULL;
- char **oldav=av;
- signed char pendredir;
- int oldac=ac, oldmax=max_ac, err, ccno, cstat;
-
- max_ac= MAXACDEF;
- av=(char **)falloc( frameptr, max_ac*sizeof(char *));
- ac=0;
-
- if (++alias_count >= MAXALIAS) { /* Recursion getting too deep? */
- fprintf(stderr,"Alias Loop\n");
- err = 20;
- goto done1;
- }
-
- nextcommand:
- command = NULL;
- pend_alias= NULL;
- err = 0;
- has_wild = 0;
- firstrun = 1;
- ccno=cstat= 0;
- elast = 1;
- block = 0;
- nobuiltin = 0;
- pendredir = 0;
- redir_in = redir_out = 0;
-
- if (*str == 0)
- goto done1;
-
- if ( *str == HOT_EXCL) {
- UBYTE *p, c;
- char *istr; /* fix to allow !cmd1;!cmd2 */
- for(p = str; *p && *p != HOT_SEMI ; ++p);
- c = *p;
- *p = 0;
- if( str[1]==HOT_EXCL ) str[1]='!';
- istr = get_history((char *)str);
- *p = c;
- replace_head(istr);
- str = format_insert_string( frameptr, str, istr );
- }
-
- /*******************************************************
- * Part one of the parser:
- * The argument line is generated as an array of strings
- */
-
- nextstr = str;
- ac = 0;
- do { /* outer loop: each pass typically generates one av[ac] */
- UBYTE *ptr, *arg;
- signed char redir, doexpand, cont, inc;
-
- av[ac] = NULL;
- cont = 1;
- doexpand = redir = inc = 0;
-
- while (cont && elast) { /* inner loop: adds one piece to av[ac] */
- ptr = exarg(&nextstr,&elast);
- inc = 1;
- cont = (elast == 0x80);
- if( (UBYTE)*ptr<0x80 )
- arg=ptr;
- else {
- switch ((UBYTE)*ptr) { /* arg must be set in every case */
- case HOT_IN:
- redir = -2;
- case HOT_OUT:
- if (cstat & (ST_NORED | ST_COND)) { /* don't extract */
- redir = 0; /* <> stuff if its */
- arg = ptr; /* external cmd. */
- break;
- }
- ++redir;
- arg = ptr + 1;
- if (*arg == HOT_OUT) {
- redir = 2; /* append >> */
- ++arg;
- }
- cont = 1;
- break;
- case HOT_DOLLAR:
- /* restore args if from set command or pend_alias */
- if ((arg = get_var(LEVEL_SET, ptr + 1))) {
- UBYTE *pe, sv;
- while (pe = Index(arg,0xA0)) {
- sv = *pe;
- *pe = '\0';
- CHECKAV( 1 );
-
- if (av[ac]) {
- av[ac] = frealloc( frameptr,av[ac],Strlen(arg));
- Strcat(av[ac++], arg);
- } else
- av[ac++] = push_cpy(frameptr,arg);
-
- *pe = sv;
- av[ac] = NULL;
- arg = pe+1;
- }
- } else
- arg = ptr;
- break;
- case HOT_LASTCD:
- if ((!ptr[1] || ptr[1]=='/')&&(arg=get_var(LEVEL_SET, v_lcd))) {
- if( ptr[1] ) {
- Strcpy(Buf,arg);
- Strcat(Buf,ptr+1);
- arg=(UBYTE*)Buf;
- }
- #if 0
- /* AMK: detecting DOS patterns BEGIN */
- /*else if (ptr[2]==HOT_PM1 || ptr[2]==HOT_PM2)*/
- else if (elast==0x80)
- arg = ptr;
- /* AMK: detecting DOS patterns END */
- #endif
- } else
- arg = ptr;
- break;
- case HOT_CURDIR:
- arg=ptr;
- if( !ptr[1] && elast!=0x80 || ptr[1]=='/' ) {
- if( ac==0 ) nobuiltin=1;
- arg= ptr[1]=='/' ? ptr+2 : ptr+1;
- }
- break;
- case HOT_PARDIR:
- arg=ptr;
- if( !ptr[2] && elast!=0x80 || ptr[2]=='/' )
- arg= ptr[2]=='/' ? ptr+2 : (UBYTE*)"/";
- break;
-
- #if 0
- /* AMK --> detect DOS patterns */
- case HOT_PM1:
- case HOT_PM2:
- /* <-- AMK */
- #endif
- case HOT_STAR:
- case HOT_QUES:
- if( !(cstat & ST_NOEXP) && !(pend_alias && *pend_alias=='*'))
- if( ac!=1 || av[1]&&*av[1] || *ptr!=HOT_QUES || ptr[1] )
- doexpand = 1;
- arg = ptr;
- break;
- default:
- arg = ptr;
- break;
- }
- }
-
- /* Append arg to av[ac] */
-
- if (av[ac]) {
- av[ac] = frealloc( frameptr,av[ac],Strlen(arg));
- Strcat(av[ac], arg);
- } else {
- av[ac] = push_cpy( frameptr, arg );
- }
-
- if (elast != 0x80)
- break;
- }
-
- /* one argument is now complete */
-
- backg = *av[ac] && (UBYTE)av[ac][Strlen(av[ac])-1]==HOT_BACKG;
- override= (UBYTE)*av[ac] == HOT_BSLASH;
-
- if( firstrun && (UBYTE)*av[0] == HOT_CURLL ) {
- char *end;
- av[0]++;
- if( end=index(av[0],HOT_CURLR)) *end=0;
- block=1;
- }
-
- if( (UBYTE)*av[ac]==HOT_BEGOUT || (UBYTE)*av[ac]==HOT_APOSTR ) {
- BPTR cout, oldcout= Myprocess->pr_COS;
- FILE *in;
- UBYTE *t;
- int apo;
-
- apo= (UBYTE)*av[ac]==HOT_APOSTR;
- inc=0;
- if( t=Index(av[ac]+1, apo ? HOT_APOSTR : HOT_ENDOUT ))
- *t=0;
-
- if(!(cout = Open(tempname(2),MODE_NEWFILE))) {
- err= 20;
- ierror (NULL, 504);
- } else {
- Myprocess->pr_COS = DEVTAB(stdout) = cout;
- execute(av[ac]+2-apo);
- fflush(stdout);
- Close(cout);
-
- if(!(in=fopen(tempname(2),"r"))) {
- err= 1;
- ierror (NULL, 504);
- } else {
- while( myfgets(Buf,in)) {
- char *str=Buf, *get, quote=0;
- CHECKAV( 1 );
- if( apo ) {
- while( *str==' ' ) str++;
- for( get=str; *get; ) {
- if( *get=='\"' )
- quote=1-quote, get++;
- else if( *get==' ' && !quote ) {
- *get++=0;
- CHECKAV( 1 );
- while( *get==' ' ) get++;
- if( !*get ) break;
- av[ac++]=push_cpy(frameptr,str);
- str=get;
- } else
- get++;
- }
- av[ac++]= push_cpy(frameptr,str);
- } else
- av[ac++]= push_cpy(frameptr,(UBYTE*)Buf);
- }
- fclose(in);
- DeleteFile(tempname(2));
- av[ac]=NULL;
- }
- }
-
- Myprocess->pr_COS = DEVTAB(stdout) = oldcout;
- }
-
- backtrans( (UBYTE *)av[ac] );
-
- if (doexpand) { /* process expansion */
- char **eav, **ebase;
- int eac;
- has_wild = 1;
- eav = ebase = expand(av[ac], &eac);
- inc = 0;
- if (eav) {
- /* FUTURE: check retval */
- CHECKAV( eac );
- for (; eac; --eac, ++eav)
- av[ac++] = push_cpy(frameptr,*eav);
- free_expand (ebase);
- }
- else {
- /* always warn if pattern doesn't match */
- fprintf(stderr,"%s: No match.\n",av[0]);
- if (o_nomatch) {
- /*
- AMK: Abort command execution if pattern
- does not match. Don't abort if
- "_nomatch" is set.
- */
- /* AMK: how to abort here? */
- goto done1;
- /* AMK: or should we use done0? */
- /* AMK: pipes are causing problems, when
- jumping to done0 -- the program
- after the pipe gets no stdin and
- hangs (e.g. "echo *.dfsdf | wc")
- With done1 the complete line is
- aborted (further commands are ignored).
- It works -- but differs from Unix-csh
- behaviour!
- */
- }
- }
- } else if( av[ac] && av[ac][0]==')' ) {
- int i;
- UBYTE *pe, sv;
- for( i=ac-1; i>0; i-- )
- if( *av[i]=='@' )
- break;
- if( i>0 && av[i][Strlen(av[i])-1]=='(' ) {
- extern int exec_fn_err;
- char *avi=av[i], *last=av[ac];
- av[i]=v_value; av[ac]=NULL;
- arg=(UBYTE*)exec_function( avi+1, av+i, ac-i );
- av[i]=avi; av[ac]=last;
- inc=0;
- if( exec_fn_err<0 )
- ac++;
- else if( exec_fn_err>0 || !arg )
- ac=i, av[ac]=NULL;
- else {
- ac=i;
- while (pe = Index(arg,0xA0)) {
- sv = *pe;
- *pe = '\0';
- CHECKAV( 1 );
- av[ac++] = push_cpy(frameptr,arg);
- *pe = sv;
- arg= pe+1;
- }
- av[ac] = falloc(frameptr,Strlen(arg)+Strlen(last+1)+4);
- Strcpy(av[ac],arg);
- Strcat(av[ac++], last+1 );
- }
- }
- }
-
- /*******************************
- * special handling of first arg
- */
-
- if( firstrun ) { /* we just found out the command */
- firstrun=0;
- command=av[0];
-
- if (command==NULL || *command==0)
- goto done0;
-
- if( block )
- pend_alias=command;
- else if ( override )
- memmove( command, command+1, Strlen(command));
- else {
- pend_alias=get_var(LEVEL_ALIAS,command); /* if not \command */
- if( pend_alias && pend_alias==from )
- pend_alias=NULL;
- }
-
- if( pend_alias )
- ccno= *pend_alias=='%' || *pend_alias=='*' ? 2 : 1;
- else
- ccno= nobuiltin ? 0 : find_command(command);
- cstat=Command[ccno].stat;
-
- if ( !(cstat & ST_COND) && (disable || forward_goto) ) {
- while (elast && elast != HOT_SEMI && elast != HOT_PIPE)
- exarg(&nextstr,&elast);
- goto done0;
- }
- }
-
- /********************************
- * handling of redirection
- */
-
- if( pendredir )
- redir=pendredir, pendredir=0;
-
- if (redir && !err) { /* store redirection */
- char *file = (doexpand) ? av[--ac] : av[ac];
-
- if( !*file )
- pendredir=redir;
- else if (redir < 0)
- cin_name = file;
- else {
- cout_name = file;
- cout_append = (redir == 2);
- }
- inc = 0;
- }
-
- if (inc) { /* check elast for space */
- ++ac;
- CHECKAV( 1 ); /* FUTURE: check retval */
- }
- } while( elast==HOT_BLANK );
- av[ac] = NULL;
-
- /******************************************************************
- * Part two:
- * The argument line is processed (pipes, commands, recursive calls
- */
-
- /* process pipes via files */
-
- if (elast == HOT_PIPE && !err) {
- static int which; /* 0 or 1 in case of multiple pipes */
- which = 1 - which;
- cout_name = tempname( which );
- cout_ispipe = 1;
- }
-
- if (err)
- goto done0;
-
- {
- char *avline=NULL;
- char delim = ' ';
- BPTR oldcin = Myprocess->pr_CIS, cin=NULL;
- BPTR oldcout = Myprocess->pr_COS, cout=NULL;
- char *cin_buf=NULL;
- struct FileHandle *ci=NULL;
- long oldbuf=NULL;
-
- if( backg ) {
- char *larg=av[ac-1];
- memmove( av+1, av, ac*sizeof(*av));
- command=av[0]=push_cpy( frameptr, (UBYTE*)o_rback);
- ccno=find_command(command);
- cstat=Command[ccno].stat;
- if( Strlen(larg)>1 )
- larg[Strlen(larg)-1]=0, ac++;
- }
-
- if( ccno==2 || (cstat & ST_A0)) /* alias with argument */
- delim = 0xA0;
-
- if( cstat&ST_AVLINE || pend_alias || Verbose&VERBOSE_ALIAS )
- avline=compile_avf(frameptr,av,(pend_alias?1:0), ac, delim,ccno==1);
-
- fflush(stdout);
- LastCommand=command;
- if ( !(cstat & (ST_NORED | ST_COND))) { /* redirection not disabled */
- if (cin_name) {
- filemap(cin_name,0);
- if (!(cin = extOpen(cin_name,MODE_OLDFILE))) {
- ierror (NULL, 504);
- err = 20;
- cin_name = NULL;
- } else {
- redir_in=cin;
- if( !(cstat&ST_NORED)) {
- Myprocess->pr_CIS = DEVTAB(stdin) = cin;
- ci = (struct FileHandle *)(cin<<2);
- cin_buf = SAllocMem(202L, MEMF_PUBLIC);
- oldbuf = ci->fh_Buf;
- if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */
- ci->fh_Buf = (long)cin_buf>>2;
- }
- }
- }
- if (cout_name) {
- filemap(cout_name,0);
- if (cout_append && (cout =extOpen(cout_name,1005L))) {
- Seek(cout, 0L, OFFSET_END );
- } else {
- cout = extOpen(cout_name,MODE_NEWFILE);
- }
- if (cout == NULL) {
- err = 20;
- ierror (NULL, 504);
- cout_name = NULL;
- cout_append = 0;
- } else {
- redir_out=cout;
- if( !(cstat&ST_STORED))
- Myprocess->pr_COS = DEVTAB(stdout) = cout;
- }
- }
- }
-
- if( Verbose&VERBOSE_ALIAS ) {
- if( Verbose&VERBOSE_HILITE )
- fprintf(stderr,"%s",o_hilite), fflush(stderr);
- if( pend_alias )
- fprintf(stderr,"%-*s%s %s\n",alias_count,">",av[0],avline);
- else
- fprintf(stderr,"%-*s%s\n",alias_count,">",avline);
- if( Verbose&VERBOSE_HILITE )
- fprintf(stderr,"%s",o_lolite), fflush(stderr);
- }
-
- if( pend_alias ) {
- UBYTE *ptr, *scr;
- FRAME *subframe=NULL;
-
- if( ccno==2 ) { /* has arguments */
- char *val=avline;
- int clen;
-
- ptr=pend_alias;
- clen=Strlen(ptr)*2+20;
- newframe( &subframe, clen+DEFAULTFRAME );
- push_locals( (ROOT *)falloc( &subframe, sizeof(ROOT) ));
- do { /* set all args */
- char *varname, *gap=NULL;
- for( varname= ++ptr; *ptr && *ptr!=' ' && *ptr!='%'; ++ptr);
- if( *ptr=='%' && (gap=index(val,0xA0 )) ) *gap=0;
- set_var( LEVEL_LOCAL, varname, val );
- val= gap ? gap+1 : "";
- } while( *ptr=='%' );
- scr = falloc(&subframe,clen);
- } else {
- int clen=Strlen(pend_alias)+Strlen(avline)+20;
-
- newframe( &subframe,3*clen+DEFAULTFRAME );
- push_locals( (ROOT *)falloc( &subframe, sizeof(ROOT) ));
- ptr = falloc( &subframe,clen );
- sprintf(ptr,"%s %s",pend_alias,avline);
- scr = falloc( &subframe, 2*clen );
- }
- preformat( ptr,scr );
- err=fcomm (scr,&subframe,pend_alias );
- pop_locals();
- deleteframe(subframe);
- } else {
- if (ac < Command[ccno].minargs + 1) {
- show_usage( NULL );
- err = 20;
- } else if (!err) {
- int (*func)(char*,int)=Command[ccno].func;
- get_opt( av, &ac, ccno, &err );
- if( err || ccno>0 && ac==2 && !strcmp(av[1],"?") )
- show_usage(av[0]);
- else
- err = (*func)(avline, Command[ccno].val); /* do the call */
- }
- }
-
- if (err < 0)
- err = 20;
- if (E_stack == 0 )
- seterr(err);
- fflush(stderr);
-
- if (!(cstat & (ST_NORED | ST_COND))) {
- if (cin_name && !(cstat & ST_STORED)) {
- ci->fh_Buf = oldbuf;
- fflush(stdin);
- clearerr(stdin);
- RESETIO( stdin );
- extClose(cin);
- FreeMem(cin_buf, 202L);
- }
- if (cout_name && !(cstat & ST_STORED)) {
- fflush(stdout);
- clearerr(stdout);
- #ifdef AZTEC_C
- stdout->_flags &= ~_IODIRTY; /* because of nil: device */
- #endif
- extClose(cout);
- cout_append = 0;
- }
- }
- Myprocess->pr_CIS = DEVTAB(stdin) = oldcin;
- Myprocess->pr_COS = DEVTAB(stdout) = oldcout;
-
- if (cin_ispipe && cin_name)
- DeleteFile(cin_name);
- if (cout_ispipe) {
- cin_name = cout_name; /* ok to assign.. static name */
- cin_ispipe = 1;
- } else {
- cin_name = NULL;
- }
- cout_name = NULL;
- cout_ispipe = 0;
- }
-
- done0:
- {
- char *exc;
- if (err && E_stack==0) {
- exc = get_var(LEVEL_SET, v_except);
- if (err >= ((exc)?atoi(exc):1)) {
- if (exc) {
- ++H_stack, ++E_stack;
- a0tospace(exc);
- exec_command(exc);
- --E_stack, --H_stack;
- } else {
- Exec_abortline = 1;
- }
- }
- seterr(err);
- }
- if (elast != 0 && Exec_abortline == 0) {
- memmove( str, nextstr, Strlen(nextstr)+1 );
- goto nextcommand;
- }
- Exec_abortline = 0;
- if (cin_name)
- DeleteFile(cin_name);
- }
- done1:
-
- av=oldav; ac=oldac; max_ac=oldmax;
- --alias_count;
- return err; /* TRUE = error occured */
- }
-
-
- static UBYTE *
- exarg(UBYTE **ptr, UBYTE *elast)
- {
- UBYTE *end, *start;
-
- start = end = *ptr;
- while ( *(signed char *)end>0 || *end && *end != 0x80 &&
- *end != HOT_SEMI && *end != HOT_PIPE && *end != HOT_BLANK)
- ++end;
- *elast = *end;
- *end = '\0';
- *ptr = end + 1;
- return start;
- }
-
-
- static void
- newframe(FRAME **frameptr, int bytes)
- {
- FRAME *new;
-
- new=salloc( bytes + 4 + sizeof(FRAME) );
- new->next= *frameptr;
- new->bytesleft = bytes;
- new->ptr = new->mem;
- *frameptr=new;
- }
-
- static void *
- falloc( FRAME **frameptr, int bytes )
- {
- FRAME *frame= *frameptr;
- char *mem;
-
- bytes+=2; /* 2 extra bytes for do_run */
- bytes|=3;
- bytes++;
-
- if( frame->bytesleft <= bytes )
- newframe( frameptr, bytes+DEFAULTFRAME ), frame=*frameptr;
-
- mem=frame->ptr;
- frame->bytesleft-=bytes;
- frame->ptr +=bytes;
- return mem;
- }
-
- static void *
- frealloc( FRAME **frameptr, char *oldstring, int morebytes )
- {
- char *mem=oldstring;
-
- morebytes|=3;
- morebytes++;
-
- if( (*frameptr)->bytesleft <= morebytes ) {
- int oldlen=(*frameptr)->ptr-oldstring;
- newframe( frameptr, oldlen+morebytes+DEFAULTFRAME );
- mem= (*frameptr)->ptr;
- strcpy((*frameptr)->ptr,oldstring);
- oldlen+=morebytes;
- (*frameptr)->ptr +=oldlen;
- (*frameptr)->bytesleft-=oldlen;
- }
- (*frameptr)->bytesleft-=morebytes;
- (*frameptr)->ptr +=morebytes;
- return mem;
- }
-
- static void
- funalloc( FRAME **frameptr, int bytes )
- {
- bytes&=~3;
- (*frameptr)->bytesleft+=bytes;
- (*frameptr)->ptr -=bytes;
- }
-
-
-
- static void
- deleteframe(FRAME *frame)
- {
- FRAME *nxt;
-
- for( ; frame; frame=nxt ) {
- nxt=frame->next;
- free(frame);
- }
- }
-
- /*
- * Insert 'from' string in front of 'str' while deleting the
- * first entry in 'str'. if freeok is set, then 'str' will be
- * free'd
- */
-
- static UBYTE *
- format_insert_string(FRAME **frameptr, UBYTE *str, char *from)
- {
- UBYTE *new, *strskip;
- int len;
-
- strskip=skipword( str );
- len = Strlen(from)*3+20;
- new = falloc( frameptr, len);
- preformat(from, new);
- funalloc( frameptr, len -Strlen(new) - 2 );
- frealloc( frameptr, (char*)new, Strlen(strskip)+2);
- strcat((char*)new, (char*)strskip);
- new[Strlen(new)+1] = 0;
- return new;
- }
-
- static UBYTE *
- skipword( UBYTE *strskip )
- {
- for ( ; *(signed char *)strskip>0
- || *strskip && *strskip != HOT_BLANK
- && *strskip != HOT_SEMI && *strskip != HOT_PIPE
- && *strskip != 0x80; ++strskip);
- return strskip;
- }
-
- char *
- find_internal( char *str )
- {
- return Command[find_command(str)].name;
- }
-
- static int
- find_command( char *str )
- {
- int i, len = Strlen(str);
- struct COMMAND *com;
- char c=*str;
-
- if( o_abbrev!=2 )
- for( com=Command, i=0; com->func; com++, i++ )
- if ( c==*com->name && !strncmp(str, com->name, len))
- if(o_abbrev || len==Strlen(com->name))
- return i;
- if( !stricmp(FilePart(str),"Execute") || !stricmp(FilePart(str),"Run"))
- return COM_EXEC;
-
- return 0;
- }
-
- int exec_fn_err;
-
- extern struct FUNCTION {
- short id, minargs, maxargs;
- char *name;
- } Function[];
-
-
- char *gotfunc( int i, char **fav, int fac );
-
- char *
- exec_function( char *str, char **fav, int fac)
- {
- int len=Strlen(str)-1, i;
-
- exec_fn_err=0;
- for (i = 0; Command[i].func; ++i)
- if ( Command[i].stat&ST_FUNC && !strncmp(str,Command[i].name,len)) {
- if( fac<Command[i].minargs ) {
- exec_fn_err=20;
- return NULL;
- } else {
- int (*func)( void )=Command[i].func;
- char **oldav=av;
- int oldac=ac;
- av=fav-1, ac=fac+1;
- exec_fn_err=(*func)();
- av=oldav, ac=oldac;
- return get_var( LEVEL_SET, fav[0] );
- }
- }
- for (i = 0; Function[i].id; ++i)
- if ( len==Strlen(Function[i].name)&&!strncmp(str,Function[i].name,len))
- return gotfunc( i,fav,fac );
-
- exec_fn_err=-1;
- return NULL;
- }
-
- int
- echofunc(void)
- {
- int i;
- char *str;
-
- if( !strlen(av[0]) ) return -1;
- exec_fn_err=0;
- for (i = 0; Function[i].id; ++i)
- if ( !strcmp(av[0],Function[i].name)) {
- if(str=gotfunc( i,av,ac ))
- printf("%s\n",str);
- return exec_fn_err;
- }
- return -1;
- }
-
-
- char *
- gotfunc( int i, char **fav, int fac )
- {
- fac--; fav++;
- if( fac<Function[i].minargs ) {
- fprintf( stderr, "Not enough arguments for @%s\n",
- Function[i].name );
- exec_fn_err=20;
- return NULL;
- } else if( fac>Function[i].maxargs ) {
- if( ac > Function[i].maxargs )
- fprintf( stderr, "Too many arguments for @%s\n",
- Function[i].name );
- exec_fn_err=20;
- return NULL;
- } else {
- exec_fn_err=dofunc( Function[i].id, fav, fac);
- return exec_fn_err ? (char *)NULL : (char *)get_var(LEVEL_SET, v_value);
- }
- return NULL;
- }
-
-
-
- do_help()
- {
- struct COMMAND *com;
- int i=0;
-
- for (com = &Command[FIRSTCOMMAND]; com->func; ++com) {
- printf ("%-12s", com->name);
- if (++i % 6 == 0) printf("\n");
- }
-
- if (options&1) {
- int num;
- printf("\n\n");
- for (i=0,num=0; Function[num].id; ++num) {
- printf("@%-11s",Function[num].name);
- if (++i % 6 == 0) printf("\n");
- }
- }
-
- printf("\n\nUse man <command> for more information\n");
- return 0;
- }
-
- do_nothing()
- {
- return 0;
- }
-
- static char *
- push_cpy(FRAME **frameptr, void *s)
- {
- return strcpy(falloc(frameptr,Strlen(s)+1), s);
- }
-
- void
- exec_every(void)
- {
- char *str = o_every;
-
- if (str) {
- ++H_stack, ++E_stack;
- a0tospace( str );
- exec_command(str);
- --E_stack, --H_stack;
- }
- }
-
- char *
- a0tospace( char *str )
- {
- char *get=str, *put=str;
-
- while( *get )
- if( (UBYTE)*get==0xA0 )
- *put++=' ', get++;
- else
- put++,get++;
- return str;
- }
-
- void
- show_usage( char *str )
- {
- int ccno, first=0, err=0;
- char *get, *put, buf[300];
-
- if( !str )
- str=LastCommand, err=1;
- for( put=str; *put && (*put&127)!=32; put++ ) ;
- *put=0;
-
- put=buf;
- ccno = find_command (str);
- if( get= Command[ccno].usage ) {
- do {
- put+=sprintf(put, first++?" %s ":"Usage: %s ",
- Command[ccno].name );
- if( *get=='-' ) {
- *put++='['; *put++='-';
- get++;
- while( *get && *get!=' ' && *get!=',' )
- *put++=*get++;
- *put++=']';
- }
- while( *get && *get!=',' )
- *put++=*get++;
- *put++='\n';
- } while( *get++ );
- *put=0;
- fprintf( err ? stderr : stdout, "%s", buf );
- }
- }
-
- do_exec( char *str )
- {
- if( !options )
- return execute( next_word( str ) );
- execute( next_word(next_word( str )));
- return 0;
- }
-
- static int
- checkav( FRAME **frameptr, int n )
- {
- char **tmp;
- int newac;
-
- if( ac+n+10>=max_ac ) {
- newac=max_ac+n+40;
- tmp=(char **)falloc(frameptr,newac*sizeof(char *));
- memcpy(tmp,av,max_ac*sizeof(char *));
- av=tmp; max_ac=newac;
- }
- return 0;
- }
-
- /* Parse the options specified in sw[]
- Setting a bit in global variable options
- for each one found
- */
-
- int
- get_opt( char **av, int *ac, int ccno, int *err )
- {
- static char opts[2];
- char **get=av+1,**put=av+1, *c, *s, *str;
- int i=1, l, usage=0, nac;
- long oldopts, origopts=options;
-
- *err=0;
- options=0;
- if( !ccno )
- return 0;
- if( ccno>0 ) {
- if ((str=Command[ccno].options)==NULL)
- return 0; /* command has no options */
- }
- else
- str=opts, opts[0]=-ccno;
-
- for( ; i<*ac && *av[i]=='-'; i++, get++ ) {
- if( !*(c=*get+1))
- goto stop;
- if( *c=='-' && !c[1] ) {
- i++, get++;
- goto stop;
- }
- oldopts=options;
- for ( ; *c ; c++) {
- if( (*c<'a' || *c>'z') && (*c<'A' || *c>'Z') )
- { options=oldopts; goto stop; }
- for( l=0, s=str; *s && *s != *c; ++s )
- ++l;
- if ( *s )
- options |= (1 << l);
- else if( !usage ) {
- usage=1;
- if( ccno>0 )
- *err=20;
- }
- }
- }
- stop:
- if( ccno>0 ) {
- for( nac=1; i<*ac; i++ )
- *put++=*get++, nac++;
- *put=NULL;
- *ac=nac;
- } else {
- i=options;
- options=origopts;
- return i;
- }
- return 0;
- }
-
- #if 0
- USHORT Options[160];
-
- int
- do_options()
- {
- for( i=1; i<ac; i+=2 ) {
- if( ac-i<=1 )
- { ierror( av[i], 500 ); return 20; }
- if( *av[i+1]!='-' )
- { ierror( av[i+1], 500 ); return 20; }
- options=0;
- parseopts( av[i+1]+1 );
- }
- }
- #endif
-
- extern char *MyMem;
- static char Pipe[3][32];
-
- static char *
- tempname( int which )
- {
- sprintf(Pipe[which],"%spipe%c%d_%lx",o_pipe,'A'+which,alias_count,MyMem);
- return Pipe[which];
- }
-
- int
- hasspace( char *s )
- {
- if( !*s )
- return 1;
- for ( ; *s; s++)
- if (ISSPACE(*s) || *s==';') return 1;
- return 0;
- }
-
- static char *
- compile_avf(FRAME **framep,char **av, int start, int end, char delim, int quote)
- {
- char *cstr, *p, *s;
- int len, i;
-
- len = 3;
- for (i = start; i < end; ++i) len += Strlen(av[i]) + 3;
- if( framep ) {
- p = cstr = falloc(framep,len);
- } else
- p = cstr = salloc(len);
- *cstr = '\0';
-
- for (i = start; i < end; ++i) {
- if (quote && hasspace(av[i]))
- p += sprintf(p, "\"%s\"", av[i]);
- else {
- for( s=av[i]; *p++=*s++; ) ;
- p--;
- }
- if (i+1 < end) *p++=delim;
- }
- *p='\0';
-
- return cstr;
- }
-
- char *
- compile_av(char **av, int start, int end, char delim, int quote)
- {
- return compile_avf(NULL,av, start, end, delim, quote);
- }
-
- int
- myfgets( char *buf, FILE *in )
- {
- int l;
- char *ret;
- if( ret=fgets(buf,253,in) ) {
- l=Strlen(buf);
- if( buf[l-1]=='\n' )
- buf[l-1]=0;
- }
- return ret!=NULL && !dobreak();
- }
-
-
-
- /* AMK: last char of a string */
- char lastch(char *str)
- {
- int len;
- if (str) {
- if (len=strlen(str))
- return(str[len-1]);
- else
- return('\0');
- }
- else
- return('\0');
- }
-
-
-
- /* AMK: replaced ARP's BtoCStr() and CtoBStr() with own routines */
-
- ULONG BtoCStr(char *cstr, BSTR bstr, LONG maxlen)
- {
- char *astr;
- int i;
- astr = (char *)(bstr << 2);
-
- for ( i=1; i <= astr[0] && i <= maxlen; i++)
- cstr[i-1] = astr[i];
- cstr[i-1] = '\0';
- return((ULONG)(i-1));
- }
-
- ULONG CtoBStr(char *cstr, BSTR bstr, LONG maxlen)
- {
- char *astr;
- int i,l;
- astr = (char *)(bstr << 2);
-
- for ( i=0,l=strlen(cstr); i < l && i < maxlen && i < 255; i++)
- astr[i+1] = cstr[i];
- astr[0] = i;
- return((ULONG)(i));
- }
-
-