		INSTRUCTIONS FOR SHELL V2.05M    20-Jan-87
		-----------------------------

SHELL V2.04. (C)Copyright 1986, Matthew Dillon, All Rights Reserved.
You may distribute this program for non-profit only.

		Shell V2.05M by Steve Drew.
		--------------------------
--------------------------------------------------------------------------
Note:
    These Instructions are my specific 2.05M Instructions and Matt's 2.04
    merged together. 
    A preceding | indicates that funtionality has been changed/enhanced,
    a preceding * indicates that this is functionality or a command
    that has been added in my manx version.

    for version releases see readme file. 
---------------------------------------------------------------------------

      (A)   Compiling
      (B)   Overview
      (C)   Quicky tech notes on implimentation.
 
      (D)   Command pre-processor
      (E)   Command Line Editing
      (F)   Function Keys
      (G)   Command-list
      (H)   special SET variables
 
      (I)   example .login file.
 

 
(A) COMPILING:
 
|   makefile supplied.
|
|   Your manx should be patched for 1.2 (c.lib) otherwise fexec wont work
|   and you'll just get "command not found" for all external commands.


(B) OVERVIEW:
 
   OVERVIEW of the major features:
 
   -simple history
   -redirection
   -piping
   -command search path 
   -aliases
   -variables & variable handling (embedded variables)
   -file name expansion via '?' and '*'
   -conditional
