[comp.sources.amiga] v02i041: Shell 2.07M

drew@decwrl.dec.com (10/08/87)

#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	comm1.c
#	comm2.c
#	rawconsole.c
# This archive created: Fri Oct  2 09:10:22 1987
echo shar: extracting comm1.c
cat << \SHAR_EOF > comm1.c
/*
 * COMM1.C
 *
 * Matthew Dillon, August 1986
 *
 * Version 2.07M by Steve Drew 10-Sep-87
 *
 */

#include "shell.h"
typedef struct FileInfoBlock FIB;

#define DIR_SHORT 0x01
#define DIR_FILES 0x02
#define DIR_DIRS  0x04

extern int has_wild;
char cwd[256];

/*
    Parse the options specified in sw[]
    Setting a bit for each one found
*/
get_opt(sw,count)
char *sw;
int *count;
{
   int l,i = 0, opt = 0;
   char *c,*s;

   while((++i < ac) && (av[i][0] == '-')) {
	for (c = av[i]+1; *c ; c++) {
	    for(l = 0,s = sw;*s && *s != *c; ++s) ++l;
	    if (*s) opt |= (1 << l);
	}
   }
   *count = i;
   return(opt);
}

do_sleep()
{
   register int i;

   if (ac == 2) {
      i = atoi(av[1]);
      while (i > 0) {
	 Delay ((long)100);
	 i -= 2;
	 if (CHECKBREAK())
	    break;
      }
   }
   return (0);
}


do_number()
{
   return (0);
}

do_cat()
{
   FILE *fopen(), *fi;
   int i;
   char buf[256];

   if (ac == 1) {
      while (gets(buf)) {
	 if (CHECKBREAK()) break;
	 puts(buf);
	 }
      clearerr(stdin);
      return (0);
   }

   for (i = 1; i < ac; ++i) {
      if ((fi = fopen (av[i], "r")) != 0) {
	   while (fgets(buf,256,fi)) {
	    fputs(buf,stdout);
	    fflush(stdout);
	    if (CHECKBREAK()) {
	       breakreset();
	       break;
	    }
	 }
	 fclose (fi);
      } else {
	 ierror(av[i], 205);
      }
   }
   return (0);
}

do_devinfo()
{
   struct DPTR		*dp;
   struct InfoData	*info;
   int stat,i;
   char *p,*s,*get_pwd(),*index();

   if (ac == 1) {
      ++ac;
      av[1] = "";
   }
   for (i=1; i < ac; ++i) {
      if (!(dp = dopen (av[i], &stat)))
	 continue;
      info = (struct InfoData *)AllocMem((long)sizeof(struct InfoData), MEMF_PUBLIC);
      if (Info (dp->lock, info)) {

	 s = get_pwd(dp->lock);
	 p = index(s,':');
	 *p = '\0';

	 printf ("Unit:%2ld  Errs:%3ld  Used: %-5ld %3ld%%  Free: %-5ld  Volume: %s\n",
	     info->id_UnitNumber,
	     info->id_NumSoftErrors,
	     info->id_NumBlocksUsed,
	     (info->id_NumBlocksUsed * 100)/ info->id_NumBlocks,
	     (info->id_NumBlocks - info->id_NumBlocksUsed),
	     s);

      } else {
	     pError (av[i]);
      }
      FreeMem (info,(long) sizeof(*info));
      dclose(dp);
   }
   return(0);
}



/* things shared with display_file */

char  lspec[128];
int   filecount, col;
long  bytes, blocks;

/*
 * the args passed to do_dir will never be expanded
 */
do_dir()
{
   void display_file();
   int i, options;

   col = filecount = 0;
   bytes = blocks = 0L;
   *lspec = '\0';

   options  = get_opt("sfd",&i);

   if (ac == i) {
      ++ac;
      av[i] = "";
   }
   if (!(options & (DIR_FILES | DIR_DIRS)))  options |= (DIR_FILES | DIR_DIRS);

   for (; i < ac; ++i) {
      char **eav;
      int c,eac;
      if (!(eav = expand(av[i], &eac)))
	 continue;
      QuickSort(eav, eac);
      for(c=0;c < eac && !breakcheck();++c) display_file(options,eav[c]);
      free_expand (eav);
      if (CHECKBREAK()) break;
   }
   if (col)  printf("\n");
   if (filecount > 1) {
      blocks += filecount;     /* account for dir blocks */
      printf (" %ld Blocks, %ld Bytes used in %d files\n", blocks, bytes, filecount);
   }
   return (0);
}

void
display_file(options,filestr)
int options;
char *filestr;
{
   long atol();
   int isadir,slen;
   char sc;
   char *c,*s,*fi;
   struct FileLock *lock;
   char *get_pwd();
   char *strcpy();
   
/*     if current dir different from lspec then
       look for ':' or '/' if found lock it and get_pwd.
       else then use cwd.
*/
   for(s = c = filestr; *c; ++c) if (*c == ':' || *c == '/') s = c;
   if (*s == ':') ++s;
   sc = *s;
   *s = '\0';
   c = filestr;
   if (!*c) c = cwd;
   if (strcmp (c, &lspec))  {
      strcpy(lspec, c);
      if (col)	  printf("\n");
      if (lock = (struct FileLock *)Lock(c,SHARED_LOCK)) {
	 printf ("Directory of %s\n", get_pwd(lock));
	 UnLock(lock);
      }
      col = 0;
   }
   *s = sc;
   if (sc == '/') s++;
   slen = strlen(s);
   fi = s + slen + 1;
   isadir = (fi[9] =='D');

   if (!(((options & DIR_FILES) && !isadir) ||
	 ((options & DIR_DIRS)	&& isadir)))
      return;

   if (options & DIR_SHORT) {
      if ((col == 3) && slen >18) {
	 printf("\n");
	 col = 0;
      }
      if (isadir)  {
	 printf ("\033[33m");
      }
      if (slen >18) {
	 printf(" %-37s",s);
	 col += 2;
      }
      else {
	 printf(" %-18s",s);
	 col++;
      }
      if (col > 3) {
	 printf("\n");
	 col = 0;
      }
      if (isadir) printf("\033[0m");
   }
   else		/* print full info */
      printf("   %-24s %s",s ,fi);
   fflush(stdout);
   fi[13] = fi[18] = '\0';
   bytes  += atol(fi+7);
   blocks += atol(fi+14);
   filecount++;
   return;
}

