[comp.sources.amiga] v91i003: CShell 4.02A - alternative command interface, Part01/03

amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (02/07/91)

Submitted-by: Cesare.Dieni@p1.f602.n332.z2.fidonet.org (Cesare Dieni)
Posting-number: Volume 91, Issue 003
Archive-name: shells/cshell-4.02a/part01

Shell provides a convient AmigaDos alternative command interface.
All its commands are internal and thus does not rely on the c:
commands for any functionality.

Major features include:

	-command line editing
	-shell & Amigados search path support
	-simple history
	-redirection of any command
	-piping
	-aliases
	-variables & variable handling (embedded variables)
	-file name expansion via conventional wild carding ('?', '*' and more)
	-conditionals (if/else ect..)
	-source files  (w/ gotos and labels)
	-many built in commands to speed things up

New to 4.02A:
- Fixed bug that caused loss of memory on exit.
- cp now copies protection bits; use -f switch if you want to avoid this.
- Added  commands: man (and alias manlist), uniq, head, tail, tee.
- This doc has been reformatted to work with man.

For any problems contact me at:

 FIDONET: 2:332/602.1@fidonet.org 
 UUCP:    root@wolf.sublink.org 
 ARPA:    Cesare_Dieni@p1.f602.n332.z2.fidonet.sublink.org 
 BITNET:  PERUGIA@ICNUCEVM.CNUCE.CNR.IT 

Thanx in advance,

-Cesare Dieni 

#!/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 1 (of 3)."
# Contents:  src src/comm2.c src/globals.c src/main.c src/makefile
#   src/rawconsole.c src/run.c src/set.c src/shell.h
#   src/shellfunctions.h src/sub.c
# Wrapped by tadguy@ab20 on Wed Feb  6 19:54:18 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'src' ; then
    echo shar: Creating directory \"'src'\"
    mkdir 'src'
fi
if test -f 'src/comm2.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/comm2.c'\"
else
echo shar: Extracting \"'src/comm2.c'\" \(13217 characters\)
sed "s/^X//" >'src/comm2.c' <<'END_OF_FILE'
X/*
X * COMM2.C
X *
X * (c)1986 Matthew Dillon     9 October 1986
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
X/* Casting conveniences */
X#define BPTR_TO_C(strtag, var)  ((struct strtag *)(BADDR( (ULONG) var)))
X#define PROC(task)              ((struct Process *)task)
X#define CLI(proc)               (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
X
X/* Externs */
Xextern int has_wild;                    /* flag set if any arg has a ? or * */
X
X/* globals */
Xint cp_update, cp_date, cp_flags;
X
Xdo_abortline()
X{
XExec_abortline = 1;
Xreturn 0;
X}
X
Xdo_return()
X{
Xregister int retcode=(ac<2 ? 0 : atoi(av[1]));
X   Exec_abortline = 1;
X   if (Src_stack) {
X       FILE *ptr = (FILE *)Src_base[Src_stack - 1];
X       ptr->_bp = ptr->_bend;
X       ptr->_flags |= _EOF;
X/*     fseek (Src_base[Src_stack - 1], 0L, 2); */
X      return retcode;
X   } else main_exit(retcode);
X}
X
X/*
X * STRHEAD
X *
X * place a string into a variable removing everything after and including
X * the 'break' character
X *
X * strhead varname breakchar string
X *
X */
X
Xdo_strhead()
X{
Xchar *s;
Xif (s=index(av[3],*av[2])) *s='\0';
Xset_var (LEVEL_SET, av[1], av[3]);
Xreturn 0;
X}
X
Xdo_strtail()
X{
Xchar *s;
Xif (s=index(av[3],*av[2])) s++; else s=av[3];
Xset_var (LEVEL_SET, av[1], s);
Xreturn 0;
X}
X
Xlong dptrtosecs(d)
Xstruct DPTR *d;
X{
Xregister struct DateStamp *ds=(&d->fib->fib_Date);
Xreturn ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
X}
X
Xlong timeof(s)
Xchar *s;
X{
Xstruct DPTR *d;
Xint dummy;
Xlong n;
X
Xif ( (d=dopen(s,&dummy))==NULL ) return 0L;
Xn=dptrtosecs(d);
Xdclose(d);
Xreturn n;
X}
X
X/*
X * if -f file (exists) or:
X *
X * if A < B   <, >, =, <=, >=, <>, where A and B are either:
X * nothing
X * a string
X * a value (begins w/ number)
X */
X
Xdo_if(garbage, com)
Xchar *garbage;
X{
Xint result;
Xint i;
X
Xswitch (com) {
X    case 0:
X	if (If_stack && If_base[If_stack - 1]) If_base[If_stack++] = 1;
X	else {
X		get_opt("rftmdvn",&i);
X		result=evalif(i);
X		If_base[If_stack++]=(options & 64 ? result : !result);
X		}
X	break;
X    case 1:
X	if (If_stack > 1 && If_base[If_stack - 2]) break;
X	if (If_stack) If_base[If_stack - 1] ^= 1;
X	break;
X    case 2:
X	if (If_stack) --If_stack;
X	break;
X     }
Xdisable = (If_stack) ? If_base[If_stack - 1] : 0;
Xif (If_stack >= MAXIF) {
X	fprintf(stderr,"If's too deep\n");
X	disable = If_stack = 0;
X	return -1;
X	}
Xif (forward_goto) disable = If_base[If_stack - 1] = 0;
Xreturn 0;
X}
X
Xevalif(i)
Xregister unsigned int i;
X{
Xchar c;
Xlong num, t0, isint;
Xlong AvailMem();
X
Xswitch(options & ~64) {
X    case 0:
X	if (ac-i != 3) return (ac>i && *av[i]);
X	num  = Atol(av[i]);
X	isint  = ! IoErr();
X	num -= Atol(av[i+2]);
X	isint &= ! IoErr();
X	if (!isint) num=strcmp(av[i],av[i+2]);
X	if (num < 0)	   c='<';
X	else if (num > 0)  c='>';
X	else if (num == 0) c='=';
X	return index(av[i+1], c) != NULL;
X    case 1:
X	return do_rpn(NULL,i);
X    case 2:
X	return exists(av[i]);
X    case 4:
X	t0=timeof(av[i++]);
X	for ( ; i<ac ; i++)
X		if (t0<=timeof(av[i])) return 1;
X	return 0;
X    case 8:
X	return (AvailMem( (long)MEMF_FAST )!=0);
X    case 16:
X	return (isdir(av[i])!=0);
X    case 32:
X	return (get_var(LEVEL_SET,av[i]) != 0);
X    default:
X	ierror(NULL,500);
X	return 0;
X    }
X}
X
Xdo_label()
X{
X   char aseek[32];
X
X   if (Src_stack == 0) {
X      ierror (NULL, 502);
X      return (-1);
X   }
X
X   sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack);
X   set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek);
X   if (!strcmp(av[1],get_var(LEVEL_SET,v_gotofwd)))
X      forward_goto = 0;
X   return 0;
X}
X
Xdo_goto()
X{
X   int new;
X   long pos;
X   char *lab;
X
X   if (Src_stack == 0) {
X      ierror (NULL, 502);
X   } else {
X      lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]);
X      if (lab == NULL) {
X         forward_goto = 1;
X         set_var (LEVEL_SET, v_gotofwd, av[1]);
X         return(0);
X      } else {
X         pos = atoi(lab);
X         fseek (Src_base[Src_stack - 1], pos, 0);
X         Src_pos[Src_stack - 1] = pos;
X         new = atoi(next_word(lab));
X         for (; If_stack < new; ++If_stack)
X            If_base[If_stack] = 0;
X         If_stack = new;
X      }
X   }
X   Exec_abortline = 1;
X   return (0);      /* Don't execute rest of this line */
X}
X
X
Xdo_inc(garbage, com)
Xchar *garbage;
X{
Xchar *var, num[32];
X
Xif (ac>2) com *= atoi(av[2]);
Xif (var = get_var (LEVEL_SET, av[1])) {
X	sprintf (num, "%d", atoi(var)+com);
X	set_var (LEVEL_SET, av[1], num);
X	}
Xreturn 0;
X}
X
Xdo_input()
X{
Xchar in[256], *p,*s;
Xunsigned int i;
X
Xfor (i=1; i < ac; ++i)
X    if (gets(in)) {
X	for(p = in; *p; p = s) {
X		s = next_word(p);
X		if (*s) *(s-1) = 0xA0;
X		}
X	set_var (LEVEL_SET, av[i], in);
X	}
Xreturn 0;
X}
X
Xdo_ver()
X{
Xextern char shellname[];
X
Xputs(shellname);
Xputs("(c)1986 Matthew Dillon\n\
XManx (M) versions by Steve Drew\n\
XARP (A) versions by Carlo Borreo & Cesare Dieni\n");
Xreturn 0;
X}
X
Xdo_ps()
X{
X/* this code fragment based on ps.c command by Dewi Williams */
X
Xregister int	count;		/* loop variable		*/
Xstruct Task	*task;		/* EXEC descriptor		*/
Xchar		strbuf[64+1];	/* scratch for btocstr()	*/
Xchar		cmd[40+1];	/* holds cmd name		*/
Xlong ncli;
X
Xprintf("Proc Command Name         CLI Type    Pri.  Address  Directory\n");
XForbid();
X
Xncli=(long)FindCLI(0L);
Xfor (count = 1; count <= ncli ; count++)
X		/* or just assume 20?*/
X    if (task = (struct Task *)FindCLI((long)count)) {
X	if (task==NULL) continue;
X	/* Sanity check just in case */
X	if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0) continue;
X							/* or complain? */
X	BtoCStr(cmd,   CLI(PROC(task))->cli_CommandName, 40L);
X	BtoCStr(strbuf,CLI(PROC(task))->cli_SetName    , 64L);
X	printf("%2d   %-20.20s %-11.11s %3d  %8lx  %s\n",
X		count,
X		cmd,
X		task->tc_Node.ln_Name,
X		task->tc_Node.ln_Pri,
X		task,
X		strbuf);
X	}
XPermit();
Xreturn 0;
X}
X
X/*
X * CP [-d] [-u] file file
X * CP [-d] [-u] file file file... destdir
X * CP [-r][-u][-d] dir dir dir... destdir
X */
X
Xchar *errstr;          /* let's be alittle more informative */
X
Xdo_copy()
X{
Xregister int recur, ierr;
Xregister char *destname;
Xregister char destisdir;
Xregister FIB *fib;
Xint i;
X
Xerrstr = "";
Xierr = 0;
X
Xfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
X
Xget_opt("rudf",&i);
Xrecur     = (options & 0x01);
Xcp_update = (options & 0x02);
Xcp_date   = (!(options & 0x04)); /* the default is keep orignal file date */
Xcp_flags  = (!(options & 0x08)); /* and flags */
X
Xdestname = av[ac - 1];
X
Xif (ac < i + 2) {
X	ierr = 500;
X	goto done;
X	}
Xdestisdir = isdir(destname);
Xif (ac > i + 2 && !destisdir) {
X	ierr = 507;
X	goto done;
X	}
X
X/*
X * copy set:                        reduce to:
X *    file to file                     file to file
X *    dir  to file (NOT ALLOWED)
X *    file to dir                      dir to dir
X *    dir  to dir                      dir to dir
X *
X */
X
Xfor (; i<ac-1 && !dobreak(); ++i) {
X	short srcisdir = isdir(av[i]);
X	if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
X		continue;		     /* getting copied if specified */
X					     /* from wild expansion */
X	if (srcisdir) {
X		BPTR srcdir, destdir;
X		if (!destisdir) {
X			if (exists(destname)) {
X				ierr = 507;	/* disallow dir to file */
X				goto done;
X				}
X			if (destdir = CreateDir(destname)) UnLock(destdir);
X			destisdir = 1;
X			}
X		if (!(destdir = Lock(destname, ACCESS_READ))) {
X			ierr = 205;
X			errstr = destname;
X			goto done;
X			}
X		if (!(srcdir = Lock(av[i], ACCESS_READ))) {
X			ierr = 205;
X			errstr = av[i];
X			UnLock(destdir);
X			goto done;
X			}
X		ierr = copydir(srcdir, destdir, recur);
X		UnLock(srcdir);
X		UnLock(destdir);
X		if (ierr) break;
X		}
X	else {		/* FILE to DIR,   FILE to FILE   */
X		BPTR destdir, srcdir, tmp;
X		char *destfilename;
X
X		srcdir = (BPTR)(Myprocess->pr_CurrentDir);
X
X		if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)) {
X			if (tmp) UnLock(tmp);
X			ierr = 205;
X			errstr = av[i];
X			goto done;
X			}
X		UnLock(tmp);
X		if (destisdir) {
X			destdir = Lock(destname, ACCESS_READ);
X			destfilename = fib->fib_FileName;
X			}
X		else {
X			destdir = srcdir;
X			destfilename = destname;
X			}
X		printf(" %s..",av[i]);
X		fflush(stdout);
X		ierr = copyfile(av[i], srcdir, destfilename, destdir);
X		if (destisdir) UnLock(destdir);
X		if (ierr) break;
X		}
X	}
X
Xdone:
X
XFreeMem(fib, (long)sizeof(FIB));
Xif (ierr) {
X	ierror(errstr, ierr);
X	return(20);
X	}
Xreturn 0;
X}
X
X
Xcopydir(srcdir, destdir, recur)
Xregister BPTR srcdir, destdir;
X{
X   BPTR cwd;
X   register FIB *srcfib;
X   register BPTR destlock, srclock;
X   int ierr;
X   static int level;
X
X   level++;
X   ierr = 0;
X   srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
X   if (Examine(srcdir, srcfib)) {
X      while (ExNext(srcdir, srcfib)) {
X         if (CHECKBREAK())
X            break;
X         if (srcfib->fib_DirEntryType < 0) {
X            printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
X            fflush(stdout);
X            ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
X            if (ierr)
X               break;
X         } else {
X            if (recur) {
X               cwd = CurrentDir(srcdir);
X               if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) {
X                  CurrentDir(destdir);
X                  if (!(destlock = Lock(srcfib->fib_FileName, ACCESS_WRITE))) {
X                     destlock = CreateDir(srcfib->fib_FileName);
X                     printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
X                                " ",srcfib->fib_FileName);
X
X                        /* UnLock and re Lock if newly created
X                           for file_date() to work properly
X                        */
X                     if (destlock) UnLock(destlock);
X                     destlock = Lock(srcfib->fib_FileName, ACCESS_WRITE);
X                  }
X                  else
X                     printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
X                  if (destlock) {
X                     ierr = copydir(srclock, destlock, recur);
X                     UnLock(destlock);
X                  } else {
X                     ierr = (int)((long)IoErr());
X                  }
X                  UnLock(srclock);
X               } else {
X                  ierr = (int)((long)IoErr());
X               }
X               CurrentDir(cwd);
X               if (ierr)
X                  break;
X            }
X         }
X      }
X   } else {
X      ierr = (int)((long)IoErr());
X   }
X   --level;
X   FreeMem(srcfib, (long)sizeof(FIB));
X   return(ierr);
X}
X
X
Xcopyfile(srcname, srcdir, destname, destdir)
Xchar *srcname, *destname;
XBPTR srcdir, destdir;
X{
XBPTR cwd;
XBPTR f1, f2;
Xlong i;
Xint stat,ierr;
Xchar *buf;
Xstruct DPTR *dp, *dps = NULL;
X
Xif ((buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR))==NULL)
X	{ ierr = 103; goto fail; }
Xierr = 0;
Xcwd = CurrentDir(srcdir);
Xif ((f1=Open(srcname, MODE_OLDFILE))==NULL)
X	{ errstr = srcname; ierr = 205; goto fail; }
Xdps = dopen(srcname,&stat);
XCurrentDir(destdir);
Xif (cp_update)
X	{
X	dp=dopen(destname, &stat);
X	if ( dptrtosecs(dp) >= dptrtosecs(dps) &&
X		!strcmp(dps->fib->fib_FileName, dp->fib->fib_FileName))
X		{ dclose(dp); Close(f1); printf("..not newer\n"); goto fail; }
X	dclose(dp);
X	}
Xif ((f2=Open(destname, MODE_NEWFILE))==NULL)
X    { Close(f1); ierr = (int)((long)IoErr()); errstr=destname; goto fail;  }
Xwhile (i = Read(f1, buf, 8192L))
X	if (Write(f2, buf, i) != i) { ierr = (int)((long)IoErr()); break; }
XClose(f2);
XClose(f1);
Xif (!ierr)
X	{
X	if (cp_date) file_date(&dps->fib->fib_Date, destname);
X	if (cp_flags) SetProtection(destname, dps->fib->fib_Protection);
X	printf("..copied\n");
X	}
Xelse DeleteFile(destname);
Xfail:
X dclose(dps);
X if (buf) FreeMem(buf, 8192L);
X CurrentDir(cwd);
X return(ierr);
X}
X
Xdo_touch()
X{
Xstruct DateStamp ds;
Xregister unsigned int i;
XDateStamp(&ds);
Xfor (i=1; i<ac; i++) if (file_date(&ds, av[i])) ierror(av[i],500);
Xreturn 0;
X}
X
Xfile_date(date,name)
Xstruct DateStamp *date;
Xchar *name;
X{
Xlong packargs[7];
XUBYTE *ptr;
Xstruct MsgPort *task;
XBPTR dirlock;
Xstruct DPTR *tmp;
Xint stat;
X
Xif (!(task = (struct MsgPort *)DeviceProc(name))) return(1);
Xif (tmp = dopen(name, &stat)) {
X	dirlock = ParentDir(tmp->lock);
X	ptr=AllocMem(65L,MEMF_PUBLIC);
X	CtoBStr(tmp->fib->fib_FileName,(ULONG)ptr >> 2L,64L);
X	dclose(tmp);
X	packargs[1]=dirlock;
X	packargs[2]=(ULONG)ptr >> 2L;
X	packargs[3]=(long)date;
X	SendPacket(ACTION_SET_DATE,packargs,task);
X	UnLock(dirlock);
X	FreeMem(ptr,65L);
X	}
Xreturn 0;
X}
X
Xdo_addbuffers()
X{
Xlong packargs[7];
Xlong n;
Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
X
Xif (!task) { ierror(av[1],510); return 20; }
Xn=myatoi(av[2],1,32767); if (atoierr) return 20;
Xpackargs[0]=n;
XSendPacket(ACTION_MORE_CACHE,packargs,task);
Xreturn 0;
X}
X
Xdo_relabel()
X{
Xlong packargs[7];
XUBYTE *ptr;
Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
X
Xif (!task) { ierror(av[1],510); return 20; }
Xptr=AllocMem(65L,MEMF_PUBLIC);
XCtoBStr(av[2],(ULONG)ptr >> 2L,64L);
Xpackargs[0]=(ULONG)ptr >> 2L;
XSendPacket(ACTION_RENAME_DISK,packargs,task);
XFreeMem(ptr,65L);
Xchangedisk(task);
Xreturn 0;
X}
X
Xdo_diskchange()
X{
Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
X
Xif (!task) { ierror(av[1],510); return 20; }
Xchangedisk(task);
Xreturn 0;
X}
X
Xchangedisk(task)
Xstruct MsgPort *task;
X{
Xlong packargs[7];
X
Xpackargs[0]=1L;
XSendPacket(ACTION_INHIBIT,packargs,task);
Xpackargs[0]=0L;
XSendPacket(ACTION_INHIBIT,packargs,task);
X}
END_OF_FILE
if test 13217 -ne `wc -c <'src/comm2.c'`; then
    echo shar: \"'src/comm2.c'\" unpacked with wrong size!
