[comp.sources.amiga] v91i093: CShell 5.10 - alternative command interface, Part06/06

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.