/*
   converts dos date stamp to a time string of form dd-mmm-yy
*/
char *
dates(dss)
struct DateStamp *dss;
{
   register struct tm tm;
   register long time, t;
   register int i;
   static char timestr[40];
   static char months[12][4] = {
	"Jan","Feb","Mar","Apr","May","Jun",
	"Jul","Aug","Sep","Oct","Nov","Dec"
   };
   static char days[12] = {
	31,28,31,30,31,30,31,31,30,31,30,31
   };
   time = dss->ds_Days * 24 * 60 * 60 + dss->ds_Minute * 60 +
				       dss->ds_Tick/TICKS_PER_SECOND;
   tm.tm_sec = time % 60; time /= 60;
   tm.tm_min = time % 60; time /= 60;
   tm.tm_hour= time % 24; time /= 24;
   tm.tm_wday= time %  7;
   tm.tm_year= 78 + (time/(4*365+1)) * 4; time %= 4 * 365 + 1;
   while (time) {
	t = 365;
	if ((tm.tm_year&3) == 0) t++;
	if (time < t) break;
	time -= t;
	tm.tm_year++;
   }
   tm.tm_yday = ++time;
   for (i=0;i<12;i++) {
	t = days[i];
	if (i == 1 && (tm.tm_year&3) == 0) t++;
	if (time <= t) break;
	time -= t;
   }
   tm.tm_mon = i;
   tm.tm_mday = time;

   sprintf(timestr,"%02d-%s-%2d %02d:%02d:%02d",tm.tm_mday,
		months[tm.tm_mon],tm.tm_year,
		tm.tm_hour,tm.tm_min,tm.tm_sec);
   timestr[18] = '\n';
   timestr[19] = '\0'; /* protection against bad timestamped files */
   return(timestr);

}

date()
{
   struct   DateStamp	dss;
   char *dates();

   DateStamp(&dss);
   printf("%s",dates(&dss));
   return(0);
}

do_quit()
{
   if (Src_stack) {
      Quit = 1;
      return(do_return());
   }
   main_exit (0);
}


do_echo(str)
char *str;
{
   register char *ptr;
   char nl = 1;

   for (ptr = str; *ptr && *ptr != ' '; ++ptr);
   if (*ptr == ' ')
      ++ptr;
   if (av[1] && strcmp (av[1], "-n") == 0) {
      nl = 0;
      ptr += 2;
      if (*ptr == ' ')
	 ++ptr;
   }
   printf("%s",ptr);
   fflush(stdout);
   if (nl)
      printf("\n");
   return (0);
}

do_source(str)
char *str;
{
   register FILE *fi;
   char buf[256], *s;

   if (Src_stack == MAXSRC) {
      ierror(NULL,217);
      return(-1);
   }
   if ((fi = fopen (av[1], "r")) == 0) {
      ierror(av[1], 205);
      return(-1);
   }
   set_var(LEVEL_SET, V_PASSED, next_word(next_word(str)));
   ++H_stack;
   Src_pos[Src_stack] = 0;
   Src_base[Src_stack] = (long)fi;
   ++Src_stack;
   while (fgets (buf, 256, fi)) {
      int len = strlen(buf); 
      buf[len-1] = '\0';
      Src_pos[Src_stack - 1] += len;
      if (Verbose && !forward_goto)
	 fprintf(stderr,"%s\n",buf);
      exec_command (buf);
      if (CHECKBREAK())
	 break;
   }
   --H_stack;
   --Src_stack;
   if (forward_goto)
      ierror(NULL,501);
   forward_goto = 0;
   unset_level(LEVEL_LABEL + Src_stack);
   unset_var(LEVEL_SET, V_GOTOFWD);
   unset_var(LEVEL_SET, V_PASSED);
   fclose (fi);
   return (0);
}

/*
 * return ptr to string that contains full cwd spec.
 */
char *
get_pwd(flock)
struct FileLock *flock;
{
   char *ptr;
   char *name;
   int err=0;
   static char pwdstr[256];

   struct FileLock *lock, *newlock;
   FIB *fib;
   int i, len;

   lock = (struct FileLock *)DupLock(flock);
         
   fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
   pwdstr[i = 255] = '\0';

   while (lock) {
      newlock = (struct FileLock *)ParentDir(lock);
      if (!Examine(lock, fib)) ++err;
      name = fib->fib_FileName;
      if (*name == '\0')	    /* HACK TO FIX RAM: DISK BUG */
	 name = "RAM";
      len = strlen(name);
      if (newlock) {
	 if (i == 255) {
	    i -= len;
	    bmov(name, pwdstr + i, len);
	 } else {
	    i -= len + 1;
	    bmov(name, pwdstr + i, len);
	    pwdstr[i+len] = '/';
	 }
      } else {
	 i -= len + 1;
	 bmov(name, pwdstr + i, len);
	 pwdstr[i+len] = ':';
      }
      UnLock(lock);
      lock = newlock;
   }
   FreeMem(fib, (long)sizeof(FIB));
   movmem(pwdstr + i, pwdstr, 256 - i);
   if (err) return(cwd);
   return(pwdstr);
}