fi
# end of 'src/comm2.c'
fi
if test -f 'src/globals.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/globals.c'\"
else
echo shar: Extracting \"'src/globals.c'\" \(3551 characters\)
sed "s/^X//" >'src/globals.c' <<'END_OF_FILE'
X
X/*
X * GLOBALS.C
X *
X * (c)1986 Matthew Dillon     9 October 1986
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X *
X *    Most global variables.
X *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
Xchar v_titlebar	[]="_titlebar";	/* Window title				*/
Xchar v_prompt	[]="_prompt";	/* your prompt (ascii command)		*/
Xchar v_hist	[]="_history";	/* set history depth (value)		*/
Xchar v_histnum	[]="_histnum";	/* set history numbering var		*/
Xchar v_debug	[]="_debug";	/* set debug mode			*/
Xchar v_verbose	[]="_verbose";	/* set verbose for source files		*/
Xchar v_stat	[]="_maxerr";	/* worst return value to date		*/
Xchar v_lasterr	[]="_lasterr";	/* return value from last comm.		*/
Xchar v_cwd	[]="_cwd";	/* current directory			*/
Xchar v_except	[]="_except";	/* "nnn;command"			*/
Xchar v_passed	[]="_passed";	/* passed arguments to source file	*/
Xchar v_path	[]="_path";	/* search path for external commands	*/
Xchar v_gotofwd	[]="_gtf";	/* set name for fwd goto name		*/
Xchar v_linenum	[]="_linenum";	/* name for forline line #		*/
X
Xstruct HIST *H_head, *H_tail;	/* HISTORY lists */
X
Xstruct PERROR Perror[]= {	/* error code->string */
X	103,	"Insufficient free storage",
X	105,	"Task table full",
X	120,	"Argument line invalid or too long",
X	121,	"File is not an object module",
X	122,	"Invalid resident library during load",
X	201,	"No default directory",
X	202,	"Object in use",
X	203,	"Object already exists",
X	204,	"Directory not found",
X	205,	"Object not found",
X	206,	"Bad stream name",
X	207,	"Object too large",
X	209,	"Action not known",
X	210,	"Invalid stream component name",
X	211,	"Invalid object lock",
X	212,	"Object not of required type",
X	213,	"Disk not validated",
X	214,	"Disk write protected",
X	215,	"Rename across devices",
X	216,	"Directory not empty",
X	217,	"Too many levels",
X	218,	"Device not mounted",
X	219,	"Seek error",
X	220,	"Comment too long",
X	221,	"Disk full",
X	222,	"File delete protected",
X	223,	"File write protected",
X	224,	"File read protected",
X	225,	"Not a DOS disk",
X	226,	"No disk",
X
X /* custom error messages */
X
X	500,	"Bad arguments",
X	501,	"Label not found",
X	502,	"Must be within source file",
X	503,	"Syntax Error",
X	504,	"Redirection error",
X	505,	"Pipe error",
X	506,	"Too many arguments",
X	507,	"Destination not a directory",
X	508,	"Cannot mv a filesystem",
X	509,	"Error in command name",
X	510,	"Bad drive name",
X	511,	"Illegal number",
X	0,	NULL
X};
X
Xchar *av[MAXAV];		/* Internal argument list		*/
Xlong Src_base[MAXSRC];		/* file pointers for source files	*/
Xlong Src_pos[MAXSRC];		/* seek position storage for same	*/
Xchar If_base[MAXIF];		/* If/Else stack for conditionals	*/
Xint H_len, H_tail_base;		/* History associated stuff		*/
Xint H_stack;			/* AddHistory disable stack		*/
Xint E_stack;			/* Exception disable stack		*/
Xint Src_stack, If_stack;	/* Stack Indexes			*/
Xint forward_goto;		/* Flag for searching for foward lables	*/
Xint ac;				/* Internal argc			*/
Xint debug;			/* Debug mode				*/
Xint disable;			/* Disable com. execution (conditionals)*/
Xint Verbose;			/* Verbose mode for source files	*/
Xint Lastresult;			/* Last return code			*/
Xint Exec_abortline;		/* flag to abort rest of line		*/
Xint Quit;			/* Quit flag				*/
Xlong Cout, Cin;			/* Current input and output file handles*/
Xlong Cout_append;		/* append flag for Cout			*/
Xchar *Cin_name, *Cout_name;	/* redirection input/output name or NULL*/
Xchar *Pipe1, *Pipe2;		/* the two pipe temp. files		*/
Xstruct Process *Myprocess;
Xstruct CommandLineInterface *Mycli;
Xint S_histlen = 20;		/* Max # history entries		*/
Xunsigned int options;
END_OF_FILE
if test 3551 -ne `wc -c <'src/globals.c'`; then
    echo shar: \"'src/globals.c'\" unpacked with wrong size!
