[comp.os.minix] Official Clam Patch #2

wtoomey@gara.une.oz (Warren Toomey) (06/01/89)

	Here is the second official patch to Clam. For those who missed,
Clam is a Tcsh-like shell with command line editing, history, aliases etc.

	Callum (the author) is starting to attack the code again, and has
removed several small bugs. Most notably, he has sprinkled many free()s
around the code, so Clam will now not crash after about 100-200 commands.

	He is also currently rewriting parts of the UCB job control, and
terminal control, so these patches won't work too well on UCB machines;
it does work well on Minix, and as the original copyright notice says, you
shouldn't be running Clam under anything but Minix !

	The following postings consist of several context diffs on the
Clam files, and where the diff is very big, the file is included
instead. Please apply them to your source, as I will base the next
patches on this version.

	Thanks for all those people who have sent in bugs & bug patches
for Clam! 

Before I forget, in part 1 a crc of the main files in Clam is given.

					Cheers all!

						Warren Toomey

wtoomey@gara.une.oz (Warren Toomey) (06/01/89)

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# CRCLIST builtin.cdif clex.cdif

echo x - CRCLIST
cat > "CRCLIST" << '//E*O*F CRCLIST//'
57497   4917 alias.c
29568  27856 builtin.c
50076  18172 clex.c
41126  18739 comlined.c
15958   3449 cx.c
34060    189 dotclamr
60211    278 dotlogin
58306  16755 exec.c
53894    977 file.c
02377   1132 global.c
19850   8673 hash.c
60345   7427 header.h
18466   4529 hist.c
34831  10067 job.c
42195  21184 main.c
58968   2660 makefile
53495  26347 meta.c
26813   9392 parse.c
07214  11738 var.c
//E*O*F CRCLIST//

echo x - builtin.cdif
cat > "builtin.cdif" << '//E*O*F builtin.cdif//'
*** ../Patch1/builtin.c	Thu Jun  1 17:01:14 1989
--- builtin.c	Thu Jun  1 16:53:15 1989
***************
*** 57,62
  # endif
  #endif
    else write(2,"Can't get cwd properly\n",23);
  }
  
  static

--- 57,63 -----
  # endif
  #endif
    else write(2,"Can't get cwd properly\n",23);
+   free(argv[1]);	/* just in case? */
  }
  
  static
***************
*** 66,71
    bool appnd,bckgnd;
  {
    extern void setdown();
    extern int fromfile,isanum();
  
    if (argc>2 || (!isanum(argv[1]) && argc!=1))

--- 67,73 -----
    bool appnd,bckgnd;
  {
    extern void setdown();
+   extern bool loginsh;
    extern int fromfile,isanum();
    void logout();	/* just down from here... */
  
***************
*** 67,72
  {
    extern void setdown();
    extern int fromfile,isanum();
  
    if (argc>2 || (!isanum(argv[1]) && argc!=1))
    {

--- 69,75 -----
    extern void setdown();
    extern bool loginsh;
    extern int fromfile,isanum();
+   void logout();	/* just down from here... */
  
    if (loginsh==TRUE)
      logout(argc,argv,infd,outfd,errfd,ifil,ofil,efil,appnd,bckgnd);
***************
*** 68,73
    extern void setdown();
    extern int fromfile,isanum();
  
    if (argc>2 || (!isanum(argv[1]) && argc!=1))
    {
      write(2,"Bad argument to exit.\n",22);

--- 71,78 -----
    extern int fromfile,isanum();
    void logout();	/* just down from here... */
  
+   if (loginsh==TRUE)
+     logout(argc,argv,infd,outfd,errfd,ifil,ofil,efil,appnd,bckgnd);
    if (argc>2 || (!isanum(argv[1]) && argc!=1))
    {
      write(2,"Bad argument to exit.\n",22);
***************
*** 645,650
  {
    extern void joblist();
  
    joblist();
  }
  

--- 650,656 -----
  {
    extern void joblist();
  
+ /* Have -i or -l flag which gives more info. (stuff in job struct) */
    joblist();
  }
  
***************
*** 759,765
    int pid,i;
  
    signal(SIGCHLD,SIG_IGN);		/* so that checkjobs doesn't update */
-   setexec();			/* set the signal-sending keys */
    if (argc==1)
    {
  #ifdef DEBUG

--- 765,770 -----
    int pid,i;
  
    signal(SIGCHLD,SIG_IGN);		/* so that checkjobs doesn't update */
    if (argc==1)
    {
  #ifdef DEBUG
***************
*** 768,774
      if (currentjob)
      {
        pid=currentjob->pid;				/* current job */
!       if (setpgrp(pid,getpgrp(0))==-1)	/* set process group to the shell's */
        {
          write(2,"Can't fg this pid\n",18);
          return;

--- 773,779 -----
      if (currentjob)
      {
        pid=currentjob->pid;				/* current job */
!       if (pid!=getpgrp(pid))
        {
  	fprintf(stderr,"Can't bring pid:%d to the foreground. Impossible?\n",pid);
  	fflush(stderr);
***************
*** 770,775
        pid=currentjob->pid;				/* current job */
        if (setpgrp(pid,getpgrp(0))==-1)	/* set process group to the shell's */
        {
          write(2,"Can't fg this pid\n",18);
          return;
        }

--- 775,791 -----
        pid=currentjob->pid;				/* current job */
        if (pid!=getpgrp(pid))
        {
+ 	fprintf(stderr,"Can't bring pid:%d to the foreground. Impossible?\n",pid);
+ 	fflush(stderr);
+ 	return;
+       }
+ #ifdef DEBUG
+       fprintf(stderr,"setting terminal pg to %d\n",pid);
+ #endif
+       if (ioctl(0,TIOCSPGRP,&pid)) perror("fg spg");
+       setdown();
+       /*if (setpgrp(pid,getpgrp(0))==-1)  /* set process group to the shell's 
+       {
          write(2,"Can't fg this pid\n",18);
          return;
        } *** This is wrong. All are in their own process group now */
***************
*** 772,778
        {
          write(2,"Can't fg this pid\n",18);
          return;
!       }
        c=vget("cwd");
        if (strcmp(currentjob->dir,c))	/* if directory has changed */
  	fprintf(stderr,"[%d] %d %s (wd now: %s)\n",currentjob->jobnumber,currentjob->pid,currentjob->name,currentjob->dir);

--- 788,794 -----
        {
          write(2,"Can't fg this pid\n",18);
          return;
!       } *** This is wrong. All are in their own process group now */
        c=vget("cwd");
        if (strcmp(currentjob->dir,c))	/* if directory has changed */
  	fprintf(stderr,"[%d] %d %s (wd now: %s)\n",currentjob->jobnumber,currentjob->pid,currentjob->name,currentjob->dir);
***************
*** 781,788
        fflush(stderr);
        update(pid,0);		/* clear status */
        newcurr();		/* change current job to this one (with luck) */
!       kill(pid,SIGCONT);
!       (void) waitfor(pid);			/* do the waiting here. */
        return;
      }
      else

--- 797,807 -----
        fflush(stderr);
        update(pid,0);		/* clear status */
        newcurr();		/* change current job to this one (with luck) */
! #ifdef DEBUG
!       fprintf(stderr,"sending CONT to %d grp\n",pid);
! #endif
!       if (killpg(pid,SIGCONT)) perror("killpg");
!       else (void) waitfor(pid);			/* do the waiting here. */
        return;
      }
      else
***************
*** 812,818
  #ifdef DEBUG
  fprintf(stderr,"fg-ing %d\n",pid);
  #endif
!     if (setpgrp(pid,getpgrp(0))==-1)	/* set process group to the shell's */
      {
        write(2,"Can't fg this pid\n",18);
        return;

--- 831,837 -----
  #ifdef DEBUG
  fprintf(stderr,"fg-ing %d\n",pid);
  #endif
!     if (pid!=getpgrp(pid))
      {
        fprintf(stderr,"Can't bring pid:%d to the foreground.\n",pid);
        fflush(stderr);
***************
*** 814,819
  #endif
      if (setpgrp(pid,getpgrp(0))==-1)	/* set process group to the shell's */
      {
        write(2,"Can't fg this pid\n",18);
        return;
      }

--- 833,845 -----
  #endif
      if (pid!=getpgrp(pid))
      {
+       fprintf(stderr,"Can't bring pid:%d to the foreground.\n",pid);
+       fflush(stderr);
+       continue;
+     }
+     setexec(pid);	/* 
+     /*if (setpgrp(pid,getpgrp(0))==-1)	/* set process group to the shell's 
+     {
        write(2,"Can't fg this pid\n",18);
        return;
      } *** This is wrong. All things are in their own group now */
***************
*** 816,822
      {
        write(2,"Can't fg this pid\n",18);
        return;
!     }
      ptr=findjob(pid);
      c=vget("cwd");
      if (strcmp(ptr->dir,c))	/* if directory has changed */

--- 842,848 -----
      {
        write(2,"Can't fg this pid\n",18);
        return;
!     } *** This is wrong. All things are in their own group now */
      ptr=findjob(pid);
      c=vget("cwd");
      if (strcmp(ptr->dir,c))	/* if directory has changed */
***************
*** 826,833
      fflush(stderr);
      update(pid,0);		/* clear status */
      newcurr();			/* change current job to this one (with luck) */
!     kill(pid,SIGCONT);
!     (void) waitfor(pid);			/* do the waiting here. */
    }
  }
  

--- 852,862 -----
      fflush(stderr);
      update(pid,0);		/* clear status */
      newcurr();			/* change current job to this one (with luck) */
! #ifdef DEBUG
!     fprintf(stderr,"sending CONT to %d pg\n",pid);
! #endif
!     if (killpg(pid,SIGCONT)) perror("killpg");
!     else (void) waitfor(pid);			/* do the waiting here. */
    }
  }
  
***************
*** 848,854
      if (currentjob)
      {
        pid=currentjob->pid;				/* current job */
!       if (setpgrp(pid,pid)==-1)
        {
          write(2,"Can't bg this pid\n",18);
          return;

--- 877,883 -----
      if (currentjob)
      {
        pid=currentjob->pid;				/* current job */
!       /*if (setpgrp(pid,pid)==-1)
        {
          write(2,"Can't bg this pid\n",18);
          return;
***************
*** 852,858
        {
          write(2,"Can't bg this pid\n",18);
          return;
!       }
        fprintf(stderr,"[%d] %d %s\n",currentjob->jobnumber,currentjob->pid,currentjob->name);
        fflush(stderr);
        update(pid,0);		/* clear status */

--- 881,887 -----
        {
          write(2,"Can't bg this pid\n",18);
          return;
!       }   *** Don't need this, already done now */
        fprintf(stderr,"[%d] %d %s\n",currentjob->jobnumber,currentjob->pid,currentjob->name);
        fflush(stderr);
        update(pid,0);		/* clear status */
***************
*** 857,863
        fflush(stderr);
        update(pid,0);		/* clear status */
        newcurr();		/* change current job to this one (with luck) */
!       kill(pid,SIGCONT);
      }
      else
      {

--- 886,895 -----
        fflush(stderr);
        update(pid,0);		/* clear status */
        newcurr();		/* change current job to this one (with luck) */
! #ifdef DEBUG
!       fprintf(stderr,"killpg on pid %d\n",pid);
! #endif
!       if (killpg(pid,SIGCONT)) perror("killpg");
      }
      else
      {
***************
*** 883,889
        if (!isanum(c)) continue;
        pid=atoi(c);
      }
!     if (setpgrp(pid,pid)==-1)
      {
        write(2,"Can't bg this pid\n",18);
        return;

--- 915,921 -----
        if (!isanum(c)) continue;
        pid=atoi(c);
      }
!     /*if (setpgrp(pid,pid)==-1)
      {
        write(2,"Can't bg this pid\n",18);
        return;
***************
*** 887,893
      {
        write(2,"Can't bg this pid\n",18);
        return;
!     }
      ptr=findjob(pid);
      fprintf(stderr,"[%d] %d %s\n",ptr->jobnumber,ptr->pid,ptr->name);
      fflush(stderr);

--- 919,925 -----
      {
        write(2,"Can't bg this pid\n",18);
        return;
!     }  *** Don't need this, now, already done */
      ptr=findjob(pid);
      fprintf(stderr,"[%d] %d %s\n",ptr->jobnumber,ptr->pid,ptr->name);
      fflush(stderr);
***************
*** 893,899
      fflush(stderr);
      update(pid,0);		/* clear status */
      newcurr();			/* change current job to this one (with luck) */
!     kill(pid,SIGCONT);
    }
  }
  

--- 925,931 -----
      fflush(stderr);
      update(pid,0);		/* clear status */
      newcurr();			/* change current job to this one (with luck) */
!     if (killpg(pid,SIGCONT)) perror("killpg");
    }
  }
  
//E*O*F builtin.cdif//

echo x - clex.cdif
cat > "clex.cdif" << '//E*O*F clex.cdif//'
*** ../Patch1/clex.c	Thu Jun  1 17:01:44 1989
--- clex.c	Thu Jun  1 16:53:46 1989
***************
*** 129,135
    int i=0,max,looping=1,bltin;
    char c;
  
-   buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat)));
    yankprev(line,*pos,word);	/* first get the thing we're trying to expand */
  
  /* Look for a slash to see if its a relative path name or current directory.

--- 129,134 -----
    int i=0,max,looping=1,bltin;
    char c;
  
    yankprev(line,*pos,word);	/* first get the thing we're trying to expand */
  
  /* Look for a slash to see if its a relative path name or current directory.
***************
*** 205,210
        }
        max=strlen(&word[i+1]);
        start=0;
        while ((entry=readdir(dd))!=NULL)
  /* Check to see if the chars we typed match so far */
  	if (!strncmp(&word[i+1],entry->d_name,max))

--- 204,210 -----
        }
        max=strlen(&word[i+1]);
        start=0;
+       buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat)));
        while ((entry=readdir(dd))!=NULL)
  /* Check to see if the chars we typed match so far */
  	if (!strncmp(&word[i+1],entry->d_name,max))