/*
 * set process cwd name and $_cwd, if str != NULL also print it.
 */
do_pwd(str)
char *str;
{
   char *ptr;

   if ((struct FileLock *)Myprocess->pr_CurrentDir == 0)
       attempt_cd(":"); /* if we just booted 0 = root lock */
   strcpy(cwd,get_pwd(Myprocess->pr_CurrentDir,1));
   if (str)
      puts(cwd);
   set_var(LEVEL_SET, V_CWD, cwd);
   /* put the current dir name in our CLI task structure */
   ptr = (char *)((ULONG)((struct CommandLineInterface *)
      BADDR(Myprocess->pr_CLI))->cli_SetName << 2);
   ptr[0] = strlen(cwd);
   movmem(cwd,ptr+1,(int)ptr[0]);
   return(0);
}


/*
 * CD
 *
 * CD(str, 0)	    -do CD operation.
 *
 *    standard operation: breakup path by '/'s and process independantly
 *    x:    -reset cwd base
 *    ..    -remove last cwd element
 *    N	    -add N or /N to cwd
 */

do_cd(str)
char *str;
{
   char sc, *ptr;
   int err=0;

   str = next_word(str);
   if (*str == '\0') {
      puts(cwd);
      return(0);
   }
   str[strlen(str)+1] = '\0';	       /* add second \0 on end */
   while (*str) {
      for (ptr = str; *ptr && *ptr != '/' && *ptr != ':'; ++ptr);
      switch (*ptr) {
      case ':':
	 sc = ptr[1];
	 ptr[1] = '\0';
	 err = attempt_cd(str);
	 ptr[1] = sc;
	 break;
      case '\0':
      case '/':
	 *ptr = '\0';
	 if (strcmp(str, "..") == 0 || str == ptr)
	    str = "/";
	 if (*str) err = attempt_cd(str);
	 break;
      }
      if (err) break;
      str = ptr + 1;
   }
   do_pwd(NULL);	 /* set $_cwd */
   return(err);
}

attempt_cd(str)
char *str;
{
   struct FileLock *oldlock, *filelock;

   if (filelock = (struct FileLock *)Lock(str, ACCESS_READ)) {
      if (isdir(str)) {
	 if (oldlock = (struct FileLock *)CurrentDir(filelock))
	    UnLock(oldlock);
	 return (0);
      }
      UnLock(filelock);
      ierror(str, 212);
   } else {
      ierror(str, 205);
   }
   return (-1);
}

do_mkdir()
{
   register int i;
   register struct FileLock *lock;

   for (i = 1; i < ac; ++i) {
      if (lock = (struct FileLock *)Lock(av[i],ACCESS_READ)) {
	 ierror(av[i],203);
	 UnLock (lock);
	 continue;
      }
      if (lock = (struct FileLock *)CreateDir (av[i])) {
	 UnLock (lock);
	 continue;
      }
      pError (av[i]);
   }
   return (0);
}


do_mv()
{
   char dest[256];
   register int i;
   char *str;

   --ac;
   if (isdir(av[ac])) {
      for (i = 1; i < ac; ++i) {
	 str = av[i] + strlen(av[i]) - 1;
	 while (str != av[i] && *str != '/' && *str != ':')
	    --str;
	 if (str != av[i])
	    ++str;
	 if (*str == 0) {
	    ierror(av[i], 508);
	    return (-1);
	 }
	 strcpy(dest, av[ac]);
	 if (dest[strlen(dest)-1] != ':')
	    strcat(dest, "/");
	 strcat(dest, str);
	 if (Rename(av[i], dest) == 0)
	    break;
      }
      if (i == ac)
	 return (1);
   } else {
      i = 1;
      if (ac != 2) {
	 ierror("", 507);
	 return (-1);
      }
      if (Rename (av[1], av[2]))
	 return (0);
   }
   pError (av[i]);
   return (-1);
}

rm_file(file)
char *file;
{
      if (has_wild) printf("  %s...",file);
      fflush(stdout);
      if (!DeleteFile(file))
	 pError (file);
      else
	 if (has_wild) printf("Deleted\n");
}

do_rm()
{
   int i, recur;

   recur = get_opt("r",&i);

   for (; i < ac; ++i) {
      if (CHECKBREAK()) break;
      if (isdir(av[i]) && recur)
	 rmdir(av[i]);
      if (!(recur && av[i][strlen(av[i])-1] == ':'))
	 rm_file(av[i]);
   }
   return (0);
}

rmdir(name)
char *name;
{
   register struct FileLock *lock, *cwd;
   register FIB *fib;
   register char *buf;

   buf = (char *)AllocMem(256L, MEMF_PUBLIC);
   fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);

   if (lock = (struct FileLock *)Lock(name, ACCESS_READ)) {
      cwd = (struct FileLock *) CurrentDir(lock);
      if (Examine(lock, fib)) {
	 buf[0] = 0;
	 while (ExNext(lock, fib)) {
	    if (CHECKBREAK()) break;
	    if (isdir(fib->fib_FileName))
	       rmdir(fib->fib_FileName);
	    if (buf[0]) {
	       rm_file(buf);
	    }
	    strcpy(buf, fib->fib_FileName);
	 }
	 if (buf[0] && !CHECKBREAK()) {
	    rm_file(buf);
	 }
      }
      UnLock(CurrentDir(cwd));
   } else {
      pError(name);
   }
   FreeMem(fib, (long)sizeof(FIB));
   FreeMem(buf, 256L);
}