fi
# end of 'src/globals.c'
fi
if test -f 'src/main.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/main.c'\"
else
echo shar: Extracting \"'src/main.c'\" \(4936 characters\)
sed "s/^X//" >'src/main.c' <<'END_OF_FILE'
X/*
X * MAIN.C
X *
X * Matthew Dillon, 24 Feb 1986
X * (c)1986 Matthew Dillon     9 October 1986
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
Xchar shellname[]="Shell V4.02A";
Xchar shellctr []="CshCounter";
X
Xint aux; /* for use with aux: driver */
Xchar *oldtitle;
Xchar trueprompt[100];
Xchar Inline[260];
Xstruct IntuitionBase *IntuitionBase;
Xstruct Window *w;
Xstruct ArpBase *ArpBase;
X
Xmain(argc, argv)
Xregister char *argv[];
X{
X#if RAW_CONSOLE
X	char *rawgets();
X#endif
X
Xregister unsigned int i;
Xextern int Enable_Abort;
Xchar buf[10];
Xstatic char pipe1[32], pipe2[32];
Xstruct Window *getwindow();
X
XArpBase=(struct ArpBase *)OpenLibrary("arp.library",34L);
Xif (ArpBase==NULL) { printf("No arp library\n"); exit(0); }
X
XForbid();
X
Xi=0;
Xif (Getenv(shellctr,buf,10L)) i=atoi(buf);
Xsprintf(buf, "%d", i+1);
XSetenv(shellctr, buf);
XPermit();
X
XIntuitionBase=(struct IntuitionBase *)ArpBase->IntuiBase;
X
Xstdin->_flags	|= 0x80;	/* make sure we're set as a tty */
Xstdout->_flags	|= 0x80;	/* in case of redirection in .login */
XClose(_devtab[2].fd);
X_devtab[2].mode |= O_STDIO;
X_devtab[2].fd = _devtab[1].fd;	/* set stderr to Output() otherwise */
X				/* don't work with aux driver */
XMyprocess = (struct Process *)FindTask(0L);
XMycli=(struct CommandLineInterface *)((long)Myprocess->pr_CLI << 2);
Xw=getwindow();
X
Xoldtitle=(char *)(w->Title);
X
XPipe1 = pipe1;
XPipe2 = pipe2;
Xsprintf(pipe1, "ram:pipe1_%ld", Myprocess);
Xsprintf(pipe2, "ram:pipe2_%ld", Myprocess);
X
Xsprintf(buf,"%ld",Myprocess->pr_TaskNum);
Xset_var(LEVEL_SET, "_clinumber", buf);
X
Xset_var(LEVEL_SET, v_titlebar, shellname);
Xset_var(LEVEL_SET, v_prompt,
X	(IsInteractive(Input())) ? "\23337m%p> \2330m" : "");
Xset_var(LEVEL_SET, v_hist, "20");
Xset_var(LEVEL_SET, v_lasterr, "0");
Xset_var(LEVEL_SET, v_stat, "0");
Xset_var(LEVEL_SET, v_path, "RAM:,RAM:c/,df0:c/,df1:c/,sys:system/");
Xset_var(LEVEL_SET, "_insert", "1");
Xset_var(LEVEL_SET, "f1", "cdir df0:\15");
Xset_var(LEVEL_SET, "F1", "cdir df1:\15");
Xset_var(LEVEL_SET, "f3", "cdir RAM:\15");
Xset_var(LEVEL_SET, "F3", "cdir vd0:\15");
Xset_var(LEVEL_SET, "f4", "cd df0:\15");
Xset_var(LEVEL_SET, "F4", "cd df1:\15");
Xset_var(LEVEL_SET, "f5", "cls; ls\15");
Xset_var(LEVEL_SET, "F5", "cdir ");
Xset_var(LEVEL_SET, "f6", "ls -s\15");
Xset_var(LEVEL_SET, "f7", "info\15");
Xset_var(LEVEL_SET, "F7", "assign \15");
Xset_var(LEVEL_SET, "f8", "window -lf\15");
Xset_var(LEVEL_SET, "F8", "window -sb\15");
Xset_var(LEVEL_SET, "f10", "cls\15");
Xset_var(LEVEL_SET, "F10", "exit\15");
Xset_var(LEVEL_ALIAS, "cls", "echo -n ^l");
Xset_var(LEVEL_ALIAS, "kr", "rm -r RAM:* >NIL:");
Xset_var(LEVEL_ALIAS, "cdir", "%q cd $q; cls; dir");
Xset_var(LEVEL_ALIAS, "exit", "endcli;quit");
Xset_var(LEVEL_ALIAS, "lp", "cat >PRT:");
Xset_var(LEVEL_ALIAS, "manlist", "sea -qwn doc:shell.doc \"    *\"");
Xseterr();
Xif (Myprocess->pr_CurrentDir == NULL)
X	do_cd("x :");
Xelse do_pwd(NULL);
XEnable_Abort = 0;
X
Xif (exists(av[1] = "S:.login")) do_source("x S:.login");
X
Xfor (i = 1; i < argc; ++i) {
X	if (!strcmp(argv[i],"-c")) {
X		Inline[0] = ' ';
X		Inline[1] = '\0';
X		while (++i < argc)
X			{ strcat(Inline,argv[i]); strcat(Inline," "); }
X		exec_command(Inline);
X		main_exit(Lastresult);
X		}
X	if (!strcmp(argv[i],"-a")) { aux = 1; continue; }
X	sprintf (Inline, "source %s",argv[i]);
X	av[1] = argv[i];
X	do_source (Inline);
X	}
Xfor (;;) {
X   if (breakcheck())
X	while (WaitForChar(Input(), 100L) || stdin->_bp < stdin->_bend)
X		gets(Inline);
X   clearerr(stdin);  /* prevent acidental quit */
X#if RAW_CONSOLE
X   if (Quit || !rawgets(Inline, disable ? "_ " : trueprompt)) main_exit(0);
X#else
X   printf("%s", disable ? "_ " : trueprompt);
X   fflush(stdout);
X   if (Quit || !gets(Inline)) main_exit(0);
X#endif
X   breakreset();
X   if (*Inline) exec_command(Inline);
X   }
X}
X
Xmain_exit(n)
X{
Xregister int i;
Xchar buf[10];
X
XGetenv(shellctr,buf,10L);
Xi=atoi(buf);
Xsprintf(buf,"%d",i-1);
XSetenv(shellctr,buf);
XSetWindowTitles(w,oldtitle,-1L);
Xfor (i=1; i<MAXMYFILES; i++) myclose(i);
XCloseLibrary(ArpBase);
Xexit(0);
X}
X
Xbreakcheck()
X{
Xreturn (int)(SetSignal(0L,0L) & SIGBREAKF_CTRL_C);
X}
X
Xbreakreset()
X{
XSetSignal(0L, SIGBREAKF_CTRL_C);
X}
X
Xdobreak()
X{
Xif (breakcheck()) { printf("^C\n"); return(1); }
Xreturn(0);
X}
X
X/* this routine causes manx to use this Chk_Abort() rather than it's own */
X/* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */
X/* is zero).  Since we want to check for our own ^C's			 */
X
XChk_Abort()
X{
Xreturn(0);
X}
X
X_wb_parse()
X{
X}
X
Xdo_howmany()
X{
Xchar buf[10];
X
XGetenv(shellctr, buf, 10L);
Xprintf("Shell(s) running: %s\n",buf);
X}
X
Xstruct Window *getwindow()
X{
Xstruct InfoData *infodata;
Xstruct Window *win;
Xlong args[8];
X
Xinfodata=AllocMem((long)sizeof(struct InfoData),MEMF_CLEAR | MEMF_PUBLIC);
Xargs[0]=(long)infodata >> 2;
XSendPacket(ACTION_DISK_INFO,args,Myprocess->pr_ConsoleTask);
Xwin=(struct Window *)infodata->id_VolumeNode;
XFreeMem(infodata,(long)sizeof(struct InfoData));
Xreturn win;
X}
END_OF_FILE
if test 4936 -ne `wc -c <'src/main.c'`; then
    echo shar: \"'src/main.c'\" unpacked with wrong size!