***************
*** 227,232
  	  else ptr->c_isdir=FALSE;
  	}
        closedir(dd);
      }
    }
    else /* no slash */

--- 227,233 -----
  	  else ptr->c_isdir=FALSE;
  	}
        closedir(dd);
+       free(buf);
      }
    }
    else /* no slash */
***************
*** 239,244
  	printf("\n%sCan't open %s\n",beep,PASSWD);
  	prprompt(1);
  	show(line,curs,TRUE);
        }
        for (i=0;word[i];i++)
  	word[i]=word[i+1];

--- 240,246 -----
  	printf("\n%sCan't open %s\n",beep,PASSWD);
  	prprompt(1);
  	show(line,curs,TRUE);
+ 	return;
        }
        for (i=0;word[i];i++)
  	word[i]=word[i+1];
***************
*** 318,323
  	}
  	if (t!=WORD) continue;		/* illegal path component ignored */
  	if ((dd=opendir(dir))==NULL) continue;	/* same again */
  	while ((entry=readdir(dd))!=NULL)
  	/* Check to see if the chars we typed match so far */
  	  if (!strncmp(word,entry->d_name,max))

--- 320,326 -----
  	}
  	if (t!=WORD) continue;		/* illegal path component ignored */
  	if ((dd=opendir(dir))==NULL) continue;	/* same again */
+ 	buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat)));
  	while ((entry=readdir(dd))!=NULL)
  	/* Check to see if the chars we typed match so far */
  	  if (!strncmp(word,entry->d_name,max))
***************
*** 340,345
  	    else ptr->c_isdir=FALSE;
  	  }
          closedir(dd);
        } /* end while retsym*/
      } /* end else ~ */
    } /* end else findslash */

--- 343,349 -----
  	    else ptr->c_isdir=FALSE;
  	  }
          closedir(dd);
+ 	free(buf);
        } /* end while retsym*/
      } /* end else ~ */
    } /* end else findslash */
***************
*** 416,422
    int i,bltin,max,index=0,maxlength=0,temp,compare();
    extern int beeplength;
    
-   buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat)));
    if ((pos==0) || (line[pos-1]==' '))
      strcpy(word,"");		/* nothing there to get */
    else

--- 420,425 -----
    int i,bltin,max,index=0,maxlength=0,temp,compare();
    extern int beeplength;
    
    if ((pos==0) || (line[pos-1]==' '))
      strcpy(word,"");		/* nothing there to get */
    else
***************
*** 488,493
  	show(line,curs,TRUE);
  	return;
        }
        while ((entry=readdir(dd))!=NULL)
        {
  	if (entry->d_name[0]=='.' && (entry->d_name[1]=='.' || entry->d_name[1]==EOS))

--- 491,497 -----
  	show(line,curs,TRUE);
  	return;
        }
+       buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat)));
        while ((entry=readdir(dd))!=NULL)
        {
  	if (entry->d_name[0]=='.' && (entry->d_name[1]=='.' || entry->d_name[1]==EOS))
***************
*** 512,517
  	}
        }
        closedir(dd);
      }
    }
    else	/* no slash */

--- 516,522 -----
  	}
        }
        closedir(dd);
+       free(buf);
      }
    }
    else	/* no slash */
//E*O*F clex.cdif//

exit 0

wtoomey@gara.une.oz (Warren Toomey) (06/01/89)

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# comlined.c

echo x - comlined.c
cat > "comlined.c" << '//E*O*F comlined.c//'
/******************************************************************************
**                                                                           **
**                                comlined.c                                 **
**                 This file contains the COMmand LINe EDitor.               **
**                                                                           **
******************************************************************************/

#include "header.h"

	/* Minix seems to have a strange stdio.h FILE struct */

#ifdef MINIX
#define _file	_fd
#endif

extern char termcapbuf[];
extern FILE *zin,*zout,*fopen();

#ifndef ATARI_ST
void mputc(c,f,curs)
  char c;
  FILE *f;
  int curs[];
{
  extern int wid;

  write(f->_file,&c,1);
  curs[0]++;
  if (curs[0]>=wid)
  {
    write(f->_file,"\n",1);			/* goto start of next line */
    curs[0]=curs[0]%wid;			/* hopefully gives zero */
    curs[1]++;
  }
}
#else
void mputc(c,f,curs)
  int c;
  FILE *f;
  int curs[];
{
  extern int wid;
  char cc = c;
  
  write(f->_file,&cc,1);
  curs[0]++;
  if (curs[0]>=wid)
  {
    write(f->_file,"\n",1);			/* goto start of next line */
    curs[0]=curs[0]%wid;			/* hopefully gives zero */
    curs[1]++;
  }
}
#endif

#ifndef ATARI_ST
void oputc(c)
  char c;
{
  write(zout->_file,&c,1);
}
#else
int oputc(c)
  int c;
{
    char cc = c;
    return write(zout->_file,&cc,1);
}
#endif

void go(curs,hor,vert)
  int curs[],hor,vert;
{
  extern char bs[],nd[],up[];
  int hdiff,vdiff;

  vdiff=vert-curs[1];			/* vertical difference between */
					/* current and future positions */

  if (vdiff<=0)				/* if negative go up */
    for(;vdiff;vdiff++) tputs(up,1,oputc);
  else					/* else go down */
  {
    for(;vdiff;vdiff--) write(1,"\n",1);
    curs[0]=0;
  }
    
  hdiff=hor-curs[0];			/* horizontal difference between */
					/* current and future positions */
  curs[0]=hor; curs[1]=vert;		/* a new current pos, hopefully */
	/* assigned here because hor changed below and curs needed above */

  if (hdiff<0)				/* if negative go back */
    if (-hdiff<=hor)			/* if shorter distance just use ^H */
      for(;hdiff;hdiff++) write(zout->_file,bs,strlen(bs));
    else				/* else cr and go forward */
    {
      write(zout->_file,"\r",1);
      for (;hor;hor--) tputs(nd,1,oputc);
    }
  else					/* have to go forward */
   for (;hdiff;hdiff--) tputs(nd,1,oputc);

}

