home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
488.lha
/
csh_v5.0
/
src
/
csh500src.lzh
/
execom.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-17
|
31KB
|
1,222 lines
/*
* EXECOM.C
*
* Matthew Dillon, 10 August 1986
* Finally re-written.
*
* 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
*
*/
#include "shell.h"
/* execom.c */
static void preformat(char *s, char *d);
static void backtrans(char *str);
static int fcomm(char *str);
static char *exarg(char **ptr);
static void mpush_base(void);
static char *mpush(int bytes);
static void mpop_tobase(void);
static char *format_insert_string(char *str, char *from);
static int cmd_stat(char *str);
static int find_command(char *str);
static char *push_cpy(char *s);
static void exec_every(void);
static void show_usage(char *str);
static void get_opt(char **av, int *ac, int ccno);
static int checkav( int n );
int has_wild = 0; /* set if any arg has wild card */
char *LastCommand;
struct COMMAND {
int (*func)();
short minargs;
short stat;
int val;
char *name;
char *options;
char *usage;
};
extern int do_basename(), do_tackon();
extern int do_fltupper(), do_fltlower(), do_linecnt();
extern int do_strleft(), do_strright(), do_strmid(), do_strlen();
extern int do_fornum(), do_forline(), do_exec();
extern int do_diskchange(), do_stack(), do_fault(), do_path(), do_pri();
extern int do_rpn(), do_resident(), do_truerun(), do_aset(), do_howmany();
extern int do_open(), do_close(), do_fileslist(), do_htype(), do_aget();
extern int do_run(), do_number(), do_assign(), do_join();
extern int do_quit(), do_set_var(), do_unset_var();
extern int do_echo(), do_source(), do_mv(), do_addbuffers();
extern int do_cd(), do_pwd(), do_rm(), do_mkdir(), do_history();
extern int do_mem(), do_cat(), do_dir(), do_info(), do_inc();
extern int do_foreach(), do_return(), do_if(), do_label(), do_goto();
extern int do_input(), do_ver(), do_sleep(), do_help();
extern int do_strhead(), do_strtail(), do_relabel();
extern int do_copy(), do_date(), do_protect(), do_ps();
extern int do_forever(), do_abortline(), do_strings(), do_touch();
extern int do_window(), do_search(), do_filenote(), do_rxrec(), do_rxsend();
extern int do_ascii(), do_whereis(), do_sort(), do_qcd(), do_usage();
extern int do_uniq(), do_man(), do_head(), do_tee(), do_menu(), do_readfile();
extern int do_rxreturn(), do_split(), do_which(), do_class();
extern int do_action(), do_keymap();
#define ST_COND 0x01
#define ST_NORED 0x02
#define ST_NOEXP 0x04
#define ST_AV 0x08 /* delimit args within a variable */
#define ST_FUNC 0x10
#define COND ST_COND
#define NORED ST_NORED
#define NOEXP ST_NOEXP
#define AV ST_AV
#define FUNC ST_FUNC
#define ALIAS LEVEL_ALIAS
#define SET LEVEL_SET
BPTR OldCin;
struct COMMAND Command[] = {
do_run, 0, AV, 0, "\001", NULL, NULL, /* may call do_source, do_cd */
do_abortline, 0, 0, 0, "abortline", NULL, "",
do_action, 2, 0, 9, "action", "av", "action file [args]",
do_addbuffers,2, 0, 0, "addbuffers", NULL, "{drive bufs}",
do_set_var, 0, 0, ALIAS, "alias", NULL, "[name [string] ]",/* uses avline */
do_ascii, 0, 0, 0, "ascii", "oh", "-oh [string]",
do_aset, 1, 0, 0, "aset", NULL, "name value",
do_assign, 0, 0, 0, "assign", "ln", ",logical,-ln {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_class, 0, AV, 0, "class", "n", "-n name {type=param} \"actions\" {action=command}",
do_close, 0, 0, 0, "close", NULL, "filenumber",
do_copy, 1, 0, 0, "copy", "rudpf","-rudpf file file,-ud file...file dir,-ud dir...dir dir",
do_copy, 1, 0, 0, "cp", "rudpf","-rudpf 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", "rp", "-pr file...file",
do_dir, 0,NOEXP, 0, "dir", "sfdcnhltbuikqavo","-abcdfhiklnoqstuv [path...path]",
do_diskchange,1, 0, 0, "diskchange", NULL, "drive",
do_echo, 0, AV, 0, "echo", "ne", "-ne string",
do_if, 0, COND, 1, "else", NULL, "",
do_if, 0, COND, 2, "endif", NULL, "",
do_exec, 1, 0, 0, "exec", NULL, "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,NORED, 0, "foreach", "v", "-v varname ( string ) command",
do_forever, 1,NORED, 0, "forever", NULL, "command",
do_forline, 3,NORED, 0, "forline", NULL, "var filename command",
do_fornum, 4,NORED, 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, 1, 0, 0, "head", NULL, "filename [num]",
do_help, 0, 0, 0, "help", NULL, "",
do_history, 0, 0, 0, "history", NULL, "[partial_string]",
do_howmany, 0, 0, 0, "howmany", NULL, "",
do_htype, 1, 0, 0, "htype", "r", "-r file...file",
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",
do_inc, 1, 0, 1, "inc", NULL, "varname [step]",
do_info, 0, 0, 0, "info", NULL, "[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_linecnt, 0, 0, 0, "linecnt", NULL, "<in >out",
do_dir, 0,NOEXP, 0, "ls", "sfdcnhltbuikqav","-abcdfhiklnqstuv [path...path]",
do_man, 0, 0, 0, "man", NULL, "command...command",
do_mkdir, 0, 0, 0, "md", NULL, "name...name",
do_mem, 0, 0, 0, "mem", "cfqsr","-cfqsr",
do_menu, 0, 0, 0, "menu", "n", "-n [title item...item]",
do_mkdir, 0, 0, 0, "mkdir", NULL, "name...name",
do_mv, 2, 0, 0, "mv", NULL, "from to,from...from todir",
do_open, 3, 0, 0, "open", NULL, "file mode number",
do_path, 0, 0, 0, "path", "r", "-r [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", "le", "-el [commandname...commandname]",
do_pwd, 0, 0, 0, "pwd", NULL, "",
do_qsort, 0, 0, 0, "qsort", NULL, "<in >out",
do_quit, 0,NORED, 0, "quit", NULL, "",
do_truerun, 1,NORED, 1, "rback", NULL, "command",
do_mv, 2, 0, 0, "rename", NULL, "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", "rp", "-rp file...file",
do_rpn, 0,NOEXP, 0, "rpn", NULL, "expression",
do_rxrec, 0, 0, 0, "rxrec", NULL, "[portname]",
do_rxsend, 2, 0, 0, "rxsend", "rl", "-lc portname string",
do_truerun, 1,NORED, 0, "run", NULL, "command",
do_search, 2, 0, 0, "search", "rcwneqvbfalo","-abceflnoqrvw file...file string",
do_set_var, 0, AV, 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,NORED|AV, 0, "source", NULL, "file", /* uses avline */
do_stack, 0, 0, 0, "stack", NULL, "[bytes]",
do_strhead, 3, FUNC, 0, "strhead", NULL, "varname breakchar string",
do_strings, 1, 0, 0, "strings", "r", "-r 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, 1, 0, 1, "tail", NULL, "filename [num]",
do_tee, 0, 0, 0, "tee", NULL, "<in >out",
do_touch, 0, 0, 0, "touch", NULL, "file...file",
do_truncate, 0, 0, 0, "truncate", NULL, "<in >out",
do_cat, 0, 0, 0, "type", NULL, "-n [file...file]",
do_unset_var, 0, 0, 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",
NULL, 0, 0, 0, NULL, NULL, NULL,
};
/* do_which, 1, 0, 0, "which", NULL, "command", */
static char elast; /* last end delimeter */
char Cin_ispipe, Cout_ispipe;
#ifdef isalphanum
char isalph[256];
#endif
int
exec_command( char *base )
{
char *scr;
char buf[32];
if (!H_stack && S_histlen>1) {
add_history(base);
sprintf(buf, "%d", H_tail_base + H_len);
set_var(LEVEL_SET, v_histnum, buf);
}
scr = malloc((strlen(base) << 2) + 2);
preformat(base, scr);
return (fcomm(scr) ? -1 : 1);
}
#ifndef isalphanum
isalphanum( char c )
{
return (
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
(c == '_')
);
}
#endif
#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_APOSTR 0x8b
#define HOT_USAGE 0x8c
#define HOT_SBLANK 0xA0
static void
preformat( char *s, char *d )
{
int qm, i;
qm = 0;
while (*s == ' ' || *s == 9) ++s;
if (*s == '\\' ) { *d++=HOT_BSLASH; if( *d++=*++s ) ++s; }
else if (*s == '~' ) { *d++=HOT_APOSTR; s++; }
while (*s) {
if (qm ) {
while( *s && *s != '\"' && *s != '\\')
*d++ = *s++;
if( !*s ) break;
}
switch (*s) {
case ' ':
case 9:
*d++ = HOT_BLANK;
while (*s == ' ' || *s == 9) ++s;
if (*s == '~' ) { *d++=HOT_APOSTR; s++; }
else if (*s == 0 || *s == '|' || *s == ';') --d;
break;
case '*':
*d++ = HOT_GAP;
*d++ = HOT_STAR;
++s;
break;
case '?':
*d++ = HOT_GAP;
*d++ = HOT_QUES;
++s;
break;
case '!':
*d++ = HOT_EXCL;
++s;
break;
case '#':
*d++ = '\0';
while (*s) ++s;
break;
case ';':
case '|':
*d++= (*s++==';') ? HOT_SEMI : HOT_PIPE;
while (*s == ' ' || *s == 9) ++s;
if (*s == '\\' ) { *d++=HOT_BSLASH; if( *d++=*++s ) ++s; }
break;
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 '$': /* search end of var name and place false space */
*d++ = HOT_GAP;
*d++ = HOT_DOLLAR;
++s;
while (isalphanum(*s)) *d++ = *s++;
*d++ = HOT_GAP;
break;
default:
*d++ = *s++;
break;
}
}
*d++=0;
*d=0;
if (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d);
}
static void
backtrans( char *str )
{
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_APOSTR: *str++='~'; break;
default : str++; break;
}
}
}
void *
mymalloc( int len )
{
return malloc(len);
}
extern BPTR extOpen();
/*
* 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
fcomm( char *str )
{
static int alias_count;
int p_alias_count;
char *istr, *nextstr, *command;
char *pend_alias;
int err;
++alias_count;
entry:
p_alias_count = 0;
pend_alias = NULL;
err=0;
has_wild = 0;
mpush_base();
if (*str == 0)
goto done1;
step1:
if (alias_count >= MAXALIAS || p_alias_count >= MAXALIAS) {
fprintf(stderr,"Alias Loop\n");
err = 20;
goto done1;
}
istr = NULL;
if ( *str == HOT_BSLASH )
memmove( str, str+1, strlen(str));
else
istr = get_var (LEVEL_ALIAS, str); /* only if not \command */
if (istr) {
p_alias_count++;
if (*istr == '%' || *istr=='*') {
pend_alias = istr;
} else {
str = format_insert_string(str, istr );
goto step1;
}
}
if (*str == HOT_EXCL) {
char *p, c; /* fix to allow !cmd1;!cmd2 */
for(p = str; *p && *p != HOT_SEMI ; ++p);
c = *p;
*p = '\0';
istr = get_history(str,1);
*p = c;
replace_head(istr);
str = format_insert_string(str, istr );
goto step1;
}
nextstr = str;
command = exarg(&nextstr);
if (*command == 0)
goto done0;
if (pend_alias == 0) {
if (cmd_stat(command) & ST_COND)
goto skipgood;
}
if (disable || forward_goto) {
while (elast && elast != HOT_SEMI && elast != HOT_PIPE)
exarg(&nextstr);
goto done0;
}
skipgood:
{
char *arg, *ptr;
short redir;
short doexpand;
short cont;
short inc;
ac = 1;
av[0] = command;
backtrans( av[0] );
step5: /* ac = nextac */
if (!elast || elast == HOT_SEMI || elast == HOT_PIPE)
goto stepdone;
av[ac] = NULL;
cont = 1;
doexpand = redir = inc = 0;
while (cont && elast) {
int cstat = cmd_stat(command);
ptr = exarg(&nextstr);
inc = 1;
arg = "";
cont = (elast == 0x80);
switch (*ptr) {
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)) != NULL) {
char *pe, sv;
while (pe = index(arg,0xA0)) {
sv = *pe;
*pe = '\0';
checkav(1);
av[ac++] = push_cpy(arg);
*pe = sv;
av[ac] = NULL;
arg = pe+1;
}
} else
arg = ptr;
break;
case HOT_APOSTR:
if ((arg = get_var(LEVEL_SET, v_lcd)) != NULL) {
if( ptr[1] ) {
strcpy(Buf,arg);
appendslash(Buf);
strcat(Buf,ptr+1);
arg=Buf;
}
} else
arg = ptr;
break;
case HOT_STAR:
case HOT_QUES:
if((cstat & ST_NOEXP) == 0 && !(pend_alias && *istr=='*'))
if(ac==1&&(av[1]==NULL||!*av[1])&& *ptr==HOT_QUES&& !ptr[1])
;
else
doexpand = 1;
arg = ptr;
break;
default:
arg = ptr;
break;
}
/* Append arg to av[ac] */
if (av[ac]) {
char *old = av[ac];
av[ac] = mpush(strlen(arg)+strlen(av[ac]));
strcpy(av[ac], old);
strcat(av[ac], arg);
} else
av[ac] = push_cpy(arg);
if (elast != 0x80)
break;
}
/* process expansion */
backtrans( av[ac] );
if (doexpand) {
char **eav, **ebase;
int eac;
has_wild = 1;
eav = ebase = expand(av[ac], &eac);
inc = 0;
if (eav) {
if( checkav( eac ) ) {
ierror (NULL, 506);
err = 1;
} else {
QuickSort(eav, eac);
for (; eac; --eac, ++eav)
av[ac++] = push_cpy(*eav);
}
free_expand (ebase);
}
} else if( av[ac][0]==')' ) {
int i;
char *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 *exec_function();
char *avi=av[i], *last=av[ac];
av[i]=v_value; av[ac]=NULL;
arg=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++]="";
else {
ac=i;
while (pe = index(arg,0xA0)) {
sv = *pe;
*pe = '\0';
checkav( 2 );
av[ac++] = push_cpy(arg);
*pe = sv;
arg= pe+1;
}
av[ac] = mpush(strlen(arg)+strlen(last+1)+4);
strcpy(av[ac],arg);
strcat(av[ac++], last+1 );
}
}
}
/* process redirection */
if (redir && !err) {
char *file = (doexpand) ? av[--ac] : av[ac];
if (redir < 0)
Cin_name = file;
else {
Cout_name = file;
Cout_append = (redir == 2);
}
inc = 0;
}
/* check elast for space */
if (inc) {
++ac;
if (ac + 2 > MAXAV) {
ierror (NULL, 506);
err = 1; /* error condition */
elast = 0; /* don't process any more arguemnts */
}
}
if (elast == HOT_BLANK)
goto step5;
}
stepdone:
av[ac] = NULL;
/* 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 = (which) ? Pipe1 : Pipe2;
Cout_ispipe = 1;
}
if (err)
goto done0;
{
int i;
char save_elast;
char *avline;
char delim = ' ';
char *larg=av[ac-1];
if( *larg && larg[strlen(larg)-1]=='&' ) {
memmove( av+1, av, (ac-1)*sizeof(*av));
command=av[0]="rback";
if( strlen(larg)>1 )
larg[strlen(larg)-1]=0, ac++;
}
save_elast = elast;
if (pend_alias || (cmd_stat(command) & ST_AV))
delim = 0xA0;
avline = compile_av(av,((pend_alias) ? 1 : 0), ac, delim, 0);
if (pend_alias) { /* special % alias */
char *ptr, *scr, *varname, *val=avline, *gap;
ptr=pend_alias;
do { /* set all args */
for ( varname= ++ptr; *ptr && *ptr!=' ' && *ptr!='%'; ++ptr);
if( *ptr=='%' && (gap=index(val,0xA0 )) ) *gap=0;
set_var( LEVEL_SET, varname, val );
val= gap ? gap+1 : "";
} while( *ptr=='%' );
free (avline);
scr = malloc((strlen(ptr) << 2) + 2);
preformat (ptr, scr);
fcomm (scr);
ptr=pend_alias;
do { /* unset all args */
for ( varname=++ptr; *ptr && *ptr!=' ' && *ptr!='%'; ++ptr);
unset_var( LEVEL_SET, varname );
} while( *ptr=='%' );
unset_var (LEVEL_SET, pend_alias + 1);
} else { /* normal command */
int ccno;
BPTR oldcin = Myprocess->pr_CIS;
BPTR oldcout = Myprocess->pr_COS;
char *Cin_buf;
struct FileHandle *ci;
long oldbuf;
OldCin=oldcin;
fflush(stdout);
LastCommand=command;
ccno = find_command ( command);
if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
if (Cin_name) {
if ((Cin = (long)extOpen(Cin_name,1005L)) == 0) {
ierror (NULL, 504);
err = 1;
Cin_name = NULL;
} else {
Myprocess->pr_CIS = DEVTAB(stdin) = Cin;
ci = (struct FileHandle *)(((long)Cin)<<2);
Cin_buf = AllocMem(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) {
if (Cout_append && (Cout =(long)extOpen(Cout_name,1005L))) {
Seek(Cout, 0L, 1L);
} else {
Cout = (long)extOpen(Cout_name,1006L);
}
if (Cout == NULL) {
err = 1;
ierror (NULL, 504);
Cout_name = NULL;
Cout_append = 0;
} else {
Myprocess->pr_COS = DEVTAB(stdout) = Cout;
}
}
}
if (ac < Command[ccno].minargs + 1) {
show_usage( NULL );
err = -1;
} else if (!err) {
int (*func)(char*,int)=Command[ccno].func;
get_opt( av, &ac, ccno );
i=0;
if( ccno>0 && ac>1 && !strcmp(av[1],"?") )
show_usage(avline);
else
i = (*func)(avline, Command[ccno].val);
fflush(stderr);
if (i < 0)
i = 20;
err = i;
}
free (avline);
if (E_stack == 0 && Lastresult != err) {
Lastresult = err;
seterr();
}
if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
if (Cin_name) {
ci->fh_Buf = oldbuf;
fflush(stdin);
clearerr(stdin);
#ifdef AZTEC_C
stdin->_bp=stdin->_bend;
#else
stdin->_rcnt=stdin->_wcnt;
#endif
extClose(Cin);
FreeMem(Cin_buf, 202L);
}
if (Cout_name) {
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;
elast = save_elast;
}
mpop_tobase(); /* free arguments */
mpush_base(); /* push dummy base */
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;
}
}
}
if (elast != 0 && Exec_abortline == 0) {
memmove( str, nextstr, strlen(nextstr)+1 );
goto entry;
}
Exec_abortline = 0;
if (Cin_name)
DeleteFile(Cin_name);
Cin_name = NULL;
Cin_ispipe = 0;
}
done1:
mpop_tobase();
free(str);
--alias_count;
return err; /* TRUE = error occured */
}
static char *
exarg(ptr)
char **ptr;
{
char *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 char **Mlist;
static void
mpush_base()
{
char *str;
str = malloc(5);
*(char ***)str = Mlist;
str[4] = 0;
Mlist = (char **)str;
}
static char *
mpush(bytes)
{
char *str;
str = malloc(6 + bytes + 2); /* may need extra 2 bytes in do_run() */
*(char ***)str = Mlist;
str[4] = 1;
Mlist = (char **)str;
return (str + 5);
}
static void
mpop_tobase()
{
char *next;
while (Mlist) {
next = *Mlist;
if (((char *)Mlist)[4] == 0) {
free (Mlist);
Mlist = (char **)next;
break;
}
free (Mlist);
Mlist = (char **)next;
}
}
/*
* 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 char *
format_insert_string(char *str, char *from)
{
char *new1, *new2;
char *strskip;
int len;
for (strskip = str; *(signed char *)strskip>0 ||
*strskip && *strskip != HOT_BLANK
&& *strskip != HOT_SEMI && *strskip != HOT_PIPE
&& *strskip != 0x80; ++strskip);
len = strlen(from);
new1 = malloc((len << 2) + 2);
preformat(from, new1);
len = strlen(new1) + strlen(strskip);
new2 = malloc(len+2);
strcpy(new2, new1);
strcat(new2, strskip);
new2[len+1] = 0;
free (new1);
free (str);
return new2;
}
static int
cmd_stat( char *str )
{
return (int)Command[find_command(str)].stat;
}
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;
for( com=Command, i=0; com->func; com++, i++ )
if ( c==*com->name && !strncmp(str, com->name, len))
return i;
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 get_var( LEVEL_SET, v_value );
}
return NULL;
}
do_help()
{
struct COMMAND *com;
int i=0;
for (com = &Command[1]; com->func; ++com) {
printf ("%-12s", com->name);
if (++i % 6 == 0) printf("\n");
}
printf("\n\nUse man <command> for more information\n");
return 0;
}
static char *
push_cpy(s)
char *s;
{
return strcpy(mpush(strlen(s)), s);
}
void
exec_every(void)
{
char *str = get_var(LEVEL_SET, v_every);
if (str) {
++H_stack, ++E_stack;
a0tospace( str );
exec_command(str);
--E_stack, --H_stack;
}
}
char *
a0tospace( str )
char *str;
{
char *get=str, *put=str;
while( *get )
if( *get==0xA0 )
*put++=' ', get++;
else
*put++=*get++;
return str;
}
void
show_usage( str )
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 );
}
}
int
execute( char *str )
{
char **tav=av, telast=elast;
int tac=ac;
ULONG toptions=options;
int thas_wild=has_wild;
if( !str ) return -1;
++H_stack;
exec_command(str);
--H_stack;
av=tav; ac=tac; elast=telast; options=toptions; has_wild=thas_wild;
return 0;
}
do_exec( char *str )
{
return execute( next_word( str ) );
}
int
interactive( void )
{
return IsInteractive(Output());
}
static int
checkav( int n )
{
char **tmp;
int newac;
if( ac+n+10>=max_ac ) {
newac=max_ac+n+40;
if( tmp=(char **)malloc(newac*sizeof(char *))) {
memcpy(tmp,av,max_ac*sizeof(char *));
free(av);
av=tmp; max_ac=newac;
} else
return 1;
}
return 0;
}
/* Parse the options specified in sw[]
Setting a bit in global variable options
for each one found
*/
static void
get_opt( char **av, int *ac, int ccno )
{
char **get=av+1,**put=av+1, *c, *s;
int i=1, l, usage=0, nac;
long oldopts;
options=0;
if( !ccno )
return;
for( ; i<*ac && *av[i]=='-'; i++, get++ ) {
if( !*(c=*get+1) )
goto stop;
oldopts=options;
for ( ; *c ; c++) {
if( *c<'a' || *c>'z' )
{ options=oldopts; goto stop; }
for( l=0, s=Command[ccno].options; *s && *s != *c; ++s )
++l;
if ( *s )
options |= (1 << l);
else if( !usage ) {
usage=1;
show_usage(NULL);
}
}
}
stop:
for( nac=1; i<*ac; i++ )
*put++=*get++, nac++;
*put=NULL;
*ac=nac;
}
#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