fi
# end of 'src/main.c'
fi
if test -f 'src/makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/makefile'\"
else
echo shar: Extracting \"'src/makefile'\" \(1019 characters\)
sed "s/^X//" >'src/makefile' <<'END_OF_FILE'
X######################################################################
X#
X# Makefile to build Shell 4.01A
X# by Carlo Borreo & Cesare Dieni 17-Feb-90
X#
X######################################################################
X
XOBJS	= run.o main.o comm1.o comm2.o comm3.o execom.o set.o sub.o \
X	  globals.o rawconsole.o
X
XINCL	= shell.h
X
XShell   : Shell.syms $(OBJS)
X	ln  +q -m -o Shell $(OBJS) -la -lc32
X
XShell.syms : $(INCL)
X	cc +L +HShell.syms shell.h -DAZTEC_C
X
Xrawconsole.o : rawconsole.c $(INCL)
X	cc +L +IShell.syms rawconsole.c
X
Xrun.o   : run.c $(INCL)
X	cc +L +IShell.syms run.c
X
Xmain.o  : main.c $(INCL)
X	cc +L +IShell.syms main.c
X
Xcomm1.o : comm1.c $(INCL)
X	cc +L +IShell.syms comm1.c
X
Xcomm2.o : comm2.c $(INCL)
X	cc +L +IShell.syms comm2.c
X
Xcomm3.o : comm3.c $(INCL)
X	cc +L +IShell.syms comm3.c
X
Xset.o   : set.c $(INCL)
X	cc +L +IShell.syms set.c
X
Xsub.o   : sub.c $(INCL)
X	cc +L +IShell.syms sub.c
X
Xglobals.o : globals.c $(INCL)
X	cc +L +IShell.syms globals.c
X
Xexecom.o : execom.c $(INCL)
X	cc +L +IShell.syms execom.c
END_OF_FILE
if test 1019 -ne `wc -c <'src/makefile'`; then
    echo shar: \"'src/makefile'\" unpacked with wrong size!
fi
# end of 'src/makefile'
fi
if test -f 'src/rawconsole.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/rawconsole.c'\"
else
echo shar: Extracting \"'src/rawconsole.c'\" \(9156 characters\)
sed "s/^X//" >'src/rawconsole.c' <<'END_OF_FILE'
X/*
X * RawConsole.c
X *
X * Shell 2.07M  17-Jun-87
X * console handling, command line editing support for Shell
X * using new console packets from 1.2.
X * Written by Steve Drew. (c) 14-Oct-86.
X * 16-Dec-86 Slight mods to rawgets() for Disktrashing.
X *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
X#if RAW_CONSOLE
X
Xchar *tyahdptr;
X
Xmyget()
X{
Xif (*tyahdptr) return *tyahdptr++;
Xreturn getchar();
X}
X
Xextern int aux; /* for use with aux: */
X
X#define SETRAW setrawcon(-1L);
X#define SETCON setrawcon(0L);
X
Xint width;
X
Xnewwidth()
X{
Xextern struct Window *w;
X
Xwidth=(w->Width- (w->BorderLeft + w->BorderRight)) / w->RPort->TxWidth;
X}
X
Xchar *rawgets(line,prompt)
Xchar *line, *prompt;
X{
Xchar *get_var();
Xchar *gets();
Xregister int n, pl;
Xregister int max, i;
Xunsigned char c1,c2,c3;
Xchar fkeys[5];
Xchar *s;
Xchar *ps;
Xchar typeahd[256];
Xint fkey, savn;
Xint insert = 1;
Xint recall = -1;
Xstruct HIST *hist;
X
Xnewwidth();
X
Xif (aux) {
X	printf("%s",prompt);
X	fflush(stdout);
X	}
Xif (!IsInteractive(Input()) || aux ) return(gets(line));
Xif (WaitForChar((long)Input(), 100L) ||   /* don't switch to 1L ...*/
X		stdin->_bp < stdin->_bend) {     /* else causes read err's*/
X	gets(line);
X	return(line);
X	}
XSETRAW;
Xprintf("\015%s\2336n",prompt);
Xsavn = pl = n = 0;
Xtyahdptr = typeahd;
Xwhile((typeahd[n]=getchar()) != 'R') {
X	if ((unsigned char)typeahd[n] == 155) savn = n;
X	n++;
X	}
X	/* typeahd now contains possible type a head chars
X	   followed by <CSI> cursor position report.
X	*/
Xtypeahd[savn]  = '\0';
Xif (typeahd[n-2] != ';') pl = (typeahd[n-2] - 48) * 10;
Xpl += typeahd[n-1] - 49;
Xps = line + pl;
Xline[max = i = pl] = '\0';
X
Xif (s = get_var (LEVEL_SET, "_insert")) insert = atoi(s) ? 1 : 0;
X
Xwhile( (c1 = myget()) != 255) {
X        switch(c1) {
X            case 155:
X                 c2 = myget();
X                 switch(c2) {
X                     case 'A':                  /* up arrow   */
X                        n = ++recall;
X                     case 'B':                  /* down arrow */
X                        line[pl] = '\0';
X                        if (recall >= 0 || c2 == 'A') {
X                            if (c2 == 'B') n = --recall;
X                            if (recall >= 0) {
X                                for(hist = H_head; hist && n--;
X                                    hist = hist->next);
X                                if (hist) strcpy(&line[pl],hist->line);
X                                else recall = H_len;
X                            }
X                        }
X                        if (i != pl)
X                            printf("\233%dD",i);
X                        printf("\015\233J%s%s",prompt,ps);
X                        i = max = strlen(ps) + pl;
X                        break;
X                     case 'C':                  /* right arrow*/
X                        if (i < max) {
X                            i++;
X                            printf("\233C");
X                        }
X                        break;
X                     case 'D':                  /* left arrow */
X                        if (i > pl) {
X                            i--;
X                            printf("\233D");
X                        }
X                        break;
X                     case 'T':           /* shift-up   */
X                       n = recall = H_len-1;
X                     case 'S':           /* shift-down */
X                       line[pl] = '\0';
X                       if (c2 == 'S') {
X                           n = recall = 0;
X                           if (H_head) strcpy(&line[pl], H_head->line);
X                       }
X                       else if (H_tail) strcpy(&line[pl], H_tail->line);
X                       printf("\015\233J%s%s", prompt, ps);
X                       i = max = strlen(ps) + pl;
X                       break;
X                    case ' ':                   /* shift -> <-*/
X                        c3 = myget();
X                                     switch(c3) {
X                    case('@'):      /* shift ->   */
X                        while (ps[i-pl-1] == ' ' && i<max) {
X      		            i++;
X      		            printf("\233C");
X		        }
X                        while (ps[i-pl-1] != ' ' && i<max) {
X      		            i++;
X		            printf("\233C");
X               		}
X                        break;
X                    case('A'):      /* shift <-   */
X                        while (ps[i-pl-1] == ' ' && i>pl) {
X                            i--;
X                            printf("\233D");
X                        }
X                        while (ps[i-pl-1] != ' ' && i>pl) {
X                            i--;
X                            printf("\233D");
X                        }
X                        break;
X                        default:
X                        break;
X                    }
X                        break;
X                    default:
X                        c3 = myget();
X                        if (c3 == '~') {
X                            fkey = c2;
X                            fkeys[0] = 'f';
X                            if (c2 == '?') {
X                                strcpy(ps,"help");
X                                goto done;
X                            }
X                        }
X                        else if (myget() != '~') { /* window was resized */
X                            while(myget() != '|');
X                            newwidth();
X                            break;
X                        }
X                        else {
X                            fkey = c3;
X                            fkeys[0] = 'F';
X                        }
X                        sprintf(fkeys+1,"%d",fkey - 47);
X                        if (s = get_var(LEVEL_SET, fkeys))
X                                tyahdptr = strcpy(typeahd,s);
X                        break;
X                    }
X                break;
X            case 8:
X                if (i > pl) {
X                    i--;
X                    printf("\010");
X                }
X                else break;
X            case 127:
X                if (i < max) {
X                    int j,t,l = 0;
X                    movmem(&line[i+1],&line[i],max-i);
X                    --max;
X                    printf("\233P");
X                    j = width - i % width - 1;   /* amount to end     */
X                    t = max/width - i/width;     /* no of lines       */
X                    for(n = 0; n < t; n++) {
X                        l += j;                  /* no. of char moved */
X                        if (j) printf("\233%dC",j); /* goto eol       */
X                        printf("%c\233P",line[width*(i/width+n+1)-1]);
X                        j = width-1;
X                    }
X                    if (t)
X                    printf("\233%dD",l+t);   /* get back */
X                }
X                break;
X            case 18:
X                n = i/width;
X                if (n) printf("\233%dF",n);
X                printf("\015\233J%s%s",prompt,ps);
X                i = max;
X                break;
X            case 27:
X                break;
X            case 1:
X                insert ^= 1;
X                break;
X            case 21:
X            case 24:
X            case 26:
X                if (i>pl) printf("\233%dD",i-pl);
X                i = pl;
X                if (c1 == 26) break;
X            case 11:        /* ^K */
X                printf("\233J");
X                max = i;
X                line[i] = '\0';
X                break;
X            case 28:        /* ^\ */
X                SETCON;
X                return(NULL);
X            case 5:
X                if (i!=max) printf("\233%dC",max - i);
X                i = max;
X                break;
X            case 10:
X            case 13:
X                line[max] = '\0';
Xdone:           printf("\233%dC\n",max - i);
X
X                SETCON;
X                strcpy(line, ps);
X                return(line);
X            default:
X                c1 &= 0x7f;
X                if (c1 == 9) c1 = 32;
X                if (c1 > 31 & i < 256) {
X                    if (i < max && insert) {
X                        int j,t,l = 0;
X                        movmem(&line[i], &line[i+1], max - i);
X                        printf("\233@%c",c1);
X                        t = max/width - i/width;
X                        j = width - i % width - 1;
X                        for(n = 0; n < t; n++) {
X                            l += j;
X                            if (j) printf("\233%dC",j);
X                            printf("\233@%c",line[width*(i/width+n+1)]);
X                            j = width-1;
X                        }
X                        if (t) printf("\233%dD",l + t);
X                        ++max;
X                    }
X                    else {
X                        if(i == pl && max == i) printf("\015%s%s",prompt,ps);
X                        putchar(c1);
X                    }
X                    line[i++] = c1;
X                    if (max < i) max = i;
X                    line[max] = '\0';
X                }
X        }
X	}
XSETCON;
Xreturn(NULL);
X}
X
Xsetrawcon(flag) /* -1L=RAW:, 0L=CON: */
Xlong flag;
X{
Xlong packargs[8];
X
Xpackargs[0]=flag;
XSendPacket(994L, packargs, Myprocess->pr_ConsoleTask);
X}
X
X#endif
END_OF_FILE
if test 9156 -ne `wc -c <'src/rawconsole.c'`; then
    echo shar: \"'src/rawconsole.c'\" unpacked with wrong size!