do_echo comm1.c /^do_echo(
do_source comm1.c /^do_source(
do_cd comm1.c /^do_cd(
attempt_cd comm1.c /^attempt_cd(
rmlast comm1.c /^rmlast(
do_mkdir comm1.c /^do_mkdir(
do_mv comm1.c /^do_mv(
rm_file comm1.c /^rm_file(
do_rm comm1.c /^do_rm(
rmdir comm1.c /^rmdir(
do_history comm1.c /^do_history(
do_mem comm1.c /^do_mem(
do_foreach comm1.c /^do_foreach(
do_forever comm1.c /^do_forever(
do_copy comm1.c /^do_copy(
copydir comm1.c /^copydir(
copyfile comm1.c /^copyfile(
do_run run.c /^do_run(
FindIt run.c /^FindIt(
exec_command execom.c /^exec_command(
isalphanum execom.c /^isalphanum(
preformat execom.c /^preformat(
fcomm execom.c /^fcomm(
exarg execom.c /^exarg(
mpush_base execom.c /^mpush_base(
mpush execom.c /^mpush(
mpop_tobase execom.c /^mpop_tobase(
format_insert_string execom.c /^format_insert_string(
find_command execom.c /^find_command(
do_help execom.c /^do_help(
initconsole rawconsole.c /^initconsole(
->ne       = last;
         if (base == Mbase[level])
            Mbase[level] = base->next;
         Free (base->name);
         Free (base->text);
         Free (base);
         return (1);
      }
      last = base;
      base = base->next;
   }
   return (-1);
}


do_unset_var(str, level)
char *str;
{
   register int i;

   for (i = 1; i < ac; ++i)
      unset_var (level, av[i]);
   return (0);
}

do_set_var(command, level)
char *command;
{
   register struct MASTER *base = Mbase[level];
   register char *str;

   if (ac == 1) {
      while (base) {
	 if (CHECKBREAK())
	     return(0);
         printf ("%-10s ", base->name);
         puts (base->text);
         base = base->next;
      }
      return (0);
   }
   if (ac == 2) {
      str = get_var (level, av[1]);
      if (str) {
         printf ("%-10s ", av[1]);
         puts(str);
      } else if (level == LEVEL_SET) { /* only create var if set command */
         set_var (level, av[1], "");
      }
   }
   if (ac > 2)
      set_var (level, av[1], next_word (next_word (command)));
   if (*av[1] == '_') {
      S_histlen = (str = get_var(LEVEL_SET, V_HIST))   ? atoi(str) : 0;
      debug     = (str = get_var(LEVEL_SET, V_DEBUG))  ? atoi(str) : 0;
      Verbose   = (get_var(LEVEL_SET, V_VERBOSE)) ? 1 : 0;
      if (S_histlen < 2)   S_histlen = 2;
   }
   return (0);
}
[     k - 1], pos, 0);
         Src_pos[Src_stack - 1] = pos;
         new = atoi(next_word(lab));
         for (; If_stack < new; ++If_stack)
            If_base[If_cksum + bufr[j]) & 0xff;
			}
		    if (checksum == readchar() && timeout == GOODREAD)
			{
			errors = 0;
			sectnum++;
			bufptr += SECSIZ;
			bytes_xferred += SECSIZ;
			emits("verified\n");
			if (bufptr == BufSize)
			    {
			    if (write(fd, bufr, BufSize-128) == EOF)
				{
				emits("\nError Writing File\n");
				return FALSE;
				}
			    bufptr = 128;
			    for (j = 0; j < 128; j++)
				bufr[j] = bufr[(BufSize-128)+j];
			    }
			sendchar(ACK);
			}
		    else
			{
			errorflag = TRUE;
			if (timeout == USERABORT) return FALSE;
			}
		    }
		else
		    {
		    /* got a duplicate sector */	
		    if (sectcurr == (sectnum & 0xff))
			{
			/* wait until we time out for 5secs */
			do {
			    readchar();
			    } while (timeout == GOODREAD);
			if (timeout == USERABORT) return FALSE;
			emits("\nReceived Duplicate Sector\n");
			sendchar(ACK);
			}
		    else errorflag = TRUE;
    		    }
		}
	    else errorflag = TRUE;
	    }
	if (errorflag == TRUE)
	    {
	    errors++;
	    emits("\nError\n");
	    sendchar(NAK);
	    }
	}        /* end while */
    if ((firstchar == EOT) && (errors < ERRORMAX))
	{
	sendchar(ACK);
	while (bufptr > 0 && (bufr[--bufptr] == 0x00 ||
			      bufr[bufptr]   == 0x1A)) ;
	write(fd, bufr, ++bufptr);
	close(fd);
	return TRUE;
	}
    return FALSE;
    }

int XMODEM_Send_File(file)
char *file;
    {
    int sectnum, bytes_to_send, size, attempts, c;
    unsigned checksum, j, bufptr;
    char numb[10];
    bytes_xferred = 0;
    ttime = TTIME_LONG;
    want_message = TRUE; /* tell readchar to print any error msgs */

    if ((fd = open(file, 0)) < 0) {
	emits("Cannot Open Send File\n");
	return FALSE;
	}
    else
    emits("Sending File\n\nType <ESC> to abort transfer\n");
    attempts = 0;
    sectnum = 1;
    /* wait for sync char */
    j=1;
    while (((c = readchar()) != NAK) && (j++ < ERRORMAX))
	if (timeout == USERABORT) return(FALSE);
    if (j >= (ERRORMAX))
	{
	emits("\nReceiver not sending NAKs\n");
	return FALSE;
	}

    while ((bytes_to_send = read(fd, bufr, BufSize)) && attempts != RETRYMAX)
	{
	if (bytes_to_send == EOF)
	    {
	    emits("\nError Reading File\n");
	    return FALSE;
	    }

	bufptr = 0;
	while (bytes_to_send > 0 && attempts != RETRYMAX)
	    {
	    attempts = 0;
	    emits("Block ");
	    sprintf(numb, "%d ", sectnum);
	    emits(numb);
	    do {
		emits(".");    
		sendchar(SOH);
		sendchar(sectnum);
		sendchar(~sectnum);
		checksum = 0;
		size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send;
		bytes_to_send -= size;
		for (j = bufptr; j < (bufptr + SECSIZ); j++)
		if (j < (bufptr + size)) {
		    sendchar(bufr[j]);
		    checksum += bufr[j];
		    }
		else sendchar(0);
		sendchar(checksum);
		attempts++;
		c = readchar();
		if (timeout == USERABORT) {emits("\n"); return FALSE;}
		} while ((c != ACK) && (attempts != RETRYMAX));
	    bufptr += size;
	    bytes_xferred += size;
	         `          5mnf`fn`       `     
 o`fogc	am`fff`cf`fo t laf`l`fgf` c`ulaf`fl`gcccc`telc`c````(                       =         f
       ff ff`     i g	fgf``Rfffafc gofMAffffc 	f`````mmffdggc f``llff`  falc                        #e        `        !ra`   `      `         paacc        ")၀fc fffff`        ;
afcg`        oaac `f fa       1u``fac       1u                         ,y cc a `  %s afffc`a   )) agfag	a`s aǇ` aa`ffue ` `	a`gyP ff`afes cc灀ct)                           )                   3e `     `               (T g              /_ fcff c               P fcfc                $  gf``f             $e g             .i                          2_        `          =        `   `         )m gc         D fff`cff`         %. fff`g`         2_ fff`cfa        ** c`c        **                           /
                            i                           !y                           $e                                                        **                           **                            I                           )n     	nwqwp  Áwwp  0;wwp   wwp,e   wpnpw   pwwp =wqwp  Áps 1sp   = 135;
                                                          |                           )l                                                        )                           .S                           -[                           .]                           n                           8t                           4[                           .]                           $e                                                                                     i                                                        ;
                           4I                           %x                           
F                           "A                           e                           i                           m                           e                           
F                           "K                           4                            
F                           "K                           8t                           
/                           **                           **                           5n                           5r                           /                            0i                           **                           **                           */                           

                            a                           2(                            R                           .+                           0;                            n                                                        	t                           E                                                        >(                           )l                           4e<I?>>8<~?8[~?>>8x8n8?>>88x<n?>>8x?B?>>8<~??M?>8<<<?fore an                         .L                    0E`   f`                   /nnfg                    %x`ffc                   1]macf`                   "alaff`                   bl`c                   "r                          2e                            %ak;
    d                           ;
                           E                            C                           ,i                           %m                                                       =                            .                           S                            4800";
     P].IText = (UBYTE *)"   9600";
}

/*****************************************************************/
/*    The following function initializes the structure arrays    */
/*    needed to provide the Transfer Mode menu topic.            */
/*****************************************************************/
void InitXFItems()
{
int n;

/* initialize each menu item and IntuiText with loop */
for( n=0; n<XFMAX; n++ )
   {
   XFItem[n].NextItem = &XFItem[n+1];
   XFItem[n].LeftEdge = 0;
   XFItem[n].TopEdge = 11 * n;
   XFItem[n].Width = 85;
   XFItem[n].Height = 11;
   XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT;
   XFItem[n].MutualExclude = (~(1 << n));
   XFItem[n].ItemFill = (APTR)&XFText[n];
   XFItem[n].SelectFill = NULL;
   XFItem[n].Command = 0;
   XFItem[n].SubItem = NULL;
   XFItem[n].NextSelect = 0;

   XFText[n].FrontPen = 0;
   XFText[n].BackPen = 1;
   XFText[n].DrawMode = JAM2;     /* render in fore and background */
   XFText[n].LeftEdge = 0;
   XFText[n].TopEdge = 1;
   XFText[n].ITextFont = NULL;
   XFText[n].NextText = NULL;
   }
XFItem[XFMAX-1].NextItem = NULL;
/* mode checked */
XFItem[p_mode].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT | CHECKED;

/* initialize text for specific menu items */
XFText[0].IText = (UBYTE *)"  image";
XFText[1].IText = (UBYTE *)"  CR LF";
}


/*****************************************************************/
/*    The following function initializes the structure arrays    */
/*   needed to provide the Script menu topic.                    */
/*****************************************************************/
void InitScriptItems()
{
int n;

/* initialize each menu item and IntuiText with loop */
for( n=0; n<SCRIPTMAX; n++ )
   {
   ScriptItem[n].NextItem = &ScriptItem[n+1];
   ScriptItem[n].LeftEdge = 0;
   ScriptItem[n].TopEdge = 11 * n;
   ScriptItem[n].Width = 155;
   ScriptItem[n].Height = 11;
   ScriptItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX;
   ScriptItem[n].MutualExclude = 0;
   ScriptItem[n].ItemFill = (APTR)&ScriptText[n];
   ScriptItem[n].SelectFill = NULL;
   ScriptItem[n].Command = 0;
   ScriptItem[n].SubItem = NULL;
   ScriptItem[n].NextSelect = 0;

   ScriptText[n].FrontPen = 0;
   ScriptText[n].BackPen = 1;
   ScriptText[n].DrawMode = JAM2;     /* render in fore and background */
   ScriptText[n].LeftEdge = 0;
   ScriptText[n].TopEdge = 1;
   ScriptText[n].ITextFont = NULL;
   ScriptText[n].NextText = NULL;
   }
ScriptItem[SCRIPTMAX-1].NextItem = NULL;

/* initialize text for specific menu items */
ScriptText[0].IText = (UBYTE *)"Execute file";
ScriptText[1].IText = (UBYTE *)"Abort Execution";
}

/**********************************************************************/
/*   The following function initializes the Menu structure array with */
/*  appropriate values for our simple menu strip.  Review the manual  */
/*  if you need to know what each value means.                        */
/**********************************************************************/
void InitMenu()
{
menu[0].NextMenu = &menu[1];
menu[0].LeftEdge = 5;
menu[0].TopEdge = 0;
menu[0].Width = 50;
menu[0].Height = 10;
menu[0].Flags = MENUENABLED;
menu[0].MenuName = "File";           /* text for menu-bar display */
menu[0].FirstItem = &FileItem[0];    /* pointer to first item in list */

menu[1].NextMenu = &menu[2];
menu[1].LeftEdge = 65;
menu[1].TopEdge = 0;
menu[1].Width = 85;
menu[1].Height = 10;
menu[1].Flags = MENUENABLED;
menu[1].MenuName = "BaudRate";        /* text for menu-bar display */
menu[1].FirstItem = &RSItem[0];    /* pointer to first item in list */

menu[2].NextMenu = &menu[3];
menu[2].LeftEdge = 160;
menu[2].TopEdge = 0;
menu[2].Width = 85;
menu[2].Height = 10;
menu[2].Flags = MENUENABLED;
menu[2].MenuName = "Xfer Mode";        /* text for menu-bar display */
menu[2].FirstItem = &XFItem[0];    /* pointer to first item in list */

menu[3].NextMenu = NULL;
menu[3].LeftEdge = 255;
menu[3].TopEdge = 0;
menu[3].Width = 85;
menu[3].Height = 10;
menu[3].Flags = MENUENABLED;
menu[3].MenuName = "Script";        /* text for menu-bar display */
menu[3].FirstItem = &ScriptItem[0];    /* pointer to first item in list */
}

     ze = 0; (msgpkt[size] = leftover[size]) != '\0'; size++) ;
   *leftover = '\0';
   rpt = 0;
   eof = 0;
   while (!eof) {
      next = getc(fp);
      if (next == EOF) {
         first = -1;
         eof   =  1;
         }
      else totbytes++;
      osize = size;
      encode(t);
      t = next;
      if (size == spsiz-3) return(size);
      if (size > spsiz-3) {
         for (i = 0; (leftover[i] = msgpkt[osize+i]) != '\0'; i++) ;
         size = osize;
         msgpkt[size] = '\0';
         return(size);
         }
      }
   return(size);
   }

void encode(a)
char a;
   {
   int a7,b8;

   if (p_mode == 1 && a == '\n') {
      rpt = 0;
      msgpkt[size++] = quote;
      msgpkt[size++] = ctl('\r');
      if (size <= spsiz-3) osize = size;
      msgpkt[size++] = quote;
      msgpkt[size++] = ctl('\n');
      msgpkt[size]   = '\0';
      return;
      }
   if (rptflg) {
      if (a == next && (first == 0)) {
         if (++rpt < 94) return;
         else if (rpt == 94) {
            msgpkt[size++] = rptq;
            msgpkt[size++] = tochar(rpt);
            rpt = 0;
            }
         }
      else if (rpt == 1) {
         rpt = 0;
         encode(a);
         if (size <= spsiz-3) osize = size; 
         rpt = 0;
         encode(a);
         return;
         }
      else if (rpt > 1) {
         msgpkt[size++] = rptq;
         msgpkt[size++] = tochar(++rpt);
         rpt = 0;
         }
      }
   a7 = a & 0177;
   b8 = a & 0200;
   if ((a7 < SP) || (a7==DEL)) {
      msgpkt[size++] = quote;
      a = ctl(a);
      }
   if (a7 == quote) msgpkt[size++] = quote;
   if ((rptflg) && (a7 == rptq)) msgpkt[size++] = quote;
   msgpkt[size++] = a;
   msgpkt[size] = '\0';
   }

void decode()
   {
   USHORT  a, a7;
   char *buf;

   buf = msgpkt;
   rpt = 0;
   
   while ((a = *buf++) != '\0') {
      if (rptflg) {
         if (a == rptq) {
            rpt = unchar(*buf++);
            a = *buf++;
            }
         }
      if (a == quote) {
         a  = *buf++;
         a7 = a & 0177;
         if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') a = ctl(a);
         }
      if (rpt == 0) rpt = 1;
      if (p_mode == 1 && a == '\r') continue;
      totbytes += rpt;
      for (; rpt > 0; rpt--) putc(a, fp);
      }
   return;
   }

void spar(data)
char data[];
   {
   data[0] = tochar(MAXPACKSIZ);
   data[1] = tochar(TTIME_LONG);
   data[2] = tochar(MYPAD);
   data[3] = ctl(MYPCHAR);
   data[4] = tochar(MYEOL);
   data[5] = MYQUOTE;
   data[6] = 'N';
   data[7] = '1';
   data[8] = MYRPTQ;
   data[9] = '\0';
   }

void rpar(data)
char data[];
   {
   spsiz   = unchar(data[0]);
   timint  = unchar(data[1]);
   pad     = unchar(data[2]);
   padchar = ctl(data[3]);
   eol     = unchar(data[4]);
   quote   = data[5];
   rptflg  = 0;
   if (data[6] == 0) return;
   if (data[7] == 0) return;
   if (data[8] == 0) return;
   rptq    = data[8];
   rptflg  = ((rptq > 040 && rptq < 0100) || (rptq > 0140 && rptq < 0177));
   }

saybye()
  {
  int len,num;
  shutdown = 0;
  spack('G',n,1,"F");  /* shut down server no more files */
  rpack(&len,&num,ackpkt);
  }

statusline()
  {
  emits ("\nFile:                 Pckt:   Pckt No:      Retrn:    Bytes:         Stat:      ");
  x = 48;
  curmode = 1;
  emits (filnam);
  return(0);
  }

dostats(type)
char type;
  {
   if (type != 'Y' && type != 'N' && type != 'G') {
      x = 224;
      emit(type);
      x = 312;
      sprintf(snum,"%4d",n+(tp * 64));
      emits(snum);
      if (n==63) tp++;
      x = 408;
      sprintf(snum,"%2d",retry-1);
      emits(snum);
      x = 488;
      sprintf(snum,"%6ld",(long)totbytes);
      emits(snum);
      }
  }

/* allow for multi file xfers separated by commas under kermit and XMODEM */

multi_xfer(name,mode,do_send)
char *name;
int (*mode)();
int do_send;
    {
    int done = 0;
    int status;
    char *p;
    
    p = name;  
    while(*p && *p != ',')   p++;
    if (*p == '\0') { 
         done = TRUE; 
         if (multi == 1) multi++;
         }
     else multi = 1;
    *p = '\0';
    status = ((*mode)(name, multi));
    if (status == TRUE) {
        if (do_send) emits("Sent File: ");
          else emits("Received File: ");
    	emits(name);
    	emits("\n");
    	emit(8);
        }
    else if (status == FALSE)
        {
        close(fd);
        if (do_send) emits("Send Failed: ");
          else emits("Receive Failed: ");
        emits(name);
        emits("\n");	
        emit(8);
        }    
    if (!done) multi_xfer(++p, mode, do_send);
    server = 0;
    multi = 0;
    }

/* gobble up all garb that we received while getting file name strings */

eatup()
   {
  while(CheckIO(Read_Request))  {
     	WaitIO(Read_Request);
     	BeginIO(Read_Request);
        }
   }   

 */
      LL             /* nextselect */
};

struct Menu MyMenu = {
   NULL,          /* pointer to next menu */
   0,0,150,0,     /* left,0,Width,0 */
   MENUENABLED,   /* flags */
   "SpeachToy Menu",   /* menu name */
   &MyMenuItem    /* First Item in list */
};

struct IntuiText ReqText1 = {
   BLUP,         /* Front Pen */
   WHTP,         /* Back pen */
   JAM2,         /* Draw Mode */
   5,            /* Left Edge */
   23,           /* Top */
   &TestFont,    /* pointer to TextFont */
   "Version 1.1  21 Dec, 1985",  /* text */
   NULL          /* next */
};
struct IntuiText ReqText2 = {
   BLUP,         /* Front Pen */
   WHTP,         /* Back pen */
   JAM2,         /* Draw Mode */
   5,            /* Left Edge */
   13,           /* Top */
   &TestFont,    /* pointer to TextFont */
   "Freeware - Public Domain ", /* text */
   &ReqText1     /* next */
};
struct IntuiText ReqText3 = {
   BLUP,         /* Front Pen */
   WHTP,         /* Back pen */
   JAM2,         /* Draw Mode */
   5,            /* Left Edge */
   3,            /* Top */
   &TestFont,    /* pointer to TextFont */
   "Written by David M Lucas ", /* text */
   &ReqText2     /* next */
};

struct IntuiText OKIText = {
   BLUP, WHTP, /* FrontPen, BackPen */
   JAM2,       /* Dra