[net.sources] VSH sources 4 of 6

dan@rna.UUCP (Dan Ts'o) (06/28/85)

# Here is part 4 of the sources to VSH, a visual shell.
#
#
#					Cheers,
#					Dan Ts'o
#					Dept. Neurobiology
#					Rockefeller Univ.
#					1230 York Ave.
#					NY, NY 10021
#					212-570-7671
#					...cmcl2!rna!dan
echo src/readarg.c
sed 's/^X//' > src/readarg.c << 'All work and no play makes Jack a dull boy'
X#include "hd.h"
X#include "strings.h"
X
X/* Table for scanner machine.  The machine can handle any regular
X   expression.  Table elements come in pairs.  The first is
X   the match character and the second is the next state assoc with
X   that character.  The character '*' matches all character.
X*/
Xstatic char st00[] = 
X{
X    ' ',  0, '\t', 0, '\n', 3, '\\', 1,
X	'\'', 8, '"', 10, '*',  4
X} ;
Xstatic char st01[] = 
X{
X    '\n', 0, '*',  4
X} ;
Xstatic char st02[] = 
X{
X    '\n', 3, '*',  0
X} ;
Xstatic char st03[] = 
X{
X    '*',  0
X} ;
Xstatic char st04[] = 
X{
X    '*',  5
X} ;
Xstatic char st05[] = 
X{
X    ' ',  2, '\n', 2, '\t', 2, '\\', 6, '\'', 8,
X	'"', 10, '*',  4
X} ;
Xstatic char st06[] = 
X{
X    '\n', 5, '*',  4
X} ;
Xstatic char st07[] = 
X{
X    '*',  0
X} ;
Xstatic char st08[] = 
X{
X    '\'', 5, '*', 9
X} ;
Xstatic char st09[] = 
X{
X    '*',  8
X} ;
Xstatic char st10[] = 
X{
X    '"',  5, '\\',12, '*',11
X} ;
Xstatic char st11[] = 
X{
X    '*', 10
X} ;
Xstatic char st12[] = 
X{
X    '\n',10, '*', 11
X} ;
X
Xstatic char *lextab[] = 
X{
X    st00, st01, st02, st03, st04, st05, st06,
X	st07, st08, st09, st10, st11, st12
X} ;
X
X/* Readarg reads a line from pstream and converts it into
X   argv-argc format.  One may use a format similar to the shell.
X*/
Xreadarg (pstream, pline, pargc, pargv, pbuf)
XFILE *pstream;	/* Stream being read */
Xint *pline;	/* Current line number */
Xint *pargc;	/* Count of words */
Xchar *pargv [ARGVMAX];	/* Array of pointers to the words */
Xchar pbuf [STRMAX];	/* Buf to hold the words themselves */
X{
X    /* Space is allocated from pargv and pbuf as words are read.
X       These vars keep track of the allocations.
X    */
X    char **cargv = pargv;	/* Current allocations */
X    char * cbuf  = pbuf;
X    /* Limit of allocation */
X    char **largv = pargv + ARGVMAX - 1;
X    char * lbuf  = pbuf  + STRMAX - 1;
X
X    /* Scanner vars */
X    register int state = 0;	/* Scanner machine state */
X    register int ch;	/* Current char */
X    register char *ltp;	/* Lexical table pointer */
X
X    int prompt;	/* Flag indicates when to prompt */
X#define	NOPR	0	/* Don't */
X#define	FPR	1	/* First prompt */
X#define	CPR	2	/* Continuation prompt */
X
X    /* Initialization */
X    *pargc = 0;
X    cargv[0] = pbuf;
X    prompt = FPR;
X
X    for (;;) 
X    {
X	switch (state) 
X	{
X
X	    /* Get a char */
X	  case 0: 
X	  case 1: 
X	  case 5: 
X	  case 6: 
X	  case 8:
X	  case 10: 
X	  case 12:
X	    if (prompt && pstream == stdin) {
X		hilite((prompt == FPR) ? "Parameter:" : ":");
X		printf(" ");
X	    }
X	    ch = fgetch (pstream);
X	    prompt = (ch == LF) ? CPR : NOPR;
X	    if (ch == (QUITCHAR-'@') || ascii [ch] == EF) 
X	    {
X		if (*pargc != 0) lderror
X		    ("Incomplete line", *pline);
X		return BAD;
X	    }
X	    else if (ENDLINE (ch)) ++*pline;
X	    else if (ascii [ch] == UD) 
X	    {
X		lderror ("Non-Ascii character", *pline);
X		continue;
X	    }
X	    break;
X
X	    /* Store a char */
X	  case 4: 
X	  case 9: 
X	  case 11:
X	    if (cbuf >= lbuf || cargv >= largv) 
X	    {
X		lderror ("Too long", *pline);
X		return BAD;
X	    }
X	    *cbuf++ = ch;
X	    break;
X
X	    /* Store a word */
X	  case 2: 
X	  case 7:
X	    *cbuf++ = 0;
X	    *++cargv = cbuf;
X	    ++*pargc;
X	    break;
X
X	    /* Return from readarg */
X	  case 3:
X	    *cargv = CNULL; return GOOD;
X	}
X	for (ltp = lextab [state];
X	*ltp != ch && *ltp != '*'; ltp += 2);
X	state = *++ltp;
X    }
X}
X
X/* Load error */
Xlderror (cp, line) char *cp; int line; 
X{
X    hilite ("Line %d:  %s\r\n", line, cp);
X    getrtn ();
X}
All work and no play makes Jack a dull boy
echo src/remove.c
sed 's/^X//' > src/remove.c << 'All work and no play makes Jack a dull boy'
X
X#include "hd.h"
X#include "mydir.h"
X#include "command.h"
X#include <signal.h>
X
X#define	ISDIR	((scr_stb.st_mode & S_IFMT) == S_IFDIR)
X#define	paction(arg)	{ \
X	atfile (file, OFFARROW+colfield*pageoff);printf (action [cpage+pageoff][file] ? "//" : "  ");}
X
X/* User first indicates which files to remove by selecting them
X   with a-t keypresses.  Selected files are stored in the action
X   array.  When ready, the user presses R, and the files are gone.
X*/
X
Xchar quitcmds[] = 
X{
X    CR, LF, EOT, 0
X} ;
X
X/* ^L, ^F, ^U, ^I */
Xchar dircmds [] = 
X{
X    "0123456789+-L\014\006\025\011\002\026"
X} ;
X
Xstatic char *rmmsg[] = 
X{
X    "\tSelect the files you wish to remove, then press -R-",
X	"\tPress -Return- to leave with out removing files. -?- for more help"
X} ;
X
Xstatic int rcount;	/* Count of number of files removed */
Xstatic int rlast;	/* Last file removed */
Xextern int nointer;	/* SIGINT flag */
X
Xremove () 
X{			/* remove (unlink) files */
X
X    register cmd, file; register char *cp;
X    int pe;
X    short starmode;
X#define	OFF	0
X#define	ON	1
X#define	UNDEF	2
X
X    char (*action)[maxnfpp];
X    int (*oldsig)();
X    extern catch();
X    extern int didlong;
X
X    if (access (DOT, 3)) 
X    {
X	myperror ("Cannot remove files");
X	return NOREPLOT;
X    }
X
X    *selectname = 0;
X
X    /* Allocate memory for action flags */
X    file = malloc(cmd = (sizeof action[0]) * tfiles);
X    action = (char **) file;
X    if (action == NULL) {
X	putmsg("Out of memory");
X	return NOREPLOT;
X    }
X
X    for (cp = (char *) file; cp < cmd + (char *) file; *cp++ = OFF);
X    rcount = 0;
X
X    dispaction (action);
X    disprmmsg ();
X
X    for (;;) 
X    {
X	atxy (80, window-1);
X	cmd = getch ();
X	file = cmd - 'a';
X	if (cmd == (PAGECHAR-'@'))
X		cmd = '+';
X	if (cmd == (QUITCHAR-'@') || any(cmd, quitcmds) != NULL) 
X	    break;
X	if (didlong)
X	    rmdispdir(action);
X	if (any(cmd, dircmds) != NULL) 
X	{
X	    if (command(cmd, DIRCMD) & REPLOT) rmdispdir (action);
X	    else if (cmd == '.') disprmmsg();
X	}
X	else if (cmd == '*') 
X	{
X	    starmode = UNDEF;
X	    pe = pgend();
X	    for (file = 0; file < pe; file++) 
X	    {
X		cp = &action [cpage+pageoff][file];
X
X		if (compe (filename (file), DOT));
X		else if (compe (filename (file), DOTDOT));
X
X		else if (starmode == UNDEF)
X		    *cp = starmode = !*cp;
X		else *cp = starmode;
X	    }
X	    dispaction (action);
X	}
X
X	else if (cmd == 'R') break;
X	else if (cmd == '?') 
X	{
X	    help (RMHELP);
X	    rmdispdir (action);
X	}
X	else if (cmd >= 'a' && cmd <= 'z' && file < pgend()) 
X	{
X	    if (compe (filename (file), DOT));
X	    else if (compe (filename (file), DOTDOT));
X	    else
X	    {
X		action [cpage+pageoff][file] ^= 1;
X		paction (file);
X	    }
X	}
X    }
X    if (cmd == 'R') {
X	nointer = 1;
X	oldsig = signal(SIGINT, catch);
X	act (action);
X	signal(SIGINT, oldsig);
X    }
X    free(action);
X	if (rcount) {
X		rlast = 1 + ((rlast-rcount)/nfpp);
X		if (rlast < cpage || rlast > cpage+column-1) {
X			cpage = rlast;
X			pageoff = 0;
X		}
X	}
X	clearmsg(1);
X	hilite(" (%d file(s) removed)", rcount);
X	sleep(1);
X    return REPLOT;
X}
X
Xdispaction (action) char action [][maxnfpp]; 
X{
X    register file;
X    register int pe;
X    int opageoff;
X
X    bufout ();
X    opageoff = pageoff;
X    for (pageoff = 0; pageoff < column; pageoff++) {
X	pe = pgend();
X	for (file = 0; file < pe; file++)
X		paction (file);
X	if (pe < nfpp)
X		break;
X    }
X    pageoff = opageoff;
X    unbufout ();
X}
X
Xrmdispdir (action) char action [][maxnfpp]; 
X{
X    dispdir (0);
X    dispaction (action);
X    disprmmsg ();
X}
X
Xdisprmmsg () 
X{
X    clearmsg (2);
X    bufout ();
X    hilite ("%s\r\n%s", rmmsg [0], rmmsg [1]);
X    unbufout ();
X}
X
X/* This does the actual removing */
Xact (action) char action [][maxnfpp]; 
X{
X    register page, file;
X
X    clearmsg (1);
X    for (page = 1; page <= tpages; page ++)
X	for (file = 0; file < nfpp; file++)
X	if (!nointer)
X		return;
X	else if (action [page][file]) {
X		if (page < cpage || page > cpage+column-1) {
X			pageoff = 0;
X			cpage = page; dispdir (0);
X			dispaction (action); clearmsg (1);
X		}
X		else
X			pageoff = page - cpage;
X		atfile (file, OFFARROW+colfield*pageoff); printf (arrow);
X		atxy (1, window-1);
X#ifdef	SYMLINK
X		if (lstat (filename (file), &scr_stb)) {
X#else
X		if (stat (filename (file), &scr_stb)) {
X#endif
X			myperror (filename (file));
X	    		if (rmerror ()) return;
X		}
X		else if(ISDIR && f_exec("/bin/rmdir", "+", filename(file), 0)) {
X			if (rmerror ()) return;
X		}
X		else if (!ISDIR && unlink (filename (file))) {
X			myperror (filename (file));
X			if (rmerror ()) return;
X		}
X		else {
X			bufout();
X			atfile (file, OFFARROW+colfield*pageoff);
X			if (column > 1)
X				for (rlast = 0; rlast < colfield; rlast++)
X					putch(' ');
X			else
X				clearline();
X			unbufout();
X			rcount++;
X			rlast = ((page-1)*nfpp) + file;
X		}
X	}
X    return;
X}
X
Xrmerror () 
X{		/* Error in removing file */
X    register ch;
X
X    atxy (65, window-1);
X    hilite ("Press -Return-");
X    ch = getch ();
X    clearmsg (0);
X    return (ch == EOT);
X}
All work and no play makes Jack a dull boy
echo src/show.c
sed 's/^X//' > src/show.c << 'All work and no play makes Jack a dull boy'
X#include "hd.h"
X#include "strings.h"
X#include "command.h"
X
Xstatic char EONE [] = "+1";	/* Default editor parameter */
X
X/* Global data about file being shown */
X
XFILE *sstream;	/* Stream being shown */
X
Xint cline;	/* Current (next) line to be shown */
Xint tline;	/* Top line of page */
X
Xchar *sdesc [2] = 
X{
X    "Grep", "Make"
X} ;
X
Xshowerror () 
X{
X    return show (MAKEMODE);
X}
Xshowgrep () 
X{
X    return show (GREPMODE);
X}
X
Xshow (p) int p; 
X{		/* Use parms GREPMODE or MAKEMODE */
X
X    FILE *showopen ();
X    register int cmd, next, number;
X    int replot;
X    int spaces;
X    int (*cproc)();
X    extern grep(), wmake(), showerror(), showgrep();
X
X    sstream = showopen ("r", p);
X    if (sstream == NULL) return NOREPLOT;
X
X    cline = 1;
X    next = REPLOT;
X    replot = REPLOT;
X
X    for (;;) 
X    {
X	if (next & REPLOT) 
X	{
X	    sdisp (p);
X	    number = spaces = 0;
X	}
X
X	if (number == 0)  
X	{
X	    atxy (1, window-1);
X	    printf ("  \r");
X	}
X	cmd = getch ();
X	putch(cmd);
X	next = REPLOT;
X
X	/* This accumulates a number */
X	if (NUMERIC (cmd) && spaces == 0) 
X	{
X	    number = number * 10 + TONUM (cmd);
X	    next = 0;
X	}
X	else if (cmd == '\b' || cmd == 0177) 
X	{
X	    if (spaces > 0) --spaces;
X	    else number /= 10;
X	    if (cmd == 0177)
X		printf("%s", BC);
X	    printf (" %s", BC);
X	    next = 0;
X	}
X	else if (cmd == '-' || cmd == 025) {
X	    putch (CR);
X	    number = cline-(window-7)*(number > 1 ? number : 2);
X	    seekline (number < 0 ? 0 : number);
X	    number = 0;
X	}
X	/* These commands use number */
X	else if (cmd == LF || cmd == CR || cmd == 'e' || cmd == (PAGECHAR-'@')) 
X	{
X	    putch (CR);
X	    next = sedit (p, number);
X	    number = spaces = 0;
X	}
X	else if (cmd == ' ') 
X	{
X	    if (number > 0) ++spaces;
X	    next = 0;
X	}
X	else if (cmd == 'p') 
X	{
X	    putch (CR);
X	    seekline (number);
X	}
X	else
X	{
X	    number = spaces = 0; putch (CR);
X	    cproc = cmdproc(cmd);
X	    if (cproc == showerror || cproc == showgrep) 
X	    {
X		next = cmd | REPLOT;
X		break;
X	    }
X	    else if (cmd == '?') 
X	    {
X		next = help (SHOWHELP);
X	    }
X	    else if (cproc == grep) 
X	    {
X		next = grep ();
X		if (next != NOREPLOT) break;
X	    }
X	    else if (cproc == wmake) 
X	    {
X		next = wmake ();
X		if (next != NOREPLOT) break;
X	    }
X	    else if (cmd == 'q' || cmd == EOT || cmd == (QUITCHAR - '@')) 
X	    {
X		break;
X	    }
X	    else
X	    {
X		if (any(cmd,
X		"0123456789+L.\014\006\011\005\020\016\001\002\026hjkl")) {
X			next = cmd;
X			replot = NOREPLOT;
X			dispdir(0);
X			break;
X		}
X		next = command (cmd, SHOWCMD);
X	    }
X	    if (next & ENTERDIR)
X		break;
X	    if (next & REPLOT)
X		seekline (tline);
X	}
X    }
X    fclose (sstream);
X    if (replot == NOREPLOT)
X	next &= ~REPLOT;
X    return next|replot;
X}
X
X/* Position show file at specified location */
Xseekline (line) int line; 
X{
X
X    register ch;
X
X    cline = 1; rewind (sstream);
X    while (cline < line && (ch = getc (sstream)) != EOF)
X	if (ch == LF) cline++;
X
X    if (feof (sstream)) 
X    {
X	if (cline <= 2) 
X	{
X	    rewind (sstream); cline = 1;
X	}
X	else 
X	{
X	    seekline (cline - 1);
X	}
X    }
X}
X
Xsdisp (p)  int p; 
X{	/* display sstream */
X
X    register ch;	/* work char */
X    int eline;	/* end line -- line to stop display */
X    short lflag;	/* True if chars have printed on current line */
X    register int col;
X    extern char wdname [];	/* Name of working dir */
X
X    if (feof (sstream)) seekline (1);
X
X    tline = cline;
X    eline = cline + window - 7;
X
X    clearmsg (-1); bufout (); tty_push (COOKEDMODE);
X
X    erase (); hilite("%s", wdname);
X    atxy (61, 1); hilite("Showfile -- %s", sdesc [p]);
X    printf("\r\n");
X
X    while (cline < eline) 
X    {
X	lflag = 0;
X	col = 0;
X	do
X	{
X	    ch = getc (sstream);
X	    if (ch == EOF) ch = LF;
X	    if (ch == CR)
X		continue;
X	    else if (!lflag)  
X	    {
X		hilite ("%4d", cline);
X		printf (" ");
X		lflag = 1;
X	    }
X	    switch(ch) {
X	    case '\t':
X		col += 8 - (col&7);
X		break;
X	    case '\r':
X		col = 0;
X		break;
X	    case '\b':
X		if (col > 0)
X		    col--;
X		break;
X	    case 0177:
X		break;
X	    default:
X		if (ch >= ' ')
X		    col++;
X		break;
X	    }
X	    if (col >= CO-5) {
X		printf("\r\n     ");
X		eline--;
X		col = 0;
X	    }
X	    putchar (ch);
X	}
X	while (ch != LF);
X
X	cline++;
X	if (feof (sstream)) 
X	{
X	    seekline (1); printf ("** End of File **\r\n");
X	    break;
X	}
X    }
X    printf ("\r\n     ");
X    hilite ("Type the number of the line you wish to edit.");
X    printf ("\r\n     ");
X    hilite ("Type ^D to Leave.  Type ? for more options.");
X
X    atxy (1, window-1); unbufout (); tty_pop ();
X}
X
Xsedit (p, number) int p, number; 
X{
X    char inbuf [STRMAX];
X
X    int oldline;
X
X    oldline = cline;
X    if (number == 0) return REPLOT;
X    seekline (number);
X
X    fgetline (sstream, inbuf);
X    if (p == GREPMODE && grepfmt (inbuf));
X    else if (p == MAKEMODE &&
X	(ccfmt (inbuf) || grepfmt (inbuf) || cmdfmt (inbuf)));
X    else
X    {
X	putmsg ("Cannot find file name");
X	seekline (oldline);
X	return NOREPLOT;
X    }
X    seekline (number);
X    return REPLOT;
X}
X
X/* Extract file names and line numbers from various formats.  */
X
Xccfmt (inbuf) char inbuf [STRMAX]; 
X{	/*  Error from C compiler */
X    char filebuf [STRMAX];	/*  or lint               */
X    char *enumber ();
X    register char *cpi, *cpo;
X
X    cpi = inbuf;
X    while (*cpi != '"') if (*cpi++ == 0) return 0;
X
X    cpi++; cpo = filebuf;
X    while (*cpi != '"') 
X    {
X	if (*cpi == 0) return 0;
X	*cpo++ = *cpi++;
X    }
X    *cpo = 0;
X
X    return nedit (filebuf, enumber (cpi));
X}
X
Xgrepfmt (inbuf) char inbuf [STRMAX]; 
X{	/*  Line from grep        */
X    char filebuf [STRMAX];	/*  or C preprocessor     */
X    char *enumber ();
X    register char *cpi, *cpo;
X
X    cpi = inbuf; cpo = filebuf;
X    while (*cpi != ':') 
X    {
X	if (*cpi == 0) return 0;
X	*cpo++ = *cpi++;
X    }
X    if (*cpi == 0) return 0;
X    *cpo = 0;
X
X    return nedit (filebuf, enumber (cpi));
X}
X
Xcmdfmt (inbuf) char inbuf [STRMAX]; 
X{	/*  Command line          */
X    char filebuf [STRMAX];
X    register char *cpi, *cpo;
X
X    cpi = inbuf;
X
X    do
X    {
X	while (!WHITESPACE (*cpi)) if (*cpi++ == 0) return 0;
X	while ( WHITESPACE (*cpi)) cpi++;
X    }
X    while (*cpi == '-');
X
X    if (*cpi == 0) return 0;
X
X    cpo = filebuf;
X    while (!WHITESPACE (*cpi) && *cpi != 0) *cpo++ = *cpi++;
X    *cpo = 0;
X
X    return nedit (filebuf, EONE);
X}
X
X/* Extract number from line */
X
Xchar *
X    enumber (cpi) register char *cpi; 
X{
X
X    static char numbuf [8];
X
X#define	NUMBUFLIM	(numbuf + sizeof numbuf)
X
X    register char *cpo;
X    cpo = numbuf; *cpo++ = '+';
X
X    while (!NUMERIC (*cpi)) if (*cpi++ == 0) return EONE;
X
X    while (NUMERIC (*cpi)) 
X    {
X	if (cpo >= NUMBUFLIM) return EONE;
X	*cpo++ = *cpi++;
X    }
X    *cpo = 0;
X
X    return numbuf;
X}
X
Xnedit (file, number) char *file, *number; 
X{
X
X    if (access (file, 4)) return NOREPLOT;
X    if (strcmp(EDITOR, "vi") && strcmp(EDITOR, "jove"))
X	f_exec(EDITOR, EDITOR, file, 0);
X    else
X	f_exec (EDITOR, EDITOR, number, file, 0);
X    return REPLOT;
X}
All work and no play makes Jack a dull boy
echo src/showopen.c
sed 's/^X//' > src/showopen.c << 'All work and no play makes Jack a dull boy'
X#include "hd.h"
X
X/* Open a showfile */
X/* Open with rwmode of "r" or "w" just like fopen */
X/* Smode GREPMODE opens for grep;  Smode MAKEMODE opens for Make;  */
X
XFILE *showopen (rwmode, smode) char *rwmode; int smode; 
X{
X
X    char buf[STRMAX + 20];
X    FILE *tfile;
X    register char *fname;
X
X    fname = smode == GREPMODE ? GREPOUT : MAKERROR;
X    tfile = fopen (fname, rwmode);
X    if (tfile == NULL && smode == GREPMODE) 
X    {
X	if (access (fname, 0) == 0) 
X	{
X	    myperror (fname);
X	    return NULL;
X	}
X	strcpy (buf, HOME);
X	strcat (buf, "/");
X	strcat (buf, fname);
X	tfile = fopen (buf, rwmode);
X    }
X    if (tfile == NULL) 
X    {
X	myperror (fname);
X    }
X    return tfile;
X}
All work and no play makes Jack a dull boy
echo src/strings.c
sed 's/^X//' > src/strings.c << 'All work and no play makes Jack a dull boy'
X#
X/* Useful string handling routines */
X#
X#include "hd.h"
X#include "strings.h"
X
X#define	ALARMARROW			/* choose ALARM or EMPTY code */
X
X#ifdef VT100ARROW
X#ifdef ALARMARROW			/* Use alarm(2) implementation */
X#include <setjmp.h>
X#include <signal.h>
Xstatic int caught = 0;
Xjmp_buf arrowsave;
Xint arrowcatch();
X#endif
X#ifndef EMPTY
X#ifdef V7TTY
X#ifdef VENIX
X#include <sgtty.h>
X#else
X#include <sys/ioctl.h>
X#endif
X#endif
X#endif
X#endif
X
X/* Scanspace reads in the standard input and returns the first character
X   which is not a space.  Note this could be an end of file.  */
X
Xscanspace () 
X{
X    register ch;
X
X    while (WHITESPACE (ch = getch ()));
X    return ch;
X}
X
X/* Scanend scans to the end of a line */
X
Xscanend () 
X{
X    register ch;
X
X    while (!ENDLINE (ch =  getch ()));
X    return ch;
X}
X
X/* Xgetword inputs a string up to clim - 1 chars long */
X/* String is returned in argument;  Length is return value.  */
X
X/* Use getword (char_array) instead.  Clim is filled in for you. */
X
Xxgetword (input, clim) char *input; int clim; 
X{
X
X#define LASTCHAR	(input + clim - 1)
X
X    register ch; register char *cp, *lchar;
X
X    ch = scanspace ();
X    cp = input; lchar = LASTCHAR;
X
X    while (cp < lchar &&
X	!ENDLINE (ch) &&
X	!WHITESPACE (ch)) 
X    {
X
X	*cp++ = ch; ch = getch ();
X    }
X
X    while (!ENDLINE (ch)) ch = getch ();
X    *cp = 0;
X    return (cp - input);
X}
X
X/* Xgetline inputs a string up to clim - 1 chars long */
X/* String is returned in argument;  Length is return value.  */
X
X/* Use getline (char_array) instead.  Clim is filled in for you. */
X/* Use fgetline (stream, char_array) to get a line from a file   */
X/* other than stdin. */
X
Xxgetline (stream, input, clim) FILE *stream; char *input; int clim; 
X{
X
X    register ch; register char *cp, *lchar;
X    cp = input; lchar = LASTCHAR;
X
X    do
X    {
X	ch = fgetch(stream);
X	if (cp > lchar) cp = lchar;
X	*cp++ = ch;
X    }
X    while (!ENDLINE (ch));
X
X    *--cp = 0;
X    return (cp - input);
X}
X
Xgetrtn () 
X{		/* Ask person to press return */
X    printf ("  ");
X    hilite ("Press");
X    printf (" -Return-");
X    scanend ();
X}
X
Xputch (ch) int ch; 
X{
X    putchar (ch);
X}
X
X/*
X * Added to patch anomaly with fgetc returning EOF
X *	probably caused by switch between CBREAK and cooked modes
X */
Xfgetch(stream)
XFILE *stream;
X{
X	if (stream == stdin)
X		return getch();
X	else
X		return fgetc(stream);
X}
X
X#ifndef VT100ARROW
X
Xgetch () 
X{
X    char c;
X    static int errcnt = 0;
X
X    if (read(0, &c, 1) != 1) {
X	if (errcnt++ > 10) {
X		printf(" (\07Input error)\r\n\n");
X		leave();
X	}
X	c = QUITCHAR-'@';
X    }
X    else
X	errcnt = 0;
X    return (0177&c);
X}
X
X#else
X#define NEMPTY 500	/* Yuck! Basically a timed loop. Make this larger for
X				machines faster than a 780 and smaller for
X				machines slower than a 750. Better yet, rewrite
X				this code to use the termcap(5) arrow key
X				definitions and select(2) for 4.2BSD or MINTIME
X				for System V. Unfortunately, it will still leave
X				other machines "out in the cold." */
Xgetch () 
X{
X    register int i, j;
X    char c;
X    static int errcnt = 0;
X    static char peek[2] = { 0377, 0377 };
X
X    if ((peek[0]&0377) != 0377) {
X	c = peek[0]&0177;
X	peek[0] = 0377;
X    }
X    else if ((peek[1]&0377) != 0377) {
X	c = peek[1]&0177;
X	peek[1] = 0377;
X    }
X    else if (read(0, &c, 1) != 1) {
X	if (errcnt++ > 10) {
X		printf(" (\07Input error)\r\n\n");
X		leave();
X	}
X	c = QUITCHAR-'@';
X    }
X    else {
X	errcnt = 0;
X	c &= 0177;
X	if (c == 033) {
X		peek[0] = peek[1] = 0377;
X#ifdef ALARMARROW
X		i = caught = 0;
X		setjmp(arrowsave);
X		if (!caught) {
X			signal(SIGALRM, arrowcatch);
X			/* If your system doesn't guarantee at least .1 seconds
X				use alarm(2) (or nap(.1 second)) */
X			alarm(1);
X			i = (read(0, &peek[0], 1) == 1) ? 1 : 0;
X			if (i) {
X				peek[0] &= 0177;
X				if (read(0, &peek[1], 1) == 1) {
X					peek[1] &= 0177;
X					i++;
X				}
X			}
X			alarm(0);
X		}
X		signal(SIGALRM, SIG_IGN);
X#else
X#ifdef nokludge
X		if (!empty(0)
X			sleep(1);
X		if (!empty(0)) {
X			i = read(0, peek, 2);
X#else
X		/* empty() loop kludge */
X		for (j = 0; j < NEMPTY; j++)
X			if (!empty(0)) {
X				if (i = (read(0, &peek[0], 1) == 1) ? 1 : 0)
X					peek[0] &= 0177;
X				for (j = 0; j < NEMPTY; j++)
X					if (!empty(0)) {
X						if (read(0, &peek[1], 1) == 1) {
X							peek[1] &= 0177;
X							i++;
X						}
X						break;
X					}
X				break;
X			}
X#endif
X#endif
X		if (i == 2 && (peek[0] == 'O' || peek[0] == '['))
X			switch(peek[1]) {
X				case 'A':
X					c = 020;	/* up */
X					peek[0] = peek[1] = 0377;
X					break;
X				case 'B':
X					c = 016;	/* down */
X					peek[0] = peek[1] = 0377;
X					break;
X				case 'C':
X					c = 06;		/* right */
X					peek[0] = peek[1] = 0377;
X					break;
X				case 'D':
X					c = 02;		/* left */
X					peek[0] = peek[1] = 0377;
X					break;
X			}
X	}
X    }
X    return c;
X}
X
X#ifdef ALARMARROW
Xarrowcatch()
X{
X	signal(SIGALRM, arrowcatch);
X	caught = 1;
X	longjmp(arrowsave);
X}
X#else
X#ifndef EMPTY
X#ifdef VENIX
X
X/*
X * VENIX empty call - check if tty has any characters in input queue
X */
X
Xempty(fd)
Xint fd;
X{
X	struct sgttyb sg;
X
X	ioctl(fd, TIOCQCNT, &sg);
X	return (sg.sg_ispeed == 0);
X}
X
Xfull(fd)
Xint fd;
X{
X	struct sgttyb sg;
X
X	ioctl(fd, TIOCQCNT, &sg);
X	return sg.sg_ispeed;
X}
X
X#else
X
X/*
X * empty(fildes) - For BSD systems
X * Is the tty or pipe empty ? (Will a read() block)
X */
X
Xempty(fd)
Xint fd;
X{
X	long nchar;
X	int f;
X
X	f = ioctl(fd, FIONREAD, &nchar);
X	if (f == -1)
X		return -1;
X	if (nchar)
X		return 0;
X	return 1;
X}
X
X#endif
X#endif
X#endif
X#endif
X
Xany(c, s)
Xregister char c, *s;
X{
X
X	while(*s)
X		if(c == *s++)
X			return(1);
X	return(0);
X}
All work and no play makes Jack a dull boy
echo src/strings.h
sed 's/^X//' > src/strings.h << 'All work and no play makes Jack a dull boy'
X/*  Ascii control table.  There are 129 entries.  To find the class
X    of a character, mask out the parity bit (if raw I/O is being
X    used) and use it as an index the the ascii array.  With "cooked"
X    I/O, EOF is -1.  EOF with "parity" masked out is 7f, which is also
X    coded as an eof.  With "raw" I/O, EOT acts as an eof. */
X
X/*	Each entry in the table has the following bits:
X	1	End of line
X	2	End of file
X	4	Alpha
X	8	Upper case
X	16	Number
X	32	Special character
X	64	White space
X*/
X/*	Codes for loading table	*/
X
X#define UD	0	/* Undefined--assorted control characters */
X#define EL	1	/* End of line */
X#define EF	3	/* End of File (and line) */
X#define LA	4	/* Lower case alpha */ 
X#define UA	12	/* Upper case alpha */
X#define NU	16	/* Numeric */
X#define	SC	32	/* Special character */
X#define WS	64	/* White space */
X
X
X/* Ascii acts like an array indexed from -1 to 128 */
X
Xextern char charclass [];
X#define ascii	(charclass + 1)
X
X/* Useful macro functions */
X
X#define WHITESPACE(arg)	(ascii [arg] == WS)
X#define	NUMERIC(arg)	(ascii [arg] == NU)
X#define ENDLINE(arg)	(ascii [arg] & EL)
X
X#define	TONUM(arg)	(arg - '0')
X
X/* This reads a line from stdin and returns the first word */
X#define getword(arg)	xgetword (arg, sizeof arg)
X
X/* Read a line from stdin */
X#define getline(arg)	xgetline (stdin, arg, sizeof arg)
X
X/* Read a line from any stream */
X#define fgetline(arg1,arg2)	xgetline (arg1, arg2, sizeof arg2)
All work and no play makes Jack a dull boy
echo src/system.c
sed 's/^X//' > src/system.c << 'All work and no play makes Jack a dull boy'
X/* @(#)system.c	4.1 (Berkeley) 12/21/80 */
X#include	<signal.h>
X#ifdef	VSH
X#include	"hd.h"
X#endif
X
Xsystem(s)
Xchar *s;
X{
X	int status, pid, w;
X	register int (*istat)(), (*qstat)();
X
X#ifdef	VFORK
X	if ((pid = vfork()) == 0) {
X#else
X	if ((pid = fork()) == 0) {
X#endif
X		signal(SIGINT, SIG_DFL);
X		signal(SIGQUIT, SIG_DFL);
X		for (pid = 3; pid < 20; close(pid++));
X#ifdef	VSH
X		if (SHELL && *SHELL)
X			execl(SHELL, "sh", "-c", s, 0);
X#endif
X		execl("/bin/sh", "sh", "-c", s, 0);
X		_exit(127);
X	}
X	istat = signal(SIGINT, SIG_IGN);
X	qstat = signal(SIGQUIT, SIG_IGN);
X	while ((w = wait(&status)) != pid && w != -1)
X		;
X	if (w == -1)
X		status = -1;
X	signal(SIGINT, istat);
X	signal(SIGQUIT, qstat);
X	return(status);
X}
All work and no play makes Jack a dull boy
echo src/tty.c
sed 's/^X//' > src/tty.c << 'All work and no play makes Jack a dull boy'
X#include "hd.h"
X#ifdef	PWBTTY
X#include <sys/sgtty.h>
X#endif
X#ifdef	V7TTY
X#include <sgtty.h>
X#endif
X#ifdef	USGTTY
X#include <termio.h>
X#endif
X
X/* This module controls tty options.
X
X   Tty states are treated as a stack.  Use tty_push and tty_pop.
X
X   Push COOKEDMODE and RAWMODE onto the stack.  RAWMODE is now actually
X   CBREAK mode.
X*/
X
X#ifdef	PWBTTY
Xstruct sgtty newstty, oldstty;	/* sgtty structures */
X#endif
X#ifdef	V7TTY
Xstruct sgttyb newstty, oldstty;	/* sgtty structures */
X#endif
X#ifdef	USGTTY
Xstruct termio newstty, oldstty; /* termio structure */
X#endif
X
Xint ttysp;	/* Sp for tty stack */
Xextern short ospeed;	/* Speed for Joy's routines */
X
X#define	TTYLIM	16
Xchar tty_stack [TTYLIM];	/* The tty stack */
X
X/* Initialize tty structures */
X
Xtty_init () 
X{
X#ifdef	USGTTY
X	ioctl(infile, TCGETA, &oldstty);
X#else
X    gtty (infile, &oldstty);
X#endif
X	newstty = oldstty;
X#ifdef	PWBTTY
X    oldstty.sg_flag &= ~RAW;
X    newstty.sg_flag |= CBREAK;
X    newstty.sg_flag &= ~(CRMOD|ECHO);
X    ospeed = oldstty.sg_ospd;
X#endif
X#ifdef	V7TTY
X    oldstty.sg_flags &= ~(CBREAK|RAW);
X    newstty.sg_flags |= CBREAK;
X    newstty.sg_flags &= ~(CRMOD|ECHO);
X    ospeed = oldstty.sg_ospeed;
X#endif
X#ifdef	USGTTY
X	oldstty.c_lflag |= ICANON;
X	newstty.c_lflag &= ~(ICANON|ECHO);
X	newstty.c_iflag &= ~ICRNL;
X	newstty.c_cc[VMIN] = 1;
X	newstty.c_cc[VTIME] = 1;
X	ospeed = oldstty.c_cflag&CBAUD;
X#endif
X
X    ttysp = 0; tty_set (COOKEDMODE);
X}
X
X/* Push a new tty mode.  Use RAWMODE and COOKEDMODE as parameters. */
X
Xtty_push (pmode) int pmode; 
X{
X    ttysp++;
X    if (ttysp >= TTYLIM) 
X    {
X	putmsg ("Tty stack overflow\r\n");
X	leave ();
X    }
X    tty_set (pmode);
X}
X
Xtty_pop () 
X{
X    ttysp--;
X    if (ttysp < 0) 
X    {
X	putmsg ("Tty stack underflow\r\n");
X	leave ();
X    }
X    tty_set (tty_stack [ttysp]);
X}
X
X/* Tty_set sets the tty mode indicated by its parameter.  Stty is only
X   executed if a change will result.
X*/
X
Xtty_set (pmode) int pmode; 
X{
X
X    static int curmode = -1;	/* Current tty mode */
X
X    tty_stack [ttysp] = pmode;
X    if (pmode == curmode) return;
X    curmode = pmode;
X    if (pmode == RAWMODE) tty_raw ();
X    else tty_cooked ();
X}
X
Xtty_raw () 
X{
X#ifdef	USGTTY
X	ioctl(infile, TCSETAF, &newstty);
X#else
X    stty (infile, &newstty); 
X#endif
X}
X
Xtty_cooked () 
X{
X#ifdef	USGTTY
X	ioctl(infile, TCSETAF, &oldstty);
X#else
X    stty (infile, &oldstty); 
X#endif
X}
All work and no play makes Jack a dull boy
echo src/vshrc.gen
sed 's/^X//' > src/vshrc.gen << 'All work and no play makes Jack a dull boy'
XTERM=tvi950; HOME=nowhere; export TERM HOME;
Xvsh -f > /dev/null << eof
XO| options vsh.out
Xquit
X|
XOquitchar z
Xquit
X::
Xeof
Xsed -e '/^|/d' vsh.out > dflt.vshrc
Xrm vsh.out
All work and no play makes Jack a dull boy
echo src/xecute.c
sed 's/^X//' > src/xecute.c << 'All work and no play makes Jack a dull boy'
X
X#include "hd.h"
X#include "strings.h"
X#include "command.h"
X
X/* Interface to general execute */
X
X#define	REXEC	0
X
Xxecute(f)
Xchar **f;
X{
X	static char inline[STRMAX];
X	char stmp[STRMAX];
X	register char *s, *t, *u;
X	int ret;
X	register int argcnt, i;
X	char **v;
X	char lastc;
X	char c1, c2;
X
X	tty_push(COOKEDMODE);
X	clearmsg(2);
X	ewin();
X	lastc = 1;
X	ret = NOREPLOT;
X	if (f != REXEC) {
X		v = f;
X		if (*v != CNULL) {
X			for (s = inline; *v; v++) {
X				t = *v;
X				while (*s++ = *t++);
X				s[-1] = ' ';
X			}
X			*s = 0;
X		}
X		else {
Xagain:
X			printf("\r");
X			hilite("Command:");
X			printf(" ");
X			c1 = inline[0];
X			c2 = inline[1];
X			getline(inline);
X			if (*inline == 0) {
X				lastc = 0;
X				inline[0] = c1;
X				inline[1] = c2;
X			}
X		}
X	}
X	else if (*inline == 0) {
X		printf("\r");
X		hilite("No command");
X	}
X	if (lastc && *inline) {
X		if (VSHMODE == SELECTMODE && selecttype == DIRCMD) {
X			s = stmp;
X			t = inline;
X			u = 0;
X			argcnt = 0;
X			while (*t) {
X				if (*t == '$') {
X					if (t[1] == ' ' || t[1] == 0) {
X						i = 0;
X						if (*selectname) {
X							u = selectname;
X							while (*u)
X								*s++ = *u++;
X							t++;
X							i++;
X						}
X						else if (!NOARG) {
X							if (argcnt == 0)
X								hilite("(%s)\n", inline);
X							hilite("Arg%d:", ++argcnt);
X							putch(' ');
X							i = xgetline(stdin, s, (&stmp[STRMAX]-s));
X							if (i) {
X								s += i;
X								s[0] = ' ';
X								t++;
X							}
X						}
X						if (i == 0) {
X							hilite("(Missing argument)\r\n");
X							t++;
X						}
X						continue;
X					}
X				}
X				*s++ = *t++;
X			}
X			*s = 0;
X			s = t = stmp;
X			if (*s == ';')
X				s++;
X			if (u || f == REXEC) {
X				printf("\r");
X				hilite("Command: %s\r\n", s);
X			}
X			system(s);
X		}
X		else {
X			s = t = inline;
X			if (*s == ';')
X				s++;
X    			if (f == REXEC) {
X				printf("\r");
X				hilite("Command: %s\r\n", s);
X			}
X			system(s);
X		}
X		if (*t != ';') {
X			f = (char **)!REXEC;
X			ret = REPLOT;
X			goto again;
X		}
X		tty_pop();
X		return REPLOT;
X	}
X	else {
X		vwin();
X		sleep(1);
X		clearmsg(1);
X		tty_pop();
X	}
X	return ret;
X}
X
Xrexecute()
X{
X	return xecute(REXEC);
X}
X
All work and no play makes Jack a dull boy
echo src/xeq.c
sed 's/^X//' > src/xeq.c << 'All work and no play makes Jack a dull boy'
X#include "hd.h"
X#include <signal.h>
X#include <errno.h>
X
X/*  F_exec forks and executes a process.  It then waits for the
X    forked process to finish.
X    Use f_exec like execl, except f_exec waits for termination of the
X    called program and then falls through.
X*/
X
Xextern leave ();
X
X#define pipein	pipefile [0]
X#define pipeout	pipefile [1]
X
X/*VARARGS1*/
Xf_exec (a, b) char *a, *b; 
X{
X
X    int retval;
X    int p;
X
X    tty_push (COOKEDMODE);
X    ewin();
X    if ((p = myfork ()) == 0) myexecv (a, &b);
X    else retval = join (p);
X    tty_pop ();
X    vwin();
X    return retval;
X}
X
X/* Exec takes parameters like a command and interfaces properly
X   to the command processor in command.c. */
X
Xexec (argv, argv1) char **argv, **argv1; 
X{
X    register char **v;
X    register int p;
X    register int pflag;
X    int pipefile[2];
X    char argbuf[STRMAX];
X    register char *s;
X    register int argcnt, i;
X    int query;
X    FILE *stream;
X
X    pflag = 0;
X    /* Page output */
X    if (argv == 0) {
X	argv = argv1;
X	pflag++;
X    }
X    if (*argv == CNULL) 
X    {
X	putmsg ("Exec: missing command");
X	return NOREPLOT;
X    }
X
X    if (pflag) {
X	if (mypipe(pipefile))
X		return NOREPLOT;
X    }
X    else
X	tty_push (COOKEDMODE);
X    ewin();
X    if ((p = myfork ()) == 0) {
X	v = argv;
X	if (**v == ';')
X		(*v)++;
X	s = argbuf;
X	argcnt = 0;
X	for (; *v; v++) {
X		query = (v[0][0] == '?' && v[0][1] == '?') ? 1 : 0;
X		if (query || strcmp(*v, "$") == 0) {
X			if (!query && VSHMODE == SELECTMODE
X				&& selecttype == DIRCMD && *selectname)
X				*v = selectname;
X			else if (query || !NOARG) {
X				tty_push(COOKEDMODE);
X				if (argcnt == 0) {
X					hilite(1);
X					printf("\r(");
X					for (i = 0;;) {
X						if (query && (argv+i) >= v)
X							break;
X						printf("%s", argv[i++]);
X						if (argv[i])
X							putch(' ');
X						else
X							break;
X					}
X					printf(")\n");
X					hilite(0);
X				}
X				if (query) {
X					hilite("%s", &v[0][2]);
X					argcnt++;
X				}
X				else
X					hilite("Arg%d:", ++argcnt);
X				putch(' ');
X				i = xgetline(stdin, s, (&argbuf[STRMAX]-s));
X				tty_pop();
X				if (i) {
X					*v = s;
X					s += i+1;
X				}
X				else
X					*v = 0;
X			}
X			else
X				*v = 0;
X			if (*v == 0) {
X				p++;
X				if (query) {
X					hilite("(Missing argument, aborting)");
X					printf("\n\r");
X					exit(-1);
X				}
X				else
X					hilite("(Missing Argument)");
X				continue;
X			}
X		}
X		*(v - p) = *v;
X	}
X	if (pflag) {
X		close(outfile);
X		dup(pipeout);
X		close(errorfile);
X		dup(pipeout);
X		close(pipein);
X		close(pipeout);
X		/* Not clear whether closing stdin is a good decision... */
X		close(infile);
X		open("/dev/null", 0);
X	}
X	else
X		clearline();
X	myexecv (*argv, argv);
X    }
X    else {
X	if (pflag) {
X		stream = fdopen(pipein, "r");
X		close(pipeout);
X		page(stream, "");
X		fclose(stream);
X	}
X	join (p);
X    }
X    if (!pflag && **argv != ';')
X	getrtn ();
X    if (!pflag)
X	tty_pop ();
X    vwin();
X    return REPLOT;
X}
X
Xmypipe(fd)
Xint *fd;
X{
X	register int f;
X
X	f = pipe(fd);
X	if (f)
X		myperror("pipe()");
X	return f;
X}
X
Xpagexec(argv)
Xchar **argv;
X{
X	return exec(0, argv);
X}
X/* Mysystem is similar to system, except the bugs are fixed.  In
X   addition, the tty is set to cooked mode and the command is printed.
X*/
Xmysystem (name)  char *name; 
X{
X
X    int pipefile[2];
X    register int p;
X    FILE *stream;
X
X    if (mypipe (pipefile))
X	return NOREPLOT;
X    tty_push (COOKEDMODE);
X
X    if ((p = myfork()) == 0) 
X    {
X	close (infile); dup (pipein);
X#ifdef	PWBTTY
X	myexecl ("/bin/sh", "+", "-p", 0);
X#else
X	myexecl (SHELL, "+", 0);
X#endif
X    }
X    else
X    {
X	stream = fdopen (pipeout, "w");
X	close (pipein);
X	hilite ("%s", name);
X	printf ("\r\n");
X	fprintf (stream, "%s\n", name);
X	fclose (stream);
X	join (p);
X    }
X    tty_pop ();
X    return REPLOT;
X}
X
X/* p_exec is just like f_exec except output is paged */
X
X/*VARARGS1*/
Xp_exec (a, b, c, d) char *a, *b, *c, *d; 
X{
X
X    int pipefile [2];
X    register int p;
X    FILE *stream;
X
X    if (mypipe (pipefile))
X	return NOREPLOT;
X    ewin();
X    if ((p = myfork ()) == 0) 
X    {
X	close (outfile); dup (pipeout);
X	close (errorfile); dup (pipeout);
X	close (pipein); close (pipeout);
X	if (a == 0) {
X		if (close(infile) || open(b, 0)) {
X			myperror(b);
X			_exit(1);
X		}
X		myexecv (c, &d);
X	}
X	else
X		myexecv (a, &b);
X    }
X    else
X    {
X	stream = fdopen (pipein, "r");
X	close (pipeout);
X	page (stream, "");
X	fclose (stream);
X	join (p);
X    }
X    vwin();
X    return REPLOT;
X}
X
X/* Special interfaces to exec */
X/* Myexecl and myexecv close files numbered > 3 and
X   print their arguments. */
X
X/*VARARGS1*/
Xmyexecl (a, b) char *a, *b; 
X{
X    myexecv (a, &b);
X}
X
Xdoexecv (a, b) char *a, **b; 
X{
X    register char **v;
X    register char *s, *t;
X    register char *p;
X    int i;
X    char buf[STRMAX];
X    char c;
X    extern errno;
X
X    v = b;
X    if (**v != '+') 
X    {
X	clearline();
X	hilite(1);
X	while (*v)
X		printf (" %s", *v++);
X	v = b;
X	hilite(0);
X	printf("\r\n");
X    }
X    for (i = 3; i <= _NFILE; i++) close (i);
X    if (*a != '/') {
X	p = PATH;
X	while (*p) {
X		s = buf;
X		t = p;
X		while (*t && *t != ':')
X			*s++ = *t++;
X		if (*p != ':')
X			*s++ = '/';
X		if (*(p = t))
X			p++;
X		t = a;
X		while (*s++ = *t++);
X		execv(buf, v);
X		if (errno == ENOEXEC) {
X			a = buf;
X			break;
X		}
X	}
X    }
X    else
X	execv(a, v);
X    if (errno == ENOEXEC) {
X	*v = a;
X	/* This may be a no-no, but what the hell... */
X	*--v = "sh";
X	p = "/bin/sh";
X	if ((i = open(a, 0)) > 0) {
X		if (read(i, &c, 1) > 0 && c == '#')
X			p = "/bin/csh";
X		close(i);
X	}
X	execv(p, v);
X	printf("%s: No shell\r\n", p);
X	errno = ENOEXEC;
X	sleep(2);
X    }
X}
X
Xmyexecv(a, b) char *a, **b;
X{
X    doexecv(a, b);
X    myperror (a); getrtn (); _exit (1);
X}
X
X/* Myfork acts like fork but never fails */
X#define	MAXTRIES	50	/* Max tries of a fork */
Xmyfork () 
X{
X    register int p;	/* process number */
X    register int tries;	/* number of tries */
X
X    for (tries = 1; tries <= MAXTRIES; tries++) 
X    {
X	p = fork ();
X	if (p > 0)
X		signal (SIGINT, SIG_IGN);
X	else if (p == 0) {
X		signal (SIGINT, SIG_DFL);
X		signal (SIGQUIT, SIG_DFL);
X	}
X	if (p != -1) return p;
X	myperror ("Cannot fork");
X	sleep (tries);
X	clearmsg (0);
X    }
X    putmsg ("Fatal error -- cannot fork\r\n");
X    leave ();
X    return -1;
X}
X
X/* Join is the compliment of fork */
X
Xjoin (p) int p; 
X{
X
X    int status [2]; int w;
X
X    status[0] = -1;
X    do
X    {
X	w = wait (status);
X    }
X    while (p != -1 && w != p && w != -1);
X
X    signal (SIGINT, SIG_IGN);		/* dyt, was leave */
X
X    return (status [0]);
X}
X
X/* Exec without fork */
Xchain(argv)
Xchar **argv;
X{
X	if (*argv == CNULL) {
X		putmsg("Chain: missing command");
X		return NOREPLOT;
X	}
X	tty_push(COOKEDMODE);
X	goout();
X	putmsg("Chaining to");
X	signal(SIGINT, SIG_DFL);
X	signal(SIGQUIT, SIG_DFL);
X	doexecv(*argv, argv);
X	signal(SIGINT, SIG_IGN);
X	signal(SIGQUIT, SIG_IGN);
X	myperror(*argv);
X	comein();
X	tty_pop();
X	return NOREPLOT;
X}
X
All work and no play makes Jack a dull boy
echo src/ALL
sed 's/^X//' > src/ALL << 'All work and no play makes Jack a dull boy'
X$* Makefile* vshrc.gen asfix \
Xaccount.c ascii.c at.c classify.c classify.h cmdini.c cmdload.c \
Xcmdrun.c command.h curdir.c curses.c dir.c dircmd.c dirlist.c enterf.c \
Xfile.c find.c grep.c hd.h help.c main.c make.c misccmd.c mydir.h options.c \
Xpage.c process.c readarg.c remove.c show.c showopen.c strings.c strings.h \
Xsystem.c tty.c xecute.c xeq.c
All work and no play makes Jack a dull boy
echo src/Makefile.bsd
sed 's/^X//' > src/Makefile.bsd << 'All work and no play makes Jack a dull boy'
XCC=cc
XSHELL=/bin/sh
XCFLAGS= -O -DVSH -DSTOPABLE -DVT100ARROW
XLDFLAGS= -g
XLOCALLIB=strlib.a
XLIBS=
XBIN=/usr/local/bin
XDESTDIR=/usr/lib/vsh
XOBJECTS= main.o at.o dir.o xeq.o curdir.o process.o enterf.o \
X	help.o page.o dirlist.o tty.o remove.o file.o show.o \
X	ascii.o make.o grep.o showopen.o strings.o \
X	curses.o account.o cmdrun.o misccmd.o dircmd.o cmdini.o \
X	readarg.o cmdload.o classify.o options.o xecute.o find.o system.o
X
X.c.o:
X	$(CC) $(CFLAGS) -c $<
X
Xvsh:	$(OBJECTS) mydir.h hd.h $(LOCALLIB)
X	cc -n -o nvsh $(LDFLAGS) $(OBJECTS) $(LOCALLIB) -ltermlib $(LIBS)
X	-mv vsh ovsh
X	mv nvsh vsh
X	-rm -f ovsh
X	size vsh
X
Xinstall: vsh
X	mv $(BIN)/vsh /usr/tmp/vsh
X	cp vsh $(BIN)/vsh
X	chmod 755 $(BIN)/vsh
X	-rm -f /usr/tmp/vsh
X	echo 'Do make docs to install documentation'
X
Xdocs:
X	-mkdir $(DESTDIR)
X	cp vshrc.gen ../doc/vshelp ../doc/genhelp* ../doc/rmhelp ../doc/showhelp $(DESTDIR)
X	echo 'Look over ../doc/vshrc* and ../doc/genhelp.dan to see a sample of'
X	echo 'how to configure VSH for a nicer interface. See ../termcap for'
X	echo 'additions to your /etc/termcap for a better display.'
X	echo 'A manual page for VSH can be found in ../doc .'
X
Xstrlib.a:
X	(cd ../strlib; $(CC) $(CFLAGS) -c str*.c)
X	ar rv $(LOCALLIB) ../strlib/str*.o
X	-ranlib $(LOCALLIB)
X
Xlint:
X	lint -bxac *.c
X
Xoldinstall: vsh
X	vshrc.gen
X	cp vsh $(BIN)
X	cp genhelp $(DESTDIR)
X	cp rmhelp $(DESTDIR)
X	cp showhelp $(DESTDIR)
X	cp dflt.vshrc $(DESTDIR)
X
Xclean:
X	rm -f $(OBJECTS) vsh
All work and no play makes Jack a dull boy
echo src/Makefile.noid
sed 's/^X//' > src/Makefile.noid << 'All work and no play makes Jack a dull boy'
XCC=v7cc
XSHELL=/bin/sh
XCFLAGS= -O -DVSH -DVT100ARROW
XLOCALLIB= local.a
XOUTPUT= vsh.noid
XOBJECTS= main.o at.o dir.o xeq.o curdir.o process.o enterf.o \
X	help.o page.o dirlist.o tty.o remove.o file.o show.o \
X	ascii.o make.o grep.o showopen.o strings.o \
X	curses.o account.o cmdrun.o misccmd.o dircmd.o cmdini.o \
X	readarg.o cmdload.o classify.o options.o xecute.o find.o system.o
X
X.c.o:
X	$(CC) $(CFLAGS) -c $<
X
X$(OUTPUT):   $(OBJECTS)
X	cc -n -o $(OUTPUT) $(OBJECTS) $(LOCALLIB) -ltermlib -lretro -lS -lv7 -lS
X	size $(OUTPUT)
X
Xlint:
X	lint -bxac *.c
X
Xprint:
X	/bin/csh /usr/ucb/vprint *.h *.c makefile showhelp genhelp rmhelp
X
Xinstall:
X	vshrc.gen
X	install -s vsh ${DESTDIR}/usr/local/vsh
X	install -c genhelp ${DESTDIR}/usr/local/lib
X	install -c rmhelp ${DESTDIR}/usr/local/lib
X	install -c showhelp ${DESTDIR}/usr/local/lib
X	install dflt.vshrc ${DESTDIR}/usr/local/lib
X
Xclean:
X	rm -f ${OBJECTS} vsh
All work and no play makes Jack a dull boy
echo src/Makefile.pwb
sed 's/^X//' > src/Makefile.pwb << 'All work and no play makes Jack a dull boy'
XCC=v7cc
XSHELL=/bin/sh
XCFLAGS= -O -DVSH -DVT100ARROW -DEMPTY
XLOCALLIB= local.a
XLDFLAGS= -i
XBIN=/usr/bin
XOBJECTS= main.o at.o dir.o xeq.o curdir.o process.o enterf.o \
X	help.o page.o dirlist.o tty.o remove.o file.o show.o \
X	ascii.o make.o grep.o showopen.o strings.o \
X	curses.o account.o cmdrun.o misccmd.o dircmd.o cmdini.o \
X	readarg.o cmdload.o classify.o options.o xecute.o find.o system.o
X
X.c.o:
X	$(CC) $(CFLAGS) -c $<
X
Xvsh:   $(OBJECTS)
X	cc $(LDFLAGS) -o nvsh $(OBJECTS) $(LOCALLIB) -ltermlib -lretro -lS -lv7 -lS
X	-mv vsh ovsh
X	mv nvsh vsh
X	-rm -f ovsh
X	size vsh
X
Xinstall:	vsh
X	-rm -f /usr/tmp/vsh
X	mv $(BIN)/vsh /usr/tmp/vsh
X	cp vsh $(BIN)/vsh
X	chmod 755 $(BIN)/vsh
X	-rm -f /usr/tmp/vsh
X
XVSH:
X	cc -o vsh -x $(OBJECTS) -ltermlib
X
Xlint:
X	lint -bxac *.c
X
Xprint:
X	/bin/csh /usr/ucb/vprint *.h *.c makefile showhelp genhelp rmhelp
X
Xinstall.old: vsh
X	vshrc.gen
X	install -s vsh $(BINDIR)
X	install -c genhelp $(DESTDIR)
X	install -c rmhelp $(DESTDIR)
X	install -c showhelp $(DESTDIR)
X	install dflt.vshrc $(DESTDIR)
X
Xclean:
X	rm -f $(OBJECTS) vsh
All work and no play makes Jack a dull boy
echo src/Makefile.venix
sed 's/^X//' > src/Makefile.venix << 'All work and no play makes Jack a dull boy'
XCC=cc
XSHELL=/bin/sh
XCFLAGS= -O -DVSH -DVENIX -DVT100ARROW
XLDFLAGS=
XLOCALLIB=strlib.a
XLIBS=
XBIN=/usr/local/bin
XOBJECTS= main.o at.o dir.o xeq.o curdir.o process.o enterf.o \
X	help.o page.o dirlist.o tty.o remove.o file.o show.o \
X	ascii.o make.o grep.o showopen.o strings.o \
X	curses.o account.o cmdrun.o misccmd.o dircmd.o cmdini.o \
X	readarg.o cmdload.o classify.o options.o xecute.o find.o system.o
X
X.c.o:
X	$(CC) $(CFLAGS) -c $<
X
Xvsh:	$(OBJECTS) mydir.h hd.h $(LOCALLIB)
X	cc -n -o nvsh $(LDFLAGS) $(OBJECTS) $(LOCALLIB) -ltermlib $(LIBS)
X	-mv vsh ovsh
X	mv nvsh vsh
X	-rm -f ovsh
X	size vsh
X
Xcp:	vsh
X	mv $(BIN)/vsh /usr/tmp/vsh
X	cp vsh $(BIN)/vsh
X	chmod 755 $(BIN)/vsh
X	-rm -f /usr/tmp/vsh
X
Xstrlib.a:
X	(cd ../strlib; $(CC) $(CFLAGS) -c str*.c)
X	ar rv $(LOCALLIB) ../strlib/str*.o
X	-ranlib $(LOCALLIB)
X
Xlint:
X	lint -bxac *.c
X
Xinstall:
X	vshrc.gen
X	cp vsh ${BINDIR}
X	cp genhelp ${DESTDIR}
X	cp rmhelp ${DESTDIR}
X	cp showhelp ${DESTDIR}
X	cp dflt.vshrc ${DESTDIR}
X
Xclean:
X	rm -f ${OBJECTS} vsh
All work and no play makes Jack a dull boy
exit