do_history()
{
   register struct HIST *hist;
   register int i = H_tail_base;
   register int len = (av[1]) ? strlen(av[1]) : 0;

   for (hist = H_tail; hist; hist = hist->prev) {
      if (len == 0 || strncmp(av[1], hist->line, len) == 0) {
	 printf ("%3d ", i);
	 puts (hist->line);
      }
      ++i;
      if (CHECKBREAK())
	 break;
   }
   return (0);
}

do_mem()
{
   long cfree, ffree;
   extern long AvailMem();

   Forbid();
   cfree = AvailMem (MEMF_CHIP);
   ffree = AvailMem (MEMF_FAST);
   Permit();

   if (ffree)	    {
   printf ("FAST memory: %ld\n", ffree);
   printf ("CHIP memory: %ld\n", cfree);
   }
   printf ("Total  Free: %ld\n", cfree + ffree);
   return(0);
}

/*
 * foreach var_name  ( str str str str... str ) commands
 * spacing is important (unfortunately)
 *
 * ac=0	   1 2 3 4 5 6 7
 * foreach i ( a b c ) echo $i
 * foreach i ( *.c )   "echo -n "file ->";echo $i"
 */

do_foreach()
{
   register int i, cstart, cend, old;
   register char *cstr, *vname, *ptr, *scr;
   char **fav;
   
   cstart = i = (*av[2] == '(') ? 3 : 2;
   while (i < ac) {
      if (*av[i] == ')')
	 break;
      ++i;
   }
   if (i == ac) {
      fprintf (stderr,"')' expected\n");
      return (-1);
   }
   ++H_stack;
   cend = i;
   
   vname = strcpy(malloc(strlen(av[1])+1), av[1]);
   fav = (char **)malloc(sizeof(char *) * (ac));
   cstr = compile_av (av, cend + 1, ac, ' ');
   
   for (i = cstart; i < cend; ++i) {
   	fav[i] = av[i];
   }
      
   for (i = cstart; i < cend; ++i) {
      set_var (LEVEL_SET, vname, fav[i]);
      if (CHECKBREAK())
         break;
      exec_command (cstr);
   }    	
   --H_stack;
   free (fav);
   free (cstr);
   unset_var (LEVEL_SET, vname);
   free (vname);
   return (0);
}

do_forever(str)
char *str;
{
   int rcode = 0;
   char *ptr = next_word(str);

   ++H_stack;
   for (;;) {
      if (CHECKBREAK()) {
	 rcode = 20;
	 break;
      }
      if (exec_command (ptr) < 0) {
	 str = get_var(LEVEL_SET, V_LASTERR);
	 rcode = (str) ? atoi(str) : 20;
	 break;
      }
   }
   --H_stack;
   return (rcode);
}

SHAR_EOF
if test 14617 -ne "`wc -c comm1.c`"
then
echo shar: error transmitting comm1.c '(should have been 14617 characters)'
fi
echo shar: extracting comm2.c
cat << \SHAR_EOF > comm2.c
/*
 * COMM2.C
 *
 * (c)1986 Matthew Dillon     9 October 1986
 *
 * Version 2.07M by Steve Drew 10-Sep-87
 *
 */

#include "shell.h"
typedef struct FileInfoBlock FIB;

/* Casting conveniences */
#define BPTR_TO_C(strtag, var)	((struct strtag *)(BADDR( (ULONG) var)))
#define PROC(task)		((struct Process *)task)
#define ROOTNODE		((struct RootNode *)DOSBase->dl_Root)
#define CLI(proc)		(BPTR_TO_C(CommandLineInterface, proc->pr_CLI))

/* Externs */
extern int has_wild;			/* flag set if any arg has a ? or * */
extern struct DosLibrary *DOSBase;	/* dos library base pointer         */

/* globals */
int cp_update;
int cp_date;

do_abortline()
{
   Exec_abortline = 1;
   return (0);
}

do_return()
{
   Exec_abortline = 1;
   if (Src_stack) {
       FILE *ptr = (FILE *)Src_base[Src_stack - 1];
       ptr->_bp = ptr->_bend;
       ptr->_flags |= _EOF;
/*     fseek (Src_base[Src_stack - 1], 0L, 2); */
      return ((ac < 2) ? 0 : atoi(av[1]));
   } else {
      main_exit ((ac < 2) ? 0 : atoi(av[1]));
   }
}

/*
 * STRHEAD
 *
 * place a string into a variable removing everything after and including
 * the 'break' character or until a space is found in the string.
 *
 * strhead varname breakchar string
 *
 */

do_strhead()
{
   register char *str = av[3];
   char bc = *av[2];

   while (*str && *str != bc)
      ++str;
   *str = '\0';
   set_var (LEVEL_SET, av[1], av[3]);
   return (0);
}

do_strtail()
{
   register char *str = av[3];
   char bc = *av[2];

   while (*str && *str != bc)
      ++str;
   if (*str)
      ++str;
   set_var (LEVEL_SET, av[1], str);
   return (0);
}



/*
 * if -f file (exists) or:
 *
 * if A < B   <, >, =, <=, >=, !=, where A and B are either:
 * nothing
 * a string
 * a value (begins w/ number)
 */