fi
# end of 'src/rawconsole.c'
fi
if test -f 'src/run.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/run.c'\"
else
echo shar: Extracting \"'src/run.c'\" \(1712 characters\)
sed "s/^X//" >'src/run.c' <<'END_OF_FILE'
X
X/*
X * RUN.C
X *
X * (c)1986 Matthew Dillon     9 October 1986
X *
X *    RUN   handles running of external commands.
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
Xchar *FindIt();
X
Xdo_run(str)
Xchar *str;
X{
Xint retcode;
Xchar buf[200]; /* enough space for 100 char cmd name + path stuff */
Xchar *path, *argline, *trueargline, *copy, *p = av[0];
X
Xwhile(*p++) *p &= 0x7F;      /* allow "com mand" */
X
Xargline=compile_av(av, 1, ac, ' ', 1);
Xtrueargline= (*argline ? argline : "\n");
X
Xif (strlen(av[0]) > 100) { ierror(NULL,509); return -1; }
X
Xsprintf(buf,"res_%s",BaseName(av[0]));
Xif (Getenv(buf, buf+100, 90L) && loadres(av[0])) Setenv(buf,NULL);
Xretcode=SyncRun(av[0],trueargline,0L,0L);
Xif (retcode>=0) { free(argline); return retcode; }
Xif (path = FindIt(av[0],"",buf)) {
X	retcode = SyncRun(path,trueargline,0L,0L);
X	free(argline);
X	return retcode;
X	}
Xelse free(argline);
Xif ((path = FindIt(av[0],".sh",buf)) == NULL) {
X	fprintf(stderr,"Command Not Found %s\n",av[0]);
X	return -1;
X	}
Xav[1] = buf;
Xcopy = malloc(strlen(str)+3);
Xsprintf(copy,"x %s",str);
Xretcode = do_source(copy);
Xfree(copy);
Xreturn retcode;
X}
X
Xchar *dofind(cmd, ext, buf)
Xchar *cmd, *ext, *buf;
X{
Xchar *ptr, *s;
X
Xsprintf(buf,"%s%s",cmd,ext);
Xif (exists(buf)) return buf;
Xif (BaseName(buf)==buf) {
X	s = get_var(LEVEL_SET, v_path);
X	while (*s) {
X		for (ptr=buf; *s && *s!=','; ) *ptr++ = *s++;
X		sprintf(ptr, "%s%s", cmd, ext);
X		if (exists(buf)) return buf;
X		if (*s) s++;
X		}
X	}
Xreturn NULL;
X}
X
Xchar *FindIt(cmd,ext,buf)
Xchar *cmd, *ext, *buf;
X{
Xchar *response;
X
XMyprocess->pr_WindowPtr = (APTR)(-1);
Xresponse=dofind(cmd,ext,buf);
XMyprocess->pr_WindowPtr = NULL;
Xreturn response;
X}
END_OF_FILE
if test 1712 -ne `wc -c <'src/run.c'`; then
    echo shar: \"'src/run.c'\" unpacked with wrong size!
fi
# end of 'src/run.c'
fi
if test -f 'src/set.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/set.c'\"
else
echo shar: Extracting \"'src/set.c'\" \(3884 characters\)
sed "s/^X//" >'src/set.c' <<'END_OF_FILE'
X
X/*
X * SET.C
X *
X * (c)1986 Matthew Dillon     9 October 1986
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
Xextern struct Window *w;
X
X#define MAXLEVELS (3 + MAXSRC)
X
Xstruct MASTER {
X	struct MASTER *next;
X	struct MASTER *last;
X	char *name;
X	char *text;
X};
X
Xstatic struct MASTER *Mbase[MAXLEVELS];
X
Xchar *set_var(level, name, str)
Xregister char *name, *str;
X{
X   register struct MASTER *base = Mbase[level];
X   register struct MASTER *last;
X   register int len;
X
X   for (len = 0; isalphanum(name[len]); ++len);
X   while (base != NULL) {
X      if (strlen(base->name) == len && strncmp (name, base->name, len) == 0) {
X         Free (base->text);
X         goto gotit;
X      }
X      last = base;
X      base = base->next;
X   }
X   if (base == Mbase[level]) {
X      base = Mbase[level] = (struct MASTER *)malloc (sizeof(struct MASTER));
X      base->last = NULL;
X   } else {
X      base = (struct MASTER *)malloc (sizeof(struct MASTER));
X      base->last = last;
X      last->next = base;
X   }
X   base->name = malloc (len + 1);
X   bmov (name, base->name, len);
X   base->name[len] = 0;
X   base->next = NULL;
Xgotit:
X   base->text = malloc (strlen(str) + 1);
X   strcpy (base->text, str);
X   if (*name=='_') sys_vars();
X   return (base->text);
X}
X
Xchar *get_var (level, name)
Xregister char *name;
X{
X   register struct MASTER *base = Mbase[level];
X   register unsigned char *scr;
X   register int len;
X
X   for (scr = (unsigned char *)name; *scr && *scr != 0x80 && *scr != ' ' && *scr != ';' && *scr != '|'; ++scr);
X   len = scr - name;
X
X   while (base != NULL) {
X      if (strlen(base->name) == len && strncmp (name, base->name, len) == 0)
X         return (base->text);
X      base = base->next;
X   }
X   return (NULL);
X}
X
Xunset_level(level)
X{
X   register struct MASTER *base = Mbase[level];
X
X   while (base) {
X      Free (base->name);
X      Free (base->text);
X      Free (base);
X      base = base->next;
X   }
X   Mbase[level] = NULL;
X}
X
Xunset_var(level, name)
Xchar *name;
X{
X   register struct MASTER *base = Mbase[level];
X   register struct MASTER *last = NULL;
X   register int len;
X
X   for (len = 0; isalphanum(name[len]); ++len);
X   while (base) {
X      if (strlen(base->name) == len && strncmp (name, base->name, len) == 0) {
X         if (base != Mbase[level])
X            last->next = base->next;
X         else
X            Mbase[level] = base->next;
X         if (base->next != NULL)
X            base->next->last = last;
X         if (base == Mbase[level])
X            Mbase[level] = base->next;
X         Free (base->name);
X         Free (base->text);
X         Free (base);
X         return (1);
X      }
X      last = base;
X      base = base->next;
X   }
X   return (-1);
X}
X
Xdo_unset_var(str, level)
Xchar *str;
X{
Xregister unsigned int i;
X
Xfor (i = 1; i < ac; ++i) unset_var (level, av[i]);
Xsys_vars();
Xreturn 0;
X}
X
Xdo_set_var(command, level)
Xchar *command;
X{
Xregister struct MASTER *base = Mbase[level];
Xregister char *str;
X
Xswitch (ac) {
Xcase 1:
X	while (base && !dobreak()) {
X		printf ("\2330m%-10s %s\n", base->name, base->text);
X		base = base->next;
X		}
X	break;
Xcase 2:
X	if (str=get_var(level,av[1])) printf ("%-10s %s\n", av[1], str);
X	break;
Xdefault:
X	set_var (level, av[1], next_word (next_word (command)));
X	if (*av[1]=='_') sys_vars();
X	break;
X	}
Xreturn 0;
X}
X
Xsys_vars()
X{
Xregister char *str, *t;
Xextern char trueprompt[100];
X
Xif (strcmp(w->Title, str=get_var(LEVEL_SET, v_titlebar)))
X	SetWindowTitles(w, str, -1L);
XS_histlen=(str = get_var(LEVEL_SET, v_hist)) ? atoi(str) : 0;
Xdebug  =(get_var(LEVEL_SET, v_debug)  !=NULL);
XVerbose=(get_var(LEVEL_SET, v_verbose)!=NULL);
Xif (S_histlen < 2) S_histlen=2;
X
Xif ( (str=get_var(LEVEL_SET,v_prompt)) ==NULL) str="$ ";
Xt=trueprompt;
Xwhile (*str)
X	if (*str=='%' && str[1]=='p') {
X		str+=2;
X		strcpy(t,get_var(LEVEL_SET, "_cwd"));
X		t+=strlen(t);
X		}
X	else *t++=*str++;
Xstrcpy(t,"\2330m");
X}
END_OF_FILE
if test 3884 -ne `wc -c <'src/set.c'`; then
    echo shar: \"'src/set.c'\" unpacked with wrong size!
fi
# end of 'src/set.c'
fi
if test -f 'src/shell.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/shell.h'\"
else
echo shar: Extracting \"'src/shell.h'\" \(3029 characters\)
sed "s/^X//" >'src/shell.h' <<'END_OF_FILE'
X
X/*
X * SHELL.H
X *
X * (c)1986 Matthew Dillon     9 October 1986
X *
X *
X * SHELL include file.. contains shell parameters and extern's
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
X#define RAW_CONSOLE 1   /* Set to 0 to compile out Cmd Line Editing */
X
X#include <stdio.h>
X#include <exec/exec.h>
X#include <time.h>
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <intuition/intuition.h>
X#include <intuition/intuitionbase.h>
X#include "shellfunctions.h"
X#include <fcntl.h>
X#include <libraries/arpbase.h>
X
Xtypedef struct FileInfoBlock FIB;
X
X#define bmov movmem
X
X#define MAXAV		256		/* Max. # arguments		*/
X#define MAXSRC		5		/* Max. # of source file levels */
X#define MAXIF		10		/* Max. # of if levels		*/
X#define MAXALIAS	20		/* Max. # of alias levels	*/
X#define MAXMYFILES	9		/* Max. # of internal files	*/
X
X#define LEVEL_SET	0		/* which variable list to use   */
X#define LEVEL_ALIAS	1
X#define LEVEL_LABEL	2
X
X	/* EXECOM.C defines */
X
X#define FL_DOLLAR	0x01  /* One of the following */
X#define FL_BANG		0x02
X#define FL_PERCENT	0x04
X#define FL_QUOTE	0x08
X#define FL_IDOLLAR	0x10  /* Any or all of the following may be set */
X#define FL_EOC		0x20
X#define FL_EOL		0x40
X#define FL_OVERIDE	0x80
X#define FL_WILD		0x100
X#define FL_MASK		(FL_DOLLAR|FL_BANG|FL_PERCENT|FL_QUOTE)
X
X#ifndef NULL
X#define NULL 0L
X#endif
X
X#define CHECKBREAK() dobreak()
X
X#ifndef AZTEC_C
Xstruct _dev {
X	long  fd;
X	short mode;
X	};
X#endif
X
Xstruct HIST {
X	struct HIST *next, *prev;	/* doubly linked list */
X	char *line;			/* line in history    */
X};
X
Xstruct PERROR {
X	int errnum;			/* Format of global error lookup */
X	char *errstr;
X};
X
Xstruct DPTR {				/* Format of directory fetch pointer */
X	BPTR lock;			/* lock on directory   */
X	FIB *fib;			/* mod'd fib for entry */
X	};
X
Xextern struct HIST *H_head, *H_tail;
Xextern struct PERROR Perror[];
Xextern struct DPTR *dopen();
Xextern char *set_var(), *get_var(), *next_word();
Xextern char *get_history(), *compile_av(), *get_pwd();
Xextern char *malloc(), *strcpy(), *strcat(), *index();
Xextern char **expand();
Xextern char *av[];
Xextern char *Current;
Xextern int  H_len, H_tail_base, H_stack;
Xextern int  E_stack;
Xextern int  Src_stack, If_stack, forward_goto;
Xextern int  ac;
Xextern int  debug, Rval, Verbose, disable, Quit;
Xextern int  Lastresult, atoierr;
Xextern int  Exec_abortline;
Xextern int   S_histlen;
Xextern unsigned int options;
Xextern long  Cin, Cout, Cout_append;
Xextern char *Cin_name, *Cout_name;
Xextern char  Cin_type,  Cout_type;  /* these variables are in transition */
Xextern char *Pipe1, *Pipe2;
X
Xextern long Src_base[MAXSRC];
Xextern long Src_pos[MAXSRC];
Xextern char If_base[MAXIF];
Xextern struct Process *Myprocess;
Xextern struct CommandLineInterface *Mycli;
X
Xextern struct ArpBase *ArpBase;
X
Xextern long atol(), Atol(), myatol();
X
Xextern char	v_titlebar[], v_prompt[], v_hist[], v_histnum[], v_debug[],
X		v_verbose[], v_stat[], v_lasterr[], v_cwd[], v_except[],
X		v_passed[], v_path[], v_gotofwd[], v_linenum[];
END_OF_FILE
if test 3029 -ne `wc -c <'src/shell.h'`; then
    echo shar: \"'src/shell.h'\" unpacked with wrong size!