void backward(curs)
  int curs[];
{
  extern int wid;
  extern char bs[];

  if (curs[0]==0)
    go(curs,wid-1,curs[1]-1);
  else
  {
    write(zout->_file,bs,strlen(bs));
    curs[0]--;
  }
}

void forward(curs)
  int curs[];
{
  extern int wid;
  extern char nd[];

  curs[0]++;
  if (curs[0]>=wid)
  {
    write(zout->_file,"\n",1);		/* goto start of next line */
    curs[0]=curs[0]%wid;		/* hopefully gives zero */
    curs[1]++;
  }
  else tputs(nd,1,oputc);
}

void clrscrn()
{
  extern char cl[];

  tputs(cl,1,oputc);			/* clear the screen */
}

void insert(line,pos,letter,curs)
  char *line,letter;
  int pos,curs[];
{
  extern int wid;
  int i,horig,vorig;
  char c;

  for (i=pos;line[i];i++);			/* goto end of line */
  for (;i!=pos;i--) line[i]=line[i-1];		/* copy characters forward */
  line[pos]=letter;				/* insert new char */
  if (letter<32) horig=curs[0]+2;
  else horig=curs[0]+1;
  vorig=curs[1];
  if (horig>wid-1)
  {
    horig=horig%wid;
    vorig++;
  }
  for (c=line[pos];c;c=line[++pos])		/* write out rest of line */
  {
    if (c<32)					/* if it's a control char */
    {
      mputc('^',zout,curs);			/* print out the ^ and */
      mputc(c+64,zout,curs);			/* the equivalent char for it*/
    }
    else mputc(c,zout,curs);
  }
  go(curs,horig,vorig);
}

#ifdef __STDC__
void show(char *line, int *curs, bool clearing)
#else
void show(line,curs,clearing)
  char *line;
  int curs[];
  bool clearing;
#endif
{
  extern int lenprompt;
  int pos=0,horig,vorig;
  char c;

  horig=curs[0];vorig=curs[1];			/* save original values */
  if (clearing==TRUE)
  {
    curs[0]=lenprompt;curs[1]=0;
  }
  else
  {
    go(curs,lenprompt,0);			/* goto start of line */
  }
  for (c=line[pos];c!=EOS;c=line[++pos])	/* write out rest of line */
    if (c<32)					/* if it's a control char */
    {
      mputc('^',zout,curs);			/* print out the ^ and */
      mputc(c+64,zout,curs);			/* the equivalent char for it*/
    }
    else mputc(c,zout,curs);
  go(curs,horig,vorig);			/* go back from whence you came */
}

void goend(line,pos,curs)
  char *line;
  int *pos,curs[];
{
  char c;

  for (c=line[*pos];c;c=line[++(*pos)])
  {
    if (c<32)
    {
      mputc('^',zout,curs);
      mputc(c+64,zout,curs);
    }
    else mputc(c,zout,curs);
  }
}

void copyback(line,pos,curs,count)
  char *line;
  int pos,curs[],count;
{
  char c;
  int i,horig,vorig,wipe;

#ifdef DEBUG
  fprintf(stderr,"pos %d count %d\n",pos,count);
#endif
  if ((i=pos+count)<MAXLL)
  {
    wipe=0;
    for (;line[i]!=EOS;++i)		/* copy line back count chars */
      line[i-count]=line[i];
    for (horig=i-count;i>horig && i<MAXLL+1;i--)
    {
      if (line[i-count]<32) wipe+=2;	/* tally how much we need to wipe */
      else wipe++;
      line[i-1]=EOS;			/* end with nulls */
    }
  }
  else
  {
    write(2,"count passed to copyback is too big\n",35);
    return;
  }
  horig=curs[0];vorig=curs[1];
  for (c=line[pos];c;c=line[++pos])
    if (c<32)
    {
      mputc('^',zout,curs);
      mputc(c+64,zout,curs);
    }
    else mputc(c,zout,curs);
#ifdef DEBUG
  fprintf(stderr,"wipe %d\n",wipe);
#endif
  for (i=0;i<wipe;i++) mputc(' ',zout,curs);	/* blank old chars */
  go(curs,horig,vorig);
}

void delnextword(line,pos,curs)
  char *line;
  int pos,curs[];
{
  int inword=0,l=1,charcount=0;

  while(l)
    switch(line[pos+charcount])
    {
      case EOS:
	l=0;
	break;
      case ' ':case '\t':case '>':case '<':case '|':
      case ';':case '=':case '+':case '&':case '`':
	if (inword) l=0;
	else charcount++;
	break;
      default:
	inword=1;
	charcount++;
    }
#ifdef DEBUG
  fprintf(stderr,"Deleting %d chars\n",charcount);
#endif
  copyback(line,pos,curs,charcount);
}

void delprevword(line,pos,curs)
  char *line;
  int *pos,curs[];
{
  int inword=0,l=1,charcount=0;
  char c;

  while(l)
    if ((*pos)>0)
      switch (c=line[(*pos)-1])
      {
	case ' ':case '\t':case '<':case '>':case '|':
	case ';':case '=':case '+':case '&':case '`':
	  if (inword) l=0;
	  else
	  {
	    charcount++;
	    (*pos)--;
	  }
	  break;
	default:
	  inword=1;
	  charcount++;
	  (*pos)--;
      }
    else l=0;
#ifdef DEBUG
  fprintf(stderr,"Deleting %d chars\n",charcount);
#endif
/* l should be zero already, aren't I naughty! */
  for (;l<charcount;l++) backward(curs);	/* move back */
  copyback(line,*pos,curs,charcount);		/* and copy the line on top */
}

void backword(line,pos,curs)
  char *line;
  int *pos,curs[];
{
  int inword=0,l=1;
  char c;

  while(l)
    if ((*pos)>0)
      switch (c=line[(*pos)-1])
      {
	case ' ':case '\t':case '<':case '>':case '|':
	case ';':case '=':case '+':case '&':case '`':
	  if (inword) l=0;
	  else
	  {
	    backward(curs);
	    (*pos)--;
	  }
	  break;
	default:
	  inword=1;
	  if (c<32) backward(curs);
	  backward(curs);
	  (*pos)--;
      }
    else l=0;
}

void forword(line,pos,curs)
  char *line;
  int *pos,curs[];
{
  int inspace=0,l=1;
  char c;

  while(l)
    switch (c=line[*pos])
    {
      case EOS:
	l=0;
	break;
      case ' ':case '\t':case '<':case '>':case '|':
      case ';':case '=':case '+':case '&':case '`':
	inspace=1;
	forward(curs);
	(*pos)++;
	break;
      default:
	if (inspace) l=0;
	else
	{
	  if (c<32) forward(curs);
	  forward(curs);
	  (*pos)++;
	}
    }
}

void yanknext(line,pos,yankbuf)
  char *line,*yankbuf;
  int pos;
{
  int l=1,inword=0,i=0;

  while(l)
    switch(line[pos])
    {
      case EOS:
	l=0;
	yankbuf[i]=EOS;
	break;
      case ' ':case '\t':case '<':case '>':case '|':
      case ';':case '=':case '+':case '&':case '`':
	if (inword)
	{
	  l=0;
	  yankbuf[i]=EOS;
	}
	else
	  yankbuf[i++]=line[pos++];
	break;
      default:
	inword=1;
	yankbuf[i++]=line[pos++];
    }
}

void yankprev(line,pos,yankbuf)
  char *line,*yankbuf;
  int pos;
{
  int stpos=pos,inword=0,l=1;

  while(l && stpos>0)			/* this loop finds the start of the */
    switch(line[stpos-1])		/* previous word (at stpos) */
    {
      case ' ':case '\t':case '>':case '<':case '|':case '"':
      case ';':case '=':case '+':case '&':case '`':case '\'':
	if (inword) l=0;
	else stpos--;
	break;
      default:
	inword=1;
	stpos--;
    }
  for (l=0;stpos<pos;stpos++,l++)	/* then copy from stpos upto pos */
    yankbuf[l]=line[stpos];
  yankbuf[l]=EOS;
}

void clrline(line,pos,curs)
  char *line;
  int pos,curs[];
{
  extern bool tflagexist();
  extern char cd[];
  int i,horig,vorig;

  if (tflagexist("cd",termcapbuf)==TRUE)	/* If there's a special char for clr */
  {					/* then use it */
    tputs(cd,1,oputc);
    for (i=pos;line[i];i++) line[i]=EOS;
  }
  else					/* else we gotta use spaces. */
  {
    horig=curs[0];vorig=curs[1];	/* Orginal values for curs set. */

    for (i=pos;line[i];i++)		/* Wipe out all those chars */
    {					/* with spaces (so slow), */
      mputc(' ',zout,curs);
      if (line[i]<32) mputc(' ',zout,curs);
      line[i]=EOS;
    }
    go(curs,horig,vorig);		/* restore original curs position */
  }
}

void transpose(line,pos,curs)
  char *line;
  int pos,curs[];
{
  char temp;

  if (line[pos-1]<32) backward(curs);
  backward(curs);
  temp=line[pos];
  line[pos]=line[pos-1];
  line[pos-1]=temp;
  if (line[pos-1]<32)
  {
    mputc('^',zout,curs);
    mputc(line[pos-1]+64,zout,curs);
  }
  else mputc(line[pos-1],zout,curs);
  if (line[pos]<32)
  {
    mputc('^',zout,curs);
    mputc(line[pos]+64,zout,curs);
  }
  else mputc(line[pos],zout,curs);
  if (line[pos]<32) backward(curs);
  backward(curs);
}

int strip(line)
  char *line;
{
  int i,nosave=0;

  for (i=0;line[i]==' ';i++);
  if (line[i]=='#')
  {
    nosave=1;
    i++;
  }
  if (i) strcpy(line,&line[i]);
  return(nosave);
}