do_if(garbage, com)
char *garbage;
{
   char *v1, *v2, *v3, result, num;
   int n1, n2;
   struct FileLock *lock;

   switch (com) {
   case 0:
      if (If_stack && If_base[If_stack - 1]) {
	 If_base[If_stack++] = 1;
	 break;
      }
      result = num = 0;

      if (!strcmp(av[1],"-f")) {
      	 if (ac == 3 && (lock=(struct FileLock *)Lock(av[2], ACCESS_READ))) {
      	     UnLock(lock);
      	     result = 1;
      	 }
  	 goto do_result;
      }
      if (ac <= 2) {	   /* if $var; */
	 if (ac == 1 || strlen(av[1]) == 0 || (strlen(av[1]) == 1 && *av[1] == ' '))
	    goto do_result;
	 result = 1;
	 goto do_result;
      }
      if (ac != 4) {
	 ierror(NULL, 500);
	 break;
      }
      v1 = av[1]; v2 = av[2]; v3 = av[3];
      while (*v1 == ' ')
	 ++v1;
      while (*v2 == ' ')
	 ++v2;
      while (*v3 == ' ')
	 ++v3;
      if (*v1 >= '0' && *v1 <= '9') {
	 num = 1;
	 n1 = atoi(v1);
	 n2 = atoi(v3);
      }
      while (*v2) {
	 switch (*v2++) {
	 case '>':
	    result |= (num) ? (n1 >  n2) : (strcmp(v1, v3) > 0);
	    break;
	 case '<':
	    result |= (num) ? (n1 <  n2) : (strcmp(v1, v3) < 0);
	    break;
	 case '=':
	    result |= (num) ? (n1 == n2) : (strcmp(v1, v3) ==0);
	    break;
	 default:
	    ierror (NULL, 503);
	    break;
	 }
      }
do_result:
      If_base[If_stack++] = !result;
      break;
   case 1:
      if (If_stack > 1 && If_base[If_stack - 2])
	 break;
      if (If_stack)
	 If_base[If_stack - 1] ^= 1;
      break;
   case 2:
      if (If_stack)
	 --If_stack;
      break;
   }
   disable = (If_stack) ? If_base[If_stack - 1] : 0;
   if (If_stack >= MAXIF) {
      fprintf(stderr,"If's too deep\n");
      disable = If_stack = 0;
      return(-1);
      }
   if (forward_goto) disable = If_base[If_stack - 1] = 0;
   return (0);
}

do_label()
{
   char aseek[32];

   if (Src_stack == 0) {
      ierror (NULL, 502);
      return (-1);
   }
   
   sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack);
   set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek);
   if (!strcmp(av[1],get_var(LEVEL_SET,V_GOTOFWD)))
      forward_goto = 0;
   return (0);
}

do_goto()
{
   int new;
   long pos;
   char *lab;

   if (Src_stack == 0) {
      ierror (NULL, 502);
   } else {
      lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]);
      if (lab == NULL) {
	 forward_goto = 1;
	 set_var (LEVEL_SET, V_GOTOFWD, av[1]);
	 return(0);
      } else {
	 pos = atoi(lab);
	 fseek (Src_base[Src_stack - 1], pos, 0);
	 Src_pos[Src_stack - 1] = pos;
	 new = atoi(next_word(lab));
	 for (; If_stack < new; ++If_stack)
	    If_base[If_stack] = 0;
	 If_stack = new;
      }
   }
   Exec_abortline = 1;
   return (0);	    /* Don't execute rest of this line */
}


do_inc(garbage, com)
char *garbage;
{
   char *var;
   char num[32];

   if (ac == 3)
      com = atoi(av[2]);
   var = get_var (LEVEL_SET, av[1]);
   if (var) {
      sprintf (num, "%d", atoi(var)+com);
      set_var (LEVEL_SET, av[1], num);
   }
   return (0);
}

do_input()
{
   char in[256], *p,*s;
   int i;
   
   for (i=1; i < ac; ++i) {
      if ((gets(in)) != 0) {
	 for(p = in; *p; p = s) {
	    s = next_word(p);
	    if (*s) *(s-1) = 0xA0;
	 }
         set_var (LEVEL_SET, av[i], in);
      }
   }
   return (0);
}

do_ver()
{
   puts (VERSION);
   return (0);
}


do_ps()
{
	/* this code fragment based on ps.c command by Dewi Williams */

	register ULONG	 *tt;		/* References TaskArray		*/
	register int	 count;		/* loop variable		*/
	register UBYTE	 *port;		/* msgport & ptr arith		*/
	register struct Task *task;	/* EXEC descriptor		*/
	char		 strbuf[64];    /* scratch for btocstr()	*/
	char		 cmd[40];	/* holds cmd name		*/
	char		 *btocstr();	/* BCPL BSTR to ASCIIZ		*/

	tt = (unsigned long *)(BADDR(ROOTNODE->rn_TaskArray));

	printf("Proc Command Name	  CLI Type    Pri.  Address  Directory\n");
	Forbid();		/* need linked list consistency */

	for (count = 1; count <= (int)tt[0] ; count++) {/* or just assume 20?*/
		if (tt[count] == 0) continue;		/* nobody home */

		/* Start by pulling out MsgPort addresses from the TaskArray
		 * area. By making unwarranted assumptions about the layout
		 * of Process and Task structures, we can derive these
		 * descriptors. Every task has an associated process, since
		 * this loop drives off a CLI data area.
		 */

		port = (UBYTE *)tt[count];
		task = (struct Task *)(port - sizeof(struct Task));

		/* Sanity check just in case */
		if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0)
			continue;		/* or complain? */

			
			printf("%2d   %-20.20s %-11.11s %3d  %8lx  %s\n",
			   count,btocstr(CLI(PROC(task))->cli_CommandName, cmd),
			   task->tc_Node.ln_Name,
			   task->tc_Node.ln_Pri,task,
			   btocstr(CLI(PROC(task))->cli_SetName, strbuf)); 

	}
	Permit();		/* outside critical region */
	return(0);
}