fi
# end of 'src/shell.h'
fi
if test -f 'src/shellfunctions.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/shellfunctions.h'\"
else
echo shar: Extracting \"'src/shellfunctions.h'\" \(9694 characters\)
sed "s/^X//" >'src/shellfunctions.h' <<'END_OF_FILE'
Xtypedef	long	cList;
Xextern int Enable_Abort;
X
Xlong					AbleICR();
Xlong					AbortIO();
Xlong					ActivateGadget();
Xvoid					ActivateWindow();
Xvoid					AddAnimOb();
Xvoid					AddBob();
Xvoid					AddConfigDev();
Xvoid					AddDevice();
Xlong					AddDosNode();
Xvoid					AddFont();
Xvoid					AddFreeList();
Xshort					AddGadget();
Xunsigned short				AddGList();
Xvoid					AddHead();
Xstruct Interrupt *			AddICRVector();
Xvoid					AddIntServer();
Xvoid					AddLibrary();
Xlong					AddMemList();
Xvoid					AddPort();
Xvoid					AddResource();
Xvoid					AddSemaphore();
Xvoid					AddTail();
Xvoid					AddTask();
Xvoid					AddTime();
Xvoid					AddVSprite();
Xlong					Alert();
Xvoid *					AllocAbs();
Xlong					AllocBoardMem();
XcList					AllocCList();
Xstruct ConfigDev *			AllocConfigDev();
Xstruct MemList *			AllocEntry();
Xunsigned long				AllocExpansionMem();
Xvoid *					AllocMem();
Xlong					AllocPotBits();
Xvoid *					AllocRaster();
Xchar *					AllocRemember();
Xlong					AllocSignal();
Xlong					AllocTrap();
Xstruct WBObject *			AllocWBObject();
Xvoid *					Allocate();
Xvoid					AlohaWorkbench();
Xvoid					AndRectRegion();
Xlong					AndRegionRegion();
Xvoid					Animate();
Xshort					AreaDraw();
Xlong					AreaEllipse();
Xvoid					AreaEnd();
Xshort					AreaMove();
Xvoid					AskFont();
Xlong					AskSoftStyle();
Xlong					AttemptLockLayerRom();
Xlong					AttemptSemaphore();
Xshort					AutoRequest();
Xlong					AvailFonts();
Xlong					AvailMem();
Xvoid					BeginIO();
Xvoid					BeginRefresh();
Xvoid					BeginUpdate();
Xvoid					BeginLayer();
Xlong					BltBitMap();
Xlong					BltBitMapRastPort();
Xvoid					BltClear();
Xvoid					BltMaskBitMapRastPort();
Xvoid					BltPattern();
Xvoid					BltTemplate();
Xstruct Window *				BuildSysRequest();
Xchar *					BumpRevision();
Xvoid					Cause();
Xvoid					CBump();
Xstruct Events *				CDInputHandler();
Xvoid					ChangeSprite();
Xstruct IORequest *			CheckIO();
Xshort					ClearDMRequest();
Xvoid					ClearEOL();
Xvoid					ClearMenuStrip();
Xvoid					ClearPointer();
Xvoid					ClearRegion();
Xlong					ClearRectRegion();
Xvoid					ClearScreen();
Xvoid					ClipBit();
Xvoid					Close();
Xvoid					CloseDevice();
Xvoid					CloseFont();
Xvoid					CloseLibrary();
Xvoid					CloseScreen();
Xvoid					CloseWindow();
Xshort					CloseWorkBench();
Xvoid					CMove();
Xshort					CmpTime();
Xlong					ConcatCList();
Xlong					ConfigBoard();
Xlong					ConfigChain();
Xlong					ConsoleDevice();
Xlong					CopperListInit();
XcList					CopyCList();
Xvoid					CopyMem();
Xvoid					CopyMemQuick();
Xvoid					CopySBitMap();
Xstruct Layer *				CreateBehindLayer();
XBPTR		CreateDir();
Xstruct MsgPort *			CreatePort();
Xstruct Process *			CreateProc();
Xstruct IOStdReq *			CreateStdIO();
Xstruct Task *				CreateTask();
Xstruct Layer *				CreateUpfrontLayer();
XBPTR					CurrentDir();
Xvoid					CurrentTime();
Xvoid					CWait();
Xlong *					DateStamp();
Xvoid					Deallocate();
Xvoid					Debug();
Xvoid					Delay();
Xshort					DeleteFile();
Xvoid					DeleteLayer();
Xvoid					DeletePort();
Xvoid					DeleteStdIO();
Xvoid					DeleteTask();
Xstruct Process *			DeviceProc();
Xvoid					Disable();
Xvoid					DisownBlitter();
Xshort					DisplayAlert();
Xvoid					DisplayBeep();
Xvoid					DisposeRegion();
Xvoid					DoCollision();
Xlong					DoIO();
Xshort					DoubleClick();
Xvoid					Draw();
Xvoid					DrawBorder();
Xvoid					DrawEllipse();
Xvoid					DrawGList();
Xvoid					DrawImage();
XBPTR					DupLock();
Xvoid					Enable();
Xvoid					EndRefresh();
Xvoid					EndRequest();
Xvoid					EndUpdate();
Xvoid					Enqueue();
Xshort					ExNext();
Xshort					Examine();
Xshort					Execute();
Xvoid					Exit();
Xstruct ConfigDev *			FindConfigDev();
Xstruct Node *				FindName();
Xstruct MsgPort *			FindPort();
Xstruct Resident *			FindResident();
Xstruct SignalSemaphore *		FindSemaphore();
Xstruct Task *				FindTask();
Xchar *					FindToolType();
Xshort					Flood();
Xvoid					FlushCList();
Xvoid					Forbid();
Xvoid					FreeBoardMem();
Xvoid					FreeCList();
Xvoid					FreeColorMap();
Xvoid					FreeConfigDev();
Xvoid					FreeCopList();
Xvoid					FreeCprList();
Xvoid					FreeDiskObject();
Xvoid					FreeEntry();
Xvoid					FreeExpansionMem();
Xvoid					FreeFreeList();
Xvoid					FreeGBuffers();
Xvoid					FreeMem();
Xvoid					FreePotBits();
Xvoid					FreeRaster();
Xvoid					FreeRemember();
Xvoid					FreeSignal();
Xvoid					FreeSprite();
Xvoid					FreeSysRequest();
Xvoid					FreeTrap();
Xvoid					FreeVPortCopLists();
Xvoid					FreeWBObject();
Xlong					GetCC();
Xlong					GetCLBuf();
Xshort					GetCLChar();
Xshort					GetCLWord();
Xstruct ColorMap *			GetColorMap();
Xlong					GetCurrentBinding();
Xstruct Preferences *			GetDefPrefs();
Xstruct DiskObject *			GetDiskObject();
Xshort					GetGBuffers();
Xlong					GetIcon();
Xstruct Message *			GetMsg();
Xstruct Preferences *			GetPrefs();
Xshort					GetRGB4();
Xlong					GetScreenData();
Xshort					GetSprite();
Xstruct WBObject *			GetWBObject();
Xlong					IncrCLMark();
Xshort					Info();
Xvoid					InitArea();
Xvoid					InitBitMap();
Xlong					InitCLPool();
Xvoid					InitCode();
Xvoid					InitGMasks();
Xvoid					InitGels();
Xvoid					InitMasks();
Xvoid					InitRastPort();
Xvoid					InitRequester();
Xvoid					InitResident();
Xvoid					InitSemaphore();
Xvoid					InitStruct();
Xvoid					InitTmpRas();
Xvoid					InitVPort();
Xvoid					InitView();
XBPTR					Input();
Xvoid					Insert();
Xstruct Region *				InstallClipRegion();
Xlong					IntuiTextLength();
Xstruct InputEvent *			Intuition();
Xlong					IoErr();
Xshort					IsInteractive();
Xstruct MenuItem *			ItemAddress();
Xvoid					LoadRGB4();
Xstruct Segment *			LoadSeg();
Xvoid					LoadView();
XBPTR					Lock();
Xvoid					LockLayer();
Xvoid					LockLayerInfo();
Xvoid					LockLayerRom();
Xvoid					LockLayers();
Xstruct DeviceNode *			MakeDosNode();
Xlong					MakeFunctions();
Xstruct Library *			MakeLibrary();
Xvoid					MakeScreen();
Xvoid					MakeVPort();
Xlong					MarkCList();
Xlong					MatchToolValue();
Xvoid					ModifyIDCMP();
Xvoid					ModifyProp();
Xvoid					Move();
Xlong					MoveLayer();
Xvoid					MoveScreen();
Xvoid					MoveSprite();
Xvoid					MoveWindow();
Xvoid					MrgCop();
Xvoid					NewList();
Xvoid					NewModifyProp();
Xstruct Region *				NewRegion();
Xvoid					ObtainConfigBinding();
Xvoid					ObtainSemaphore();
Xvoid					ObtainSemaphoreList();
Xvoid					OffGadget();
Xvoid					OffMenu();
Xvoid					OnGadget();
Xvoid					OnMenu();
XBPTR					Open();
Xlong					OpenDevice();
Xstruct Font *				OpenDiskFont();
Xstruct Font *				OpenFont();
Xvoid					OpenIntuition();
Xstruct Library *			OpenLibrary();
Xstruct MiscResource *			OpenResource();
Xstruct Screen *				OpenScreen();
Xstruct Window *				OpenWindow();
Xshort					OpenWorkBench();
Xvoid					OrRectRegion();
Xlong					OrRegionRegion();
XBPTR					Output();
Xvoid					OwnBlitter();
XBPTR					ParentDir();
Xshort					PeekCLMark();
Xvoid					Permit();
Xvoid					PolyDraw();
Xvoid					PrintIText();
Xlong					PutCLBuf();
Xlong					PutCLChar();
Xlong					PutCLWord();
Xshort					PutDiskObject();
Xlong					PutIcon();
Xvoid					PutMsg();
Xlong					PutWBObject();
Xvoid					QBSBlit();
Xvoid					QBlit();
Xshort					RawKeyConvert();
Xlong					Read();
Xchar					ReadExpansionByte();
Xlong					ReadExpansionRom();
Xshort					ReadPixel();
Xvoid					RectFill();
Xvoid					RefreshGadgets();
Xvoid					RefreshGList();
Xvoid					RefreshWindowFrame();
Xvoid					ReleaseConfigBinding();
Xvoid					ReleaseSemaphore();
Xvoid					ReleaseSemaphoreList();
Xvoid					RemConfigDev();
Xlong					RemDevice();
Xvoid					RemFont();
Xstruct Node *				RemHead();
Xvoid					RemIBob();
Xvoid					RemICRVector();
Xvoid					RemIntServer();
Xlong					RemLibrary();
Xunsigned short				RemoveGList();
Xvoid					RemPort();
Xvoid					RemResource();
Xvoid					RemSemaphore();
Xstruct Node *				RemTail();
Xvoid					RemTask();
Xvoid					RemVSprite();
Xvoid					RemakeDisplay();
Xvoid					Remove();
Xunsigned short				RemoveGadget();
Xshort					Rename();
Xvoid					ReplyMsg();
Xvoid					ReportMouse();
Xshort					Request();
Xvoid					RethinkDisplay();
Xvoid					ScreenToBack();
Xvoid					ScreenToFront();
Xvoid					ScrollLayer();
Xvoid					ScrollRaster();
Xvoid					ScrollVPort();
Xlong					Seek();
Xvoid					SendIO();
Xvoid					SetAPen();
Xvoid					SetBPen();
Xvoid					SetCollision();
Xshort					SetComment();
Xvoid					SetCurrentBinding();
Xshort					SetDMRequest();
Xvoid					SetDRMd();
Xlong					SetExcept();
Xlong					SetFont();
Xlong					SetFunction();
Xlong					SetICR();
Xstruct Interrupt *			SetIntVector();
Xshort					SetMenuStrip();
Xvoid					SetPointer();
Xstruct Preferences *			SetPrefs();
Xshort					SetProtection();
Xvoid					SetRast();
Xvoid					SetRGB4();
Xvoid					SetRGB4CM();
Xlong					SetSR();
Xlong					SetSignal();
Xlong					SetSoftStyle();
Xshort					SetTaskPri();
Xvoid					SetWindowTitles();
Xvoid					ShowTitle();
Xvoid					Signal();
Xlong					SizeCList();
Xshort					SizeLayer();
Xvoid					SizeWindow();
Xvoid					SortGList();
XcList					SplitCList();
XcList					SubCList();
Xvoid					SubTime();
Xvoid					SubLibrary();
Xvoid					SumKickData();
Xlong					SuperState();
Xvoid					SwapBitsRastPortClipRect();
Xvoid					SyncSBitMap();
Xlong					Text();
Xlong					TextLength();
Xlong					Translate();
Xlong					UnGetCLChar();
Xlong					UnGetCLWord();
Xvoid					UnLoadSeg();
Xvoid					UnLock();
Xshort					UnPutCLChar();
Xshort					UnPutCLWord();
Xvoid					UnlockLayer();
Xvoid					UnlockLayerInfo();
Xvoid					UnlockLayerRom();
Xvoid					UnlockLayers();
Xshort					UpfrontLayer();
Xvoid					UserState();
Xshort					VBeamPos();
Xstruct View *				ViewAddress();
Xstruct ViewPort *			ViewPortAddress();
Xshort					WBenchToBack();
Xshort					WBenchToFront();
Xlong					Wait();
Xvoid					WaitBOVP();
Xvoid					WaitBlit();
Xshort					WaitForChar();
Xlong					WaitIO();
Xstruct Message *			WaitPort();
Xvoid					WaitTOF();
Xstruct Layer *				WhichLayer();
Xshort					WindowLimits();
Xvoid					WindowToBack();
Xvoid					WindowToFront();
Xlong					Write();
Xlong					WriteExpansionByte();
Xvoid					WritePixel();
Xvoid					WritePotgo();
Xvoid					XorRectRegion();
Xlong					XorRegionRegion();
END_OF_FILE
if test 9694 -ne `wc -c <'src/shellfunctions.h'`; then
    echo shar: \"'src/shellfunctions.h'\" unpacked with wrong size!