void tardis(line,pos,curs)
  char *line;
  int *pos,curs[];
{
  extern void loadhist();
  extern char beep[];
  extern int curr_hist,matchhist(),beeplength;
  int hnum;

/* matchhist finds the history line matching the previous command and returns
   the one after that, predicting that you want to do the same thing. */
  hnum=matchhist(curr_hist-1);
  if (hnum) loadhist(line,pos,hnum,curs);
  else write(1,beep,beeplength);
}

bool getline(line,nosave,feature_off)
  char *line;
  int *nosave,feature_off;
{
  extern int curr_hist,maxhist,lenprompt,O_echoline,beeplength;
  extern char beep[],yankbuf[],*vget();
  extern void loadhist(),savehist(),leave_shell(),complete(),nameopt(),prprompt(),help();
  char c;
  int times=1,i,pos=0,hist=curr_hist,curs[2],hsave=lenprompt,vsave=0,possave=0
      ,try=0;

  curs[0]=lenprompt;	/*lenprompt global set by prprompt or when prompt set*/
  curs[1]=0;					/* start on line 0 */
  if (vget("TARDIS")!=(char *)UNDEF && !feature_off)
    tardis(line,&pos,curs);
  while (1)
  {
    c=getc(zin);
    for (;times>0;times--)
    switch(c)
    {
      case EOF : fprintf(stderr,"Help me, I'm being hit by a looney with a stick.\n");
		 if (!try)
		 {
		   fprintf(stderr,"Trying to reassign stdin...");
		   zin=stdin;
		   try=1;
		   continue;
		 }
		 else
		 {
		   fprintf(stderr,"Trying to reopen stdin...");
		   if ((zin=fopen("/dev/tty","w+"))==NULL)
		   {
		     fprintf(stderr,"failed!\n");
		     exit(1);
		   }
		   fprintf(stderr,"Successful!\n");
		   try=0;
		 }
		 continue;
      case EOS : hsave=curs[0];			/* save position (make mark) */
		 vsave=curs[1];
		 possave=pos;
		 break;
      case  1  : go(curs,lenprompt,0);	/* goto start of the line */
		 pos=0;
		 break;
      case  2  : if (pos>0)			/* if not at home, go back */
		 {
		   if (line[pos-1]<32) backward(curs);
		   backward(curs);
		   pos--;
		 }
		 else write(1,beep,beeplength);		/* else ring bell */
		 break;
      case  3  : goend(line,&pos,curs);
		 write(zout->_file,"\n",1);
		 return(FALSE);
      case  4  : if (line[0]==EOS && !feature_off) leave_shell(); /*eof*/
		 else if (line[pos]!=EOS)
			copyback(line,pos,curs,1); /* delete char */
		      else if (!feature_off) nameopt(line,pos,curs);
		 break;
      case  5  : goend(line,&pos,curs);		/* goto end of the line */
		 break;
      case  6  : if (line[pos]!=EOS)		/* if not at end, go forward */
		 {
		   if (line[pos]<32) forward(curs);
		   forward(curs);
		   pos++;
		 }
		 else write(1,beep,beeplength);		/* else ring bell */
		 break;
      case  7  : pos=0;				/* kill the whole line */
		 go(curs,lenprompt,0);		/* goto start */
		 clrline(line,0,curs);		/* and kill from pos=0 */
		 hist=curr_hist;		/* reset hist */
		 break;
      case  127:
      case  8  : if (pos>0)			/* if not at home, delete */
		 {
		   if (line[pos-1]<32) backward(curs);
		   backward(curs);
		   copyback(line,--pos,curs,1); /*move line back on to prev char*/
		 }
		 else write(1,beep,beeplength);		/* else ring bell */
		 break;
      case '\t': if (line[0]!=EOS)
		   complete(line,&pos,curs);	/* try to complete word */
		 else write(1,beep,beeplength);
		 break;
      case '\r':				/* end of the line, go and */
      case '\n': goend(line,&pos,curs);
		 write(zout->_file,"\n",1);
		 if (feature_off) return(TRUE);
		 *nosave=strip(line);			/* process it now */
		 if (line[0]!=EOS)
		 {
		   if (O_echoline)
		   {
		     write(2,line,strlen(line));
		     write(2,"\n",1);
		   }
		   return(TRUE);
		 }
		 else return(FALSE);
      case  11 : clrline(line,pos,curs);	/* kill line from cursor on */
		 break;
      case  12 : if (feature_off) break;
		 clrscrn();			/* Clear the screen */
		 prprompt(1);			/* Reprint the prompt and */
		 show(line,curs,TRUE);		/* the line typed so far. */
		 break;
      case  14 : if (feature_off) break;
		 if (hist<curr_hist)		/* put next hist in line buf */
		   loadhist(line,&pos,++hist,curs);
		 else if (hist==curr_hist)
		      	tardis(line,&pos,curs);
		      else
			write(1,beep,beeplength);
		 break;
      case  15 : continue;
      case  16 : if (feature_off) break;
		 if (hist>curr_hist-maxhist && hist>1)	/* put prev hist in line buf */
		 {
		   if (hist==curr_hist)
		     savehist(line,curr_hist,maxhist);
		   loadhist(line,&pos,--hist,curs);
		 }
		 else write(1,beep,beeplength);
		 break;
      case  17 : continue;
      case  18 : show(line,curs,FALSE);		/* reprint the line */
		 break;
      case  19 : continue;
      case  20 : if (pos>0 && line[pos]!=EOS)	/* if not home or at end */
		   transpose(line,pos,curs);	/* swap current and prev char */
		 else write(1,beep,beeplength);		/* else ring bell */
		 break;
      case  21 : times=0;
		 c=getc(zin);
		 while(isdigit(c))
		 {
		   times=times*10+c-48;
		   c=getc(zin);
		 }
		 times++;	/* need to add 1 because it's dec'ed */
		 break;	/* immediately at end of for loop */
      case  22 : if (pos>=MAXLL)
		 {
		   write(1,beep,beeplength);
		   continue;
		 }
		 mputc('"',zout,curs); backward(curs);	/* literal char */
		 c=getc(zin);
		 if (c)			/* don't allow EOS (null) */
		   insert(line,pos++,c,curs);
		 break;
      case  23 : if (pos) delprevword(line,&pos,curs);
		 else write(1,beep,beeplength);
		 break;
      case  24 : pos=possave;
		 go(curs,hsave,vsave);
		 break;
      case  25 : if (pos!=0)				/* if not at home */
		   yankprev(line,pos,yankbuf);		/* yank previous word */
		 else write(1,beep,beeplength);		/* else ring bell */
		 break;
      case  26 : continue;
      case  27 : switch(c=getc(zin))
		 {
		   case   4 : if (!feature_off) nameopt(line,pos,curs);
			      break;
		   case 0177:
		   case   8 : if (pos>0)
			      {
				backward(curs);
				copyback(line,--pos,curs,1);
			      }
			      else write(1,beep,beeplength);
			      break;
		   case  12 : if (feature_off) break;
			      clrscrn();
			      prprompt(1);
			      show(line,curs,TRUE);
			      break;
		   case  27 :
		   case '\t': if (!feature_off)
				if (line[0]!=EOS) complete(line,&pos,curs);
				else write(1,beep,beeplength);
			      break;
		   case 'b' : case 2:
		   case 'B' : if (pos>0) backword(line,&pos,curs);
			      else write(1,beep,beeplength);
			      break;
		   case 'd' :
		   case 'D' : if (line[pos]!=EOS) delnextword(line,pos,curs);
			      else write(1,beep,beeplength);
			      break;
		   case 'f' : case 6:
		   case 'F' : if (line[pos]!=EOS) forword(line,&pos,curs);
			      else write(1,beep,beeplength);
			      break;
		   case 'h' :
		   case 'H' : if (!feature_off) help(line,pos,curs);
			      break;
		   case 'p' :
		   case 'P' : if (pos>MAXLL-strlen(yankbuf))
			      {
				write(1,beep,beeplength);
				break;
			      }
			      for (i=0;yankbuf[i];i++)	/* insert yank buffer */
				insert(line,pos++,yankbuf[i],curs);
			      break;
		   case  25 : if (pos!=0)		/* as above */
				yankprev(line,pos,yankbuf);
			      else write(1,beep,beeplength);
			      break;
		   case 'y' :
		   case 'Y' : if (line[pos]!=EOS)	/* if not at end */
				yanknext(line,pos,yankbuf);/* yank next word */
			      else write(1,beep,beeplength);/* else ring bell */
			      break;
		   case 'w' : case 23:
		   case 'W' : if (pos)	/* if not at end */
				delprevword(line,&pos,curs);
			      else write(1,beep,beeplength);
			      break;
		   case '0':case '1':case '2':case '3':case '4':
		   case '5':case '6':case '7':case '8':case '9':
			      times=0;
			      while(isdigit(c))
			      {
				times=times*10+c-48;
				c=getc(zin);
			      }
			      times++;	/* need to add 1 because it's dec'ed */
			      break;	/* immediately at end of for loop */
		   case '/' : if (line[pos])		/* search forward */
			      {
				c=getc(zin);		/* char to search for */
				for (i=pos+1;line[i] && c!=line[i];i++);
				if (line[i])
				  while (pos<i)
				  {
				    pos++;
				    if (line[pos-1]<32) forward(curs);
				    forward(curs);
				  }
				else write(1,beep,beeplength);	/* not found */
			      }
			      else write(1,beep,beeplength);/* at end of line */
			      break;
		   case '?' : if (pos>0)		/* search backwards */
			      {
				c=getc(zin);		/* char to search for */
				for (i=pos-1;i>=0 && c!=line[i];i--);
				if (i>=0)
				  while (pos>i)
				  {
				    pos--;
				    if (line[pos]<32) backward(curs);
				    backward(curs);
				  }
				else write(1,beep,beeplength);	/* not found */
			      }
			      else write(1,beep,beeplength);	/* at end of line */
			      break;
		   default :  write(1,beep,beeplength);
		 }
		 break;
      case  29 : continue;
      default  : if (pos>=MAXLL)
		 {
		   write(1,beep,beeplength);
		   break;
		 }
		 insert(line,pos++,c,curs);
		 break;
    }
    times=1;
  }
}

//E*O*F comlined.c//