char *
btocstr(b, buf)
ULONG	b;
char	*buf;
{
	register char	*s;

	s = (char *)BADDR(b);	/* Shift & get length-prefixed str */
	movmem(s +1, buf, s[0]);
	buf[s[0]] = '\0';
	return buf;
}


/*
 * CP [-d] [-u] file file
 * CP [-d] [-u] file file file... destdir
 * CP [-r][-u][-d] dir dir dir... destdir
 */

char *errstr;	       /* let's be alittle more informative */
do_copy()
{
   register int recur, ierr;
   register char *destname;
   register char destisdir;
   register FIB *fib;
   int i,opt;

   errstr = "";
   ierr = 0;

   fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);

   opt = get_opt("rud",&i);
   recur     = (opt & 0x01);
   cp_update = (opt & 0x02);
   cp_date   = (!(opt & 0x04)); /* the default is keep orignal file date */

   destname = av[ac - 1];

   if (ac < i + 2) {
      ierr = 500;
      goto done;
   }

   destisdir = isdir(destname);
   if (ac > i + 2 && !destisdir) {
      ierr = 507;
      goto done;
   }

   /*
    * copy set:			       reduce to:
    *	 file to file			  file to file
    *	 dir  to file (NOT ALLOWED)
    *	 file to dir			  dir to dir
    *	 dir  to dir			  dir to dir
    *
    */

   for (; i < ac - 1; ++i) {
      short srcisdir = isdir(av[i]);
      if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
	  continue;			   /* getting copied if specified */
					   /* from wild expansion */
      if (CHECKBREAK())
	 break;
      if (srcisdir) {
	 struct FileLock *srcdir, *destdir;
	 if (!destisdir) {
	    if (destdir = (struct FileLock *)Lock(destname, ACCESS_READ)) {
	       UnLock(destdir);
	       ierr = 507;		  /* disallow dir to file */
	       goto done;
	    }
	    if (destdir = (struct FileLock *)CreateDir(destname))
	       UnLock(destdir);
	    destisdir = 1;
	 }
	 if (!(destdir = (struct FileLock *)Lock(destname, ACCESS_READ))) {
	    ierr = 205;
	    errstr = destname;
	    goto done;
	 }
	 if (!(srcdir = (struct FileLock *)Lock(av[i], ACCESS_READ))) {
	    ierr = 205;
	    errstr = av[i];
	    UnLock(destdir);
	    goto done;
	 }
	 ierr = copydir(srcdir, destdir, recur);
	 UnLock(srcdir);
	 UnLock(destdir);
	 if (ierr)
	    break;
      } else {			    /* FILE to DIR,   FILE to FILE   */
	 struct FileLock *destdir, *srcdir, *tmp;
	 char *destfilename;

	 srcdir = (struct FileLock *)(Myprocess->pr_CurrentDir);

	 if ((tmp = (struct FileLock *)Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)){
	    if (tmp) UnLock(tmp);
	    ierr = 205;
	    errstr = av[i];
	    goto done;
	 }
	 UnLock(tmp);
	 if (destisdir) {
	    destdir = (struct FileLock *)Lock(destname, ACCESS_READ);
	    destfilename = fib->fib_FileName;
	 } else {
	    destdir = srcdir;
	    destfilename = destname;
	 }
	 printf(" %s..",av[i]);
	 fflush(stdout);
	 ierr = copyfile(av[i], srcdir, destfilename, destdir);
	 if (destisdir)
	    UnLock(destdir);
	 if (ierr)
	    break;
      }
   }
done:
   FreeMem(fib, (long)sizeof(*fib));
   if (ierr) {
      ierror(errstr, ierr);
      return(20);
   }
   return(0);
}


copydir(srcdir, destdir, recur)
register struct FileLock *srcdir, *destdir;
{
   struct FileLock *cwd;
   register FIB *srcfib;
   register struct FileLock *destlock, *srclock;
   int ierr;
   static int level;

   level++;
   ierr = 0;
   srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
   if (Examine(srcdir, srcfib)) {
      while (ExNext(srcdir, srcfib)) {
	 if (CHECKBREAK())
	    break;
	 if (srcfib->fib_DirEntryType < 0) {
	    printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
	    fflush(stdout);
	    ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
	    if (ierr)
	       break;
	 } else {
	    if (recur) {
	       cwd = (struct FileLock *)CurrentDir(srcdir);
	       if (srclock = (struct FileLock *)Lock(srcfib->fib_FileName, ACCESS_READ)) {
		  CurrentDir(destdir);
		  if (!(destlock = (struct FileLock *)
				Lock(srcfib->fib_FileName))) {
		     destlock = (struct FileLock *)CreateDir(srcfib->fib_FileName);
		     printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
				" ",srcfib->fib_FileName);

			/* UnLock and re Lock if newly created
			   for file_date() to work properly
			*/   
		     if (destlock) UnLock(destlock);
		     destlock = (struct FileLock *)Lock(srcfib->fib_FileName);		     
		  }
		  else
		     printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
		  if (destlock) {
		     ierr = copydir(srclock, destlock, recur);
		     UnLock(destlock);
		  } else {
		     ierr = (int)((long)IoErr());
		  }
		  UnLock(srclock);
	       } else {
		  ierr = (int)((long)IoErr());
	       }
	       CurrentDir(cwd);
	       if (ierr)
		  break;
	    }
	 }
      }
   } else {
      ierr = (int)((long)IoErr());
   }
   --level;
   FreeMem(srcfib, (long)sizeof(FIB));
   return(ierr);
}