fi
# end of 'src/shellfunctions.h'
fi
if test -f 'src/sub.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/sub.c'\"
else
echo shar: Extracting \"'src/sub.c'\" \(13352 characters\)
sed "s/^X//" >'src/sub.c' <<'END_OF_FILE'
X
X/*
X * SUB.C
X *
X * (c)1986 Matthew Dillon     9 October 1986
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X *
X * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
X *
X */
X
X#define HM_STR 0              /* various HISTORY retrieval modes */
X#define HM_REL 1
X#define HM_ABS 2
X
Xseterr()
X{
Xchar buf[32];
Xint stat;
X
Xsprintf(buf, "%d", Lastresult);
Xset_var(LEVEL_SET, v_lasterr, buf);
Xstat = atoi(get_var(LEVEL_SET, v_stat));
Xif (stat < Lastresult) set_var(LEVEL_SET, v_stat, buf);
X}
X
X#define ISSPACE(c) ((c)==' ' || (c)==9 || (unsigned char)(c)==0xA0)
X
Xchar *next_word(str)
Xregister char *str;
X{
Xwhile (*str && ! ISSPACE(*str)) ++str;
Xwhile (*str &&   ISSPACE(*str)) ++str;
Xreturn str;
X}
X
Xhasspace(s)
Xregister char *s;
X{
Xfor ( ; *s; s++)
X	if (ISSPACE(*s)) return 1;
Xreturn 0;
X}
X
Xchar *compile_av(av, start, end, delim, quote)
Xchar **av;
Xunsigned char delim;
X{
Xregister char *cstr, *p;
Xint len;
Xregister unsigned int i;
X
Xlen = 1;
Xfor (i = start; i < end; ++i) len += strlen(av[i]) + 3;
Xp = cstr = malloc(len);
X*cstr = '\0';
Xfor (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';
Xreturn cstr;
X}
X
X/*
X * FREE(ptr)   --frees without actually freeing, so the data is still good
X *               immediately after the free.
X */
X
X
XFree(ptr)
Xchar *ptr;
X{
Xstatic char *old_ptr;
X
Xif (old_ptr) free (old_ptr);
Xold_ptr = ptr;
X}
X
X/*
X * Add new string to history (H_head, H_tail, H_len,
X *  S_histlen
X */
X
Xadd_history(str)
Xchar *str;
X{
X   register struct HIST *hist;
X
X   if (H_head != NULL && strcmp(H_head->line, str) == 0)
X       return(0);
X   while (H_len > S_histlen)
X      del_history();
X   hist = (struct HIST *)malloc (sizeof(struct HIST));
X   if (H_head == NULL) {
X      H_head = H_tail = hist;
X      hist->next = NULL;
X   } else {
X      hist->next = H_head;
X      H_head->prev = hist;
X      H_head = hist;
X   }
X   hist->prev = NULL;
X   hist->line = malloc (strlen(str) + 1);
X   strcpy (hist->line, str);
X   ++H_len;
X}
X
Xdel_history()
X{
X   if (H_tail) {
X      --H_len;
X      ++H_tail_base;
X      free (H_tail->line);
X      if (H_tail->prev) {
X         H_tail = H_tail->prev;
X         free (H_tail->next);
X         H_tail->next = NULL;
X      } else {
X         free (H_tail);
X         H_tail = H_head = NULL;
X      }
X   }
X}
X
Xchar *
Xget_history(ptr)
Xchar *ptr;
X{
X   register struct HIST *hist;
X   register int len;
X   int mode = HM_REL;
X   int num  = 1;
X   char *str;
X   char *result = NULL;
X
X   if (ptr[1] >= '0' && ptr[1] <= '9') {
X      mode = HM_ABS;
X      num  = atoi(&ptr[1]);
X      goto skip;
X   }
X   switch (ptr[1]) {
X   case '!':
X      break;
X   case '-':
X      num += atoi(&ptr[2]);
X      break;
X   default:
X      mode = HM_STR;
X      str  = ptr + 1;
X      break;
X   }
Xskip:
X   switch (mode) {
X   case HM_STR:
X      len = strlen(str);
X      for (hist = H_head; hist; hist = hist->next) {
X         if (strncmp(hist->line, str, len) == 0 && *hist->line != '!') {
X            result = hist->line;
X            break;
X         }
X      }
X      break;
X   case HM_REL:
X      for (hist = H_head; hist && num--; hist = hist->next);
X      if (hist)
X         result = hist->line;
X      break;
X   case HM_ABS:
X      len = H_tail_base;
X      for (hist = H_tail; hist && len != num; hist = hist->prev, ++len);
X      if (hist)
X         result = hist->line;
X      break;
X   }
X   if (result) {
X      fprintf(stderr,"%s\n",result);
X      return(result);
X   }
X   printf("History failed\n");
X   return ("");
X}
X
Xreplace_head(str)
Xchar *str;
X{
X   if (str == NULL)
X      str = "";
X   if (H_head) {
X      free (H_head->line);
X      H_head->line = malloc (strlen(str)+1);
X      strcpy (H_head->line, str);
X   }
X}
X
X
XpError(str)
Xchar *str;
X{
Xint ierr = (long)IoErr();
Xierror(str, ierr);
X}
X
Xierror(str, err)
Xregister char *str;
X{
X   register struct PERROR *per = Perror;
X
X   if (err) {
X      for (; per->errstr; ++per) {
X         if (per->errnum == err) {
X            fprintf (stderr, "%s%s%s\n",
X                  per->errstr,
X                  (str) ? ": " : "",
X                  (str) ? str : "");
X            return ((short)err);
X         }
X      }
X      fprintf (stderr, "Unknown DOS error %d %s\n", err, (str) ? str : "");
X   }
X   return ((short)err);
X}
X
X/*
X * Disk directory routines
X *
X * dptr = dopen(name, stat)
X *    struct DPTR *dptr;
X *    char *name;
X *    int *stat;
X *
X * dnext(dptr, name, stat)
X *    struct DPTR *dptr;
X *    char **name;
X *    int  *stat;
X *
X * dclose(dptr)                  -may be called with NULL without harm
X *
X * dopen() returns a struct DPTR, or NULL if the given file does not
X * exist.  stat will be set to 1 if the file is a directory.  If the
X * name is "", then the current directory is openned.
X *
X * dnext() returns 1 until there are no more entries.  The **name and
X * *stat are set.  *stat = 1 if the file is a directory.
X *
X * dclose() closes a directory channel.
X *
X */
X
Xstruct DPTR *
Xdopen(name, stat)
Xchar *name;
Xint *stat;
X{
Xstruct DPTR *dp;
X
X*stat = 0;
Xdp = (struct DPTR *)malloc(sizeof(struct DPTR));
Xif (*name == '\0')
X	dp->lock = DupLock(Myprocess->pr_CurrentDir);
Xelse
X	dp->lock = Lock (name,ACCESS_READ);
Xif (dp->lock == NULL) {
X	free (dp);
X	return NULL;
X	}
Xdp->fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
Xif (!Examine (dp->lock, dp->fib)) {
X	pError (name);
X	dclose (dp);
X	return NULL;
X	}
Xif (dp->fib->fib_DirEntryType >= 0) *stat = 1;
Xreturn dp;
X}
X
Xdnext(dp, pname, stat)
Xstruct DPTR *dp;
Xchar **pname;
Xint *stat;
X{
Xif (dp == NULL) return (0);
X   if (ExNext (dp->lock, dp->fib)) {
X      *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
X      *pname = dp->fib->fib_FileName;
X      return (1);
X   }
X   return (0);
X}
X
X
Xdclose(dp)
Xstruct DPTR *dp;
X{
X   if (dp == NULL)
X      return (1);
X   if (dp->fib)
X      FreeMem (dp->fib,(long)sizeof(*dp->fib));
X   if (dp->lock)
X      UnLock (dp->lock);
X   free (dp);
X   return (1);
X}
X
X
Xisdir(file)
Xchar *file;
X{
X   register struct DPTR *dp;
X   int stat;
X
X   stat = 0;
X   if (dp = dopen (file, &stat))
X      dclose(dp);
X   return (stat == 1);
X}
X
X
Xfree_expand(av)
Xregister char **av;
X{
X   char **base = av;
X
X   if (av) {
X      while (*av) {
X         free (*av);
X         ++av;
X      }
X      free (base);
X   }
X}
X
X/*
X * EXPAND(base,pac)
X *    base           - char * (example: "df0:*.c")
X *    pac            - int  *  will be set to # of arguments.
X *
X * 22-May-87 SJD.  Heavily modified to allow recursive wild carding and
X *                 simple directory/file lookups. Returns a pointer to
X *                 an array of pointers that contains the full file spec
X *                 eg. 'df0:c/sear*' would result in : 'df0:C/Search'
X *
X *                 Now no longer necessary to Examine the files a second time
X *                 in do_dir since expand will return the full file info
X *                 appended to the file name. Set by formatfile().
X *                 eg. fullfilename'\0'rwed  NNNNNN NNNN  DD-MMM-YY HH:MM:SS
X *
X *                 Caller must call free_expand when done with the array.
X *
X * base             bname =       ename =
X * ------           -------       -------
X *  "*"               ""            "*"
X *  "!*.info"         ""            "*.info" (wild_exclude set)
X *  "su*d/*"          ""            "*"      (tail set)
X *  "file.*"          ""            "file.*"
X *  "df0:c/*"         "df0:c"       "*"
X *  ""                ""            "*"
X *  "df0:.../*"       "df0:"        "*"      (recur set)
X *  "df0:sub/.../*"   "df0:sub"     "*"      (recur set)
X *
X * ---the above base would be provided by execom.c or do_dir().
X * ---the below base would only be called from do_dir().
X *
X *  "file.c"          "file.c"      ""       if (dp == 0) fail else get file.c
X *  "df0:"            "df0:"        "*"
X *  "file/file"       "file/file"   ""       (dp == 0) so fail
X *  "df0:.../"        "df0:"        "*"      (recur set)
X *
X */
X
X
Xchar **
Xexpand(base, pac)
Xchar *base;
Xint *pac;
X{
X   register char *ptr;
X   char **eav = (char **)malloc(sizeof(char *) * (2));
X   short eleft, eac;
X   char *name;
X   char *svfile();
X   char *bname, *ename, *tail;
X   int stat, recur, scr, bl;
X   register struct DPTR *dp;
X
X   *pac = recur = eleft = eac = 0;
X
X   base = strcpy(malloc(strlen(base)+1), base);
X   for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
X
X   if (!*ptr)   /* no wild cards */
X      --ptr;
X   else
X      for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
X
X   if (ptr < base) {
X      bname = strcpy (malloc(1), "");
X   } else {
X      scr = ptr[1];
X      ptr[1] = '\0';
X      if (!strcmp(ptr-3,".../")) {
X         recur = 1;
X         *(ptr-3) = '\0';
X      }
X      bname = strcpy (malloc(strlen(base)+2), base);
X      ptr[1] = scr;
X   }
X   bl = strlen(bname);
X   ename = ++ptr;
X   for (; *ptr && *ptr != '/'; ++ptr);
X   scr = *ptr;
X   *ptr = '\0';
X   if (scr) ++ptr;
X   tail = ptr;
X
X   if ((dp = dopen (bname, &stat)) == NULL || (stat == 0 && *ename)) {
X      free (bname);
X      free (base);
X      free (eav);
X      return (NULL);
X   }
X
X   if (!stat) {                /* eg. 'dir file' */
X      char *p,*s;
X      for(s = p = bname; *p; ++p) if (*p == '/' || *p == ':') s = p;
X      if (s != bname) ++s;
X      *s ='\0';
X      eav[eac++] = svfile(bname,dp->fib->fib_FileName,dp->fib);
X      goto done;
X   }
X   if (!*ename) ename = "*";    /* eg. dir df0: */
X   if (*bname && bname[bl-1] != ':' && bname[bl-1] != '/') { /* dir df0:c */
X      bname[bl] = '/';
X      bname[++bl] = '\0';
X   }
X   while ((dnext (dp, &name, &stat)) && !breakcheck()) {
X        int match = compare_ok(ename,name,0);
X      if (match && !(!recur && *tail)) {
X         if (eleft < 2) {
X               char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
X               movmem (eav, scrav, (eac + 1) << 2);
X               free (eav);
X               eav = scrav;
X               eleft = 10;
X         }
X         eav[eac++] = svfile(bname,name,dp->fib);
X         --eleft;
X      }
X      if ((*tail && match) || recur) {
X         int alt_ac;
X         char *search, **alt_av, **scrav;
X         BPTR lock;
X
X         if (!stat)           /* expect more dirs, but this not a dir */
X            continue;
X         lock = CurrentDir (dp->lock);
X         search = malloc(strlen(ename)+strlen(name)+strlen(tail)+5);
X         strcpy (search, name);
X         strcat (search, "/");
X         if (recur) {
X            strcat(search, ".../");
X            strcat(search, ename);
X         }
X         strcat (search, tail);
X         scrav = alt_av = expand (search, &alt_ac);
X         /* free(search); */
X         CurrentDir (lock);
X         if (scrav) {
X            while (*scrav) {
X               int l;
X               if (eleft < 2) {
X                  char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
X                  movmem (eav, scrav, (eac + 1) << 2);
X                  free (eav);
X                  eav = scrav;
X                  eleft = 10;
X               }
X
X               l = strlen(*scrav);
X               scrav[0][l] = ' ';
X               eav[eac] = malloc(bl+l+45);
X               strcpy(eav[eac], bname);
X               strcat(eav[eac], *scrav);
X               eav[eac][l+bl] = '\0';
X
X               free (*scrav);
X               ++scrav;
X               --eleft, ++eac;
X            }
X            free (alt_av);
X         }
X      }
X   }
Xdone:
X   dclose (dp);
X   *pac = eac;
X   eav[eac] = NULL;
X   free (bname);
X   free (base);
X   if (eac) {
X      return (eav);
X   }
X   free (eav);
X   return (NULL);
X}
X
Xchar *strupr(s)
Xregister char *s;
X{
Xwhile (*s) *s=toupper(*s), s++;
Xreturn s;
X}
X
Xchar *strlwr(s)
Xregister char *s;
X{
Xwhile (*s) *s=tolower(*s), s++;
Xreturn s;
X}
X
X/*
X * Compare a wild card name with a normal name
X */
X
Xcompare_ok(wild, name, casedep)
Xchar *wild, *name;
X{
Xint queryflag;
Xchar buf[260], wildbuf[260], *lowname;
X
Xif (queryflag=(*wild=='&')) wild++;
Xif (*wild=='!') *wild='~';
X
Xif (! casedep) {
X	strupr(wild);
X	strcpy(buf,name);
X	strupr(buf);
X	lowname=buf;
X	}
Xelse lowname=name;
X
XPreParse(wild, wildbuf);
Xif ( ! PatternMatch(wildbuf,lowname)) return 0;
X
Xif (queryflag) {
X	printf("Select \23337m%-16s\2330m [y/n] ? ",name);
X	gets(buf);
X	return (toupper(*buf)=='Y');
X	}
Xreturn 1;
X}
X
Xchar *svfile(s1,s2,fib)
Xchar *s1,*s2;
XFIB *fib;
X{
Xchar *p = malloc (strlen(s1)+strlen(s2)+45);
Xstrcpy(p, s1);
Xstrcat(p, s2);
Xformatfile(p,fib);
Xreturn p;
X}
X
X/* will have either of these formats:
X *
X *    fullfilename'\0'hsparwed   <Dir>       DD-MMM-YY HH:MM:SS\n'\0'
X *    fullfilename'\0'hsparwed  NNNNNN NNNN  DD-MMM-YY HH:MM:SS\n'\0'
X *                              1111111111222222222233333333334 4  4
X *                    01234567890123456789012345678901234567890 1  2
X */
Xformatfile(str,fib)
Xchar *str;
XFIB *fib;
X{
Xchar *dates();
Xint i;
Xwhile(*str++);
Xfor (i=7; i>=0; i--)
X    *str++ = ((fib->fib_Protection & (1L<<i)) ? "hspa----" : "----rwed")[7-i];
Xif (fib->fib_DirEntryType < 0)
X  sprintf(str,"  %6ld %4ld  ", (long)fib->fib_Size, (long)fib->fib_NumBlocks);
Xelse strcpy(str,"   <Dir>       ");
Xstrcat(str,dates(&fib->fib_Date));
X}
X
X/* Sort routines */
X
Xlong cmp(s1, s2)
Xchar **s1, **s2;
X{
Xreturn (long)Strcmp(*s1, *s2);
X}
X
XCmp() {
X#asm
X	public	_geta4
X	movem.l	d2-d3/a4/a6,-(sp)
X	movem.l	a0/a1,-(sp)
X	bsr	_geta4
X	bsr	_cmp
X	addq.l	#8,sp
X	movem.l	(sp)+,d2-d3/a4/a6
X#endasm
X}
X
XQuickSort(av, n)
Xchar *av[];
Xint n;
X{
XQSort(av, (long)n, 4L, Cmp);
X}
END_OF_FILE
if test 13352 -ne `wc -c <'src/sub.c'`; then
    echo shar: \"'src/sub.c'\" unpacked with wrong size!
fi
# end of 'src/sub.c'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 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.