exit 0

wtoomey@gara.une.oz (Warren Toomey) (06/01/89)

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# exec.cdif global.c hash.cdif header.hdif

echo x - exec.cdif
cat > "exec.cdif" << '//E*O*F exec.cdif//'
*** ../Patch1/exec.c	Thu Jun  1 17:02:51 1989
--- exec.c	Thu Jun  1 16:54:59 1989
***************
*** 19,25
  struct adefn *alias_defn;
  int stopflg,NoIoctl=0;
  
! void setexec()
  {
  #ifdef ATT
    struct termio tbuf;

--- 19,26 -----
  struct adefn *alias_defn;
  int stopflg,NoIoctl=0;
  
! void setexec(pid)
!   int pid;
  {
  #ifdef ATT
    struct termio tbuf;
***************
*** 46,51
  fprintf(stderr,"set exec\n");
  #endif
  
    termod=(struct sgttyb *) malloc ((unsigned)(sizeof(struct sgttyb)));
    if (ioctl(0,TIOCGETP,termod)) perror("ioctl in setexec");
    termod->sg_flags &= (~CBREAK);		/* cooked mode */

--- 47,53 -----
  fprintf(stderr,"set exec\n");
  #endif
  
+ /*** All this will be rewritten ***/
    termod=(struct sgttyb *) malloc ((unsigned)(sizeof(struct sgttyb)));
    if (ioctl(0,TIOCGETP,termod)) perror("ioctl in setexec");
    termod->sg_flags &= (~CBREAK);		/* cooked mode */
***************
*** 51,56
    termod->sg_flags &= (~CBREAK);		/* cooked mode */
    termod->sg_flags |= ECHO;			/* with echo */
    if (ioctl(0,TIOCSETN,termod)) perror("ioctl");
    setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars)));
    if (ioctl(0,TIOCGETC,setsigc)) perror("ioctl");
    setsigc->t_intrc=03;				/* interrupt ctrl c */

--- 53,59 -----
    termod->sg_flags &= (~CBREAK);		/* cooked mode */
    termod->sg_flags |= ECHO;			/* with echo */
    if (ioctl(0,TIOCSETN,termod)) perror("ioctl");
+   free(termod);
    setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars)));
    if (ioctl(0,TIOCGETC,setsigc)) perror("ioctl");
    setsigc->t_intrc=03;				/* interrupt ctrl c */
***************
*** 57,62
    setsigc->t_quitc=034;				/* quit ctrl \ */
    setsigc->t_eofc=04;				/* eof ctrl d */
    if (ioctl(0,TIOCSETC,setsigc)) perror("ioctl");
  # ifndef MINIX
    moresigc.t_suspc=032;				/* suspend ctrl z */
    moresigc.t_dsuspc=031;			/* delayed suspend ctrl y */

--- 60,66 -----
    setsigc->t_quitc=034;				/* quit ctrl \ */
    setsigc->t_eofc=04;				/* eof ctrl d */
    if (ioctl(0,TIOCSETC,setsigc)) perror("ioctl");
+   free(setsigc);
  # ifndef MINIX
    moresigc.t_suspc=032;				/* suspend ctrl z */
    moresigc.t_dsuspc=031;			/* delayed suspend ctrl y */
***************
*** 65,70
    moresigc.t_werasc=027;			/* word erase ctrl w */
    moresigc.t_lnextc=026;			/* literal next char ctrl v */
    if (ioctl(0,TIOCSLTC,&moresigc)) perror("ioctl");
  # endif
  
  #endif

--- 69,86 -----
    moresigc.t_werasc=027;			/* word erase ctrl w */
    moresigc.t_lnextc=026;			/* literal next char ctrl v */
    if (ioctl(0,TIOCSLTC,&moresigc)) perror("ioctl");
+   if (pid)	/* this is so when setexec is called without pid just to set the
+ 	      signal keys, it doesn't repeat this bit (if that ever happens). */
+   {
+     if (ioctl(0,TIOCSPGRP,&pid)) perror("ioctl spg");
+ #ifdef DEBUG
+     if (ioctl(0,TIOCGPGRP,&pid)) perror("Dioctl");
+     fprintf(stderr,"terminal's pgrp is %d\n",pid);
+     fprintf(stderr,"Setting pgrp to %d\n",pid);
+ #endif
+     if (setpgrp(pid,pid)) perror("setpgrp");
+     signal(SIGTTIN,SIG_DFL);
+   }
  # endif
  /*** end of rewrite ***/
  
***************
*** 66,71
    moresigc.t_lnextc=026;			/* literal next char ctrl v */
    if (ioctl(0,TIOCSLTC,&moresigc)) perror("ioctl");
  # endif
  
  #endif
  

--- 82,88 -----
      signal(SIGTTIN,SIG_DFL);
    }
  # endif
+ /*** end of rewrite ***/
  
  #endif
  
***************
*** 76,81
  #ifndef MINIX
    int pid;
  
    pid=getpid();
    setpgrp(pid,pid);
    signal(SIGTTIN,SIG_DFL);

--- 93,101 -----
  #ifndef MINIX
    int pid;
  
+ #ifdef DEBUG
+   fprintf(stderr,"setbgexec\n");
+ #endif
    pid=getpid();
    setpgrp(pid,pid);
    signal(SIGTTIN,SIG_DFL);
***************
*** 176,185
      {
        if (stopflg) break;
        retval=0;
- #if 0
-       /* WAS: same problem here as in main.c:fopen() */
-       act=intercom(line,&pos,&pid,FALSE,NULL,fromfile);
- #else
        act=intercom(line,&pos,&pid, &i, FALSE,fromfile);
  #endif
  

--- 196,201 -----
      {
        if (stopflg) break;
        retval=0;
        act=intercom(line,&pos,&pid, &i, FALSE,fromfile);
  
  #ifdef DEBUG
***************
*** 181,187
        act=intercom(line,&pos,&pid,FALSE,NULL,fromfile);
  #else
        act=intercom(line,&pos,&pid, &i, FALSE,fromfile);
- #endif
  
  #ifdef DEBUG
  fprintf(stderr,"pid returned from intercom is %d for line %s\n",pid,line);

--- 197,202 -----
        if (stopflg) break;
        retval=0;
        act=intercom(line,&pos,&pid, &i, FALSE,fromfile);
  
  #ifdef DEBUG
  fprintf(stderr,"pid returned from intercom is %d for line %s\n",pid,line);
***************
*** 187,195
  fprintf(stderr,"pid returned from intercom is %d for line %s\n",pid,line);
  fprintf(stderr,"fileno(zin) is %d\n",fileno(zin));
  #endif
- #if 0
-       for (i=3;i<=20;i++) if (i!=fileno(zin)) close(i);
- #else
        for (i=3;i<=NFILES;i++) if (i!=fileno(zin)) close(i);
  #endif
        if (pid && act!=BCKGND)

--- 202,207 -----
  fprintf(stderr,"pid returned from intercom is %d for line %s\n",pid,line);
  fprintf(stderr,"fileno(zin) is %d\n",fileno(zin));
  #endif
        for (i=3;i<=NFILES;i++) if (i!=fileno(zin)) close(i);
        if (pid && act!=BCKGND)
  	retval=waitfor(pid);
***************
*** 191,197
        for (i=3;i<=20;i++) if (i!=fileno(zin)) close(i);
  #else
        for (i=3;i<=NFILES;i++) if (i!=fileno(zin)) close(i);
- #endif
        if (pid && act!=BCKGND)
  	retval=waitfor(pid);
  #ifndef MINIX

--- 203,208 -----
  fprintf(stderr,"fileno(zin) is %d\n",fileno(zin));
  #endif
        for (i=3;i<=NFILES;i++) if (i!=fileno(zin)) close(i);
        if (pid && act!=BCKGND)
  	retval=waitfor(pid);
  #ifndef MINIX
***************
*** 552,560
  #endif
      }
    }
- #if 0
-   for (fd=3;fd<20;fd++)
- #else
    for (fd=3;fd<NFILES;fd++)
  #endif
      (void) close(fd);

--- 563,568 -----
  #endif
      }
    }
    for (fd=3;fd<NFILES;fd++)
    (void) close(fd);
  }
***************
*** 556,563
    for (fd=3;fd<20;fd++)
  #else
    for (fd=3;fd<NFILES;fd++)
! #endif
!     (void) close(fd);
  }
  	
  #ifdef __STDC__

--- 564,570 -----
      }
    }
    for (fd=3;fd<NFILES;fd++)
!   (void) close(fd);
  }
  	
  #ifdef __STDC__
***************
*** 622,629
  fprintf(stderr,"bckgnd %d piped %d\n",bckgnd,piped);
  fprintf(stderr,"maybe setexec from execute\n");
  #endif