copyfile(srcname, srcdir, destname, destdir)
char *srcname, *destname;
struct FileLock *srcdir, *destdir;
{
   struct FileLock *cwd;
   struct FileHandle *f1, *f2;
   struct DateStamp *ds;
   long i;
   int stat,ierr;
   char *buf;
   struct DPTR *dp, *dps = NULL;

   buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR);
   if (buf == NULL) {
      ierr = 103;
      goto fail;
   }

   ierr = 0;
   cwd = (struct FileLock *)CurrentDir(srcdir);
   f1 = Open(srcname, MODE_OLDFILE);
   if (f1 == NULL) {
      errstr = srcname;
      ierr = 205;
      goto fail;
   }
   dps = dopen(srcname,&stat);
   ds = &dps->fib->fib_Date;
   CurrentDir(destdir);
   if (cp_update  && (dp = dopen (destname, &stat))) {
	long desttime,srctime;
	struct DateStamp *dd;

	dd = &dp->fib->fib_Date;
	desttime = dd->ds_Days * 86400 + dd->ds_Minute * 60 +
				       dd->ds_Tick/TICKS_PER_SECOND;
	srctime	 = ds->ds_Days * 86400 + ds->ds_Minute * 60 +
				       ds->ds_Tick/TICKS_PER_SECOND;

	if (srctime <= desttime &&
	  !strcmp(dps->fib->fib_FileName,dp->fib->fib_FileName)) {
	    dclose(dp);
	    Close(f1);
	    printf("..not newer\n");
	    goto fail;
	}
	dclose(dp);
   }
   f2 = Open(destname, MODE_NEWFILE);
   if (f2 == NULL) {
      Close(f1);
      ierr = (int)((long)IoErr());
      errstr = destname;
      goto fail;
   }
   while (i = Read(f1, buf, 8192L))
      if (Write(f2, buf, i) != i) {
	 ierr = (int)((long)IoErr());
	 break;
      }
   Close(f2);
   Close(f1);
   if (!ierr)  {
      if (cp_date) file_date(ds,destname);
      printf("..copied\n");
   }
   else {
      DeleteFile(destname);
   }
fail:
   dclose(dps);
   if (buf)
      FreeMem(buf, 8192L);
   CurrentDir(cwd);
   return(ierr);
}


file_date(date,name)
struct DateStamp *date;
char *name;
{
    UBYTE *ptr;
    struct MsgPort *task;
    struct FileLock *dirlock;
    struct DPTR *tmp; 
    int stat;
    long ret, dos_packet();

    if (!(task = (struct MsgPort *)DeviceProc(name)))
	return(1);
    if (tmp = dopen(name, &stat)) {
	dirlock = (struct FileLock *)ParentDir(tmp->lock);
	ptr = (UBYTE *)AllocMem(64L,MEMF_PUBLIC);
	strcpy((ptr + 1),tmp->fib->fib_FileName);
	*ptr = strlen(tmp->fib->fib_FileName);
	dclose(tmp);
	ret = dos_packet(task,34L,NULL,dirlock,
		         (ULONG)&ptr[0] >> 2L,date);
	FreeMem(ptr,64L);
	UnLock(dirlock);
    }
}

SHAR_EOF
if test 13640 -ne "`wc -c comm2.c`"
then
echo shar: error transmitting comm2.c '(should have been 13640 characters)'
fi
echo shar: extracting rawconsole.c
cat << \SHAR_EOF > rawconsole.c
/*
 * RawConsole.c
 *
 * Shell 2.07M	17-Jun-87
 * console handling, command line editing support for Shell
 * using new console packets from 1.2.
 * Written by Steve Drew. (c) 14-Oct-86.
 * 16-Dec-86 Slight mods to rawgets() for Disktrashing.
 *
 */

#if RAW_CONSOLE
extern int aux; /* for use with aux: */

#include "shell.h"

void
setraw(onoff)
{
    if (onoff) set_raw();
    else set_con();
}