! 	       if (bckgnd==TRUE) setbgexec();
! 	       else if (!NoIoctl && piped==FALSE && !fromfile) setexec();
  	       redirect(infd,outfd,errfd,ifil,ofil,efil,appnd,bckgnd);
  	       if (alias_defn!=0)
  	       {

--- 629,636 -----
  fprintf(stderr,"bckgnd %d piped %d\n",bckgnd,piped);
  fprintf(stderr,"maybe setexec from execute\n");
  #endif
! 	       /*if (bckgnd==TRUE) setbgexec();
! 	       else*/ if (!NoIoctl && piped==FALSE && !fromfile) setexec(pid=getpid());
  	       redirect(infd,outfd,errfd,ifil,ofil,efil,appnd,bckgnd);
  	       if (alias_defn!=0)
  	       {
***************
*** 654,659
  	       for (i=argc;i;i--) argv[i]=argv[i-1];
  	       argv[1]=(char *) realloc (argv[1],(unsigned)(strlen(path)+1));
  	       strcpy(argv[1],path);		/* full path for source file */
  	       argv[0]=(char *) malloc ((unsigned)(strlen(DFLTSH)+1));
  	       strcpy(argv[0],DFLTSH);
  	       strcpy(path,DFLTSH);

--- 661,669 -----
  	       for (i=argc;i;i--) argv[i]=argv[i-1];
  	       argv[1]=(char *) realloc (argv[1],(unsigned)(strlen(path)+1));
  	       strcpy(argv[1],path);		/* full path for source file */
+ #ifdef DEBUG
+ fprintf(stderr,"argv[1] is %s<\n",argv[1]);
+ #endif
  	       argv[0]=(char *) malloc ((unsigned)(strlen(DFLTSH)+1));
  	       strcpy(argv[0],DFLTSH);
  	       strcpy(path,DFLTSH);
***************
*** 657,663
  	       argv[0]=(char *) malloc ((unsigned)(strlen(DFLTSH)+1));
  	       strcpy(argv[0],DFLTSH);
  	       strcpy(path,DFLTSH);
! 	       argc++;			/* one more arg for mankind... */
  #ifdef DEBUG
  fprintf(stderr,"path %s argv[0] %s argv[1] %s argv[2] %s\n",path,argv[0],argv[1],argv[2]);
  #endif

--- 667,673 -----
  	       argv[0]=(char *) malloc ((unsigned)(strlen(DFLTSH)+1));
  	       strcpy(argv[0],DFLTSH);
  	       strcpy(path,DFLTSH);
! 	       argv[++argc]=NULL;	/* one more arg for mankind... */
  #ifdef DEBUG
  fprintf(stderr,"path %s argv[0] %s argv[1] %s argv[2] %s\n",path,argv[0],argv[1],argv[2]);
  #endif
//E*O*F exec.cdif//

echo x - global.c
cat > "global.c" << '//E*O*F global.c//'
/******************************************************************************
**                                                                           **
**                               global.c                                    **
**          Some global declarations for the entire program.                 **
**                                                                           **
******************************************************************************/

#include "header.h"
char termcapbuf[1024],bs[10],nd[10],cl[10],cd[10],up[10],so[10],se[10],beep[20],yankbuf[256],*invokename,**arguments,*current_alias,*newenv[MAXARG];
FILE *zin,*zout,*fopen();
int lenprompt,curr_hist,maxhist=0,wid,h_hits,h_misses,hits,misses,beeplength,fromfile,disable_auto,numargs,jobdone,globpid;
int O_execstring=0,O_exiterror=0,O_faststart=0,O_interact,O_noexec=0,O_echoline=0,O_echoexp=0,O_echobefore=0,O_echoexpbefore=0;
bool hashed,loginsh;

/* Clam terminal driver characteristics which must always be set for Clam. */
struct sgttyb clam_sgttyb;
struct tchars clam_tchars;
#ifndef MINIX
struct ltchars clam_ltchars;
#endif
//E*O*F global.c//

echo x - hash.cdif
cat > "hash.cdif" << '//E*O*F hash.cdif//'
*** ../Patch1/hash.c	Thu Jun  1 17:03:06 1989
--- hash.c	Thu Jun  1 16:55:14 1989
***************
*** 31,37
    char *dir,*entname;
    int nojoin;
  {
!   struct stat *buf;
    char fpn[MAXWL];
  
    buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat)));

--- 31,37 -----
    char *dir,*entname;
    int nojoin;
  {
!   struct stat buf;
    char fpn[MAXWL];
  
    if (nojoin)
***************
*** 34,40
    struct stat *buf;
    char fpn[MAXWL];
  
-   buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat)));
    if (nojoin)
      stat(dir,buf);
    else

--- 34,39 -----
    struct stat buf;
    char fpn[MAXWL];
  
    if (nojoin)
      stat(dir,&buf);
    else
***************
*** 36,42
  
    buf=(struct stat *) malloc ((unsigned)(sizeof(struct stat)));
    if (nojoin)
!     stat(dir,buf);
    else
    {
      sprintf(fpn,"%s/%s",dir,entname);

--- 35,41 -----
    char fpn[MAXWL];
  
    if (nojoin)
!     stat(dir,&buf);
    else
    {
      sprintf(fpn,"%s/%s",dir,entname);
***************
*** 40,46
    else
    {
      sprintf(fpn,"%s/%s",dir,entname);
!     stat(fpn,buf);
    }
    if (((buf->st_mode & S_IFMT)==S_IFREG) && (buf->st_mode & 0111)) return(TRUE);
    return(FALSE);

--- 39,45 -----
    else
    {
      sprintf(fpn,"%s/%s",dir,entname);
!     stat(fpn,&buf);
    }
    if (((buf.st_mode & S_IFMT)==S_IFREG) && (buf.st_mode & 0111))
      return(TRUE);
***************
*** 42,48
      sprintf(fpn,"%s/%s",dir,entname);
      stat(fpn,buf);
    }
!   if (((buf->st_mode & S_IFMT)==S_IFREG) && (buf->st_mode & 0111)) return(TRUE);
    return(FALSE);
  }
  

--- 41,48 -----
      sprintf(fpn,"%s/%s",dir,entname);
      stat(fpn,&buf);
    }
!   if (((buf.st_mode & S_IFMT)==S_IFREG) && (buf.st_mode & 0111))
!     return(TRUE);
    return(FALSE);
  }
  
***************
*** 196,201
      return;
    }
    strcpy(path,vget("PATH"));
    for (times=0;times<HSHSIZ;times++)
    {
      hasharray[times].name=0;

--- 196,202 -----
      return;
    }
    strcpy(path,vget("PATH"));
+ /* free up previous hash table */
    for (times=0;times<HSHSIZ;times++)
    {
      free(hasharray[times].name);
***************
*** 198,205
    strcpy(path,vget("PATH"));
    for (times=0;times<HSHSIZ;times++)
    {
!     hasharray[times].name=0;
!     hasharray[times].exec_ptr.dir=EOS;
    }
    h_hits=h_misses=0;			/* reset hashing stats */
  /* hash builtins here if not in PATH variable. */

--- 199,209 -----
  /* free up previous hash table */
    for (times=0;times<HSHSIZ;times++)
    {
!     free(hasharray[times].name);
!     hasharray[times].name=NULL;
!     if (!hasharray[times].type)
!       free(hasharray[times].exec_ptr.dir);
!     hasharray[times].exec_ptr.dir=NULL;
    }
    h_hits=h_misses=0;			/* reset hashing stats */
  /* hash builtins here if not in PATH variable. */
***************
*** 223,228
        if (hashbuiltins()) return;			/* ditto */
        continue;
      }
  /* shouldn't have to malloc for entry since opendir does it, hopefully */
      if ((dd=opendir(dir))!=NULL)
      {

--- 227,283 -----
        if (hashbuiltins()) return;			/* ditto */
        continue;
      }
+     if (dir[0]=='.' && dir[1]==EOS)
+     {
+ /*
+    Hash '.' separately so that we can check for executables. We'll do it
+    here instead of checking in the loop below because it's more efficient.
+    We only have to check once for each directory on the path (~10), not for
+    each file on the path (~600). This has been added to avoid the full hashtable
+    syndrome which isn't harmful with dot at the end of the path, but annoying,
+    nevertheless. First open it, then check each one.
+ */
+       if ((dd=opendir("."))!=NULL)
+       {
+         while ((entry=readdir(dd))!=NULL)
+ 	{
+ 	  if (entry->d_name[0]=='.' && (entry->d_name[1]==EOS || entry->d_name[1]=='.')) continue;
+ 	  if (!executable(entry->d_name,"",1)) continue;
+ 	  hashval=hash(entry->d_name);
+ 	  for (times=0;hasharray[hashval].name!=NULL && times<HSHSIZ;times++)
+ 	  {
+ 	    hashval++;
+ 	    hashval%=HSHSIZ;
+ 	  }
+ 	  if (times==0) h_hits++;
+ 	  else
+ 	  {
+ #ifdef DEBUG
+ 	    fprintf(stderr,"Hash missed on %d\n",hash(entry->d_name));
+ #endif
+ 	    h_misses++;
+ 	    if (times==HSHSIZ)
+ 	    {
+ 	      write(2,"Hash table is full. Cannot complete hash.\n",42);
+ 			/* allow the partial hash and just return */
+ 	      return;
+ 	    }
+ 	  }
+ 
+ /* Having found a blank position we now malloc some space and copy the values */
+ 	  hasharray[hashval].name=(char *) malloc ((unsigned)(strlen(entry->d_name)+1));
+ 	  strcpy(hasharray[hashval].name,entry->d_name);
+ 	  hasharray[hashval].exec_ptr.dir=(char *) malloc ((unsigned)(strlen(dir)+1));
+ 	  strcpy(hasharray[hashval].exec_ptr.dir,dir);
+ 	  hasharray[hashval].type=0;
+ 	}
+ 	closedir(dd);
+       }
+       else
+         fprintf(stderr,"Can't open directory: %s\n",dir);
+     }
+ 
+ 
  /* shouldn't have to malloc for entry since opendir does it, hopefully */
      if ((dd=opendir(dir))!=NULL)
      {
***************
*** 238,243
  	if (times==0) h_hits++;
  	else
  	{
  	  h_misses++;
  	  if (times==HSHSIZ)
  	  {

--- 293,301 -----
  	if (times==0) h_hits++;
  	else
  	{
+ #ifdef DEBUG
+ 	  fprintf(stderr,"Hash missed on %d\n",hash(entry->d_name));
+ #endif
  	  h_misses++;
  	  if (times==HSHSIZ)
  	  {
//E*O*F hash.cdif//

echo x - header.hdif
cat > "header.hdif" << '//E*O*F header.hdif//'
*** ../Patch1/header.h	Thu Jun  1 17:03:20 1989
--- header.h	Thu Jun  1 16:55:28 1989
***************
*** 108,113
  /* Some general defines */
  #define EOS '\0'
  #define UNDEF -1
  
  /* Identification for error codes for metacharacter expansion function */
  #ifdef OK	/* defined somewhere on minixST */

--- 108,114 -----
  /* Some general defines */
  #define EOS '\0'
  #define UNDEF -1
+ #define NFILES 20
  
  /* Identification for error codes for metacharacter expansion function */
  #ifdef OK	/* defined somewhere on minixST */
***************
*** 215,222
  void insert(char *, int, int, int *);
  void show(char *, int *, bool);
  void goend(char *, int *, int *);
! void copyback(char *, int, int *);
! void delword(char *, int, int *);
  void backword(char *, int *, int *);
  void forword(char *, int *, int *);
  void yanknext(char *, int, char *);

--- 216,224 -----
  void insert(char *, int, int, int *);
  void show(char *, int *, bool);
  void goend(char *, int *, int *);
! void copyback(char *, int, int *, int);
! void delnextword(char *, int, int *);
! void delprevword(char *, int, int *);
  void backword(char *, int *, int *);
  void forword(char *, int *, int *);
  void yanknext(char *, int, char *);
***************
*** 230,236
  bool expand_tilde(char *, int *);
  void help(char *, int, int *);
  
! void setexec(void);
  void setbgexec(void);
  void resetsigdefaults(void);
  bool findslash(char *);

--- 232,238 -----
  bool expand_tilde(char *, int *);
  void help(char *, int, int *);
  
! void setexec(int);
  void setbgexec(void);
  void resetsigdefaults(void);
  bool findslash(char *);
//E*O*F header.hdif//

exit 0

wtoomey@gara.une.oz (Warren Toomey) (06/01/89)

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# job.cdif main.cdif meta.cdif

echo x - job.cdif
cat > "job.cdif" << '//E*O*F job.cdif//'
*** ../Patch1/job.c	Thu Jun  1 17:03:46 1989
--- job.c	Thu Jun  1 16:55:54 1989
***************
*** 399,405
  	    printf("\n%s\n",siglist[status.w_stopsig]);
  	  }
  	  else
! 	    printf("\n%s\n",siglist[status.w_termsig]);
  	  fflush(stdout);
  	}
  	c=vget("cwd");

--- 399,408 -----
  	    printf("\n%s\n",siglist[status.w_stopsig]);
  	  }
  	  else
! 	    if (status.w_coredump)
! 	      printf("\n%s (core dumped)\n",siglist[status.w_termsig]);
! 	    else
! 	      printf("\n%s\n",siglist[status.w_termsig]);
  	  fflush(stdout);
  	}
  	c=vget("cwd");
//E*O*F job.cdif//

echo x - main.cdif
cat > "main.cdif" << '//E*O*F main.cdif//'
*** ../Patch1/main.c	Thu Jun  1 17:04:26 1989
--- main.c	Thu Jun  1 16:56:32 1989
***************
*** 277,282
    termod->sg_flags &= (~ECHO);		/* do not echo chars to screen */
    if (ioctl(0,TIOCSETP,termod))		/* put it back, modified */
      perror("ioctl");
    setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars)));
    if (ioctl(0,TIOCGETC,setsigc))		/* get the tchars struct */
      perror("ioctl");