char *
rawgets(line,prompt)
char *line, *prompt;
{
    char *get_var();
    char *gets();
    register int n, pl;
    register int max, i;
    unsigned char c1,c2,c3;
    char fkeys[5];
    char *s, *tyahdptr;
    char *ps;
    int fkey, savn;
    int insert = 1;
    char rep[20];
    char typeahd[256];
    static int width;
    int recall = -1;
    struct HIST *hist;

    if (aux) {
	printf("%s",prompt);
	fflush(stdout);
    }
    if (!IsInteractive(Input()) || aux ) return(gets(line));
    if (WaitForChar((long)Input(), 100L) ||   /* don't switch to 1L ...*/
	   stdin->_bp < stdin->_bend) {	    /* else causes read err's*/
    /*	printf("%s",prompt); */
	gets(line);
	return(line);
    }
    setraw(1);
    printf("\015%s\2336n",prompt);
    savn = pl = n = 0;
    tyahdptr = typeahd;
    while((typeahd[n]=getchar()) != 'R') {    	
    	if ((unsigned char)typeahd[n] == 155) savn = n;
    	n++;
    }
    	
	/* typeahd now contains possible type a head chars
	   followed by <CSI> cursor position report.
	 */
    typeahd[savn]  = '\0';
    if (typeahd[n-2] != ';') {
        pl = (typeahd[n-2] - 48) * 10;
    }
    pl += typeahd[n-1] - 49;
    ps = line + pl;
    line[max = i = pl] = '\0';
    
    if (!width) width = 77;
    if (s = get_var (LEVEL_SET, "_insert"))
	insert = atoi(s) ? 1 : 0;
	
    while( (c1 = *tyahdptr) != '\0' || (c1 = getchar()) != 255) {
    	if (*tyahdptr) ++tyahdptr;
	switch(c1) {
	    case 155:
		 c2 = getchar();
		 switch(c2) {
		     case 'A':			/* up arrow   */
			n = ++recall;
		     case 'B':			/* down arrow */
			line[pl] = '\0';
			if (recall >= 0 || c2 == 'A') {
			    if (c2 == 'B') n = --recall;
			    if (recall >= 0) {
				for(hist = H_head; hist && n--;
				    hist = hist->next);
				if (hist) strcpy(&line[pl],hist->line);
				else recall = H_len;
			    }
			}
			if (i != pl)
			    printf("\233%dD",i);
			printf("\015\233J%s%s",prompt,ps);
			i = max = strlen(ps) + pl;
			break;
		     case 'C':			/* right arrow*/
			if (i < max) {
			    i++;
			    printf("\233C");
			}
			break;
		     case 'D':			/* left arrow */
			if (i > pl) {
			    i--;
			    printf("\233D");
			}
			break;
		    case 'T':			/* shift up   */
		    case 'S':			/* shift down */
			break;
		    case ' ':			/* shift -> <-*/
			c3 = getchar();
			break;
		    default:
			c3 = getchar();
			if (c3 == '~') {
			    fkey = c2;
			    fkeys[0] = 'f';
			    if (c2 == 63) {
				strcpy(ps,"help");
				goto done;
			    }
			}
			else if (getchar() != '~') { /* window was resized */
			    while(getchar() != '|');
			    printf("\2330 q"); /* get window bounds */
			    n = 0;
			    while((rep[n] = getchar()) != 'r' && n++ < 20);
			    width = (rep[n-3] - 48) * 10 + rep[n-2] - 48;
			    rep[n-1] = '\0';
			    set_var (LEVEL_SET, "_width", &rep[n-3]);
			    break;
			}
			else {
			    fkey = c3;
			    fkeys[0] = 'F';
			}
			sprintf(fkeys+1,"%d",fkey - 47);
			if (!(s = get_var(LEVEL_SET, fkeys))) break;
    			tyahdptr = strcpy(typeahd,s);
			break;
		    }
		break;
	    case 8:
		if (i > pl) {
		    i--;
		    printf("\010");
		}
		else break;
	    case 127:
		if (i < max) {
		    int j,t,l = 0;
		    movmem(&line[i+1],&line[i],max-i);
		    --max;
		    printf("\233P");
		    j = width - i % width - 1;	 /* amount to end     */
		    t = max/width - i/width;	 /* no of lines	      */
		    for(n = 0; n < t; n++) {
			l += j;			 /* no. of char moved */
			if (j) printf("\233%dC",j); /* goto eol	      */
			printf("%c\233P",line[width*(i/width+n+1)-1]);
			j = width-1;
		    }
		    if (t)
		    printf("\233%dD",l+t);   /* get back */
		}
		break;
	    case 18:
		n = i/width;
		if (n) printf("\233%dF",n);
		printf("\015\233J%s%s",prompt,ps);
		i = max;
		break;
	    case 27:
		break;
	    case 1:
		insert ^= 1;
		break;
	    case 21:
	    case 24:
	    case 26:
		if (i > pl)
		    printf("\233%dD",i-pl);
		i = pl;
		if (c1 == 26) break;
		printf("\233J");
		max = i;
		line[i] = '\0';
		break;
	    case 11:	    /* ^K */
		printf("\233J");
		max = i;
		line[i] = '\0';
		break;
	    case 28:	    /* ^\ */
		setraw(0);
		return(NULL);
	    case 5:
		printf("\233%dC",max - i);
		i = max;
		break;
	    case 10:
	    case 13:
		line[max] = '\0';
done:		printf("\233%dC\n",max - i);

		setraw(0);
		strcpy(line, ps);
		return(line);
	    default:
	    	c1 &= 0x7f;
		if (c1 == 9) c1 = 32;
		if (c1 > 31 & i < 256) {
		    if (i < max && insert) {
			int j,t,l = 0;
			movmem(&line[i], &line[i+1], max - i);
			printf("\233@%c",c1);
			t = max/width - i/width;
			j = width - i % width - 1;
			for(n = 0; n < t; n++) {
			    l += j;
			    if (j) printf("\233%dC",j);
			    printf("\233@%c",line[width*(i/width+n+1)]);
			    j = width-1;
			}
			if (t) printf("\233%dD",l + t);
			++max;
		    }
		    else {
			if(i == pl && max == i) printf("\015%s%s",prompt,ps);
			putchar(c1);
		    }
		    line[i++] = c1;
		    if (max < i) max = i;
		    line[max] = '\0';
		}
	}
    }
    setraw(0);
    return(NULL);
}
#endif
SHAR_EOF
if test 5391 -ne "`wc -c rawconsole.c`"
then
echo shar: error transmitting rawconsole.c '(should have been 5391 characters)'
fi
#	End of shell archive
exit 0