--- 277,283 -----
    termod->sg_flags &= (~ECHO);		/* do not echo chars to screen */
    if (ioctl(0,TIOCSETP,termod))		/* put it back, modified */
      perror("ioctl");
+   free(termod);
    setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars)));
    if (ioctl(0,TIOCGETC,setsigc))		/* get the tchars struct */
      perror("ioctl");
***************
*** 281,287
    if (ioctl(0,TIOCGETC,setsigc))		/* get the tchars struct */
      perror("ioctl");
    setsigc->t_intrc=(UNDEF);		/* no interrupt or quitting */
!   /*setsigc->t_quitc=(UNDEF);  allow quit while debugging */
    setsigc->t_eofc=(UNDEF);		/* or eof signalling */
    if (ioctl(0,TIOCSETC,setsigc))		/* put it back, modified */
      perror("ioctl");

--- 282,288 -----
    if (ioctl(0,TIOCGETC,setsigc))		/* get the tchars struct */
      perror("ioctl");
    setsigc->t_intrc=(UNDEF);		/* no interrupt or quitting */
!   /*setsigc->t_quitc=(UNDEF); Allow quit while debugging */
    setsigc->t_eofc=(UNDEF);		/* or eof signalling */
    if (ioctl(0,TIOCSETC,setsigc))		/* put it back, modified */
      perror("ioctl");
***************
*** 285,290
    setsigc->t_eofc=(UNDEF);		/* or eof signalling */
    if (ioctl(0,TIOCSETC,setsigc))		/* put it back, modified */
      perror("ioctl");
  # ifndef MINIX
    moresigc.t_suspc=(UNDEF);		/* no stopping */
    moresigc.t_dsuspc=(UNDEF);		/* or delayed stopping */

--- 286,292 -----
    setsigc->t_eofc=(UNDEF);		/* or eof signalling */
    if (ioctl(0,TIOCSETC,setsigc))		/* put it back, modified */
      perror("ioctl");
+   free(setsigc);
  # ifndef MINIX
    moresigc.t_suspc=(UNDEF);		/* no stopping */
    moresigc.t_dsuspc=(UNDEF);		/* or delayed stopping */
***************
*** 292,298
    moresigc.t_flushc=(UNDEF);		/* or flushing */
    moresigc.t_werasc=(UNDEF);		/* or word erasing */
    moresigc.t_lnextc=(UNDEF);		/* or literal quoting */
!   if (ioctl(0,TIOCSLTC,&moresigc))		/* set ltchars struct to be all undef */
      perror("ioctl");
  # endif
  #endif

--- 294,300 -----
    moresigc.t_flushc=(UNDEF);		/* or flushing */
    moresigc.t_werasc=(UNDEF);		/* or word erasing */
    moresigc.t_lnextc=(UNDEF);		/* or literal quoting */
!   if (ioctl(0,TIOCSLTC,&moresigc))	/* set ltchars struct to be all undef */
      perror("ioctl");
  # endif
  #endif
***************
*** 344,349
    struct tchars *setsigc;
  # ifndef MINIX
    struct ltchars moresigc;
  # endif
  
  #ifdef DEBUG

--- 346,352 -----
    struct tchars *setsigc;
  # ifndef MINIX
    struct ltchars moresigc;
+   int pid;
  # endif
  
  #ifdef DEBUG
***************
*** 357,362
    termod->sg_flags &= (~ECHO);		/* do not echo chars to screen */
    if (ioctl(0,TIOCSETN,termod))		/* put it back, modified */
      perror("ioctl");
    setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars)));
    if (ioctl(0,TIOCGETC,setsigc))	/* get the tchars struct */
      perror("ioctl");

--- 360,366 -----
    termod->sg_flags &= (~ECHO);		/* do not echo chars to screen */
    if (ioctl(0,TIOCSETN,termod))		/* put it back, modified */
      perror("ioctl");
+   free(termod);
    setsigc=(struct tchars *) malloc ((unsigned)(sizeof(struct tchars)));
    if (ioctl(0,TIOCGETC,setsigc))	/* get the tchars struct */
      perror("ioctl");
***************
*** 365,370
    setsigc->t_eofc=(UNDEF);		/* or eof signalling */
    if (ioctl(0,TIOCSETC,setsigc))	/* put it back, modified */
      perror("ioctl");
  # ifndef MINIX
    moresigc.t_suspc=(UNDEF);		/* no stopping */
    moresigc.t_dsuspc=(UNDEF);		/* or delayed stopping */

--- 369,375 -----
    setsigc->t_eofc=(UNDEF);		/* or eof signalling */
    if (ioctl(0,TIOCSETC,setsigc))	/* put it back, modified */
      perror("ioctl");
+   free(setsigc);
  # ifndef MINIX
    moresigc.t_suspc=(UNDEF);		/* no stopping */
    moresigc.t_dsuspc=(UNDEF);		/* or delayed stopping */
***************
*** 374,379
    moresigc.t_lnextc=(UNDEF);		/* or literal quoting */
    if (ioctl(0,TIOCSLTC,&moresigc))	/* set ltchars struct to be all undef */
      perror("ioctl");
  # endif
  #endif
  

--- 379,386 -----
    moresigc.t_lnextc=(UNDEF);		/* or literal quoting */
    if (ioctl(0,TIOCSLTC,&moresigc))	/* set ltchars struct to be all undef */
      perror("ioctl");
+   pid=getpid();
+   if (ioctl(0,TIOCSPGRP,&pid)) perror("ioctl stpg");
  # endif
  #endif
  
***************
*** 451,457
    else
    {			/* either logout or exit according to invokename*/
      if (loginsh==TRUE) logout(numargs,arguments);	/* truncated args */
!     else write(1,"Exit\n",5);
      setdown();
      exit(0);
    }

--- 458,464 -----
    else
    {			/* either logout or exit according to invokename*/
      if (loginsh==TRUE) logout(numargs,arguments);	/* truncated args */
!     else write(1,"exit\n",5);
      setdown();
      exit(0);
    }
***************
*** 565,574
        while (act!=ENDLN && act!=ERRER)
        {
  	retval=0;
! #if 0
! 	/* Was this: appears to be totally wrong */
! 	act=intercom(line,&pos,&pid,FALSE,NULL,1);
! #else
  	act=intercom(line,&pos,&pid,&i ,FALSE,1);
   /* call intercom with fromfile  set -- ?? the big question is do we */
   /* really ignore the value of outpfd - i dunno., could'nt make out, */

--- 572,581 -----
        while (act!=ENDLN && act!=ERRER)
        {
  	retval=0;
! 
! /*	 Was this: appears to be totally wrong 
! 	act=intercom(line,&pos,&pid,FALSE,NULL,1);	*/
! 
  	act=intercom(line,&pos,&pid,&i ,FALSE,1);
   /* call intercom with fromfile  set -- ?? the big question is do we */
   /* really ignore the value of outpfd - I dunno., couldn't make out, */
***************
*** 571,578
  #else
  	act=intercom(line,&pos,&pid,&i ,FALSE,1);
   /* call intercom with fromfile  set -- ?? the big question is do we */
!  /* really ignore the value of outpfd - i dunno., could'nt make out, */
!  /* so i just put in &i, otherwise obviusly this call causes bombs in */
   /* intercom() */
  #endif
  #if 0

--- 578,585 -----
  
  	act=intercom(line,&pos,&pid,&i ,FALSE,1);
   /* call intercom with fromfile  set -- ?? the big question is do we */
!  /* really ignore the value of outpfd - I dunno., couldn't make out, */
!  /* so I just put in &i, otherwise obviously this call causes bombs in */
   /* intercom() */
  	for (i=3;i<=NFILES;i++) if (i!=fileno(finp)) close(i);
  	if (pid && act!=BCKGND)
***************
*** 574,583
   /* really ignore the value of outpfd - i dunno., could'nt make out, */
   /* so i just put in &i, otherwise obviusly this call causes bombs in */
   /* intercom() */
- #endif
- #if 0
- 	for (i=3;i<=20;i++) if (i!=fileno(finp)) close(i);
- #else
  	for (i=3;i<=NFILES;i++) if (i!=fileno(finp)) close(i);
  #endif
  	if (pid && act!=BCKGND)

--- 581,586 -----
   /* really ignore the value of outpfd - I dunno., couldn't make out, */
   /* so I just put in &i, otherwise obviously this call causes bombs in */
   /* intercom() */
  	for (i=3;i<=NFILES;i++) if (i!=fileno(finp)) close(i);
  	if (pid && act!=BCKGND)
  	  retval=waitfor(pid);
***************
*** 579,585
  	for (i=3;i<=20;i++) if (i!=fileno(finp)) close(i);
  #else
  	for (i=3;i<=NFILES;i++) if (i!=fileno(finp)) close(i);
- #endif
  	if (pid && act!=BCKGND)
  	  retval=waitfor(pid);
  	if (!disable_auto && act==ERRER) exit(1);	/* exit on shell syntax error */

--- 582,587 -----
   /* so I just put in &i, otherwise obviously this call causes bombs in */
   /* intercom() */
  	for (i=3;i<=NFILES;i++) if (i!=fileno(finp)) close(i);
  	if (pid && act!=BCKGND)
  	  retval=waitfor(pid);
  	if (!disable_auto && act==ERRER) exit(1);	/* exit on shell syntax error */
***************
*** 753,762
        while (act!=ENDLN && act!=ERRER)
        {
  	retval=0;
! #if 0
! 	/* WAS: same intercom problem as in file() here */
! 	act=intercom(line,&pos,&pid,FALSE,NULL,0);
! #else
  	act=intercom(line,&pos,&pid, &i, FALSE,0);	/* call intercom with fromfile not set */
  #endif
  #if 0

--- 755,764 -----
        while (act!=ENDLN && act!=ERRER)
        {
  	retval=0;
! 
! /*	WAS: same intercom problem as in file() here 
! 	act=intercom(line,&pos,&pid,FALSE,NULL,0);	*/
! 
  	act=intercom(line,&pos,&pid, &i, FALSE,0);	/* call intercom with fromfile not set */
  
  	for (i=3;i<=NFILES;i++) close(i);
***************
*** 758,767
  	act=intercom(line,&pos,&pid,FALSE,NULL,0);
  #else
  	act=intercom(line,&pos,&pid, &i, FALSE,0);	/* call intercom with fromfile not set */
! #endif
! #if 0
! 	for (i=3;i<=20;i++) close(i);
! #else
  	for (i=3;i<=NFILES;i++) close(i);
  #endif
  	if (pid && act!=BCKGND)

--- 760,766 -----
  	act=intercom(line,&pos,&pid,FALSE,NULL,0);	*/
  
  	act=intercom(line,&pos,&pid, &i, FALSE,0);	/* call intercom with fromfile not set */
! 
  	for (i=3;i<=NFILES;i++) close(i);
  	if (pid && act!=BCKGND)
  	  retval=waitfor(pid);
***************
*** 763,769
  	for (i=3;i<=20;i++) close(i);
  #else
  	for (i=3;i<=NFILES;i++) close(i);
- #endif
  	if (pid && act!=BCKGND)
  	  retval=waitfor(pid);
  #ifndef MINIX

--- 762,767 -----
  	act=intercom(line,&pos,&pid, &i, FALSE,0);	/* call intercom with fromfile not set */
  
  	for (i=3;i<=NFILES;i++) close(i);
  	if (pid && act!=BCKGND)
  	  retval=waitfor(pid);
  #ifndef MINIX
***************
*** 819,828
    while (act!=ENDLN && act!=ERRER)
    {
      retval=0;
- #if 0
-     /* WAS: sample problem */
-     act=intercom(line,&pos,&pid,FALSE,NULL,0);	/* call intercom with fromfile not set */
- #else
      act=intercom(line,&pos,&pid, &i,FALSE,0);	/* call intercom with fromfile not set */
  #endif
  #if 0

--- 817,822 -----
    while (act!=ENDLN && act!=ERRER)
    {
      retval=0;
      act=intercom(line,&pos,&pid, &i,FALSE,0);	/* call intercom with fromfile not set */
      for (i=3;i<=NFILES;i++) close(i);
      if (pid && act!=BCKGND)
***************
*** 824,833
      act=intercom(line,&pos,&pid,FALSE,NULL,0);	/* call intercom with fromfile not set */
  #else
      act=intercom(line,&pos,&pid, &i,FALSE,0);	/* call intercom with fromfile not set */
- #endif
- #if 0
-     for (i=3;i<=20;i++) close(i);
- #else
      for (i=3;i<=NFILES;i++) close(i);
  #endif
      if (pid && act!=BCKGND)

--- 818,823 -----
    {
      retval=0;
      act=intercom(line,&pos,&pid, &i,FALSE,0);	/* call intercom with fromfile not set */
      for (i=3;i<=NFILES;i++) close(i);
      if (pid && act!=BCKGND)
        retval=waitfor(pid);
***************
*** 829,835
      for (i=3;i<=20;i++) close(i);
  #else
      for (i=3;i<=NFILES;i++) close(i);
- #endif
      if (pid && act!=BCKGND)
        retval=waitfor(pid);
  #ifndef MINIX

--- 819,824 -----
      retval=0;
      act=intercom(line,&pos,&pid, &i,FALSE,0);	/* call intercom with fromfile not set */
      for (i=3;i<=NFILES;i++) close(i);
      if (pid && act!=BCKGND)
        retval=waitfor(pid);
  #ifndef MINIX
//E*O*F main.cdif//

echo x - meta.cdif
cat > "meta.cdif" << '//E*O*F meta.cdif//'
*** ../Patch1/meta.c	Thu Jun  1 17:05:18 1989
--- meta.c	Thu Jun  1 16:57:22 1989
***************
*** 172,178
      i=0;
      while (!feof(progout))
      {
!       c = getc(progout);
  #ifdef DEBUG
  fprintf(stderr,"%o",c);
  #endif

--- 172,178 -----
      i=0;
      while (!feof(progout))
      {
!       if ((c = getc(progout))==EOF) break;
  #ifdef DEBUG
  fprintf(stderr,"%o",c);
  #endif
***************
*** 406,412
    char *line,*word;
    int *pos;
  {
!   int l=1,insym=0,inword=0,i=0;
  
    word[0]=EOS;
    while(l)

--- 406,412 -----
    char *line,*word;
    int *pos;
  {
!   int l=1,insym=0,inword=0,i=0,quote=0;
  
    word[0]=EOS;
    while(l)
***************
*** 437,442
  	}
  	else (*pos)++;
  	break;
        default:
  	if (insym)
  	{

--- 437,445 -----
  	}
  	else (*pos)++;
  	break;
+       case '"':
+ 	while((word[i++]=line[(*pos)++])!='"');
+ 	break;
        default:
  	if (insym)
  	{
***************
*** 689,694
    j=0;
    while ((err=loadpattern(line,&i,word,&pattern))==FINE)
    {
      if (pattern==FALSE)			/* if no * ? [] then add to line */
      {
        if (j!=0) newline[j++]=' ';

--- 692,700 -----
    j=0;
    while ((err=loadpattern(line,&i,word,&pattern))==FINE)
    {
+ #ifdef DEBUG
+ fprintf(stderr,"word was %s<\n",word);
+ #endif
      if (pattern==FALSE)			/* if no * ? [] then add to line */
      {
        if (j!=0) newline[j++]=' ';
***************
*** 697,702
        newline[j]=EOS;
        continue;
      }
  /* if an absolute path name is given, then chop it off the front of word and
     put it in dir. Now word contains the patterned stuff onwards. */
      finddir(word,dir);

--- 703,711 -----
        newline[j]=EOS;
        continue;
      }
+ #ifdef DEBUG
+ fprintf(stderr,"newline in pattern_match\n%s\n",newline);
+ #endif
  /* if an absolute path name is given, then chop it off the front of word and
     put it in dir. Now word contains the patterned stuff onwards. */
      finddir(word,dir);
***************
*** 1145,1150
      if (m_err=curly(line)) return(m_err);
    if (Tilde==TRUE)
      if (m_err=tilde(line)) return(m_err);
    if (Pattern==TRUE)
      if (m_err=pattern_match(line)) return(m_err);
    if (Bquote==TRUE)

--- 1154,1162 -----
      if (m_err=curly(line)) return(m_err);
    if (Tilde==TRUE)
      if (m_err=tilde(line)) return(m_err);
+ #ifdef DEBUG
+ fprintf(stderr,"line before pattern_match\n%s\n",line);
+ #endif
    if (Pattern==TRUE)
      if (m_err=pattern_match(line)) return(m_err);
  #ifdef DEBUG
***************
*** 1147,1152
      if (m_err=tilde(line)) return(m_err);
    if (Pattern==TRUE)
      if (m_err=pattern_match(line)) return(m_err);
    if (Bquote==TRUE)
      if (m_err=backquote(line)) return(m_err);
  

--- 1159,1167 -----
  #endif
    if (Pattern==TRUE)
      if (m_err=pattern_match(line)) return(m_err);
+ #ifdef DEBUG
+ fprintf(stderr,"line after pattern_match\n%s\n",line);
+ #endif
    if (Bquote==TRUE)
      if (m_err=backquote(line)) return(m_err);
  
//E*O*F meta.cdif//

exit 0