[net.sources] menunix for 4.2 BSD

perlman@wanginst.UUCP (Gary Perlman) (01/19/85)

We just changed to ULTRIX, so I updated menunix for it.
Have fun.

#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	src
# This archive created: Fri Jan 18 17:20:50 1985
# By:	Gary Perlman (Wang Institute, Tyngsboro, MA 01879 USA)
export PATH; PATH=/bin:$PATH
if test ! -d 'src'
then
	echo shar: creating directory "'src'"
	mkdir 'src'
fi
echo shar: entering directory "'src'"
cd 'src'
echo shar: extracting "'menu.defs'" '(865 characters)'
if test -f 'menu.defs'
then
	echo shar: over-writing existing file "'menu.defs'"
fi
sed 's/^X//' << \SHAR_EOF > 'menu.defs'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include "menu.h"
Xchar	menudir[100] = MENUDIR;
Xchar	maildir[100] = "/usr/spool/mail";
Xchar	*mailfile;
Xstruct MENU *savemenu;
Xint	anchored = 0;
Xint	newmenu;
Xint	ttyspeed;
X
Xchar	response[BUFSIZ];
Xchar	*command[MAXCOM];
Xchar	commandbuffer[MAXCOM][BUFSIZ];
Xint	docmode = 0;
Xint	progmode = 1;
Xstruct	VAR variables[MAXVAR];
Xint	nvar = 0;
XWINDOW *lmenu, *timewin, *history;
Xstruct MENU *menu, *rootmenu, *stdmenu;
Xstruct MENU *readmenu ();
X
Xshort	uid, gid;
Xchar	escapechar = '\\';
Xchar	varchar    = '$';
Xchar	shellchar  = '!';
Xchar	popchar    = ',';
Xchar	unixchar   = '.';
Xchar	dotdotchar = '0';
Xchar	quitchar   = '`';
Xchar	modechar   = '_';
Xint	flipped    = 0;
Xchar	dirpath[MAXDEPTH][NAMESIZ];
Xint	pathlength = 0;
Xchar	pwdname[BUFSIZ];
XWINDOW	*filewin;
Xint	nonames;
Xint	page = 1;
Xstruct FILENT filent[MAXENTRIES];
SHAR_EOF
if test 865 -ne "`wc -c 'menu.defs'`"
then
	echo shar: error transmitting "'menu.defs'" '(should have been 865 characters)'
fi
echo shar: extracting "'menu.h'" '(2600 characters)'
if test -f 'menu.h'
then
	echo shar: over-writing existing file "'menu.h'"
fi
sed 's/^X//' << \SHAR_EOF > 'menu.h'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#ifndef MENU_H
X#define MENU_H
X#include <curses.h>
X#include <ctype.h>
XFILE	*xopen ();
Xchar	*getargs (), *copy (), *interpolate (), *getresponse ();
Xextern	char	menudir[100];
Xextern	char	maildir[100];
Xextern	char	*mailfile;
Xextern	int	anchored;
Xextern	int	newmenu;
Xextern	int	ttyspeed;
X
X#define	MAXOPTION    15
X#define	MAXCOM       10
X#define	COMMAND       0
X#define MAXVAR      100
X#define	OUT_OF_RANGE -2
X#define	INDENT        5
X#define MENUTOP       1
X#define MENUBOTTOM   23
X#define HISTORY    (MAXOPTION+1)
X#define TIMELINE   (MENUBOTTOM)
X#define INFOLINE   (MENUBOTTOM-2)
X#define RESPLINE   (MENUBOTTOM-1)
X#define	NOTICES    (HISTORY-1)
X#define RIGHTMENU  (COLS/2)
X#define GETRETURN  {printf("press RETURN to continue");while(getchar()!='\n');}
Xextern char	response[BUFSIZ];
Xextern char	*command[MAXCOM];
Xextern char	commandbuffer[MAXCOM][BUFSIZ];
Xextern int	docmode;
Xextern int	progmode;
Xstruct	VAR
X	{
X	char	*name;
X	char	*value;
X	};
Xextern struct VAR variables[MAXVAR];
Xextern int	nvar;
Xextern WINDOW *lmenu, *timewin, *history;
Xstruct MENU
X	{
X	char	*menuname;
X	char	*display[MAXOPTION];
X	char	*program[MAXOPTION];
X	char	*arguments[MAXOPTION];
X	char	selector[MAXOPTION];
X	int	noptions;
X	struct MENU *nextmenu[MAXOPTION]; 
X	struct MENU *parent;
X	char	nowait[MAXOPTION];
X	};
Xextern struct MENU *menu;
Xextern struct MENU *rootmenu;
Xextern struct MENU *stdmenu;
Xextern struct MENU *savemenu;
Xextern struct MENU *readmenu ();
X
Xextern short	uid, gid;
X#define	ESC       ''
X#define	BACKSPACE ''
X#define ESCAPE    '\\'
X#define RETURN    '\n'
X#define MODECHANGE -2
X#define RUN	   -1
Xextern char	escapechar;
Xextern char	varchar    ;
Xextern char	shellchar  ;
Xextern char	popchar    ;
Xextern char	unixchar   ;
Xextern char	dotdotchar ;
Xextern char	quitchar   ;
Xextern char	modechar   ;
Xextern int	flipped    ;
X#include <sys/types.h>
X#include <sys/dir.h>
X#ifdef MAXNAMLEN
X#define NAMESIZ MAXNAMLEN
X#else
X#define NAMESIZ 16
X#endif
X#include <sys/stat.h>
X#define MAXDEPTH 10
Xextern char	dirpath[MAXDEPTH][NAMESIZ];
Xextern int	pathlength ;
Xextern char	pwdname[BUFSIZ];
Xextern WINDOW	*filewin;
X#define MAXENTRIES 250
Xextern int	nonames;
Xextern int	page ;
X#define	DIRFILE        3
X#define	PLAINFILE      1
X#define PROGFILE       2
X#define	PAGESIZE       9
Xstruct FILENT
X	{
X	char	f_name[NAMESIZ];
X	char	f_protect[12];
X	off_t	f_size;
X	};
Xextern struct FILENT filent[MAXENTRIES];
X#define begin(c) (c == '[')
X#define end(c)  (c == ']' || c == '\n' || c == NULL)
X#define separator(c) (c == ':')
X#define skipspace(ptr) while (isspace (*ptr)) ptr++;
X#endif MENU_H
SHAR_EOF
if test 2600 -ne "`wc -c 'menu.h'`"
then
	echo shar: error transmitting "'menu.h'" '(should have been 2600 characters)'
fi
echo shar: extracting "'display.c'" '(2770 characters)'
if test -f 'display.c'
then
	echo shar: over-writing existing file "'display.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'display.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include "menu.h"
Xleftdisplay (menu) struct MENU *menu;
X	{
X	int i;
X	extern	int flipped;
X	if (menu == NULL) return;
X	wclear (lmenu);
X	if (trueval ("highlight")) wstandout (lmenu);
X	mvwprintw (lmenu, 0, 0, "[%s]", menu->menuname);
X	if (trueval ("highlight")) wstandend (lmenu);
X	for (i = 0; i < menu->noptions; i++)
X		{
X		if (menu->nextmenu[i])
X			{
X			if (trueval ("highlight")) wstandout (lmenu);
X			mvwprintw (lmenu, i+1, INDENT, "[%s]", menu->display[i]);
X			if (trueval ("highlight")) wstandend (lmenu);
X			}
X		else
X			{
X			mvwprintw (lmenu, i+1, INDENT, menu->display[i]);
X			wprintw (lmenu, " (%s)", menu->program[i]);
X			}
X		if (iscntrl (menu->selector[i]))
X		mvwprintw (lmenu, i+1, 0,"^%c",menu->selector[i]-1+'A');
X		else mvwaddch (lmenu, i+1, 0, menu->selector[i]);
X		}
X	wrefresh (lmenu);
X	newmenu = 0;
X	}
X
Xlastcomm ()
X	{
X	int	i;
X	wclear (history);
X	for (i = 1; ; i++)
X		if (!*variables[i].value) continue;
X		else if (ERR == mvwprintw (history, i-1, 0, "%c%s %s",
X			varchar, variables[i].name, variables[i].value)) break;
X	wrefresh (history);
X	}
X
X#include <time.h>
Xchar	*months[] =	{ "January", "February", "March", "April",
X			"May", "June", "July", "August",
X			"September", "October", "November", "December" };
X
Xchar	*days[] =	{ "Sunday", "Monday", "Tuesday", "Wednesday",
X			"Thursday", "Friday", "Saturday"};
Xprinttime ()
X	{
X	struct	tm *date;
X	long	clock;
X	int	hour;
X
X	time (&clock);
X	date = (struct tm *) localtime (&clock);
X	if ((hour = date->tm_hour) > 12) hour %= 12;
X	if (date->tm_sec == 0)
X		checkmail (mailfile);
X	mvwprintw (timewin, 0, 0, "%s, %s %d.  %d:%02d:%02d",
X		days[date->tm_wday], months[date->tm_mon], date->tm_mday,
X		hour, date->tm_min, date->tm_sec);
X	wrefresh (timewin);
X	}
X
Xcheckmail (mailfile) char *mailfile;
X	{
X	struct	stat statbuf;
X	if (stat (mailfile, &statbuf)) return;
X	if (statbuf.st_size)
X	    {
X	    if (statbuf.st_atime > statbuf.st_mtime)
X		mvprintw (NOTICES-1, RIGHTMENU, "You have mail");
X	    else
X		mvprintw (NOTICES-1, RIGHTMENU, "You have new mail");
X	    printw (" (%d bytes)", statbuf.st_size);
X		clrtoeol ();
X	    }
X	refresh ();
X	}
X
Xdisplay (menu) struct MENU *menu;
X	{
X	int i;
X	if (menu == NULL) return;
X	clear (); refresh ();
X	printtime ();
X	nonames = newdir ();
X	page = vdir (page, nonames);
X	leftdisplay (menu);
X	lastcomm ();
X	checkmail (mailfile);
X	if (docmode)
X		{
X		mvprintw (NOTICES-3, RIGHTMENU, "Next selection gets documentation");
X		clrtoeol ();
X		}
X	if (anchored)
X		{
X		mvprintw (NOTICES-2, RIGHTMENU, "On a diversion from ");
X		if (trueval ("highlight")) standout ();
X		printw ("[%s]", savemenu->menuname);
X		if (trueval ("highlight")) standend ();
X		clrtoeol ();
X		}
X	/* mvwprintw (lmenu, 0, 0, "[%s]", menu->menuname); */
X	refresh ();
X	}
SHAR_EOF
if test 2770 -ne "`wc -c 'display.c'`"
then
	echo shar: error transmitting "'display.c'" '(should have been 2770 characters)'
fi
echo shar: extracting "'init.c'" '(3653 characters)'
if test -f 'init.c'
then
	echo shar: over-writing existing file "'init.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'init.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include "menu.h"
Xstruct MENU *
Xreadmenu (filename, header) char *filename; char *header;
X	{
X	char	*copy ();
X	FILE	*ioptr;
X	char	line[BUFSIZ];
X	char	file[100];
X	char	*p, *getvalue ();
X	struct MENU *menu = (struct MENU *) calloc (1, sizeof (struct MENU));
X	sprintf (file, "%s/%s", menudir, filename);
X	if (menu == NULL)
X		{ fprintf (stderr, "readmenu: out of space\n"); exit (1); }
X	ioptr = xopen (file, "r");
X	menu->menuname = copy (header);
X	while (p = fgets (line, BUFSIZ, ioptr))
X		{
X		while (p = getvalue (p, menu));
X		if (++menu->noptions > MAXOPTION)
X			{
X			fprintf (stderr, "readmenu: Too many options\n");
X			exit (1);
X			}
X		}
X	fclose (ioptr);
X	return (menu);
X	}
Xchar *
Xgetvalue (line, menu) char *line; struct MENU *menu;
X	{
X	char	valuebuf[BUFSIZ];
X	char	designator, *value = valuebuf;
X	*value = NULL;
X	skipspace (line);
X	if (!begin (*line++)) return (NULL);
X	skipspace (line);
X	designator = *line;
X	while (!separator (*line))
X		if (end (*line)) goto check;
X		else line++;
X	line++;
X	while (!end (*line)) *value++ = *line++;
X	*value = NULL;
X	line++;
Xcheck:
X	if (designator != 's')
X		value = copy (valuebuf);
X	switch (designator)
X	    {
X	    case 'd': menu->display[menu->noptions] = value; break;
X	    case 's': menu->selector[menu->noptions] = *valuebuf; break;
X	    case 'm': menu->nextmenu[menu->noptions]
X		    = readmenu (value, menu->display[menu->noptions]);
X		    menu->nextmenu[menu->noptions]->parent = menu;
X		    break;
X	    case 'p': menu->program[menu->noptions] = value; break;
X	    case 'a': menu->arguments[menu->noptions] = value; break;
X	    case 'w': menu->nowait[menu->noptions] = TRUE; break;
X	    default:
X		fprintf (stderr, "getvalue: bad designator '%c'\n", designator);
X	    }
X	return (line);
X	}
X
Xreadvar ()
X	{
X	char	line[BUFSIZ], *lineptr;
X	char	namebuf[BUFSIZ], *nameptr;
X	char	valuebuf[BUFSIZ], *valueptr;
X	char	*interpolate ();
X	char	*getenv ();
X	FILE	*ioptr;
X	int	i;
X	for (i = 0; i < MAXCOM; i++)
X		{
X		variables[i].value = commandbuffer[i];
X		variables[i].name  = copy (" ");
X		*variables[i].name = '0' + i;
X		}
X	nvar = MAXCOM;
X	variables[nvar].name	= copy ("dir");
X	variables[nvar++].value	= pwdname;
X	variables[nvar].name	= copy ("menu");
X	variables[nvar++].value	= copy (menudir);
X	variables[nvar].name	= copy ("home");
X	variables[nvar++].value	= getenv ("HOME");
X	variables[nvar].name	= copy ("user");
X	variables[nvar++].value	= getenv ("USER");
X	sprintf (line, "%s/%s", maildir, getenv ("USER"));
X	variables[nvar].name	= copy ("mail");
X	variables[nvar++].value	= mailfile = copy (line);
X	sprintf (line, "%s/%s", getenv ("HOME"), ".menuvar");
X	if (access (line, 4))
X		sprintf (line, "%s/setup/menunix", getenv ("HOME"));
X	if (ioptr = fopen (line, "r"))
X	    {
X	    while (fgets (line, BUFSIZ, ioptr))
X		{
X		lineptr = line;
X		nameptr = namebuf; *nameptr = NULL;
X		valueptr = valuebuf; *valueptr = NULL;
X		skipspace (lineptr);
X		while (isalnum (*lineptr))
X			*nameptr++ = *lineptr++;
X		*nameptr = NULL;
X		skipspace (lineptr);
X		if (*lineptr == '=') lineptr++;
X		skipspace (lineptr);
X		while (*lineptr != '\n')
X			*valueptr++ = *lineptr++;
X		*valueptr = NULL;
X		variables[nvar].name = copy (namebuf);
X		variables[nvar].value = copy (interpolate (valuebuf));
X		nvar++;
X		}
X	    fclose (ioptr);
X	    }
X	variables[nvar].name	= copy ("editor");
X	variables[nvar++].value = copy ("ex");
X	variables[nvar].name	= copy ("printdotfiles");
X	variables[nvar++].value	= copy ("true");
X	variables[nvar].name	= copy ("highlight");
X	variables[nvar++].value	= copy ("false");
X	variables[nvar].name	= copy ("shell");
X	variables[nvar++].value	= copy (getenv ("SHELL"));
X	}
SHAR_EOF
if test 3653 -ne "`wc -c 'init.c'`"
then
	echo shar: error transmitting "'init.c'" '(should have been 3653 characters)'
fi
echo shar: extracting "'utility.c'" '(1177 characters)'
if test -f 'utility.c'
then
	echo shar: over-writing existing file "'utility.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'utility.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include "menu.h"
XFILE *
Xxopen (name, mode) char *name, *mode;
X	{
X	FILE	*ioptr = fopen (name, mode);
X	if (ioptr == NULL)
X		{
X		fprintf (stderr, "Can't open %s\n", name);
X		exit (1);
X		}
X	}
X
Xsyscall (command) char *command;
X	{
X	char	*alias (), *interpolate ();
X	char	*c = alias (interpolate (command), "|;");
X	char	*getval (), *shell = getval ("shell");
X	char	shellcomm[BUFSIZ];
X	*shellcomm = NULL;
X	if (strcmp (shell, "/bin/sh"))
X		sprintf (shellcomm, "%s -c \"%s\"", shell, c);
X	nocrmode (); echo ();
X	printf ("%s\n", c);
X	system (*shellcomm ? shellcomm : c);
X	crmode (); noecho ();
X	}
Xchar *
Xcopy (string) char *string;
X	{
X	char	*copy = (char *) malloc (strlen (string) + 1);
X	if (copy == NULL)
X		{
X		clear (); refresh ();
X		printf ("You have run out of space\n");
X		endwin ();
X		exit (1);
X		}
X	strcpy (copy, string);
X	return (copy);
X	}
X
X#include <signal.h>
X#include <setjmp.h>
Xjmp_buf env;
Xtimeout () { longjmp (env, 1); }
Xtimegetc (secs)
X	{
X	int	c;
X	extern	timeout ();
X	signal (SIGALRM, timeout);
X	alarm (secs);
X	if (setjmp (env)) return (0);
X	c = getchar ();
X	signal (SIGALRM, SIG_IGN);
X	alarm (0);
X	return (c);
X	}
SHAR_EOF
if test 1177 -ne "`wc -c 'utility.c'`"
then
	echo shar: error transmitting "'utility.c'" '(should have been 1177 characters)'
fi
echo shar: extracting "'run.c'" '(1483 characters)'
if test -f 'run.c'
then
	echo shar: over-writing existing file "'run.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'run.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include "menu.h"
Xrun (chosenmenu, chosen) struct MENU *chosenmenu;
X	{
X	char	syscommand[BUFSIZ];
X	char	buf[BUFSIZ], *bufptr = buf;
X	char	*strptr;
X	int	i;
X	if (!chosenmenu->program[chosen]) return;
X	if (*chosenmenu->program[chosen] == '-')
X		{
X		internalrun (chosenmenu, chosen);
X		return;
X		}
X	mvprintw (INFOLINE, 0, "COMMAND: %s %s", chosenmenu->program[chosen],
X		chosenmenu->arguments[chosen]);
X	clrtoeol ();
X	if (docmode)
X		{
X		docmode = 0;
X		strptr = chosenmenu->program[chosen];
X		sprintf (variables[COMMAND].value, "man %s", strptr);
X		mvprintw (RESPLINE, 0, "Getting documentation on %s, please wait", strptr);
X		clrtoeol ();
X		move (MENUBOTTOM, 0);
X		refresh ();
X		syscall (variables[COMMAND].value);
X		GETRETURN
X		display (menu);
X		return;
X		}
X	if (chosenmenu->arguments[chosen])
X		{
X		if ((strptr = getargs (chosenmenu->arguments[chosen], NULL)) == NULL)
X			{ noecho (); crmode (); return; }
X		else sprintf (variables[COMMAND].value, "%s %s", 
X			chosenmenu->program[chosen], strptr);
X		}
X	else sprintf (variables[COMMAND].value, "%s", chosenmenu->program[chosen]);
X	clear (); refresh ();
X	syscall (variables[COMMAND].value);
X	if (!chosenmenu->nowait[chosen]) GETRETURN
X	if (anchored)
X	    {
X	    anchored = 0;
X	    display (menu = savemenu);
X	    return;
X	    }
X	for (i = MAXCOM-1; i > 0; i--)
X		variables[i].value = variables[i-1].value;
X	variables[COMMAND].value = variables[MAXCOM-1].value;
X	display (menu);
X	}
SHAR_EOF
if test 1483 -ne "`wc -c 'run.c'`"
then
	echo shar: error transmitting "'run.c'" '(should have been 1483 characters)'
fi
echo shar: extracting "'file.c'" '(7013 characters)'
if test -f 'file.c'
then
	echo shar: over-writing existing file "'file.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'file.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include "menu.h"
X
X#define	inodir(entry) (entry->d_ino)
X#ifdef MAXNAMLEN
X
X#define	namedir(entry) (entry->d_name)
X
X#else
X
X#define	DIR	FILE
X#define	opendir(path) fopen (path, "r")
X#define closedir(dirp) fclose (dirp)
Xstruct direct *
Xreaddir (dirp)
XDIR 	*dirp;
X	{
X	static	struct	direct	entry;
X	if (dirp == NULL) return (NULL);
X	for (;;)
X		{
X		if (fread (&entry, sizeof (struct direct), 1, dirp) == 0) return (NULL);
X		if (entry.d_ino) return (&entry);
X		}
X	}
Xchar	*strncpy ();
Xchar *
Xnamedir (entry)
Xstruct	direct	*entry;
X	{
X	static	char	name[NAMESIZ];
X	return (strncpy (name, entry->d_name, DIRSIZ));
X	}
X
X#endif
X
Xchar *
Xprname (s, dirpath, pathlength) char *s; char dirpath[MAXDEPTH][NAMESIZ];
X	{
X	int	i;
X	strcpy (s, "/");
X	for (i = 0; i < pathlength; i++)
X		{
X		strcat (s, dirpath[i]);
X		strcat (s, "/");
X		}
X	return (s);
X	}
X
Xchar *
Xpwd (s) char *s;
X	{
X	char	*pwd;
X	char	pathname[MAXDEPTH][NAMESIZ];
X	ino_t	inode[MAXDEPTH];
X	struct	direct *dirent;
X	struct	stat statbuf;
X	dev_t	dotdevno;
X	ino_t	rootinode;
X	DIR	*ioptr;
X	int	i;
X
X	pathlength = 0;
X	if (stat ("/", &statbuf)) printf ("Can't stat /\n");;
X	rootinode = statbuf.st_ino;
X	if (stat (".", &statbuf)) printf ("Can't stat .\n");
X	dotdevno = statbuf.st_dev;
X	for (;;)
X	{
X	if ((ioptr = opendir (".")) == NULL)
X		{
X		printf ("Can't open current directory");
X		return (NULL);
X		}
X	if ((dirent = readdir (ioptr)) == NULL)
X	    {
X	    closedir (ioptr);
X	    return (NULL);
X	    }
X	else inode[pathlength] = inodir(dirent);
X	dirent = readdir (ioptr); /* skip over .. */
X	if (pathlength)
X	    while (dirent = readdir (ioptr))
X		if (inodir(dirent) == inode[pathlength-1])
X		    {
X		    strcpy (pathname[pathlength-1], namedir(dirent));
X		    break;
X		    }
X	closedir (ioptr);
X	if (inode[pathlength] == rootinode)
X	    {
X	    chdir ("/");
X	    ioptr = opendir ("/", "r");
X	    while (dirent = readdir (ioptr))
X		{
X		if (stat (namedir(dirent), &statbuf)) continue;
X		if (statbuf.st_dev == dotdevno)
X		    {
X		    strcpy (dirpath[0], namedir (dirent));
X		    pathlength++;
X		    for (i = 1; i < pathlength; i++)
X			strcpy (dirpath[i], pathname[pathlength-i-1]);
X		    if (pathlength == 1 && dirpath[0][0] == '.')
X		    pathlength = 0;
X		    chdir (pwd = prname (s, dirpath, pathlength));
X		    closedir (ioptr);
X		    return (pwd);
X		    }
X		}
X	    }
X	pathlength++;
X	closedir (ioptr);
X	chdir ("..");
X	}
X	}
X
Xcd (dirname) char *dirname;
X	{
X	char	vardir[BUFSIZ];
X	char	*interpolate ();
X	char	*getenv ();
X	int	i;
X	if (!dirname) return (-1);
X	if (!*dirname) dirname = getenv ("HOME");
X	if (chdir (dirname))
X		{
X		sprintf (vardir, "%c%s", varchar, dirname);
X		dirname = interpolate (vardir);
X		if (*dirname == NULL) return (-1);
X		if (chdir (dirname = interpolate (vardir))) return (-1);
X		}
X	if (!strcmp (dirname, ".")) return (0);
X	if (*dirname == '/' || *dirname == '.')
X		{
X		pwd (pwdname);
X		return (0);
X		}
X	if (!strcmp (dirname, ".."))
X		if (pathlength) pathlength--;
X		else return (0);
X	else strcpy (dirpath[pathlength++], dirname);
X	prname (pwdname, dirpath, pathlength);
X	return (0);
X	}
X
Xnewdir ()
X	{
X	char	*name;
X	int	flecmp ();
X	int	nonames;
X	struct	direct *d;
X	struct	stat buf;
X	DIR	*ioptr = opendir (".");
X	if (ioptr == NULL) return (0);
X	nonames = 0;
X	while (d = readdir (ioptr))
X		{
X		name = namedir (d);
X		if (!strcmp (name, ".")) continue;
X		if (!strcmp (name, "..")) continue;
X		if ((!trueval ("printdotfiles")) && *name == '.')
X			continue;
X		if (stat (name, &buf))
X			{
X			printf ("Can't stat %s", name);
X			getchar ();
X			continue;
X			}
X		strcpy (filent[nonames].f_name, name);
X		setmode (filent[nonames].f_protect, &buf);
X		filent[nonames].f_size = buf.st_size;
X		if (++nonames == MAXENTRIES) break;
X		}
X	qsort (filent, nonames, sizeof (struct FILENT), flecmp);
X	closedir (ioptr);
X	return (nonames);
X	}
X
X#define UNSET '-'
X#define UPPER 'A'-'a'
Xsetmode (s, statbuf) char *s; struct stat *statbuf;
X	{
X	int	i;
X	short	mode = statbuf->st_mode;
X	for (i = 1; i < 10; i++) s[i] = UNSET;
X	s[10] = NULL;
X	switch (mode & S_IFMT)
X		{
X		case S_IFREG: s[0] = '-'; break;
X		case S_IFDIR: s[0] = 'd'; break;
X		case S_IFCHR: s[0] = 'c'; break;
X#ifdef S_IFBLK
X		case S_IFBLK: s[0] = 'b'; break;
X#endif
X#ifdef S_IFMPC
X		case S_IFMPC: s[0] = 'C'; break;
X#endif
X#ifdef S_IFMPB
X		case S_IFMPB: s[0] = 'B'; break;
X#endif
X		default: s[0] = '?';
X		}
X	for (i = 0; i < 9; i+=3)
X		{
X		if (mode & (S_IREAD  >> i)) s[i + 1] = 'r';
X		if (mode & (S_IWRITE >> i)) s[i + 2] = 'w';
X		if (mode & (S_IEXEC  >> i)) s[i + 3] = 'x';
X		}
X	if (uid == statbuf->st_uid)
X		{
X		for (i = 1; i <= 3; i++)
X			if (s[i] != UNSET) s[i] += UPPER;
X		}
X	else if (gid == statbuf->st_gid)
X		{
X		for (i = 4; i <= 6; i++)
X			if (s[i] != UNSET) s[i] += UPPER;
X		}
X	else for (i = 7; i <= 9; i++)
X		if (s[i] != UNSET) s[i] += UPPER;
X	}
X
Xflecmp (f1, f2) struct FILENT *f1, *f2;
X	{
X	int	strcmp ();
X	if (f1->f_protect[0] == 'd' && f2->f_protect[0] != 'd') return (-1);
X	if (f2->f_protect[0] == 'd' && f1->f_protect[0] != 'd') return (1);
X	return (strcmp (f1->f_name, f2->f_name));
X	}
X
Xvdir (page, nonames)
X	{
X	int	i;
X	int	reali;
X	char	pagecount[10];
X	int	npages = nonames/PAGESIZE + (nonames%PAGESIZE?1:0);
X	if (page < 1) page = npages;
X	else if (page > npages) page = 1;
X	wclear (filewin);
X	for (i = 0; i < PAGESIZE; i++)
X		{
X		if ((reali = i + (page-1)*PAGESIZE) == nonames) break;
X		mvwprintw (filewin,1+i, 0, "%c", '1'+i);
X		if (filent[reali].f_protect[0] == 'd') /* directory */
X			{
X			if (trueval ("highlight")) wstandout (filewin);
X			mvwprintw (filewin,1+i, INDENT, "%s/",
X				filent[reali].f_name);
X			if (trueval ("highlight")) wstandend (filewin);
X			}
X		else	mvwprintw (filewin,1+i, INDENT, "%s",
X				filent[reali].f_name);
X		mvwprintw (filewin, 1+i, 20, "%9d %10s",
X			filent[reali].f_size, filent[reali].f_protect);
X		}
X	if (trueval ("highlight")) wstandout (filewin);
X	mvwprintw (filewin,0,0, "%s", pwdname);
X	if (trueval ("highlight")) wstandend (filewin);
X	sprintf (pagecount, "%d/%d", page, npages);
X	mvwprintw (filewin,0,COLS/2-5, "%5s", pagecount);
X	wrefresh (filewin);
X	return (page);
X	}
X
Xfileprocess (c) char c;
X    {
X    char	*getargs (), *getval ();
X    char	*strptr;
X    int	i = c - '1' + (page-1)*PAGESIZE;
X    if (i >= nonames)
X	{
X	printf ("");
X	return;
X	}
X    mvwprintw (filewin, 1+c-'1', 2, "<-");
X    wrefresh (filewin);
X    if (filent[i].f_protect[0] == 'd' && access (filent[i].f_name, 1) == 0)
X	{
X	cd (filent[i].f_name);
X	nonames = newdir ();
X	page = vdir (page=1, nonames);
X	}
X    else if (access (filent[i].f_name, 1) == 0)
X	{
X	sprintf (command, "%s ", filent[i].f_name);
X	if ((strptr = getargs ("{arguments?}", NULL)) == NULL) return;
X	strcat (command, strptr);
X	clear (); refresh ();
X	syscall (command);
X	GETRETURN
X	clear (); refresh ();
X	flipped = 0;
X	display (menu);
X	}
X    else if (access (filent[i].f_name, 4) == 0)
X	{
X	sprintf (command, "$editor %s", filent[i].f_name);
X	move (LINES-1, 0); clrtoeol (); refresh ();
X	syscall (command);
X	clear (); refresh ();
X	flipped = 0;
X	display (menu);
X	}
X    else printf ("");
X    }
SHAR_EOF
if test 7013 -ne "`wc -c 'file.c'`"
then
	echo shar: error transmitting "'file.c'" '(should have been 7013 characters)'
fi
echo shar: extracting "'internalrun.c'" '(5036 characters)'
if test -f 'internalrun.c'
then
	echo shar: over-writing existing file "'internalrun.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'internalrun.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include "menu.h"
X#define skipspace(ptr) while (isspace (*ptr)) ptr++;
Xinternalrun (chosenmenu, chosen) struct MENU *chosenmenu;
X    {
X    char	syscommand[BUFSIZ];
X    char	buf[BUFSIZ], *bufptr = buf;
X    char	*strptr;
X    char	comm = chosenmenu->program[chosen][1];
X    int	i;
X    if (docmode && comm != 'd')
X	{
X	docmode = 0;
X	docinternal (comm);
X	flipped = 1;
X	return;
X	}
X    switch (comm)
X	{
X	case 'f':
X		if (flipped) leftdisplay (menu);
X		else leftdisplay (stdmenu);
X		flipped = !flipped;
X		return;
X	case 'p':
X		popchar = chosenmenu->selector[chosen];
X		flipped = 0;
X		menu = menu->parent;
X		if (ttyspeed > B9600)
X			leftdisplay (menu);
X		else newmenu = 1;
X		return;
X	case 'x':
X		finish (0);
X	case 'a':
X		if (anchored)
X			{
X			menu = savemenu;
X			newmenu = 1;
X			if (ttyspeed > B9600)
X			    leftdisplay (menu);
X			move (NOTICES-2, RIGHTMENU); clrtoeol (); refresh ();
X			}
X		else	{
X			savemenu = menu;
X			mvprintw (NOTICES-2, RIGHTMENU, "On a diversion from ");
X			if (trueval ("highlight")) standout ();
X			printw ("[%s]", savemenu->menuname);
X			if (trueval ("highlight")) standend ();
X			refresh ();
X			menu = rootmenu;
X			if (ttyspeed > B9600)
X			    leftdisplay (menu);
X			else newmenu = 1;
X			}
X		anchored = !anchored;
X		flipped = 0;
X		return;
X	case 'u':
X		unixchar = chosenmenu->selector[chosen];
X		if (anchored)
X		    {
X		    move (NOTICES-2, RIGHTMENU);
X		    clrtoeol ();
X		    refresh ();
X		    }
X		anchored = flipped = 0;
X		menu = rootmenu;
X		if (ttyspeed > B9600)
X		    leftdisplay (menu);
X		else newmenu = 1;
X		return;
X	case 'c':
X		mvprintw (INFOLINE, 0, chosenmenu->display[chosen]);
X		clrtoeol ();
X		if (cd (getargs (chosenmenu->arguments[chosen], NULL)))
X			{
X			mvprintw (INFOLINE,0, "Can't change directory");
X			clrtoeol ();
X			refresh ();
X			}
X		else page = vdir (page=1, nonames = newdir ());
X		return;
X	case '0':
X		dotdotchar = chosenmenu->selector[chosen];
X		cd ("..");
X		page = vdir (page=1, nonames=newdir ());
X		return;
X	case '+':
X		page = vdir (++page, nonames);
X		return;
X	case '-':
X		page = vdir (--page, nonames);
X		return;
X	case 'r': display (menu); flipped = 0; return;
X	case 'd':
X		if (docmode = !docmode)
X		  mvprintw (NOTICES-3, RIGHTMENU, "Next selection gets documentation");
X		else
X		  mvprintw (NOTICES-3, RIGHTMENU, "Next selection runs program");
X		clrtoeol ();
X		refresh ();
X		return;
X	case 's': 
X		shellchar = chosenmenu->selector[chosen];
X		mvprintw (INFOLINE, 0, chosenmenu->display[chosen]);
X		clrtoeol ();
X		strptr = getargs (chosenmenu->arguments[chosen], NULL);
X		if (strptr == NULL) return;
X		while (isspace (*strptr)) strptr++;
X		if (*strptr != NULL)
X		    strcpy (variables[COMMAND].value, alias (strptr, "|;"));
X		syscall (variables[COMMAND].value);
X		GETRETURN
X		display (menu);
X		return;
X	case 'v':
X		varchar = chosenmenu->selector[chosen];
X		mvprintw (INFOLINE, 0, "Setting variable");
X		clrtoeol ();
X		refresh ();
X
X		if ((strptr = getargs ("{name}", NULL)) == NULL)
X			return;
X		else strptr = copy (strptr);
X		skipspace (strptr);
X		for (i = 0; i < nvar; i++)
X			if (!strcmp (strptr, variables[i].name)) break;
X		if (i == nvar)
X		    {
X		    if (nvar+1 > MAXVAR)
X			    {
X			    mvprintw (INFOLINE, 0,"No room for more variables");
X			    clrtoeol ();
X			    refresh ();
X			    return;
X			    }
X		    mvprintw (INFOLINE, 0, "Setting new variable");
X		    variables[i].name = copy (strptr);
X		    }
X		else
X			mvprintw (INFOLINE, 0, "Changing old variable");
X		clrtoeol ();
X		refresh ();
X		if ((strptr = getargs ("{value}", variables[i].value)) == NULL)
X			return;
X		else strptr = copy (strptr);
X		skipspace (strptr);
X		variables[i].value = strptr;
X		mvprintw (INFOLINE, 0, "%c%s=%s",
X			varchar, variables[i].name, variables[i].value);
X		clrtoeol ();
X		refresh ();
X		lastcomm ();
X		if (i == nvar) nvar++;
X		return;
X	case 'i':
X		mvprintw (INFOLINE, 0, chosenmenu->display[chosen]);
X		clrtoeol ();
X		strptr = getargs (chosenmenu->arguments[chosen], NULL);
X		if (*strptr)
X		    {
X		    mvprintw (INFOLINE, 0, interpolate (strptr));
X		    clrtoeol ();
X		    refresh ();
X		    }
X		else
X		    {
X		    FILE *popen(), *ioptr;
X		    if (ioptr = popen ("/usr/ucb/more", "w"))
X			{
X			clear (); refresh ();
X			nocrmode (); echo ();
X			for (i = 0; i < nvar; i++)
X			    fprintf (ioptr, "%10s=%s\n",
X				variables[i].name, variables[i].value);
X			pclose (ioptr);
X			GETRETURN
X			clear (); refresh ();
X			crmode (); noecho ();
X			display (menu);
X			}
X		    }
X		return;
X	default:
X		mvprintw (INFOLINE, 0, "Unknown internal command\n");
X		clrtoeol ();
X		refresh ();
X		return;
X	}
X    }
X
Xdocinternal (command) char command;
X	{
X	FILE	*fopen (), *ioptr;
X	char	*getval (), *menu = getval ("menu");
X	char	docfile[BUFSIZ];
X	char	line[BUFSIZ];
X	sprintf (docfile, "%s/../doc/internal", menu);
X	move (HISTORY, 0); clrtobot (); move (HISTORY, 0); refresh ();
X	if (ioptr = fopen (docfile, "r"))
X		{
X		while (fgets (line, BUFSIZ, ioptr))
X			if (*line == command)
X				fputs (line+1, stdout);
X		fclose (ioptr);
X		}
X	GETRETURN
X	display (stdmenu);
X	}
SHAR_EOF
if test 5036 -ne "`wc -c 'internalrun.c'`"
then
	echo shar: error transmitting "'internalrun.c'" '(should have been 5036 characters)'
fi
echo shar: extracting "'input.c'" '(2232 characters)'
if test -f 'input.c'
then
	echo shar: over-writing existing file "'input.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'input.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include "menu.h"
X
Xchar *
Xgetval (name) char *name;
X	{
X	int	i = 0;
X	for (i = 0; i < nvar; i++)
X		if (!strcmp (variables[i].name, name)) break;
X	if (i == nvar) return (NULL);
X	return (variables[i].value);
X	}
X
Xtrueval (name)
X	{
X	char	*v = getval (name);
X	if (v == NULL) return (0);
X	if (*v == NULL) return (1);
X	if (strlen (v) == 1)
X		if (*v == 't' || *v == 'y' || *v == '1') return (1);
X		else return (0);
X	else if (!strcmp (v, "true") || !strcmp (v, "yes")) return (1);
X	return (0);
X	}
X
Xchar *
Xinterpolate (s) char *s;
X	{
X	static	char	interbuf[BUFSIZ];
X	char	*getval ();
X	char	*sptr = s;
X	char	*bufptr = interbuf;
X	char	namebuf[BUFSIZ], *nameptr = namebuf;
X	int	i;
X	*bufptr = NULL;
X	while (*sptr)
X		{
X		if (*sptr == varchar)
X			{
X			nameptr = namebuf;
X			sptr++;
X			while (isalnum (*sptr)) *nameptr++ = *sptr++;
X			*nameptr = NULL;
X			strcpy (bufptr, getval (namebuf));
X			while (*bufptr) bufptr++;
X			}
X		else if	(*sptr == escapechar)
X			{
X			sptr++;
X			*bufptr++ = *sptr++;
X			}
X		else	*bufptr++ = *sptr++;
X		}
X	*bufptr = NULL;
X	return (interbuf);
X	}
X
X#define	begingeneric(c) (c == '{')
X#define	endgeneric(c)   (c == '}' || end(c))
Xchar *
Xgetargs (args, initial) char *args, *initial;
X	{
X	static	char	arglist[BUFSIZ];
X	char	genericbuf[100];
X	char	*generic;
X	char	*arglistptr = arglist;
X	*arglistptr = NULL;
X	if (args == NULL) return (arglist);
X	for(;;)
X		{
X		while (!begingeneric (*args))
X			if (*args == NULL)
X				{
X				*arglistptr = NULL;
X				return (arglist);
X				}
X			else *arglistptr++ = *args++;
X		*arglistptr = NULL;
X		generic = genericbuf;
X		while (!endgeneric (*args))
X			*generic++ = *args++;
X		*generic++ = *args++;
X		*generic = NULL;
X		if (trueval ("highlight")) standout ();
X		mvprintw (RESPLINE, 0, genericbuf);
X		if (trueval ("highlight")) standend ();
X		printw (": ");
X		clrtoeol (); refresh ();
X		if (initial) strcpy (response, initial);
X		else *response = NULL;
X		if (getresponse (response) == NULL) return (NULL);
X		move (LINES-1, 0); clrtoeol (); refresh ();
X		strcat (arglist, response);
X		while (*arglistptr) arglistptr++;
X		}
X	}
X
Xchar *
Xgetresponse (s) char *s;
X	{
X	char	*linedit ();
X	int	x, y;
X	getyx (stdscr, y, x);
X	return (linedit (s, y, x));
X	}
SHAR_EOF
if test 2232 -ne "`wc -c 'input.c'`"
then
	echo shar: error transmitting "'input.c'" '(should have been 2232 characters)'
fi
echo shar: extracting "'menu.c'" '(2720 characters)'
if test -f 'menu.c'
then
	echo shar: over-writing existing file "'menu.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'menu.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include "menu.defs"
Xmain (argc, argv) char **argv;
X	{
X	initial (argc, argv);
X	process ();
X	}
X
X#include <signal.h>
Xchar	*getenv ();
Xinitial (argc, argv) char **argv;
X	{
X	int	i;
X	struct	sgttyb ttystat;
X	extern	finish (), howquit ();
X	char	*term	=getenv ("TERM");
X	WINDOW	*subwin ();
X	if (!movecursor (term))
X		{
X		printf ("This terminal (%s) can't run menus\n");
X		exit (1);
X		}
X	initscr ();
X	signal (SIGINT, howquit);
X	uid = getuid ();
X	gid = getgid ();
X	gtty (fileno (stdout), &ttystat);
X	ttyspeed = ttystat.sg_ospeed;
X	pwd (pwdname);
X	nonames = newdir ();
X	if (argc > 1) strcpy (menudir, argv[1]);
X	readvar ();
X	rootmenu = menu->parent = menu = readmenu ("UNIX", "UNIX");
X	stdmenu = readmenu ("CONTROL", "CONTROL");
X	lmenu = subwin (stdscr, MAXOPTION+1, RIGHTMENU-1, 0, 0);
X	filewin = subwin (stdscr, PAGESIZE+1, COLS/2, 0, COLS/2);
X	history = subwin (stdscr, INFOLINE-HISTORY-1, 0, HISTORY, 0);
X	timewin = subwin (stdscr, 1, 0, NOTICES, RIGHTMENU);
X	display (menu);
X	crmode (); noecho ();
X	}
X
Xprocess ()
X	{
X	int	c;
X	int	chosen;
X	for (;;)
X		{
X		if ((c = timegetc (1)) == 0)
X			{
X			if (newmenu) leftdisplay (menu);
X			printtime ();
X			}
X		else if (isdigit (c) && c != '0')
X			(fileprocess (c));
X		else if ((chosen = choose (c, stdmenu)) != OUT_OF_RANGE)
X			run (stdmenu, chosen);
X		else if ((chosen = choose (c, menu)) == OUT_OF_RANGE)
X			{
X			mvprintw (INFOLINE, 0, "BREAK to quit.  Type & for [CONTROL] commands");
X			clrtoeol ();
X			refresh ();
X			printf ("");
X			}
X		else if (menu->nextmenu[chosen])
X			{
X			menu = menu->nextmenu[chosen];
X			if (ttyspeed > B9600)
X				leftdisplay (menu);
X			else newmenu = 1;
X			flipped = 0;
X			}
X		else run (menu, chosen);
X		}
X	}
X
Xfinish ()
X	{
X	signal (SIGINT, SIG_IGN);
X	alarm (0);
X	clear ();
X	refresh ();
X	endwin ();
X	exit (0);
X	}
X
Xhowquit ()
X	{
X	extern	finish (), howquit ();
X	alarm (0);
X	signal (SIGINT, finish);
X	if (trueval ("highlight")) standout ();
X	mvprintw (INFOLINE, 0, "Type RETURN to return to menu, BREAK to exit");
X	signal (SIGINT, finish);
X	if (trueval ("highlight")) standend ();
X	clrtoeol (); refresh ();
X	crmode ();
X	while (getchar () != '\n') printf ("");
X	signal (SIGINT, howquit);
X	move (INFOLINE, 0); clrtoeol (); refresh ();
X	display (menu);
X	process ();
X	}
X
Xchoose (ch, thismenu) struct MENU *thismenu;
X	{
X	int	i;
X	int	chosen = OUT_OF_RANGE;
X	for (i = 0; i < thismenu->noptions; i++)
X		if (ch == thismenu->selector[i]) chosen = i;
X	if (chosen == OUT_OF_RANGE) return (chosen);
X	if (thismenu == stdmenu) return (chosen);
X	for (i = 0; i < thismenu->noptions; i++)
X		mvwprintw (lmenu, i + 1, 2, "  ");
X	if (!newmenu) mvwprintw (lmenu, chosen + 1, 2, "<-");
X	wrefresh (lmenu);
X	return (chosen);
X	}
X
SHAR_EOF
if test 2720 -ne "`wc -c 'menu.c'`"
then
	echo shar: error transmitting "'menu.c'" '(should have been 2720 characters)'
fi
echo shar: extracting "'CW'" '(57 characters)'
if test -f 'CW'
then
	echo shar: over-writing existing file "'CW'"
fi
sed 's/^X//' << \SHAR_EOF > 'CW'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
SHAR_EOF
if test 57 -ne "`wc -c 'CW'`"
then
	echo shar: error transmitting "'CW'" '(should have been 57 characters)'
fi
echo shar: extracting "'movecursor.c'" '(242 characters)'
if test -f 'movecursor.c'
then
	echo shar: over-writing existing file "'movecursor.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'movecursor.c'
Xmovecursor (term) char *term;
X	{
X	char	bp[1024];
X	char	*ptr = bp;
X	if (tgetent (bp, term) != 1) return (0);
X	while (*ptr)
X		{
X		while (*ptr && *ptr != ':') ptr++;
X		if (ptr[1] == 'c' && ptr[2] == 'm') return (1);
X		ptr++;
X		}
X	return (0);
X	}
SHAR_EOF
if test 242 -ne "`wc -c 'movecursor.c'`"
then
	echo shar: error transmitting "'movecursor.c'" '(should have been 242 characters)'
fi
echo shar: extracting "'image.c'" '(469 characters)'
if test -f 'image.c'
then
	echo shar: over-writing existing file "'image.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'image.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include <curses.h>
X#include <ctype.h>
Ximage ()
X	{
X	int i, j;
X	char c;
X	FILE *ioptr;
X	char file[100];
X	sprintf (file, "image.%d", getpid ());
X	ioptr = fopen (file, "w");
X	for (i = 0; i < 24; i++)
X		{
X		for (j = 0; j < 80; j++)
X			{
X			c = stdscr->_y[i][j];
X			if (isascii (c))
X			    fputc (stdscr->_y[i][j], ioptr);
X			else fputc (' ', ioptr);
X			}
X		fputc ('\n', ioptr);
X		}
X	fclose (ioptr);
X	printf ("");
X	}
SHAR_EOF
if test 469 -ne "`wc -c 'image.c'`"
then
	echo shar: error transmitting "'image.c'" '(should have been 469 characters)'
fi
echo shar: extracting "'Makefile'" '(474 characters)'
if test -f 'Makefile'
then
	echo shar: over-writing existing file "'Makefile'"
fi
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X#Copyright (c) 1981 Gary Perlman  All rights reserved
X#
X# Be sure to change MENUDIR (where all menus are kept)
X#
XMENUDIR="/b/faculty/perlman/menunix/menus"
X#
XOBJS = menu.o init.o internalrun.o file.o display.o run.o\
X	input.o linedit.o utility.o alias.o movecursor.o
XLIBES = -lcurses -ltermlib
XDESTDIR = .
Xmenu: $(OBJS)
X	cc -o $(DESTDIR)/menunix $(OBJS) $(LIBES)
X$(OBJS): menu.h
Xmenu.o: menu.defs
X	@echo Menus should be in $(MENUDIR)
X	cc -D'MENUDIR=$(MENUDIR)' -O -c menu.c
SHAR_EOF
if test 474 -ne "`wc -c 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 474 characters)'
fi
echo shar: extracting "'linedit.c'" '(6623 characters)'
if test -f 'linedit.c'
then
	echo shar: over-writing existing file "'linedit.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'linedit.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include "menu.h"
XWINDOW	*subwin ();
XWINDOW	*feedback;
Xint	neveredited = 1;
Xchar *
Xlinedit (s, y, x) char *s;
X    {
X    char	*cursormode ();
X    if (neveredited)
X	{
X	if ((feedback = subwin (stdscr, 1, 0, LINES-1, 0)) == NULL)
X	    return (NULL);
X	neveredited = 0;
X	}
X    return (cursormode (s, y, x, feedback));
X    }
X
Xchar *
Xcursormode (s, y, base_x, feedback) char *s; WINDOW *feedback;
X	{
X	extern	char	varchar;
X	char	command = 0;
X	char	saved_s[BUFSIZ];
X	char	saved[2][BUFSIZ];
X	int	x = 0;
X	int	answer;
X	int	max_x = strlen (s) - 1;
X	int	other = 0;
X	strcpy (saved_s, s);
X	strcpy (saved[0], s);
X	strcpy (saved[1], s);
X	if (*s == NULL) command = 'I'; /* auto insert */
X	else
X	    {
X	    mvwprintw (feedback, 0, 0,
X		"Cursor mode: quit with 'q', insert with 'i', undo with 'u'");
X	    wclrtoeol (feedback); wrefresh (feedback);
X	    }
X	move (y, base_x);
X	ctrlprintw (s);
X	clrtoeol ();
X	move (y, x+base_x);
X	refresh ();
X	do	{
X		strcpy (saved[other], s);
X		switch (command)
X			{
X			case 0: break;
X			case ' ': /* forward one character */
X			case 'l':
X			case 12:
X			case '+':
X				if (++x > max_x) printf ("");
X				break;
X			case '-': /* backward one character */
X			case 'h':
X			case 8:
X				 if (--x < 0) printf ("");
X				break;
X			case '^':
X			case 'H': /* all the way to left */
X				x = 0;
X				break;
X			case '$':
X			case 'L': /* all the way to right */
X				x = max_x;
X				break;
X			case 'W': /* forward one word */
X			case 'w':
X				if (x == max_x)
X					{
X					printf ("");
X					break;
X					}
X				while (isspace (s[x])) x++;
X				while (x < max_x && !isspace (s[x])) x++;
X				while (isspace (s[x])) x++;
X				break;
X			case 'B': /* backward one word */
X			case 'b':
X				if (x == 0)
X					{
X					printf ("");
X					break;
X					}
X				while (x && !isspace (s[x])) x--;
X				while (x && isspace (s[x])) x--;
X				while (x && !isspace (s[x])) x--;
X				if (isspace (s[x])) x++;
X				break;
X			case 'C': /*change to end of line */
X				clrtoeol (); refresh ();
X				s[x] = NULL;
X				max_x = --x;
X				if (max_x < 0) max_x = 0;
X			case 'A': /* append after end */
X				x = max_x;
X			case 'a': /* append after cursor */
X				other = !other;
X				if (*s == NULL) x--;
X				if ((answer = insert (s, y, base_x, feedback, x+1)) == RUN)
X					return (s);
X				x = answer - 1;
X				max_x = strlen (s) - 1;
X				break;
X			case 'r': /* replace char */
X				if (*s == NULL) printf ("");
X				else	{
X					other = !other;
X					s[x] = getchar ();
X					}
X				break;
X			case 'D':
X			case '0':
X				other = !other;
X				s[x] = NULL;
X				max_x = --x;
X				break;
X			case 'x': /* delete character */
X				other = !other;
X				strcpy (s+x, s+x+1);
X				max_x--;
X				break;
X			case 'X': /* delete line  and auto insert */
X				*s = NULL;
X				move (y, base_x);
X				clrtoeol ();
X				refresh ();
X			case 'I': /* insert before start */
X				x = 0;
X			case 'i': /* insert before  cursor */
X				other = !other;
X				if ((answer = insert (s, y, base_x, feedback, x)) == RUN)
X					return (s);
X				x = answer;
X				max_x = strlen (s) - 1;
X				break;
X			case 'U': /* undo all stuff on line */
X				other = !other;
X				strcpy (s, saved_s);
X				max_x = strlen (s) - 1;
X				x = 0;
X				break;
X			case 'u': /* undo last change */
X				other = !other;
X				strcpy (s, saved[other]);
X				max_x = strlen (s) - 1;
X				x = 0;
X				break;
X			case 'Q':
X				wclear (feedback);
X				wrefresh (feedback);
X				mvprintw (y, base_x, "Line-edit escaped");
X				clrtoeol ();
X				refresh ();
X				return (NULL);
X			default: printf ("");
X			}
X		if (max_x < 0) x = max_x = 0;
X		else if (x > max_x) x = max_x;
X		else if (x < 0) x = 0;
X		move (y, base_x);
X		ctrlprintw (s);
X		clrtoeol ();
X		move (y, x+base_x);
X		refresh ();
X		} while ((command = getchar ()) != 'q' && command != '\n');
X	return (s);
X	}
X
Xinsert (s, y, base_x, feedback, x) char *s; WINDOW *feedback;
X	{
X	int	i;
X	char	before_cursor[BUFSIZ], after_cursor[BUFSIZ];
X	char	insert_cursor[BUFSIZ];
X	char	*ptr = insert_cursor;
X	int	max_x = strlen (s) - 1;
X	before_cursor[0] = insert_cursor[0] = after_cursor[0] = NULL;
X	mvwprintw (feedback, 0, 0,
X	    "Adding text: quit with ESC, select files with '_'");
X	wclrtoeol (feedback); wrefresh (feedback);
X	if (*s)
X		{
X		sprintf (before_cursor, "%.*s", x, s);
X		strcpy (after_cursor, s+x);
X		}
X	else max_x = 0;
X	move (y, base_x);
X	ctrlprintw (s);
X	move (y, x+base_x);
X	refresh ();
X	while ((*ptr = getchar ()) != ESC && *ptr != '\n')
X	    {
X	    if (*ptr == modechar)
X		{
X		mvwprintw (feedback, 0, 0,
X		    "Selecting files: quit with '_', select files by number");
X		wclrtoeol (feedback);
X		wrefresh (feedback);
X		*ptr = NULL;
X		while ((i = getfile ()) != MODECHANGE && i != RUN)
X			{
X			sprintf (ptr, "%s ", filent[i].f_name);
X			i = strlen (filent[i].f_name) + 1;
X			x += i;
X			ptr += i;
X			move (y, base_x);
X			ctrlprintw (before_cursor);
X			ctrlprintw (insert_cursor);
X			ctrlprintw (after_cursor);
X			clrtoeol ();
X			move (y, x+base_x);
X			refresh ();
X			}
X		mvwprintw (feedback, 0, 0, "Adding text: quit with ESC");
X		wclrtoeol (feedback);
X		wrefresh (feedback);
X		}
X	    else if (*ptr == '')
X		    {
X		    if (ptr > insert_cursor)
X			    {
X			    *ptr = NULL;
X			    ptr--;
X			    *ptr = NULL;
X			    x--;
X			    }
X		    else
X			    {
X			    printf ("");
X			    ptr = insert_cursor;
X			    *ptr = NULL;
X			    }
X		    }
X	    else if (*ptr == ESCAPE)
X		    {
X		    *ptr++ = getchar ();
X		    *ptr = NULL;
X		    x++;
X		    }
X	    else	{
X		    ptr++;
X		    *ptr = NULL;
X		    x++;
X		    }
X	    move (y, base_x);
X	    ctrlprintw (before_cursor);
X	    ctrlprintw (insert_cursor);
X	    ctrlprintw (after_cursor);
X	    clrtoeol ();
X	    move (y, x+base_x);
X	    refresh ();
X	    if (i == RUN) break;
X	    }
X	if (*ptr == '\n') i = RUN;
X	*ptr = NULL;
X	sprintf (s, "%s%s%s", before_cursor, insert_cursor, after_cursor);
X	strcpy (s, interpolate (s));
X	mvwprintw (feedback, 0, 0,"Cursor mode: quit with 'q', abort with 'Q'");
X	wclrtoeol (feedback); wrefresh (feedback);
X	if (i == RUN) return (RUN);
X	return (x);
X	}
X
Xgetfile ()
X	{
X	char	c;
X	int	i;
X	for (;;)
X		{
X		c = getchar ();
X		if (c == '+')
X			page = vdir (++page, nonames);
X		else if (c == '-')
X			page = vdir (--page, nonames);
X		else if (isdigit (c) && c != '0')
X			if ((i = c - '1' + (page-1)*PAGESIZE) >= nonames)
X				printf ("");
X			else	{
X				mvwprintw (filewin, 1+c-'1', 2, "<-");
X				wrefresh (filewin);
X				return (i);
X				}
X		else if (c == RETURN) return (RUN);
X		else if (c == modechar) return (MODECHANGE);
X		else printf ("");
X		}
X	}
X
Xctrlprintw (s) char *s;
X	{
X	while (*s)
X		{
X		if (iscntrl (*s))
X			{
X			standout ();
X			addch (*s-1+'A');
X			standend ();
X			}
X		else addch (*s);
X		s++;
X		}
X	}
SHAR_EOF
if test 6623 -ne "`wc -c 'linedit.c'`"
then
	echo shar: error transmitting "'linedit.c'" '(should have been 6623 characters)'
fi
echo shar: extracting "'alias.c'" '(889 characters)'
if test -f 'alias.c'
then
	echo shar: over-writing existing file "'alias.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'alias.c'
X/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <sys/stat.h>
Xchar *
Xalias (s, delim) char *s, *delim;
X	{
X	static	char	aliased[BUFSIZ];
X	char	*alias = aliased;
X	char	name[BUFSIZ], *nameptr = name;
X	char	*getval (), *val;
X	struct	stat status;
X    checkalias:
X	*alias = NULL;
X	while (isspace (*s)) *alias++ = *s++;
X	nameptr = name;
X	*nameptr = NULL;
X	while (isalnum (*s) || *s == '_')
X		*nameptr++ = *s++;
X	*nameptr = NULL;
X	if (val = getval (name)) /* has a value */
X	    if ((stat (val, &status) == 0) /* can get status */
X		&& ((status.st_mode & S_IFMT) == S_IFDIR)) /* directory file */
X		    strcpy (alias, name);
X	    else strcpy (alias, val);
X	else
X	    strcpy (alias, name);
X	while (*alias) alias++;
X	while (*s)
X		if (index (delim, *alias++ = *s++)) goto checkalias;
X	*alias = NULL;
X	return (aliased);
X	}
SHAR_EOF
if test 889 -ne "`wc -c 'alias.c'`"
then
	echo shar: error transmitting "'alias.c'" '(should have been 889 characters)'
fi
echo shar: done with directory "'src'"
chdir ..
#	End of shell archive
exit 0

perlman@wanginst.UUCP (Gary Perlman) (01/19/85)

Here are my menus for menunix:

#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	menus
# This archive created: Fri Jan 18 17:20:33 1985
# By:	Gary Perlman (Wang Institute, Tyngsboro, MA 01879 USA)
export PATH; PATH=/bin:$PATH
if test ! -d 'menus'
then
	echo shar: creating directory "'menus'"
	mkdir 'menus'
fi
echo shar: entering directory "'menus'"
cd 'menus'
echo shar: extracting "'write'" '(816 characters)'
if test -f 'write'
then
	echo shar: over-writing existing file "'write'"
fi
sed 's/^X//' << \SHAR_EOF > 'write'
X[d:Analyze style]         [s:a][p:style][a:{file} | more]
X[d:Count lines, words, and chars] [s:c][p:wc][a:{files} | more]
X[d:Count words used]      [s:C][p:tokens][a:{< file} | more]
X[d:Decode/Encode]         [s:d][p:crypt][a:{< file} {> file}]
X[d:Edit a file]           [s:e][p:$editor][a:{files}][w]
X[d:Format text file]      [s:f][m:format]
X[d:Heading structure]     [s:h][p:headings][a:{files} | more]
X[d:Look for word in dictionary] [s:l][p:look][a:{word}]
X[d:Permuted indexer]      [s:p][p:ptx][a:{arguments}]
X[d:Reference finder]      [s:r][p:pub][a:'{probe}']
X[d:Spelling corrector]    [s:s][p:correct][a:{arguments}]
X[d:Spelling error finder] [s:S][p:spell][a:{file} > rrs; editor rrs; rm rrs][w]
X[d:Typo finder]           [s:t][p:typo][a:{file}]
X[d:Wordy sentence finder] [s:w][p:diction][a:{file} | more]
SHAR_EOF
if test 816 -ne "`wc -c 'write'`"
then
	echo shar: error transmitting "'write'" '(should have been 816 characters)'
fi
echo shar: extracting "'wordgames'" '(159 characters)'
if test -f 'wordgames'
then
	echo shar: over-writing existing file "'wordgames'"
fi
sed 's/^X//' << \SHAR_EOF > 'wordgames'
X[display:Boggle]        [selector:b][program:boggle]
X[display:Hangman]       [selector:h][program:hangman]
X[display:Write a story] [selector:w][program:story]
SHAR_EOF
if test 159 -ne "`wc -c 'wordgames'`"
then
	echo shar: error transmitting "'wordgames'" '(should have been 159 characters)'
fi
echo shar: extracting "'visgames'" '(324 characters)'
if test -f 'visgames'
then
	echo shar: over-writing existing file "'visgames'"
fi
sed 's/^X//' << \SHAR_EOF > 'visgames'
X[d:Anti-Aircraft]       [s:a] [p:shootout]
X[d:Chase]               [s:c] [p:chase]
X[d:Invasion]            [s:i] [p:aliens]
X[d:Rain]                [s:r] [p:rain]
X[d:dodge the Snake]     [s:s] [p:snake]
X[d:Snake Scores]        [s:S] [p:snscore]
X[d:Worm]                [s:w] [p:worm]
X[d:Zowie!]              [s:z] [p:worms]
SHAR_EOF
if test 324 -ne "`wc -c 'visgames'`"
then
	echo shar: error transmitting "'visgames'" '(should have been 324 characters)'
fi
echo shar: extracting "'versatec'" '(141 characters)'
if test -f 'versatec'
then
	echo shar: over-writing existing file "'versatec'"
fi
sed 's/^X//' << \SHAR_EOF > 'versatec'
X[d:Format troff file][s:f][p:vtroff][a:$macros {options} {files}]
X[d:Font information][p:vfontinfo][a:{filename}][s:F]
X[d:Queue][s:q][p:vpq]
SHAR_EOF
if test 141 -ne "`wc -c 'versatec'`"
then
	echo shar: error transmitting "'versatec'" '(should have been 141 characters)'
fi
echo shar: extracting "'tools'" '(609 characters)'
if test -f 'tools'
then
	echo shar: over-writing existing file "'tools'"
fi
sed 's/^X//' << \SHAR_EOF > 'tools'
X[d:Assembler]                 [s:a][p:as][a:{arguments}]
X[d:Combine objetc files]      [s:c][p:ld][a:{arguments}]
X[d:Debugger]                  [s:d][p:adb]
X[d:Library archiver]          [s:l][p:ar][a:{options} {files}]
X[d:Make a program]            [s:m][p:make][a:{name}]
X[d:Names in object file]      [s:n][p:nm][a:{files}]
X[d:Order files for loading]   [s:o][p:lorder][a:{files}]
X[d:Profile execution]         [s:p][p:prof][a:{program}]
X[d:Remove symbol table]       [s:r][p:strip][a:{files}]
X[d:Size of object file]       [s:s][p:size][a:{files}]
X[d:Time a command]            [s:t][p:time][a:{command}]
SHAR_EOF
if test 609 -ne "`wc -c 'tools'`"
then
	echo shar: error transmitting "'tools'" '(should have been 609 characters)'
fi
echo shar: extracting "'timeseries'" '(359 characters)'
if test -f 'timeseries'
then
	echo shar: over-writing existing file "'timeseries'"
fi
sed 's/^X//' << \SHAR_EOF > 'timeseries'
X[d:Auto-correlation]       [s:a][p:corrgram][a:{lags} {< file}]
X[d:Bivariate point plotting][s:b][p:biplot][a:{< file}]
X[d:Check data file]        [s:c][p:check][a:{< file}]
X[d:Descriptive statistics] [s:d][p:desc][a:so {< file}]
X[d:Transform data]         [s:t][p:dm][a:{expressions} {< file}]
X[d:Vincentize data]        [s:v][p:vincent][a:{#tiles} {files}]
SHAR_EOF
if test 359 -ne "`wc -c 'timeseries'`"
then
	echo shar: error transmitting "'timeseries'" '(should have been 359 characters)'
fi
echo shar: extracting "'terminal'" '(398 characters)'
if test -f 'terminal'
then
	echo shar: over-writing existing file "'terminal'"
fi
sed 's/^X//' << \SHAR_EOF > 'terminal'
X[s:i][d:control Interruptions][p:mesg][a:{y or n}]
X[s:l][d:Lock terminal][p:lock][w]
X[s:m][d:Mail arrival announcer][p:biff][a:{y or n}]
X[s:o][d:keep record of Output][p:script][a:{record name}]
X[s:r][d:Reset the terminal modes][p:reset][w]
X[s:s][d:Set/print terminal modes][p:stty][a:{argmuments (RETURN to read modes)}]
X[s:S][d:Set terminal modes][p:tset][a:{arguments}]
X[s:t][d:Tabs][p:tabs][w]
SHAR_EOF
if test 398 -ne "`wc -c 'terminal'`"
then
	echo shar: error transmitting "'terminal'" '(should have been 398 characters)'
fi
echo shar: extracting "'tape'" '(121 characters)'
if test -f 'tape'
then
	echo shar: over-writing existing file "'tape'"
fi
sed 's/^X//' << \SHAR_EOF > 'tape'
X[d:Tape archiver (new)]    [s:t][p:tar][a:{options} {files}]
X[d:Tape archiver (old)]    [s:T][p:tp][a:{options} {files}]
SHAR_EOF
if test 121 -ne "`wc -c 'tape'`"
then
	echo shar: error transmitting "'tape'" '(should have been 121 characters)'
fi
echo shar: extracting "'statistics'" '(865 characters)'
if test -f 'statistics'
then
	echo shar: over-writing existing file "'statistics'"
fi
sed 's/^X//' << \SHAR_EOF > 'statistics'
X[d:Analysis of variance]   [s:a][p:anova][a:{labels} {< file}]
X[d:Bivariate point plotting][s:b][p:biplot][a:{< file}]
X[d:Check data file]        [s:c][p:check][a:{< file}]
X[d:Descriptive statistics] [s:d][p:desc][a:so {< file}]
X[d:Frequency tables]       [s:f][p:desc][a:f {< file}]
X[d:F-ratio to probability]    [s:F][p:pof][a:{F-ratio} {df numerator} {df denominator}]
X[d:Histogram]              [s:h][p:desc][a:h {< file}]
X[d:Manipulate files]       [s:m][m:manipulate]
X[d:Paired data analysis]   [s:p][p:pair][a:{< file}]
X[d:Probability to F-ratio] [s:P][p:critf][a:{probability} {df numerator} {df denominator}]
X[d:correlation]            [s:r][p:corr][a:{< file}]
X[d:Regression]             [s:R][p:regress][a:{labels} {< file}]
X[d:Transform data]         [s:t][p:dm][a:{expressions} {< file}]
X[d:Vincentize data]        [s:v][p:vincent][a:{#tiles} {files}]
SHAR_EOF
if test 865 -ne "`wc -c 'statistics'`"
then
	echo shar: error transmitting "'statistics'" '(should have been 865 characters)'
fi
echo shar: extracting "'security'" '(201 characters)'
if test -f 'security'
then
	echo shar: over-writing existing file "'security'"
fi
sed 's/^X//' << \SHAR_EOF > 'security'
X[p:crypt]  [s:c] [d:encrypt/decrypt a file] [a:{<file} {>file}]
X[p:chmod]  [s:f] [d:file access protection] [a:{mode} {files}]
X[p:passwd] [s:p] [d:password change]
X[p:lock]   [s:t] [d:terminal lockup]
SHAR_EOF
if test 201 -ne "`wc -c 'security'`"
then
	echo shar: error transmitting "'security'" '(should have been 201 characters)'
fi
echo shar: extracting "'remind'" '(620 characters)'
if test -f 'remind'
then
	echo shar: over-writing existing file "'remind'"
fi
sed 's/^X//' << \SHAR_EOF > 'remind'
X[d:Change personal reminders]        [s:c][p:editor][a:$home/.remind][w]
X[d:Change general reminders]    [s:C][p:editor][a:/csl/bin/remindir/{file}][w]
X[d:remind you to Leave]     [s:l][p:leave][a:{time: hhmm}]
X[d:Reminders]               [s:r][p:remind][a:{day (RETURN for today's)}]
X[d:Set reminders]           [s:s][p:remind.setup]
X[d:Tomorrow's reminders]    [s:t][p:remind][a:tomorrow]
X[d:a Week's reminders]      [s:w][p:remind][a:sun mon tues wed thur fri sat | sort | uniq | grep -v Reminders]
X[d:Yesterday's reminders]   [s:y][p:remind][a:yesterday]
X[d:print a year's calendar] [s:Y][p:cal][arg:{month} {year}]
SHAR_EOF
if test 620 -ne "`wc -c 'remind'`"
then
	echo shar: error transmitting "'remind'" '(should have been 620 characters)'
fi
echo shar: extracting "'program'" '(267 characters)'
if test -f 'program'
then
	echo shar: over-writing existing file "'program'"
fi
sed 's/^X//' << \SHAR_EOF > 'program'
X[d:APL]              [s:a][p:apl][w]
X[d:C programming]    [s:c][m:c]
X[d:FORTRAN]          [s:f][m:fortran]
X[d:LISP]             [s:l][m:lisp]
X[d:MicroSOL]         [s:m][p:m.sol]
X[d:Pascal]           [s:p][m:pascal]
X[d:Tools for programming]            [s:t][m:tools]
SHAR_EOF
if test 267 -ne "`wc -c 'program'`"
then
	echo shar: error transmitting "'program'" '(should have been 267 characters)'
fi
echo shar: extracting "'print'" '(680 characters)'
if test -f 'print'
then
	echo shar: over-writing existing file "'print'"
fi
sed 's/^X//' << \SHAR_EOF > 'print'
X[d:Buffered print]       [s:b][p:more][a:{files}]
X[d:Concatenate and print][s:c][p:cat][a:{options} {files}]
X[d:Dump file]            [s:d][p:od][a:-{c(har d(ec o(ct x(hex} {file} | more]
X[d:Format text]          [s:f][m:format]
X[d:Graphics]             [s:g][m:graphics]
X[d:Lineprinter]          [s:l][m:lineprint]
X[d:Paginated print]      [s:p][p:pr][a:{files}]
X[d:See first few lines]  [s:s][p:head][a:-{number of lines} {files} | more]
X[d:See last few lines]   [s:S][p:tail][a:-{number of lines} {files} | more]
X[d:Transcribe output to file][s:t][p:tee][a:{file}]
X[d:Underlining print]    [s:u][p:ul][a:{options} {files}]
X[d:Your favorite]        [s:y][p:$display][a:{files}]
SHAR_EOF
if test 680 -ne "`wc -c 'print'`"
then
	echo shar: error transmitting "'print'" '(should have been 680 characters)'
fi
echo shar: extracting "'pattern'" '(737 characters)'
if test -f 'pattern'
then
	echo shar: over-writing existing file "'pattern'"
fi
sed 's/^X//' << \SHAR_EOF > 'pattern'
X[d:AWK pattern scanner]      [s:a][p:awk][a:{arguments}]
X[d:Binary search]            [s:b][p:look][a:{target} {sorted file}]
X[d:Convert and copy]         [s:c][p:dd][a:{option=value pairs}]
X[d:Data manipulator]         [s:d][p:dm][a:{expression list}]
X[d:Fixed string finder]      [s:f][p:fgrep][a:{strings} {file}]
X[d:Generate parser]          [s:g][p:yacc][a:{file}]
X[d:Lexical scanner generator][s:l][p:lex][a:{arguments}]
X[d:Pattern finder]           [s:p][p:grep][a:'{pattern}' {files}]
X[d:Macro preprocessor]       [s:m][p:m4][a:{arguments}]
X[d:Regular expression finder][s:r][p:egrep][a:'{pattern}' {files}]
X[d:Stream editor]            [s:s][p:sed][a:{arguments}]
X[d:Translate characters]     [s:t][p:tr][a:{options} {strings}]
SHAR_EOF
if test 737 -ne "`wc -c 'pattern'`"
then
	echo shar: error transmitting "'pattern'" '(should have been 737 characters)'
fi
echo shar: extracting "'pascal'" '(337 characters)'
if test -f 'pascal'
then
	echo shar: over-writing existing file "'pascal'"
fi
sed 's/^X//' << \SHAR_EOF > 'pascal'
X[d:Compiler]                [s:c][p:pc][a:{file}]
X[d:Debugger]                [s:d][p:adb]
X[d:interpreter and Executer][s:e][p:pix][a:{file}]
X[d:Interpreter]             [s:i][p:pi][a:{file}]
X[d:execution Profiler]      [s:p][p:pxp][a:{file}]
X[d:Symbolic debugger]       [s:s][p:sdb]
X[d:Cross-referencer]        [s:x][p:pxref][a:{file}]
SHAR_EOF
if test 337 -ne "`wc -c 'pascal'`"
then
	echo shar: error transmitting "'pascal'" '(should have been 337 characters)'
fi
echo shar: extracting "'numbers'" '(254 characters)'
if test -f 'numbers'
then
	echo shar: over-writing existing file "'numbers'"
fi
sed 's/^X//' << \SHAR_EOF > 'numbers'
X[d:Bc calculator]   [s:b][p:bc]
X[d:Calculator]      [s:c][p:calc]
X[d:Desk calculator] [s:d][p:dc]
X[d:Mathematician's assistant][s:m][p:vaxima]
X[d:Statistics]      [s:s][m:statistics]
X[d:S]               [s:S][p:S]
X[d:Time series]     [s:t][m:timeseries]
SHAR_EOF
if test 254 -ne "`wc -c 'numbers'`"
then
	echo shar: error transmitting "'numbers'" '(should have been 254 characters)'
fi
echo shar: extracting "'network'" '(480 characters)'
if test -f 'network'
then
	echo shar: over-writing existing file "'network'"
fi
sed 's/^X//' << \SHAR_EOF > 'network'
X[d:Dial CATTA][s:a][p:catt]
X[d:Dial CATTB][s:b][p:cattb]
X[d:Copy to the CSL machine][s:c][p:netcp][a:-q {file here} CSL:{CSL file}][w]
X[d:Copy to the CATT system][s:C][p:netcp][a:{file here} CATT:{CATT file}][w]
X[d:Dial an installation]   [s:d][p:dial][a:{name}][w]
X[d:Logfile listing]        [s:l][p:netlog]
X[d:Phone a number]         [s:p][p:dialout][a:{number}][w]
X[d:print my network Queue] [s:q][p:netq]
X[d:Unix to Unix copy][s:u][p:uucp][a:'sdcsvax!{file}' '{destination}']
SHAR_EOF
if test 480 -ne "`wc -c 'network'`"
then
	echo shar: error transmitting "'network'" '(should have been 480 characters)'
fi
echo shar: extracting "'manipulate'" '(495 characters)'
if test -f 'manipulate'
then
	echo shar: over-writing existing file "'manipulate'"
fi
sed 's/^X//' << \SHAR_EOF > 'manipulate'
X[d:abut files]              [s:a][p:abut][a:{files}]
X[d:Count words and lines]   [s:c][p:wc][a:{files}]
X[d:Compare two files]       [s:C][p:cmp][a:{files}]
X[d:Permut lines in a file]  [s:p][p:perm][a:{file}][waitoff:]
X[d:Reverse lines in a file] [s:r][p:rev][a:{file}]
X[d:Sort lines in a file]    [s:s][p:sort][a:{key} {file}]
X[d:Split a file into pieces][s:S][p:split][a:{file}]
X[d:Topological sort]        [s:t][p:tsort][a:{arguments}]
X[d:Unique line finder]      [s:u][p:uniq][a:{arguments}]
SHAR_EOF
if test 495 -ne "`wc -c 'manipulate'`"
then
	echo shar: error transmitting "'manipulate'" '(should have been 495 characters)'
fi
echo shar: extracting "'mail'" '(634 characters)'
if test -f 'mail'
then
	echo shar: over-writing existing file "'mail'"
fi
sed 's/^X//' << \SHAR_EOF > 'mail'
X[d:Berkeley mail]                [s:b][p:Mail][a:{RETURN to read mail}]
X[d:Help with CSL mail system][s:h][p:msghelp]
X[d:read Mail]                    [s:m][p:Mail][w]
X[d:read $home/mbox]              [s:M][p:Mail][a:-f $home/mbox][w]
X[d:read Network mail]            [s:n][p:readnews][w]
X[d:memO file information][s:o][p:msgmemo][a:{supply file for contents, RETURN for listing}| more]
X[d:Reminder service][s:r][m:remind]
X[d:Send mail]                    [s:s][p:Mail][a:{recipients}][w]
X[d:User mail names][s:u][p:msgname][a:{supply name or RETURN for listing}|more]
X[d:Write to a user's terminal]   [s:w][p:write][a:{user's name}]
SHAR_EOF
if test 634 -ne "`wc -c 'mail'`"
then
	echo shar: error transmitting "'mail'" '(should have been 634 characters)'
fi
echo shar: extracting "'lisp'" '(124 characters)'
if test -f 'lisp'
then
	echo shar: over-writing existing file "'lisp'"
fi
sed 's/^X//' << \SHAR_EOF > 'lisp'
X[d:liszt Compiler]   [s:c][p:liszt][w]
X[d:LISP]             [s:l][p:lisp][w]
X[d:Cross-referencer] [s:x][p:lxref][a:{files}]
SHAR_EOF
if test 124 -ne "`wc -c 'lisp'`"
then
	echo shar: error transmitting "'lisp'" '(should have been 124 characters)'
fi
echo shar: extracting "'lineprint'" '(214 characters)'
if test -f 'lineprint'
then
	echo shar: over-writing existing file "'lineprint'"
fi
sed 's/^X//' << \SHAR_EOF > 'lineprint'
X[d:Print to line printer]       [s:p][p:lpr][a:{file}]
X[d:Paginated print]             [s:P][p:print][a:{file}]
X[d:print the lineprinter Queue] [s:q][p:lpq]
X[d:Remove lineprinter request]  [s:r][p:lprm][a:{?????}]
SHAR_EOF
if test 214 -ne "`wc -c 'lineprint'`"
then
	echo shar: error transmitting "'lineprint'" '(should have been 214 characters)'
fi
echo shar: extracting "'knowledge'" '(177 characters)'
if test -f 'knowledge'
then
	echo shar: over-writing existing file "'knowledge'"
fi
sed 's/^X//' << \SHAR_EOF > 'knowledge'
X[display:Arithmetic] [selector:a][program:arithmetic]
X[display:Quiz]       [selector:q][program:quiz][a:| more]
X[display:Quiz on subject][selector:Q][program:quiz][a:{subject}]
SHAR_EOF
if test 177 -ne "`wc -c 'knowledge'`"
then
	echo shar: error transmitting "'knowledge'" '(should have been 177 characters)'
fi
echo shar: extracting "'information'" '(697 characters)'
if test -f 'information'
then
	echo shar: over-writing existing file "'information'"
fi
sed 's/^X//' << \SHAR_EOF > 'information'
X[d:Address finder]         [s:a] [p:grab][a:{name}]
X[d:Commands recently run]  [s:c] [p:lastcomm][a:| more][w]
X[d:Database retrieval]     [s:d] [m:database]
X[d:Find out about a user]  [s:f] [p:finger][a:{user name}]
X[d:Kill a process]         [s:k] [p:kill][a:-9 {process id (PID)}]
X[d:Last login of user]     [s:l] [p:last][a:{user}| more]
X[d:Menu system information][s:m] [p:fmt][a:< $menu/doc/menuinfo | more]
X[d:UNIX Program information][s:p] [m:help]
X[d:check system Response]  [s:r] [p:uptime]
X[d:Status of programs]     [s:s] [p:ps][a:au | more]
X[d:Terminal line used]     [s:t] [p:tty]
X[d:Users logged on]        [s:u] [p:finger][a:| more]
X[d:What are people doing]  [s:w] [p:w][a:| more]
SHAR_EOF
if test 697 -ne "`wc -c 'information'`"
then
	echo shar: error transmitting "'information'" '(should have been 697 characters)'
fi
echo shar: extracting "'help'" '(395 characters)'
if test -f 'help'
then
	echo shar: over-writing existing file "'help'"
fi
sed 's/^X//' << \SHAR_EOF > 'help'
X[d:commands Appropriate for]   [s:a][program:apropos][args:{keyword}]
X[d:Documentation on a program] [s:d][program:man][args:{program}]
X[d:Locate a program]           [s:l][program:whereis][args:{program}]
X[d:Tutorials on UNIX]          [s:t][program:learn]
X[d:which Version of a program] [s:v][program:which][args:{program}]
X[d:What is a program for]      [s:w][program:whatis][args:{program}]
SHAR_EOF
if test 395 -ne "`wc -c 'help'`"
then
	echo shar: error transmitting "'help'" '(should have been 395 characters)'
fi
echo shar: extracting "'graphics'" '(329 characters)'
if test -f 'graphics'
then
	echo shar: over-writing existing file "'graphics'"
fi
sed 's/^X//' << \SHAR_EOF > 'graphics'
X[d:Bivariate plot]            [s:b][p:biplot][a:{< file of X Y points}]
X[d:Filter graphics for output][s:f][p:plot][a:{terminal} {< file}]
X[d:Graph points]              [s:g][p:graph][a:{options} {< file}]
X[d:Leroy]                     [s:l][p:leroy][a:{file}]
X[d:Interpolate smooth curve]  [s:i][p:spline][a:{options} {< file}]
SHAR_EOF
if test 329 -ne "`wc -c 'graphics'`"
then
	echo shar: error transmitting "'graphics'" '(should have been 329 characters)'
fi
echo shar: extracting "'games'" '(383 characters)'
if test -f 'games'
then
	echo shar: over-writing existing file "'games'"
fi
sed 's/^X//' << \SHAR_EOF > 'games'
X[d:Adventure games]     [s:a] [m:adventure]
X[d:Backgammon]          [s:b] [p:vgammon]
X[d:Card games]          [s:c] [m:cardgames]
X[d:Chess]               [s:C] [p:chess]
X[d:Fortunes and adages] [s:f] [p:fortune]
X[d:Knowledge tests]     [s:k] [m:knowledge]
X[d:Monopoly]            [s:m] [p:monop]
X[d:Word games]          [s:w] [m:wordgames]
X[d:Visual games]        [s:v] [m:visgames]
SHAR_EOF
if test 383 -ne "`wc -c 'games'`"
then
	echo shar: error transmitting "'games'" '(should have been 383 characters)'
fi
echo shar: extracting "'fortran'" '(332 characters)'
if test -f 'fortran'
then
	echo shar: over-writing existing file "'fortran'"
fi
sed 's/^X//' << \SHAR_EOF > 'fortran'
X[d:Compiler]        [s:c][p:f77][a:{flags} {files}]
X[d:Debugger]        [s:d][p:adb]
X[d:Ratfor]          [s:r][p:ratfor][a:{flags} {files}]
X[d:Extended FORTRAN][s:e][p:efl][a:{flags} {files}]
X[d:Symbolic debugger][s:s][p:sdb]
X[d:Stucture FORTRAN to ratfor][s:S][p:struct][a:{files}]
X[d:Cross-referencer][s:x][p:ctags][a:-x {files}]
SHAR_EOF
if test 332 -ne "`wc -c 'fortran'`"
then
	echo shar: error transmitting "'fortran'" '(should have been 332 characters)'
fi
echo shar: extracting "'format'" '(526 characters)'
if test -f 'format'
then
	echo shar: over-writing existing file "'format'"
fi
sed 's/^X//' << \SHAR_EOF > 'format'
X[d:CSL format]              [s:c][p:nr][a:{files}]
X[d:Equation formatter]      [s:e][p:neqn][a:{options} {files}]
X[d:Equation checker]        [s:E][p:checkeq][a:{files}]
X[d:Formatted print (fancy)] [s:f][p:nroff][a:-Tcrt {macros} {files} | cat -s | ul 

perlman@wanginst.UUCP (Gary Perlman) (01/19/85)

Here are the old menunix documents.

#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	doc
# This archive created: Fri Jan 18 17:19:56 1985
# By:	Gary Perlman (Wang Institute, Tyngsboro, MA 01879 USA)
export PATH; PATH=/bin:$PATH
if test ! -d 'doc'
then
	echo shar: creating directory "'doc'"
	mkdir 'doc'
fi
echo shar: entering directory "'doc'"
cd 'doc'
echo shar: extracting "'menudoc'" '(31607 characters)'
if test -f 'menudoc'
then
	echo shar: over-writing existing file "'menudoc'"
fi
sed 's/^X//' << \SHAR_EOF > 'menudoc'
X.ds AU "Gary Perlman
X.ds LB "Cognitive Science Laboratory
X.ds AF "University of California, San Diego
X.if \nD .pl 65v \"used with Decwriter III
X.ll 6.5i        \"line length
X.nh             \"no hyphenation
X.nr PW 8.5i	\"page width
X.nr si 3n       \"section indentation
X.sz 10
X.sh 0
X.sx 1
X.nr bi 5n	\" indent of blocks
X.nr xs 0	\"space between index entries
X.de TW		\"text width
X.br
X.if \\$2 .nr PW \\$2u
X.lt \\$1u
X.ll \\$1u-\\n(siu-\\n(siu
X.po (\\n(PWu-\\$1u)u/2u
X.in \\n(siu
X.br
X..
X.de FT					\"figure table comment
X.nr % \\n%+1
X.nr \\$1\\$2 \\n%
X..
X.de (F \"begin figure
X.ls 1
X.pn \\n(F\\$1
X.ep
X.bp
X.if \\$1=1 \{
X.(x
X.sp .5v
X.ce
X\fBFIGURES\fR
X.sp .5v
X.)x _
X\}
X.hh "FIGURE \\$1: \\$2
X.sp 5i
X.(z F
X.nh
X\fBNote:\fR
X..
X.de )F
X.)z
X.ls
X..
X.de FR				\" F ratio
X(\fIF\fR\ (\\$1,\\$2)\ =\ \\$3,
X\fIp\fR\ <\ \\$4)\\$5
X..
X.de (Q				\" kept quote
X.(b L
X.(q
X.nh
X..
X.de )Q
X.)q
X.)b
X..
X.de (C				\" kept center block
X.(b M
X.(c
X..
X.de )C
X.)c
X.)b
X..
X.de BO
X.if n \&\\$1\h'|0'\&\\$1\h'|0'\\$1\h'|0'\\$1\\$2
X.if t .b "\\$1" "\\$2"
X..
X.de BI
X.if n \fI\&\\$1\h'|0'\&\\$1\h'|0'\\$1\h'|0'\\$1\\$2\fR
X.if t .b "\\$1" "\\$2"
X..
X.de hh				\"High heading
X.in 0
X.ce
X.rb
X.sz 16
X.sp 1.5v
X.NE 4i
X.BO "\\$1
X.(x
X.ti 0
X\\$1
X.)x
X.sp .5v
X.sz 10
X.r
X..
X.de mh				\"main heading
X.b
X.ce
X.NE 3i
X.sz 14
X.sp 1v
X.BO "\\$1
X.sp .75v
X.(x
X.ti 1c
X\\$1
X.)x
X.r
X.sz 10
X..
X.de lh				\"left heading
X.sp .75v
X.b
X.ti 0
X.sz 12
X.NE 2i
X.BO "\\$1
X.sp .5v
X.(x
X.ti 2c
X\\$1
X.)x _
X.r
X.sz 10
X..
X.de ph				\"paragraph heading
X.sp .5v
X.NE 1.5i
X.pp
X.b
X\\$1
X.r
X..
X.de RF				\" References
X.ep
X.bp
X'hh "References
X
X..
X..
X.de NE				\" version of .ne
X.ne \\$1
X..
X.de EG				\" example
X.sp .5v
X.ce
X\\$1
X.sp .5v
X..
X.de (a
X.nr aa 1
X.de aa )a
X.ce
X.BO ABSTRACT
X
X..
X.ds TL "MENUNIX: A MENU-DRIVEN INTERFACE TO UNIX PROGRAMS (USER MANUAL)
X.he 'Gary Perlman'- % -'MENUNIX User Manual'
X.bp
X.(x
X.ti 0
XMENUNIX: A MENU-DRIVEN INTERFACE TO UNIX PROGRAMS (USER MANUAL)
X.)x
X.(l C
X.sz 16
X.b
XMENUNIX: A MENU-DRIVEN INTERFACE
XTO UNIX PROGRAMS (USER MANUAL)
X
X.sz 14
XGary Perlman
X.r
X.sz 10
X.)l
X.de TC				\"table of contents
X.ep
X.he ''''
X.fo '\\*(dw, \\*(mo \\n(dy''Copyright  c  19\\n(yr Gary Perlman'
X.bp
X.rs
X.(l C
X.sz 20
X.b
XMENUNIX: A MENU-DRIVEN INTERFACE
XTO UNIX PROGRAMS (USER MANUAL)
X.sp .3i
X.sz 16
XGary Perlman
X.sp .2i
X\\*(LB
XDepartment of Psychology
X\\*(AF
X.sz 1O
X.r
X.)l
X.sp .3i
X.aa
X.sp .3i
X.ce
X.b
X.sz 10
XCONTENTS
X.sz 8
X
X.r
X.in 1i \" section names outdented from here
X.xp
X..
X.(a
X.(q
X.nh
X.sz 8
XThis is a manual for MENUNIX,
Xan interface to programs and files on the UNIX operating system.
XPrograms and files are displayed in menus on users' terminal screens,
Xand are selected with single keypresses of characters displayed
Xnext to menu entries.
XThe FILE menu presents the UNIX file hierarchy in menu format,
Xand commands for moving through the hierarchy in both absolute
Xand relative terms are provided.
XThe PROGRAM menu organizes UNIX commands into a hierarchy
Xin which related programs are grouped together into task oriented workbenches,
Xanalogous to files being grouped into directories.
XSpecial commands are provided for setting, examining, and using variables
Xvia a one-line editor that also allows modifying commands.
XThe PROGRAM menu hierarchy, like the FILE menu hierarchy,
Xcan be customized to the needs of individual users,
Xallowing workbenches for unusual tasks such as linear programming
Xin addition to ones for common tasks like writing.
X.)q
X.)a
X.pp
XThe UNIX\**
X.(f
X\**UNIX is a trademark of Bell Laboratories.
X.)f
Xmenu system, MENUNIX,
Xprovides a structured environment for executing UNIX commands.
XMENUNIX presents menus from which you can select
Xprograms and files displayed on a terminal screen.
XA diagram of the MENUNIX display is shown in the figure at the beginning
Xof this manual.
XThe PROGRAM MENU on the left side of the screen lets you select programs,
Xand the FILE MENU on the right side lets you select files.
XEach of the menu display entries can be selected with a single key,
Xdisplayed on the left of each entry.
XThe effects of selecting PROGRAM and FILE MENU entries will be
Xdescribed in following sections.
X.mh "The FILE MENU
X.pp
XOn the right side of the MENUNIX display is the FILE MENU,
Xthat displays the UNIX file system.
XAt its top is the full pathname of the current working directory,
Xfollowed by the page number and number of pages of that directory
X(3/5 means you are on page three of a total of five).
XDirectories typically have more entries than can
Xbe displayed on a screen,
Xso each directory is divided into pages,
Xeach containing a manageable sized part.
XAt most nine files are displayed at one time,
Xand these are selected with the number keys
X.BI 1\-9 .
XYou can leaf through the pages of a directory by using the plus
Xand minus keys.
XTyping a plus
Xgoes to the next page (if there is one),
Xand typing a minus goes to the previous one.
XTrying to go to a page that is not there causes MENUNIX to
X"wrap around" to the first or last page of a directory.
X.pp
XTo select a file, you type the number on the left of its name.
XIf you type a number without any file beside it
X(this can happen on the last page of a directory),
XMENUNIX will beep at you.
XIn general, MENUNIX beeps when you type a character that is not acceptable.
XThe effect of selecting a file depends on the type of file selected,
Xthat can be determined from the information displayed
Xon the right of its name.
XTo the right of a file is displayed its size (in characters),
Xand its access protection modes.
X.pp
XThe access protection modes contain ten characters interpreted as follows.
XThe first character indicates the type of file.
X.(b
X.ta .5i
X-	plain file
Xb	block-type special file
Xc	character-type special file
Xd	directory
XB	multiplexor-type block special file
XC	multiplexor-type character special file
X.)b
XThe next nine characters are interpreted as three sets of three bits.
XThe first set refers to access permissions of the owner of the file,
Xthe next three to permissions to others in the same user-group,
Xand the last three to permissions to all others.
XWithin each set, the three characters respectively indicate permission
Xto read, write, or execute the file as a program.
XThese permissions are coded as:
X.(b
X.ta .5i
Xr	the file is readable
Xw	the file is writable
Xx	the file is executable
X-	the indicated permission is not granted
X.)b
XThe owner of the file is coded by capital read, write,
Xand execute flags.
XThe owner of a file sees the first three bits in capital letters,
Xthe members of the owner's group see the second three bits
Xin capital letters, and all others see the last set of three
Xbits in capitals.
XIn any case, the operations one can perform
Xon a file will be in capital letters.
X.pp
XSelecting a directory causes the working directory
Xto change to that directory.
XDirectories are identified by their access modes,
Xby being followed by a slash,
Xand on some terminals by being displayed more prominently.
XSelecting an executable file (a program) causes that program to be run
Xafter arguments are requested.
XSelecting a plain file calls the
Xeditor named by the variable
X.BI editor
Xon that file (or the
X.i ex
Xeditor if it is not set).
X(See the later section on how to set variables.)
X.pp
XThe number key
X.BI 0
Xis not used to select a file but is reserved for
Xgoing "upwards" in the file system.
XPressing the number key to the left of a directory name
Xgoes into the selected directory, and the
X.BI 0
Xkey lets you pop out of a directory.
X.pp
XIn summary, the commands for the FILE MENU are:
X.(b
X.ta .5i
X0	Changes the working directory to the parent directory.
X1-9	Select the FILE MENU entry beside the number typed.
X	This edits files, executes programs, and changes directories.	
X+	Displays the next page of the working directory.
X-	Displays the previous page of the working directory.
X.)b
X.mh "The PROGRAM MENU
X.pp
XOn the top left of the MENUNIX display is the PROGRAM MENU.
XThe PROGRAM MENU organizes programs into a hierarchy
Xmuch as the file system can be used to organize files.
XEntries in the PROGRAM MENU are either programs,
Xor collections of programs, called
X.i workbenches.
XThis is analogous to entries in the FILE MENU being files,
Xor collections of files, called directories.
XAt the top of the PROGRAM MENU is the name of the workbench in use.
XThe initial workbench is [UNIX]
X(workbenches are always displayed enclosed in [square] brackets).
X[UNIX] contains the most general classification of UNIX commands,
Xso general that it does not contain any programs,
Xbut only names of task specific workbenches that contain all and only those
Xcommands that are of interest to people working on a specific task.
XFor example,
Xthere is a programming workbench
X(that contains more specific workbenches for
XC programming, FORTRAN, LISP, Pascal,
Xand general program development tools.
XOther high level workbenches are:
X.(b
X.ta 2.5i
XCalculations	Calculators and statistics
XDisplay	Displaying and formatting files
XFile System	Programs to change files
XGames	The fate of the weak
XInformation	System status and documentation
XMail	Sending and receiving mail
XNetwork	Intermachine communication
XReminder Service	Get daily reminders of events
XSearching, Pattern Matching	Regular expressions, Grammars, etc.
XWriting Aids	Spelling, style analysis, etc.
X.)b
X.pp
XEach line of the PROGRAM MENU consists of a short phrase
Xdescribing an entry (program or workbench) that
Xis selected by typing the mnemonic letter on the left of its name.
XSelecting a workbench causes
Xthe PROGRAM MENU to change to and display the one selected.
XTo get back to the [UNIX] workbench, you can type a period,
Xor repeatedly type commas
Xthat pop up one workbench at a time.
XProgram entries are displayed followed by the parenthesized name
Xof the UNIX program they call.
XHow a program executes depends on whether it needs information,
Xsuch as the name of a file.
XIf no information is needed, the screen clears and the program runs.
XAfter the program is done, MENUNIX will ask you to type a RETURN
Xif a program is expected to produce some output you might want to read
Xbefore the screen is cleared and the MENUNIX display reappears.
X.pp
XWhen a program requires that information be specified,
XMENUNIX asks for that information in a one-line editor
Xlocated at the bottom of the screen.
XFor example, in the [File\ system] workbench is an entry for
Xcopying files.
XSelecting that program causes a prompt like:
X.(b
X {files to be copied}:
X.)b
Xto appear in the line editor.
XWhen a program needs information,
Xa prompt for what is needed is placed in {curly} braces,
Xfor which you should type in the information
X(followed by a RETURN to tell it you are finished).
XImmediately above the line where you type in the requested information
Xis the command that MENUNIX is generating.
XFor the file copying program, this command looks like:
X.(b
Xcp {files to be copied} {destination}
X.)b
XThis means that MENUNIX needs two bits of information from you.
XAfter you supply the {files\ to\ be\ copied} information,
XMENUNIX will ask you for the {destination}.
XThe one-line editor is fully described in a later section.
X.mh "The [CONTROL] Menu: Controlling MENUNIX
X.pp
XThere is one workbench, [CONTROL],
Xthat is important because its entries can be accessed at any time,
Xno matter what workbench is being displayed.
XIt contains commands for controlling the PROGRAM and FILE MENUs,
Xand also some commands you are likely to need at any time,
Xsuch as your preferred editor,
Xset with the
X.BI editor
Xvariable.
X[CONTROL] contains commands for changing directories, changing directory pages,
Xchanging workbenches, stopping MENUNIX, and so on.
XSince these commands are used so often,
Xthey become memorized and their display becomes unnecessary.
XThe [CONTROL] workbench can be seen at any time by "flipping"
Xto it with an ampersand,
X.BI & .
XTyping
X.BI &
Xchanges the display in the PROGRAM MENU
Xwithout changing the commands available,
Xas though the two workbenches were one on top of the other.
XThe [CONTROL] workbench options are described below.
X.mh "Summary of MENUNIX Internal Commands
X.(b
X.(c
X.sz 8
X.ta 1.2i +.5i
X.ul
XNAME	CHAR	FUNCTION
Xampersand	&	flips to/from [CONTROL]
Xperiod	.	goes to [UNIX] (first) workbench
Xcolon	:	goes to [UNIX] workbench and returns
Xcomma	,	goes to the parent workbench
Xzero	0	goes to the parent directory
Xslash	/	changes directory to that specified in the editor
Xplus	+	displays the next directory page
Xminus	-	displays the previous directory page
Xquestion	?	changes to/from the documentation perspective
Xexclamation	!	runs the command supplied in the editor
Xdollar	$	sets a variable to a value
Xpound	#	prints the value of a string or variables
X\fBCTRL\fR-r	^R	redisplays the screen
X.sz 10
X.)c
X.)b
X.lh "Stopping MENUNIX
X.pp
X\fBBREAK\fR or \fBDEL\fR causes MENUNIX to ask if you really want to quit.
XYou can type a second \fBBREAK\fR or \fBDEL\fR to quit,
Xor type a RETURN to return to MENUNIX.
X.lh "Redisplaying the Screen
X.pp
XIf the screen gets messed up for some reason,
Xyou can redisplay it by typing \fBCTRL\fR-r.
X.lh "Changing Workbenches
X.pp
XA workbench can be entered by typing the letter beside its name.
XYou can leave that workbench by "popping" up to its parent workbench
X(the workbench you were in before entering it) with a comma.
XYou can pop up to the [UNIX] workbench by typing a period.
X.pp
XA special operation is supplied to allow you to take
Xa short diversion from what you are working on.
XFor example, MENUNIX may inform you that you have new mail,
Xand you may want to read it and immediately return to your task.
XYou can pop up to the [UNIX] workbench
Xand have MENUNIX remember where you were so that it will return after
Xyou execute a command by popping up to the [UNIX] workbench with a colon.
XIt also can be used to stop your history list of commands
Xfrom getting cluttered with unimportant commands because
Xcommands executed in this manner are not saved.
XFor example, you may be programming and notice you have mail,
Xand you could type ":mm" which would read your mail and return
Xyou to your old workbench automatically.
XYou can make an early return to the saved workbench by typing a second colon.
X.lh "Setting Variables
X.pp
XYou can set a variable to a value to be used at a later time.
XThis is done by typing the character on the left of the
X"set variable" command in [CONTROL], the dollar sign,
X.BI $ .
XThe variable setting command will ask you for a {name}
X(that must be made entirely of letters),
Xand then a {value} (that can have any content, even other variables).
XVariables can be edited using the one-line editor described later.
X.ph "Preset variables.
XThere are some variables that are set when you go into MENUNIX.
XThey can be used in your responses to MENUNIX prompts
Xby preceding their names by
X.BI $ .
XThe predefined variables are:
X.(b
X.ta .75i
Xuser	your login name
Xhome	your login directory
Xdir	the current directory
Xmail	your mail spool file
Xmenu	the menu source directory
X.)b
X.ph "User defined variables.
XWhen it starts, MENUNIX checks in your home (login)
Xdirectory for a file called
X.BI ".menuvar
Xfrom which it will read any variables you may want defined.
XVariables are set by lines in this file of the form:
X.(b C
XNAME = VALUE
X.)b
Xwhere NAME is any uninterrupted string of upper or lower case letters,
Xand VALUE is any text including predefined variables.
XFor example, you may want to have fast access to directories
Xyou often use, and define the following variables.
X.(b
Xp = $home/papers
Xpm = $p/menu
Xpp = $p/personal
X.)b
X.ph "Examining variables.
XYou can find the value of a variable by printing a string that includes them.
XTo print the value of a string,
X(this is called interpolation),
Xthe pound sign,
X.BI # ,
Xcommand is offered in [CONTROL].
XTyping
X.BI #
Xresults in MENUNIX prompting you for a string at
Xthe bottom of the screen.
XIf you type in
X.(b
X$menu
X.)b
XMENUNIX will print the name of the directory holding the
Xdefinition of the PROGRAM MENU hierarchy on the line above.
XThis directory is discussed in a later section.
XIf you type RETURN when
X.BI #
Xasks you for a string,
XMENUNIX will print all the variable names and values.
X.ph "Using variables as commands.
XThere are nine variables,
X.BI 1\-9 ,
Xthat hold the most recently executed commands.
X.BI 1
Xis the most recently executed command,
X.BI 2
Xis the next most recently executed command, and so on.
XA few of the most recently executed commands are displayed
Xin the middle of the MENUNIX display.
XYou can execute a recently used command by executing
Xthe variable set to it.
XLike any variable, you can edit these in the one-line editor described later.
X.lh "Executing Commands
X.pp
XBy typing the "Execute command" selector,
X.BI ! ,
Xyou can enter any command you would type
Xin the shell,
X.i sh,
Xoutside MENUNIX.
XAll commands constructed in MENUNIX are executed via
X.i sh
Xso commands can include pattern matching expressions
X(such as
X.BI *)
Xand redirection and piping of inputs and outputs.
XExecuting commands with
X.BI !
Xis useful for repeating a command stored as a variable
Xon the history list (variables
X.BI 1\-9 ).
XAs an example, suppose that the variable
X.BI 3
Xheld the command:
X.(b
Xsort foo.bar
X.)b
Xand that you want to save the result of that command in a file
Xin your home directory.
XYou could type a
X.BI ! ,
Xand MENUNIX would ask you for a command to execute,
Xand you would type in:
X.(b
X$3 > $home/sorted
X.)b
Xwhich would sort foo.bar and put the result in the file called "sorted"
Xin your home (login) directory.
X.pp
XInstead of typing $3\ >\ $home/sorted,
Xyou can omit the first
X.BI $
Xbecause MENUNIX checks the first field of all commands
Xand replaces it with the value of the variable by that name
X(if it exists).
X.pp
XExecuting a command with
X.BI !
Xdoes not update the history variables
X.BI 1-9,
Xbut the variable
X.BI 0
Xis always used to construct commands and so can be
Xaccessed to rerun any command.
X.lh "Changing Directory
X.pp
XBesides
X.BI 0
X(zero), which pops you up one directory,
Xand selecting directories from the FILE MENU,
Xyou can change directories with the "Change directory" command, the slash,
X.BI / .
XTyping a slash makes MENUNIX prompt you for the desired new directory.
XYou can type the full pathname of the directory you want to enter.
XThis can include variables, as usual.
XYou can also type RETURN, that has the same effect as typing $home;
Xboth return you to your home directory.
X.pp
XA common use of variables is to alias directory names,
Xand because of this, the directory changing command
Xallows you to change directory directly to a variable name.
XSo if $foo is /usr/lib/tmac, you can type
X.BI /
Xto change directories, and
X.BI foo
Xto tell MENUNIX where to go; the
X.BI $
Xis not needed.
X.lh "Getting Documentation
X.pp
XBy typing the Execution/Documentation character,
X.BI ? ,
Xyou change perspectives on the PROGRAM MENU.
XOrdinarily, selecting a program causes its execution,
Xbut by typing a
X.BI ? ,
Xyou switch into a mode in which
Xthe next PROGRAM MENU program you select will cause MENUNIX
Xto look for documentation on that program,
Xeven if it is a MENUNIX [CONTROL] command.
XOnce you get documentation on a program,
XMENUNIX automatically puts you back in the execution perspective.
XThe
X.BI ?
Xis really a toggle for changing perspectives,
Xso if you go into the documentation perspective and you want out,
Xanother
X.BI ?
Xchanges you back.
X.mh "Entering Information: MENUNIX's One-Line Editor
X.pp
XMany commands require you to supply information,
Xsuch as the names of file arguments, or option setting flags.
XTo do this, MENUNIX has you enter information in a one-line editor,
Xcalled Line-edit, located at the bottom of the screen,
XLine-edit allows you to include and delete characters from
Xanywhere inside a line you are editing,
Xas well as insert variables in responses.
XWhen MENUNIX puts you in Line-edit, it is generally to provide
Xsome information for a command it is going to be running.
XMENUNIX automatically starts you in "appending text" mode;
Xeverything you type is entered into a buffer.
XWhen in "append" mode, you can enter text and follow with a RETURN,
Xand MENUNIX will receive what you have typed.
XThis will be a common use of Line-edit,
Xhowever there are times when you will want to change something
Xyou have typed, or perhaps a variable or recent command,
Xand you will want to get into the middle of a line and make changes.
XFor this, Line-edit has "cursor mode" in which you can move the cursor
Xto any point in the line and make changes.
X.ph "Moving the cursor.
XIn cursor mode, you can move to the right or left with
Xthe keys labeled with arrows (if your terminal is so equipped).
XAn
X.BI l
X(letter 'el')
Xmoves you one character forward
X(as does a space,
X.BI + ,
Xor \fBCTRL\fR-l),
Xand an
X.BI h
Xmoves you one back (as does backspace and
X.BI - ).
XCapital letters tend to apply to a whole line rather than just a character.
XAn
X.BI L
Xmoves you to the far right of the line, an
X.BI H
Xto the far left.
XYou can move forward or backward a word at a time with
X.BI w
Xor
X.BI b
Xrespectively.
X.ph "Adding new text.
XTo append text after the cursor, type
X.BI a ,
Xand to append text after the end of the line, type
X.BI A .
XTo insert text before the cursor, type
X.BI i ,
Xand to insert text before the beginning of the line, type
X.BI I .
XMinor mistakes can be corrected by backspacing.
XOnce in an adding text mode, you can return to cursor mode by typing
Xthe key labeled \fBESC\fR (for escape).
XAlternatively, you can type RETURN and MENUNIX will immediately
Xread what you have typed.
X.ph "File selection mode.
XIn an adding text mode, you can go into a file selection mode
Xin which the names of files are added to your edit line
Xas you type the selector numbers beside their names.
XFile selection mode is entered by typing the file selection character,
Xthe underscore,
X.BI _ .
XIn this mode, every time you type the number beside a file name,
Xthat file name is added to your edit line.
XTo stop this mode, you can repress the underscore,
Xwhich will return you to the editor in an adding text mode,
Xor press RETURN to send your edit line to MENUNIX.
X.ph "Mistakes.
XIn cursor mode, typing an
X.BI x
Xremoves the character under the cursor.
XA zero,
X.BI 0 ,
Xdeletes the contents of the editor from the cursor to the end of the line.
XA capital
X.BI X
Xclears the whole line and automatically puts you into
Xappend mode.
XAny mistake you have just made can be undone by pressing
X.BI u
Xwhich gives you back your edit line as it was before the last change.
XIf you have really messed things up,
Xyou can type
X.BI U
Xwhich gives you the line you began editing,
Xwhich is unfortunately often nothing.
X.ph "Stopping line-edit.
XA RETURN will always send what you have typed to MENUNIX,
Xregardless of mode.
XIn cursor mode, a
X.BI q
Xcan also be used to quit editing.
XIf you do not want MENUNIX to look at what you have typed,
Xsay to abort a command, you can type
X.BI Q .
XAlso, if you are really desperate, you can type \fBBREAK\fR,
Xand MENUNIX will ask you if you want to quit MENUNIX completely.
X.mh "Summary of Line-Edit Commands
X.(b
X.(c
X.sz 8
X.ta 10n
Xa	append text after the cursor
XA	append text after the end of the line
Xb	back up one word
Xh	move the cursor back one character
XH	move the cursor to the beginning of the line
X\fBCTRL\fR-h	go back one character and delete if adding text
Xl	move the cursor forward one character
XL	move the cursor to the end of the line
Xq	leave Line-Edit and pass back contents
XQ	leave Line-Edit and stop command
Xu	undo the last change
XU	undo all changes
Xw	forward one word
Xx	delete the character below the cursor
XX	delete the contents of the editor and insert
X0	delete from the cursor to the end of the line
X+	move the cursor forward one character
X-	move the cursor back one character
X_	enter or leave file selection mode
X\e	ignore the special meaning of the next character
X\fBESC\fR	stop adding text
X.sz 10
X.)c
X.)b
X.hh "The Menu Definition Language
X.pp
XJust as you have control over the files in your file system,
Xyou can change the structure of the PROGRAM MENU hierarchy.
XA predefined variable in MENUNIX is
X.BI menu
Xthat holds the name of the directory holding files that
Xdefine the PROGRAM MENU hierarchy,
Xthat contains two special files:
XUNIX
Xwhich
Xdefines the [UNIX] workbench and all subsidiary workbenches;
Xand
XCONTROL
Xdefines the [CONTROL] workbench of commands available
Xat all parts of MENUNIX.
X.pp
XIn $menu is a file called UNIX that has lines that define
X.np
XThe name of each entry in the [UNIX] workbench,
X.np
XThe one character selector for that entry,
X.np
XThe type of the entry (whether the entry is that of a workbench
Xor a program).
XFor program entries, arguments may be supplied.
X.lp
XEach part of a workbench entry is defined by a bracketed field of the form:
X.(b C
X[NAME:VALUE]
X.)b
Xwhere NAME specifies the name of the field,
Xand VALUE specifies its value.
XFor example, the [UNIX] workbench has the definition:
X.(b C
X[display:UNIX][selector:.][menu:UNIX]
X.)b
XThis definition says that "UNIX" should be displayed on the
Xright of the selector character
X.BI '.'
Xand that its selection
Xwill cause the display of a menu whose definition is in
Xthe directory $menu in a file called "UNIX."
XAn example of a program entry is that for the copy command:
X.(b C
X[disp:Copy files][sel:c][prog:cp][args:{files} {destination}]
X.)b
Xwhich says that "Copy files" should be displayed on the right of
Xthe selector character "c" and that its selection will
Xcause the execution of the UNIX
X.i cp 
Xcommand.
X.(b C
Xc    Copy files (cp)
X.)b
XSince there is an argument field,
XMENUNIX knows to append it to the call to
X.i cp.
XAnything in the argument field
Xis interpolated and copied unless there is a part of the field
Xenclosed in {curly} braces.
XMENUNIX uses the convention that anything in curly braces
Xis to be used as a prompt to get a response from the user.
XFor each of the braced parts of the argument VALUE field,
XMENUNIX presents that part to the user
Xand replaces it with the interpolated response typed in.
X.pp
XAs a summary,
Xeach line of a workbench file defines a workbench entry
Xthat is either for another workbench (defined in an other file),
Xor a program that may have arguments that the user may have to supply.
XEach entry is divided into [NAME:VALUE] fields.
XThe names of these fields (that may be abbreviated to just one character)
Xare listed below,
Xalong with a description of their uses.
X.ip display 10
XDefines what is displayed.
X.ip selector 10
XDefines the character to be used to select the entry.
X.ip menu 10
XDefines that the entry is that of a workbench menu.
Xthe VALUE field holds the name of the file in $menu
Xthat contains the definition of the menu.
X.ip program 10
XDefines the name of the UNIX program to be executed when
Xthe entry is selected.
XIf the entry is for a workbench, this field is ignored.
X.ip arguments 10
XSupplies information to be appended to a UNIX command
Xdefined by the program field.
XThis information can be regular text, including variables,
Xwhich is interpolated and appended,
Xor it can be enclosed in {curly} braces,
Xwhich is replaced by the interpolated response obtained from the user after
Xpresenting the braced pattern.
X.ip waitoff 10
XTells MENUNIX to clear the screen and redisplay without
Xuser permission after a UNIX program has been executed.
XWithout this field, MENUNIX asks permission with a prompt.
XThe waitoff field has no value.
X.lp
X.mh "Defining the [CONTROL] Workbench
X.pp
XThe [UNIX] workbench is defined by a special file in the
X$menu directory, $menu/UNIX.
XAnother special file, used to define the [CONTROL] workbench,
Xis $menu/CONTROL.
XThe definition for $menu/CONTROL is just like any other workbench,
Xbut the commands in [CONTROL] are available at
Xall parts of the PROGRAM MENU.
XThis is because MENUNIX searches menus in a specific order
Xfor the selector character typed.
XFirst MENUNIX sees if the user has typed any of the numbers
X.BI 1\-9 ,
Xused to  access file entries.
XThen MENUNIX checks [CONTROL], and finally the
Xcurrent workbench.
XThis means that the numbers
X.BI 1\-9
Xare permanently reserved,
Xand that any characters in [CONTROL] should be
Xcarefully selected because they will not be available for
Xany other menus.
X.pp
XThe programs that are used in [CONTROL] should also
Xbe carefully selected because only fifteen entries are allowed.
XThe entries should be reserved especially for the commands
XMENUNIX uses to control the display, called internal commands
Xwhose names are preceded by a minus.
XThe internal commands available are listed below.
XAfter the letter is its default selector character in parentheses.
XIn $menu/CONTROL,
Xthe selectors for these internal commands are defined,
Xso if you don't like using a selector,
Xyou can choose your own.
X.(b
X.ce
XMENUNIX Internal Commands
X
X.(c
X.sz 8
X.ta 12n
Xu(.)	changes the workbench to [UNIX]
Xa(:)	changes the workbench to [UNIX] and returns
Xf(&)	flips the PROGRAM MENU display to [CONTROL]
Xp(,)	changes the workbench to the parent menu
X0(0)	changes the working directory to the parent directory
Xc(/)	changes directory
X+(+)	displays the next directory page
X-(-)	displays the previous directory page
Xd(?)	changes to and from the documentation perspective
Xs(!)	runs a command typed in the line-editor
Xv($)	sets a variable to a value
Xi(#)	prints the value of a string or prints all variable values
Xr(\fBCTRL\fR-r)	redisplays the screen
X.sz 10
X.)c
X.)b
X.mh "Making Your Own Menu System
X.pp
XChanging $menu makes it possible to customize
Xthe PROGRAM MENU hierarchy to your liking.
Xwhen you fire up MENUNIX,
Xyou can add an argument to the program call that sets
X.BI menu.
XThis must be the complete pathname of the directory with
Xthe files defining the PROGRAM MENU hierarchy.
XTo make your own PROGRAM MENU hierarchy,
Xyou would create a directory with the files UNIX and CONTROL,
Xwhich refer to other files (containing workbenches)
Xin the directory you supplied to the call to MENUNIX.
XA good way to begin is to copy all the files from the
Xstandard $menu to your preferred $menu,
Xand then make modifications.
X.(b M
X[Writing aids]                          /csl/perlman/papers/                 1/2
Xa    Analyze style (style)              1    CausalInferenc/      144 dRWXr-xr-x
Xc    Count words and lines (wc)         2    ComputPgmg/          112 dRWXr-xr-x
XC    Count words used (tokens)          3    Discrimination/       48 dRWX------
Xd    Decode/Encode (crypt)              4    ExptControl/         528 dRWXr-xr-x
Xe    Edit a file ($editor)              5    IntfaceDesign/       176 dRWXr-xr-x
Xf    [Format text file]                 6    MenUnix/             240 dRWXr-xr-x
Xh    Heading structure (headings)       7    NatArtLang/          160 dRWXr-xr-x
Xl    Look for word in dictionary (look) 8    ONR/                 112 dRWXr-xr-x
Xp    Permuted indexer (ptx)             9    Personal/            112 dRWXr-xr-x
Xr <- Reference finder (pub)                                                     
Xs    Spelling error finder (spell)                                              
XS    Spelling corrector (correct)                                               
Xt    Typo finder (typo)                                                         
Xw    Wordy sentence finder (diction)    You have new mail.                      
X                                        Friday, November 6.  3:41:59            
X$1 diction MenUnix/design | more                                                
X$2 style MenUnix/design | more                                                  
X$3 headings hh mh lh ph MenUnix/design | more                                   
X$4 correct MenUnix/design                                                       
X
XCOMMAND: pub '{probe}'                                                          
X{probe}: (subject | title) = (design                                            
XAdding text: quit with ESC, select files with '_'                               
X.)b
X.TC
SHAR_EOF
if test 31607 -ne "`wc -c 'menudoc'`"
then
	echo shar: error transmitting "'menudoc'" '(should have been 31607 characters)'
fi
echo shar: extracting "'menuinfo'" '(2826 characters)'
if test -f 'menuinfo'
then
	echo shar: over-writing existing file "'menuinfo'"
fi
sed 's/^X//' << \SHAR_EOF > 'menuinfo'
XLast revised April 18, 1981.
X
XOn the left top of your screen is the PROGRAM MENU.
XThe PROGRAM MENU contains programs, and workbenches of more programs.
XThese workbenches have been organized so that related commands are grouped together.
XPROGRAM MENUS are always in [square] brackets.
XSelecting a PROGRAM MENU (by typing the character on its left)
Xresults in you jumping into that workbenches.
XSelecting a program causes its execution
X(you may be asked to supply information on a line at the bottom
Xof the screen).
X
XAt the very top of the PROGRAM MENU is the name of the workbenches you are in.
XYou start off in the PROGRAM MENU.
XA very important workbench is [CONTROL]
Xwhich you can see by typing & (ampersand).
X[CONTROL] has commands available at all parts of the PROGRAM MENU,
Xcommands that let you control MENUNIX.
XOne such command is . which always puts you back where you started:
Xthe UNIX workbench.
X
XOn the right top of your screen is the FILE MENU.
XThe FILE MENU contains both plain files and directories of files.
XSelecting a plain file causes you to edit it.
XSelecting a directory causes you to go into that directory.
XDirectories are identified by being followed by a slash/.
XAt the very top of the FILE MENU is the complete path name
Xof your current working directory.
XOn its left is something like 1/4,
Xwhich tells which "page" of how many you are on in the current
Xdirectory.
XYou can see subsequent pages by typing + and previous pages by typing -.
XYou can change to the next directory up by typing a 0 (zero).
XThese commands should all be listed in the CONTROL MENU.
X
XIn the lower middle of the screen is your history of comands
Xexecuted from the PROGRAM MENU.
XThe variables, $1 through $9 contain the commands you executed
X(as seen by the operating system).
XYou can repeat commands by typing the "Shell Command"
Xcharacter, !, followed by a command.
XThis command can be a new command, or it can be a variable
X(for example, !$1 repeats the last command),
Xor it can be a combination of variables and new text.
XThere are some predefined variables that are of general use:
Xdir is the current directory, user is your name,
Xhome is your login directory, mail is your mail spool file,
Xand menu is the name of your menu directory.
XYou can examine the variables available by typing a #
Xand MENUNIX will ask you for a string (which can include variables)
Xor you can just type RETURN and all the variables will be printed.
X
XWhen you are typing in text (such as when you are supplying arguments,
Xyou will often want to type in file names.
XA quick way of enterning file names is by typing an underscore _,
Xwhich temporarily puts you in a special mode where you can
Xselect file names with the numbers beside them.
XIn this mode,
Xyou can go forward and backward on the pages of the current directory
Xwith + and - respectively.
SHAR_EOF
if test 2826 -ne "`wc -c 'menuinfo'`"
then
	echo shar: error transmitting "'menuinfo'" '(should have been 2826 characters)'
fi
echo shar: extracting "'internal'" '(2855 characters)'
if test -f 'internal'
then
	echo shar: over-writing existing file "'internal'"
fi
sed 's/^X//' << \SHAR_EOF > 'internal'
Xf	This command flips the PROGRAM menu display to and from
Xf	the current workbench and the [CONTROL] menu.
Xp	This command chages the workbench displayed in PROGRAM menu
Xp	to the one just above.  For example, the menu just above
Xp	[C Programming] is [Programming], and the one just above
Xp	[Programming] is the highest level one, [UNIX].
Xa	This command lets you take a short diversion from your
Xa	current workbench.  It saves the name of the current workbench,
Xa	tells you in the feedback window the name of the workbench
Xa	you are diverting from, and places you in the [UNIX] workbench.
Xa	From there, you can type a sequence of keys to call any program,
Xa	but after the program is called, you will be returned to the
Xa	workbench you started from.  Commands executed on a diversion are
Xa	not entered into the displayed history variables, 1-9, but are hidded
Xa	in variable 0.  You can return to your saved workbench
Xa	prematurely by repeating this command.
Xu	This command puts you back in the [UNIX] (highest level) workbench.
Xc	This command lets you change directory to a directory you specify
Xc	in the line-editor at the bottom of the MENUNIX display.  You can
Xc	type the name of a directory, or the name of a variable.
X0	This command changes you to your parent directory.  For example,
X0	if you are in /csl/bin/doc, typing this command will put you in
X0	/csl/bin.  Typing it once again will put you in /csl.
X+	This command changes the FILE menu display to the next page of
X+	files.  If you are on the last page of the directory, this
X+	command will "wrap around" to the first page.
X-	This command changes the FILE menu display to the previous page of
X-	files.  If you are on the first page of the directory, this
X-	command will "wrap around" to the last page.
Xr	This command redisplays the MENUNIX screen.
Xd	This command switches you to the documentation perspective
Xd	do that any command you make will get documentation on that
Xd	command instead of executing it.
Xs	This command allows you to type in commands that will get
Xs	executed as though they were typed outside MENUNIX in the
Xs	UNIX command line interpreter, the shell (sh not csh).
Xs	The command you run will not be put on display in the history
Xs	list of variables (1-9) but will be silently stored in variable 0.
Xv	This command allows you to set the value of variables.  You will
Xv	be asked for the name of the variable in the line-editor, and
Xv	if this variable exists, you will be put in the line-editor with
Xv	its current value, otherwise, you will be editing an empty line.
Xv	This command is useful for editing the history list of commands,
Xv	stored in the variables 1 through 9.  The variable 0 always
Xv	contains the last command you ran, even if it is not displayed.
Xi	This command lets you find the values of strings including
Xi	variables, or the values of all the variables so far set.
SHAR_EOF
if test 2855 -ne "`wc -c 'internal'`"
then
	echo shar: error transmitting "'internal'" '(should have been 2855 characters)'
fi
echo shar: extracting "'menunix.1'" '(2436 characters)'
if test -f 'menunix.1'
then
	echo shar: over-writing existing file "'menunix.1'"
fi
sed 's/^X//' << \SHAR_EOF > 'menunix.1'
X.TH MENUNIX 1UCSD "November 1981"
X.SH NAME
Xmenunix \- menu interface to UNIX programs and files
X.SH SYNOPSIS
X.B menunix
X[menudir]
X.SH DESCRIPTION
X.PP
XMENUNIX is a menu shell that makes extensive use of terminal screens.
XIt provides similar hierarchical menuing for files
X(like the Berkeley vsh)
Xand programs.
XThere are visual facilities based on csh
Xfor aliases,
Xand for in-line editing of commands.
XIt is not intended to be a production quality system,
Xbut more of an experimental vehicle for exploring user interfaces
Xon UNIX.
XMany of the design choices in MENUNIX are questionable,
Xbut trying them was the motivation for its creation.
X.PP
XMENUNIX uses ``hot-keys'' for most menu selections.
XThat means that single characters have immediate actions;
Xno RETURN key is used.
XThe digits 1-9 select files
X(see below for how to scroll the menu of files)
Xand letters select programs.
XSpecial characters are used for built-in commands.
X.SS "MENUNIX Built-In Commands
X.nf
X@	exit MENUNIX
X.	changes the workbench to [UNIX]
X,	changes the workbench to the parent menu
X:	changes the workbench to [UNIX] and returns
X&	flips the PROGRAM MENU display to [CONTROL]
X0	changes the working directory to the parent directory
X/	changes directory
X+	displays the next directory page
X-	displays the previous directory page
X?	changes to and from the documentation perspective
X!	runs a command typed in the line-editor
X$	sets a variable to a value
X#	prints the value of a string or prints all variable values
X^R	redisplays the screen
X.fi
X.SS "Line-editor Commands
X.nf
X.ta .5i
Xa (A)	append text after the cursor (end of line)
Xb (w)	back up (move forward) one word
Xh (H)	move the cursor back one character (to start of line)
X^H	go back one character and delete if adding text
Xl (L)	move the cursor forward one character (to end of line)
Xq (Q)	leave Line-Edit and pass back contents (abort command)
Xu (U)	undo the last change (all changes)
Xx (X)	delete the character (all characters) below the cursor
X0	delete from the cursor to the end of the line
X+	move the cursor forward one character
X-	move the cursor back one character
X_	enter or leave file selection mode
X\e	ignore the special meaning of the next character
XESC	stop adding text
XCR	send the text to MENUNIX
X.fi
X.SH FILES
X.nf
X.ta 2i
X$HOME/.menuvar	personal variables
X.SH AUTHOR
XGary Perlman
X.SH BUGS
XExcept for some fixes put in for running on Berkeley UNIX 4.2,
Xthe system has not been modified since 1981.
SHAR_EOF
if test 2436 -ne "`wc -c 'menunix.1'`"
then
	echo shar: error transmitting "'menunix.1'" '(should have been 2436 characters)'
fi
echo shar: done with directory "'doc'"
chdir ..
#	End of shell archive
exit 0

john@genrad.UUCP (John Nelson) (01/20/85)

I haven't finished compiling menunix, but I DID notice that the sources did
not extract properly, mostly due to the fact that there were imbedded
control characters in literals which seem to have been stripped out by mailers
(because the author did not use \xxx to indicate control characters.)

menu.h:		#define ESC ''	/* this should be '\033' */

file.c,menu.c,image.c,linedit.c:  in each case, the string "" should be
       replaced with "\007" wherever it occurs.

Actually, image.c is included, but not used anywhere.  I am fairly sure that
this is all that needs to be fixed, since the number of additions makes the
character count correct (if you were typing in the control character itself
instead of the \xxx sequence instead).

perlman@wanginst.UUCP (Gary Perlman) (01/23/85)

> I haven't finished compiling menunix, but I DID notice that the sources did
> not extract properly, mostly due to the fact that there were imbedded
> control characters in literals which seem to have been stripped out by mailers
> (because the author did not use \xxx to indicate control characters.)
> 
> menu.h:		#define ESC ''	/* this should be '\033' */
> 
> file.c,menu.c,image.c,linedit.c:  in each case, the string "" should be
>        replaced with "\007" wherever it occurs.
> 
> Actually, image.c is included, but not used anywhere.  I am fairly sure that
> this is all that needs to be fixed, since the number of additions makes the
> character count correct (if you were typing in the control character itself
> instead of the \xxx sequence instead).

I am very sorry for fouling up so many times.
I never new that mailers ate control characters.
I am posting yet another version, with the above fixes.
It is just another example of old software not being up to par.
I appreciate that the above person was constructive.

Gary Perlman/Wang Institute/Tyngsboro, MA/01879/(617) 649-9731

#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	src
# This archive created: Tue Jan 22 20:57:36 1985
# By:	Gary Perlman (Wang Institute, Tyngsboro, MA 01879 USA)
export PATH; PATH=/bin:$PATH
if test ! -d 'src'
then
	echo shar: creating directory "'src'"
	mkdir 'src'
fi
echo shar: entering directory "'src'"
cd 'src'
echo shar: extracting "'menu.defs'" '(865 characters)'
if test -f 'menu.defs'
then
	echo shar: over-writing existing file "'menu.defs'"
fi
cat << \SHAR_EOF > 'menu.defs'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include "menu.h"
char	menudir[100] = MENUDIR;
char	maildir[100] = "/usr/spool/mail";
char	*mailfile;
struct MENU *savemenu;
int	anchored = 0;
int	newmenu;
int	ttyspeed;

char	response[BUFSIZ];
char	*command[MAXCOM];
char	commandbuffer[MAXCOM][BUFSIZ];
int	docmode = 0;
int	progmode = 1;
struct	VAR variables[MAXVAR];
int	nvar = 0;
WINDOW *lmenu, *timewin, *history;
struct MENU *menu, *rootmenu, *stdmenu;
struct MENU *readmenu ();

short	uid, gid;
char	escapechar = '\\';
char	varchar    = '$';
char	shellchar  = '!';
char	popchar    = ',';
char	unixchar   = '.';
char	dotdotchar = '0';
char	quitchar   = '`';
char	modechar   = '_';
int	flipped    = 0;
char	dirpath[MAXDEPTH][NAMESIZ];
int	pathlength = 0;
char	pwdname[BUFSIZ];
WINDOW	*filewin;
int	nonames;
int	page = 1;
struct FILENT filent[MAXENTRIES];
SHAR_EOF
if test 865 -ne "`wc -c 'menu.defs'`"
then
	echo shar: error transmitting "'menu.defs'" '(should have been 865 characters)'
fi
echo shar: extracting "'menu.h'" '(2600 characters)'
if test -f 'menu.h'
then
	echo shar: over-writing existing file "'menu.h'"
fi
cat << \SHAR_EOF > 'menu.h'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#ifndef MENU_H
#define MENU_H
#include <curses.h>
#include <ctype.h>
FILE	*xopen ();
char	*getargs (), *copy (), *interpolate (), *getresponse ();
extern	char	menudir[100];
extern	char	maildir[100];
extern	char	*mailfile;
extern	int	anchored;
extern	int	newmenu;
extern	int	ttyspeed;

#define	MAXOPTION    15
#define	MAXCOM       10
#define	COMMAND       0
#define MAXVAR      100
#define	OUT_OF_RANGE -2
#define	INDENT        5
#define MENUTOP       1
#define MENUBOTTOM   23
#define HISTORY    (MAXOPTION+1)
#define TIMELINE   (MENUBOTTOM)
#define INFOLINE   (MENUBOTTOM-2)
#define RESPLINE   (MENUBOTTOM-1)
#define	NOTICES    (HISTORY-1)
#define RIGHTMENU  (COLS/2)
#define GETRETURN  {printf("press RETURN to continue");while(getchar()!='\n');}
extern char	response[BUFSIZ];
extern char	*command[MAXCOM];
extern char	commandbuffer[MAXCOM][BUFSIZ];
extern int	docmode;
extern int	progmode;
struct	VAR
	{
	char	*name;
	char	*value;
	};
extern struct VAR variables[MAXVAR];
extern int	nvar;
extern WINDOW *lmenu, *timewin, *history;
struct MENU
	{
	char	*menuname;
	char	*display[MAXOPTION];
	char	*program[MAXOPTION];
	char	*arguments[MAXOPTION];
	char	selector[MAXOPTION];
	int	noptions;
	struct MENU *nextmenu[MAXOPTION]; 
	struct MENU *parent;
	char	nowait[MAXOPTION];
	};
extern struct MENU *menu;
extern struct MENU *rootmenu;
extern struct MENU *stdmenu;
extern struct MENU *savemenu;
extern struct MENU *readmenu ();

extern short	uid, gid;
#define	ESC       ''
#define	BACKSPACE ''
#define ESCAPE    '\\'
#define RETURN    '\n'
#define MODECHANGE -2
#define RUN	   -1
extern char	escapechar;
extern char	varchar    ;
extern char	shellchar  ;
extern char	popchar    ;
extern char	unixchar   ;
extern char	dotdotchar ;
extern char	quitchar   ;
extern char	modechar   ;
extern int	flipped    ;
#include <sys/types.h>
#include <sys/dir.h>
#ifdef MAXNAMLEN
#define NAMESIZ MAXNAMLEN
#else
#define NAMESIZ 16
#endif
#include <sys/stat.h>
#define MAXDEPTH 10
extern char	dirpath[MAXDEPTH][NAMESIZ];
extern int	pathlength ;
extern char	pwdname[BUFSIZ];
extern WINDOW	*filewin;
#define MAXENTRIES 250
extern int	nonames;
extern int	page ;
#define	DIRFILE        3
#define	PLAINFILE      1
#define PROGFILE       2
#define	PAGESIZE       9
struct FILENT
	{
	char	f_name[NAMESIZ];
	char	f_protect[12];
	off_t	f_size;
	};
extern struct FILENT filent[MAXENTRIES];
#define begin(c) (c == '[')
#define end(c)  (c == ']' || c == '\n' || c == NULL)
#define separator(c) (c == ':')
#define skipspace(ptr) while (isspace (*ptr)) ptr++;
#endif MENU_H
SHAR_EOF
if test 2600 -ne "`wc -c 'menu.h'`"
then
	echo shar: error transmitting "'menu.h'" '(should have been 2600 characters)'
fi
echo shar: extracting "'display.c'" '(2770 characters)'
if test -f 'display.c'
then
	echo shar: over-writing existing file "'display.c'"
fi
cat << \SHAR_EOF > 'display.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include "menu.h"
leftdisplay (menu) struct MENU *menu;
	{
	int i;
	extern	int flipped;
	if (menu == NULL) return;
	wclear (lmenu);
	if (trueval ("highlight")) wstandout (lmenu);
	mvwprintw (lmenu, 0, 0, "[%s]", menu->menuname);
	if (trueval ("highlight")) wstandend (lmenu);
	for (i = 0; i < menu->noptions; i++)
		{
		if (menu->nextmenu[i])
			{
			if (trueval ("highlight")) wstandout (lmenu);
			mvwprintw (lmenu, i+1, INDENT, "[%s]", menu->display[i]);
			if (trueval ("highlight")) wstandend (lmenu);
			}
		else
			{
			mvwprintw (lmenu, i+1, INDENT, menu->display[i]);
			wprintw (lmenu, " (%s)", menu->program[i]);
			}
		if (iscntrl (menu->selector[i]))
		mvwprintw (lmenu, i+1, 0,"^%c",menu->selector[i]-1+'A');
		else mvwaddch (lmenu, i+1, 0, menu->selector[i]);
		}
	wrefresh (lmenu);
	newmenu = 0;
	}

lastcomm ()
	{
	int	i;
	wclear (history);
	for (i = 1; ; i++)
		if (!*variables[i].value) continue;
		else if (ERR == mvwprintw (history, i-1, 0, "%c%s %s",
			varchar, variables[i].name, variables[i].value)) break;
	wrefresh (history);
	}

#include <time.h>
char	*months[] =	{ "January", "February", "March", "April",
			"May", "June", "July", "August",
			"September", "October", "November", "December" };

char	*days[] =	{ "Sunday", "Monday", "Tuesday", "Wednesday",
			"Thursday", "Friday", "Saturday"};
printtime ()
	{
	struct	tm *date;
	long	clock;
	int	hour;

	time (&clock);
	date = (struct tm *) localtime (&clock);
	if ((hour = date->tm_hour) > 12) hour %= 12;
	if (date->tm_sec == 0)
		checkmail (mailfile);
	mvwprintw (timewin, 0, 0, "%s, %s %d.  %d:%02d:%02d",
		days[date->tm_wday], months[date->tm_mon], date->tm_mday,
		hour, date->tm_min, date->tm_sec);
	wrefresh (timewin);
	}

checkmail (mailfile) char *mailfile;
	{
	struct	stat statbuf;
	if (stat (mailfile, &statbuf)) return;
	if (statbuf.st_size)
	    {
	    if (statbuf.st_atime > statbuf.st_mtime)
		mvprintw (NOTICES-1, RIGHTMENU, "You have mail");
	    else
		mvprintw (NOTICES-1, RIGHTMENU, "You have new mail");
	    printw (" (%d bytes)", statbuf.st_size);
		clrtoeol ();
	    }
	refresh ();
	}

display (menu) struct MENU *menu;
	{
	int i;
	if (menu == NULL) return;
	clear (); refresh ();
	printtime ();
	nonames = newdir ();
	page = vdir (page, nonames);
	leftdisplay (menu);
	lastcomm ();
	checkmail (mailfile);
	if (docmode)
		{
		mvprintw (NOTICES-3, RIGHTMENU, "Next selection gets documentation");
		clrtoeol ();
		}
	if (anchored)
		{
		mvprintw (NOTICES-2, RIGHTMENU, "On a diversion from ");
		if (trueval ("highlight")) standout ();
		printw ("[%s]", savemenu->menuname);
		if (trueval ("highlight")) standend ();
		clrtoeol ();
		}
	/* mvwprintw (lmenu, 0, 0, "[%s]", menu->menuname); */
	refresh ();
	}
SHAR_EOF
if test 2770 -ne "`wc -c 'display.c'`"
then
	echo shar: error transmitting "'display.c'" '(should have been 2770 characters)'
fi
echo shar: extracting "'init.c'" '(3653 characters)'
if test -f 'init.c'
then
	echo shar: over-writing existing file "'init.c'"
fi
cat << \SHAR_EOF > 'init.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include "menu.h"
struct MENU *
readmenu (filename, header) char *filename; char *header;
	{
	char	*copy ();
	FILE	*ioptr;
	char	line[BUFSIZ];
	char	file[100];
	char	*p, *getvalue ();
	struct MENU *menu = (struct MENU *) calloc (1, sizeof (struct MENU));
	sprintf (file, "%s/%s", menudir, filename);
	if (menu == NULL)
		{ fprintf (stderr, "readmenu: out of space\n"); exit (1); }
	ioptr = xopen (file, "r");
	menu->menuname = copy (header);
	while (p = fgets (line, BUFSIZ, ioptr))
		{
		while (p = getvalue (p, menu));
		if (++menu->noptions > MAXOPTION)
			{
			fprintf (stderr, "readmenu: Too many options\n");
			exit (1);
			}
		}
	fclose (ioptr);
	return (menu);
	}
char *
getvalue (line, menu) char *line; struct MENU *menu;
	{
	char	valuebuf[BUFSIZ];
	char	designator, *value = valuebuf;
	*value = NULL;
	skipspace (line);
	if (!begin (*line++)) return (NULL);
	skipspace (line);
	designator = *line;
	while (!separator (*line))
		if (end (*line)) goto check;
		else line++;
	line++;
	while (!end (*line)) *value++ = *line++;
	*value = NULL;
	line++;
check:
	if (designator != 's')
		value = copy (valuebuf);
	switch (designator)
	    {
	    case 'd': menu->display[menu->noptions] = value; break;
	    case 's': menu->selector[menu->noptions] = *valuebuf; break;
	    case 'm': menu->nextmenu[menu->noptions]
		    = readmenu (value, menu->display[menu->noptions]);
		    menu->nextmenu[menu->noptions]->parent = menu;
		    break;
	    case 'p': menu->program[menu->noptions] = value; break;
	    case 'a': menu->arguments[menu->noptions] = value; break;
	    case 'w': menu->nowait[menu->noptions] = TRUE; break;
	    default:
		fprintf (stderr, "getvalue: bad designator '%c'\n", designator);
	    }
	return (line);
	}

readvar ()
	{
	char	line[BUFSIZ], *lineptr;
	char	namebuf[BUFSIZ], *nameptr;
	char	valuebuf[BUFSIZ], *valueptr;
	char	*interpolate ();
	char	*getenv ();
	FILE	*ioptr;
	int	i;
	for (i = 0; i < MAXCOM; i++)
		{
		variables[i].value = commandbuffer[i];
		variables[i].name  = copy (" ");
		*variables[i].name = '0' + i;
		}
	nvar = MAXCOM;
	variables[nvar].name	= copy ("dir");
	variables[nvar++].value	= pwdname;
	variables[nvar].name	= copy ("menu");
	variables[nvar++].value	= copy (menudir);
	variables[nvar].name	= copy ("home");
	variables[nvar++].value	= getenv ("HOME");
	variables[nvar].name	= copy ("user");
	variables[nvar++].value	= getenv ("USER");
	sprintf (line, "%s/%s", maildir, getenv ("USER"));
	variables[nvar].name	= copy ("mail");
	variables[nvar++].value	= mailfile = copy (line);
	sprintf (line, "%s/%s", getenv ("HOME"), ".menuvar");
	if (access (line, 4))
		sprintf (line, "%s/setup/menunix", getenv ("HOME"));
	if (ioptr = fopen (line, "r"))
	    {
	    while (fgets (line, BUFSIZ, ioptr))
		{
		lineptr = line;
		nameptr = namebuf; *nameptr = NULL;
		valueptr = valuebuf; *valueptr = NULL;
		skipspace (lineptr);
		while (isalnum (*lineptr))
			*nameptr++ = *lineptr++;
		*nameptr = NULL;
		skipspace (lineptr);
		if (*lineptr == '=') lineptr++;
		skipspace (lineptr);
		while (*lineptr != '\n')
			*valueptr++ = *lineptr++;
		*valueptr = NULL;
		variables[nvar].name = copy (namebuf);
		variables[nvar].value = copy (interpolate (valuebuf));
		nvar++;
		}
	    fclose (ioptr);
	    }
	variables[nvar].name	= copy ("editor");
	variables[nvar++].value = copy ("ex");
	variables[nvar].name	= copy ("printdotfiles");
	variables[nvar++].value	= copy ("true");
	variables[nvar].name	= copy ("highlight");
	variables[nvar++].value	= copy ("false");
	variables[nvar].name	= copy ("shell");
	variables[nvar++].value	= copy (getenv ("SHELL"));
	}
SHAR_EOF
if test 3653 -ne "`wc -c 'init.c'`"
then
	echo shar: error transmitting "'init.c'" '(should have been 3653 characters)'
fi
echo shar: extracting "'utility.c'" '(1177 characters)'
if test -f 'utility.c'
then
	echo shar: over-writing existing file "'utility.c'"
fi
cat << \SHAR_EOF > 'utility.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include "menu.h"
FILE *
xopen (name, mode) char *name, *mode;
	{
	FILE	*ioptr = fopen (name, mode);
	if (ioptr == NULL)
		{
		fprintf (stderr, "Can't open %s\n", name);
		exit (1);
		}
	}

syscall (command) char *command;
	{
	char	*alias (), *interpolate ();
	char	*c = alias (interpolate (command), "|;");
	char	*getval (), *shell = getval ("shell");
	char	shellcomm[BUFSIZ];
	*shellcomm = NULL;
	if (strcmp (shell, "/bin/sh"))
		sprintf (shellcomm, "%s -c \"%s\"", shell, c);
	nocrmode (); echo ();
	printf ("%s\n", c);
	system (*shellcomm ? shellcomm : c);
	crmode (); noecho ();
	}
char *
copy (string) char *string;
	{
	char	*copy = (char *) malloc (strlen (string) + 1);
	if (copy == NULL)
		{
		clear (); refresh ();
		printf ("You have run out of space\n");
		endwin ();
		exit (1);
		}
	strcpy (copy, string);
	return (copy);
	}

#include <signal.h>
#include <setjmp.h>
jmp_buf env;
timeout () { longjmp (env, 1); }
timegetc (secs)
	{
	int	c;
	extern	timeout ();
	signal (SIGALRM, timeout);
	alarm (secs);
	if (setjmp (env)) return (0);
	c = getchar ();
	signal (SIGALRM, SIG_IGN);
	alarm (0);
	return (c);
	}
SHAR_EOF
if test 1177 -ne "`wc -c 'utility.c'`"
then
	echo shar: error transmitting "'utility.c'" '(should have been 1177 characters)'
fi
echo shar: extracting "'run.c'" '(1483 characters)'
if test -f 'run.c'
then
	echo shar: over-writing existing file "'run.c'"
fi
cat << \SHAR_EOF > 'run.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include "menu.h"
run (chosenmenu, chosen) struct MENU *chosenmenu;
	{
	char	syscommand[BUFSIZ];
	char	buf[BUFSIZ], *bufptr = buf;
	char	*strptr;
	int	i;
	if (!chosenmenu->program[chosen]) return;
	if (*chosenmenu->program[chosen] == '-')
		{
		internalrun (chosenmenu, chosen);
		return;
		}
	mvprintw (INFOLINE, 0, "COMMAND: %s %s", chosenmenu->program[chosen],
		chosenmenu->arguments[chosen]);
	clrtoeol ();
	if (docmode)
		{
		docmode = 0;
		strptr = chosenmenu->program[chosen];
		sprintf (variables[COMMAND].value, "man %s", strptr);
		mvprintw (RESPLINE, 0, "Getting documentation on %s, please wait", strptr);
		clrtoeol ();
		move (MENUBOTTOM, 0);
		refresh ();
		syscall (variables[COMMAND].value);
		GETRETURN
		display (menu);
		return;
		}
	if (chosenmenu->arguments[chosen])
		{
		if ((strptr = getargs (chosenmenu->arguments[chosen], NULL)) == NULL)
			{ noecho (); crmode (); return; }
		else sprintf (variables[COMMAND].value, "%s %s", 
			chosenmenu->program[chosen], strptr);
		}
	else sprintf (variables[COMMAND].value, "%s", chosenmenu->program[chosen]);
	clear (); refresh ();
	syscall (variables[COMMAND].value);
	if (!chosenmenu->nowait[chosen]) GETRETURN
	if (anchored)
	    {
	    anchored = 0;
	    display (menu = savemenu);
	    return;
	    }
	for (i = MAXCOM-1; i > 0; i--)
		variables[i].value = variables[i-1].value;
	variables[COMMAND].value = variables[MAXCOM-1].value;
	display (menu);
	}
SHAR_EOF
if test 1483 -ne "`wc -c 'run.c'`"
then
	echo shar: error transmitting "'run.c'" '(should have been 1483 characters)'
fi
echo shar: extracting "'file.c'" '(7008 characters)'
if test -f 'file.c'
then
	echo shar: over-writing existing file "'file.c'"
fi
cat << \SHAR_EOF > 'file.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include "menu.h"

#define	inodir(entry) (entry->d_ino)
#ifdef MAXNAMLEN

#define	namedir(entry) (entry->d_name)

#else

#define	DIR	FILE
#define	opendir(path) fopen (path, "r")
#define closedir(dirp) fclose (dirp)
struct direct *
readdir (dirp)
DIR 	*dirp;
	{
	static	struct	direct	entry;
	if (dirp == NULL) return (NULL);
	for (;;)
		{
		if (fread (&entry, sizeof (struct direct), 1, dirp) == 0) return (NULL);
		if (entry.d_ino) return (&entry);
		}
	}
char	*strncpy ();
char *
namedir (entry)
struct	direct	*entry;
	{
	static	char	name[NAMESIZ];
	return (strncpy (name, entry->d_name, DIRSIZ));
	}

#endif

char *
prname (s, dirpath, pathlength) char *s; char dirpath[MAXDEPTH][NAMESIZ];
	{
	int	i;
	strcpy (s, "/");
	for (i = 0; i < pathlength; i++)
		{
		strcat (s, dirpath[i]);
		strcat (s, "/");
		}
	return (s);
	}

char *
pwd (s) char *s;
	{
	char	*pwd;
	char	pathname[MAXDEPTH][NAMESIZ];
	ino_t	inode[MAXDEPTH];
	struct	direct *dirent;
	struct	stat statbuf;
	dev_t	dotdevno;
	ino_t	rootinode;
	DIR	*ioptr;
	int	i;

	pathlength = 0;
	if (stat ("/", &statbuf)) printf ("Can't stat /\n");;
	rootinode = statbuf.st_ino;
	if (stat (".", &statbuf)) printf ("Can't stat .\n");
	dotdevno = statbuf.st_dev;
	for (;;)
	{
	if ((ioptr = opendir (".")) == NULL)
		{
		printf ("Can't open current directory");
		return (NULL);
		}
	if ((dirent = readdir (ioptr)) == NULL)
	    {
	    closedir (ioptr);
	    return (NULL);
	    }
	else inode[pathlength] = inodir(dirent);
	dirent = readdir (ioptr); /* skip over .. */
	if (pathlength)
	    while (dirent = readdir (ioptr))
		if (inodir(dirent) == inode[pathlength-1])
		    {
		    strcpy (pathname[pathlength-1], namedir(dirent));
		    break;
		    }
	closedir (ioptr);
	if (inode[pathlength] == rootinode)
	    {
	    chdir ("/");
	    ioptr = opendir ("/", "r");
	    while (dirent = readdir (ioptr))
		{
		if (stat (namedir(dirent), &statbuf)) continue;
		if (statbuf.st_dev == dotdevno)
		    {
		    strcpy (dirpath[0], namedir (dirent));
		    pathlength++;
		    for (i = 1; i < pathlength; i++)
			strcpy (dirpath[i], pathname[pathlength-i-1]);
		    if (pathlength == 1 && dirpath[0][0] == '.')
		    pathlength = 0;
		    chdir (pwd = prname (s, dirpath, pathlength));
		    closedir (ioptr);
		    return (pwd);
		    }
		}
	    }
	pathlength++;
	closedir (ioptr);
	chdir ("..");
	}
	}

cd (dirname) char *dirname;
	{
	char	vardir[BUFSIZ];
	char	*interpolate ();
	char	*getenv ();
	int	i;
	if (!dirname) return (-1);
	if (!*dirname) dirname = getenv ("HOME");
	if (chdir (dirname))
		{
		sprintf (vardir, "%c%s", varchar, dirname);
		dirname = interpolate (vardir);
		if (*dirname == NULL) return (-1);
		if (chdir (dirname = interpolate (vardir))) return (-1);
		}
	if (!strcmp (dirname, ".")) return (0);
	if (*dirname == '/' || *dirname == '.')
		{
		pwd (pwdname);
		return (0);
		}
	if (!strcmp (dirname, ".."))
		if (pathlength) pathlength--;
		else return (0);
	else strcpy (dirpath[pathlength++], dirname);
	prname (pwdname, dirpath, pathlength);
	return (0);
	}

newdir ()
	{
	char	*name;
	int	flecmp ();
	int	nonames;
	struct	direct *d;
	struct	stat buf;
	DIR	*ioptr = opendir (".");
	if (ioptr == NULL) return (0);
	nonames = 0;
	while (d = readdir (ioptr))
		{
		name = namedir (d);
		if (!strcmp (name, ".")) continue;
		if (!strcmp (name, "..")) continue;
		if ((!trueval ("printdotfiles")) && *name == '.')
			continue;
		if (stat (name, &buf))
			{
			printf ("Can't stat %s", name);
			getchar ();
			continue;
			}
		strcpy (filent[nonames].f_name, name);
		setmode (filent[nonames].f_protect, &buf);
		filent[nonames].f_size = buf.st_size;
		if (++nonames == MAXENTRIES) break;
		}
	qsort (filent, nonames, sizeof (struct FILENT), flecmp);
	closedir (ioptr);
	return (nonames);
	}

#define UNSET '-'
#define UPPER 'A'-'a'
setmode (s, statbuf) char *s; struct stat *statbuf;
	{
	int	i;
	short	mode = statbuf->st_mode;
	for (i = 1; i < 10; i++) s[i] = UNSET;
	s[10] = NULL;
	switch (mode & S_IFMT)
		{
		case S_IFREG: s[0] = '-'; break;
		case S_IFDIR: s[0] = 'd'; break;
		case S_IFCHR: s[0] = 'c'; break;
#ifdef S_IFBLK
		case S_IFBLK: s[0] = 'b'; break;
#endif
#ifdef S_IFMPC
		case S_IFMPC: s[0] = 'C'; break;
#endif
#ifdef S_IFMPB
		case S_IFMPB: s[0] = 'B'; break;
#endif
		default: s[0] = '?';
		}
	for (i = 0; i < 9; i+=3)
		{
		if (mode & (S_IREAD  >> i)) s[i + 1] = 'r';
		if (mode & (S_IWRITE >> i)) s[i + 2] = 'w';
		if (mode & (S_IEXEC  >> i)) s[i + 3] = 'x';
		}
	if (uid == statbuf->st_uid)
		{
		for (i = 1; i <= 3; i++)
			if (s[i] != UNSET) s[i] += UPPER;
		}
	else if (gid == statbuf->st_gid)
		{
		for (i = 4; i <= 6; i++)
			if (s[i] != UNSET) s[i] += UPPER;
		}
	else for (i = 7; i <= 9; i++)
		if (s[i] != UNSET) s[i] += UPPER;
	}

flecmp (f1, f2) struct FILENT *f1, *f2;
	{
	int	strcmp ();
	if (f1->f_protect[0] == 'd' && f2->f_protect[0] != 'd') return (-1);
	if (f2->f_protect[0] == 'd' && f1->f_protect[0] != 'd') return (1);
	return (strcmp (f1->f_name, f2->f_name));
	}

vdir (page, nonames)
	{
	int	i;
	int	reali;
	char	pagecount[10];
	int	npages = nonames/PAGESIZE + (nonames%PAGESIZE?1:0);
	if (page < 1) page = npages;
	else if (page > npages) page = 1;
	wclear (filewin);
	for (i = 0; i < PAGESIZE; i++)
		{
		if ((reali = i + (page-1)*PAGESIZE) == nonames) break;
		mvwprintw (filewin,1+i, 0, "%c", '1'+i);
		if (filent[reali].f_protect[0] == 'd') /* directory */
			{
			if (trueval ("highlight")) wstandout (filewin);
			mvwprintw (filewin,1+i, INDENT, "%s/",
				filent[reali].f_name);
			if (trueval ("highlight")) wstandend (filewin);
			}
		else	mvwprintw (filewin,1+i, INDENT, "%s",
				filent[reali].f_name);
		mvwprintw (filewin, 1+i, 20, "%9d %10s",
			filent[reali].f_size, filent[reali].f_protect);
		}
	if (trueval ("highlight")) wstandout (filewin);
	mvwprintw (filewin,0,0, "%s", pwdname);
	if (trueval ("highlight")) wstandend (filewin);
	sprintf (pagecount, "%d/%d", page, npages);
	mvwprintw (filewin,0,COLS/2-5, "%5s", pagecount);
	wrefresh (filewin);
	return (page);
	}

fileprocess (c) char c;
    {
    char	*getargs (), *getval ();
    char	*strptr;
    int	i = c - '1' + (page-1)*PAGESIZE;
    if (i >= nonames)
	{
	putchar (7);
	return;
	}
    mvwprintw (filewin, 1+c-'1', 2, "<-");
    wrefresh (filewin);
    if (filent[i].f_protect[0] == 'd' && access (filent[i].f_name, 1) == 0)
	{
	cd (filent[i].f_name);
	nonames = newdir ();
	page = vdir (page=1, nonames);
	}
    else if (access (filent[i].f_name, 1) == 0)
	{
	sprintf (command, "%s ", filent[i].f_name);
	if ((strptr = getargs ("{arguments?}", NULL)) == NULL) return;
	strcat (command, strptr);
	clear (); refresh ();
	syscall (command);
	GETRETURN
	clear (); refresh ();
	flipped = 0;
	display (menu);
	}
    else if (access (filent[i].f_name, 4) == 0)
	{
	sprintf (command, "$editor %s", filent[i].f_name);
	move (LINES-1, 0); clrtoeol (); refresh ();
	syscall (command);
	clear (); refresh ();
	flipped = 0;
	display (menu);
	}
	else putchar (7);
    }
SHAR_EOF
if test 7008 -ne "`wc -c 'file.c'`"
then
	echo shar: error transmitting "'file.c'" '(should have been 7008 characters)'
fi
echo shar: extracting "'internalrun.c'" '(5036 characters)'
if test -f 'internalrun.c'
then
	echo shar: over-writing existing file "'internalrun.c'"
fi
cat << \SHAR_EOF > 'internalrun.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include "menu.h"
#define skipspace(ptr) while (isspace (*ptr)) ptr++;
internalrun (chosenmenu, chosen) struct MENU *chosenmenu;
    {
    char	syscommand[BUFSIZ];
    char	buf[BUFSIZ], *bufptr = buf;
    char	*strptr;
    char	comm = chosenmenu->program[chosen][1];
    int	i;
    if (docmode && comm != 'd')
	{
	docmode = 0;
	docinternal (comm);
	flipped = 1;
	return;
	}
    switch (comm)
	{
	case 'f':
		if (flipped) leftdisplay (menu);
		else leftdisplay (stdmenu);
		flipped = !flipped;
		return;
	case 'p':
		popchar = chosenmenu->selector[chosen];
		flipped = 0;
		menu = menu->parent;
		if (ttyspeed > B9600)
			leftdisplay (menu);
		else newmenu = 1;
		return;
	case 'x':
		finish (0);
	case 'a':
		if (anchored)
			{
			menu = savemenu;
			newmenu = 1;
			if (ttyspeed > B9600)
			    leftdisplay (menu);
			move (NOTICES-2, RIGHTMENU); clrtoeol (); refresh ();
			}
		else	{
			savemenu = menu;
			mvprintw (NOTICES-2, RIGHTMENU, "On a diversion from ");
			if (trueval ("highlight")) standout ();
			printw ("[%s]", savemenu->menuname);
			if (trueval ("highlight")) standend ();
			refresh ();
			menu = rootmenu;
			if (ttyspeed > B9600)
			    leftdisplay (menu);
			else newmenu = 1;
			}
		anchored = !anchored;
		flipped = 0;
		return;
	case 'u':
		unixchar = chosenmenu->selector[chosen];
		if (anchored)
		    {
		    move (NOTICES-2, RIGHTMENU);
		    clrtoeol ();
		    refresh ();
		    }
		anchored = flipped = 0;
		menu = rootmenu;
		if (ttyspeed > B9600)
		    leftdisplay (menu);
		else newmenu = 1;
		return;
	case 'c':
		mvprintw (INFOLINE, 0, chosenmenu->display[chosen]);
		clrtoeol ();
		if (cd (getargs (chosenmenu->arguments[chosen], NULL)))
			{
			mvprintw (INFOLINE,0, "Can't change directory");
			clrtoeol ();
			refresh ();
			}
		else page = vdir (page=1, nonames = newdir ());
		return;
	case '0':
		dotdotchar = chosenmenu->selector[chosen];
		cd ("..");
		page = vdir (page=1, nonames=newdir ());
		return;
	case '+':
		page = vdir (++page, nonames);
		return;
	case '-':
		page = vdir (--page, nonames);
		return;
	case 'r': display (menu); flipped = 0; return;
	case 'd':
		if (docmode = !docmode)
		  mvprintw (NOTICES-3, RIGHTMENU, "Next selection gets documentation");
		else
		  mvprintw (NOTICES-3, RIGHTMENU, "Next selection runs program");
		clrtoeol ();
		refresh ();
		return;
	case 's': 
		shellchar = chosenmenu->selector[chosen];
		mvprintw (INFOLINE, 0, chosenmenu->display[chosen]);
		clrtoeol ();
		strptr = getargs (chosenmenu->arguments[chosen], NULL);
		if (strptr == NULL) return;
		while (isspace (*strptr)) strptr++;
		if (*strptr != NULL)
		    strcpy (variables[COMMAND].value, alias (strptr, "|;"));
		syscall (variables[COMMAND].value);
		GETRETURN
		display (menu);
		return;
	case 'v':
		varchar = chosenmenu->selector[chosen];
		mvprintw (INFOLINE, 0, "Setting variable");
		clrtoeol ();
		refresh ();

		if ((strptr = getargs ("{name}", NULL)) == NULL)
			return;
		else strptr = copy (strptr);
		skipspace (strptr);
		for (i = 0; i < nvar; i++)
			if (!strcmp (strptr, variables[i].name)) break;
		if (i == nvar)
		    {
		    if (nvar+1 > MAXVAR)
			    {
			    mvprintw (INFOLINE, 0,"No room for more variables");
			    clrtoeol ();
			    refresh ();
			    return;
			    }
		    mvprintw (INFOLINE, 0, "Setting new variable");
		    variables[i].name = copy (strptr);
		    }
		else
			mvprintw (INFOLINE, 0, "Changing old variable");
		clrtoeol ();
		refresh ();
		if ((strptr = getargs ("{value}", variables[i].value)) == NULL)
			return;
		else strptr = copy (strptr);
		skipspace (strptr);
		variables[i].value = strptr;
		mvprintw (INFOLINE, 0, "%c%s=%s",
			varchar, variables[i].name, variables[i].value);
		clrtoeol ();
		refresh ();
		lastcomm ();
		if (i == nvar) nvar++;
		return;
	case 'i':
		mvprintw (INFOLINE, 0, chosenmenu->display[chosen]);
		clrtoeol ();
		strptr = getargs (chosenmenu->arguments[chosen], NULL);
		if (*strptr)
		    {
		    mvprintw (INFOLINE, 0, interpolate (strptr));
		    clrtoeol ();
		    refresh ();
		    }
		else
		    {
		    FILE *popen(), *ioptr;
		    if (ioptr = popen ("/usr/ucb/more", "w"))
			{
			clear (); refresh ();
			nocrmode (); echo ();
			for (i = 0; i < nvar; i++)
			    fprintf (ioptr, "%10s=%s\n",
				variables[i].name, variables[i].value);
			pclose (ioptr);
			GETRETURN
			clear (); refresh ();
			crmode (); noecho ();
			display (menu);
			}
		    }
		return;
	default:
		mvprintw (INFOLINE, 0, "Unknown internal command\n");
		clrtoeol ();
		refresh ();
		return;
	}
    }

docinternal (command) char command;
	{
	FILE	*fopen (), *ioptr;
	char	*getval (), *menu = getval ("menu");
	char	docfile[BUFSIZ];
	char	line[BUFSIZ];
	sprintf (docfile, "%s/../doc/internal", menu);
	move (HISTORY, 0); clrtobot (); move (HISTORY, 0); refresh ();
	if (ioptr = fopen (docfile, "r"))
		{
		while (fgets (line, BUFSIZ, ioptr))
			if (*line == command)
				fputs (line+1, stdout);
		fclose (ioptr);
		}
	GETRETURN
	display (stdmenu);
	}
SHAR_EOF
if test 5036 -ne "`wc -c 'internalrun.c'`"
then
	echo shar: error transmitting "'internalrun.c'" '(should have been 5036 characters)'
fi
echo shar: extracting "'input.c'" '(2232 characters)'
if test -f 'input.c'
then
	echo shar: over-writing existing file "'input.c'"
fi
cat << \SHAR_EOF > 'input.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include "menu.h"

char *
getval (name) char *name;
	{
	int	i = 0;
	for (i = 0; i < nvar; i++)
		if (!strcmp (variables[i].name, name)) break;
	if (i == nvar) return (NULL);
	return (variables[i].value);
	}

trueval (name)
	{
	char	*v = getval (name);
	if (v == NULL) return (0);
	if (*v == NULL) return (1);
	if (strlen (v) == 1)
		if (*v == 't' || *v == 'y' || *v == '1') return (1);
		else return (0);
	else if (!strcmp (v, "true") || !strcmp (v, "yes")) return (1);
	return (0);
	}

char *
interpolate (s) char *s;
	{
	static	char	interbuf[BUFSIZ];
	char	*getval ();
	char	*sptr = s;
	char	*bufptr = interbuf;
	char	namebuf[BUFSIZ], *nameptr = namebuf;
	int	i;
	*bufptr = NULL;
	while (*sptr)
		{
		if (*sptr == varchar)
			{
			nameptr = namebuf;
			sptr++;
			while (isalnum (*sptr)) *nameptr++ = *sptr++;
			*nameptr = NULL;
			strcpy (bufptr, getval (namebuf));
			while (*bufptr) bufptr++;
			}
		else if	(*sptr == escapechar)
			{
			sptr++;
			*bufptr++ = *sptr++;
			}
		else	*bufptr++ = *sptr++;
		}
	*bufptr = NULL;
	return (interbuf);
	}

#define	begingeneric(c) (c == '{')
#define	endgeneric(c)   (c == '}' || end(c))
char *
getargs (args, initial) char *args, *initial;
	{
	static	char	arglist[BUFSIZ];
	char	genericbuf[100];
	char	*generic;
	char	*arglistptr = arglist;
	*arglistptr = NULL;
	if (args == NULL) return (arglist);
	for(;;)
		{
		while (!begingeneric (*args))
			if (*args == NULL)
				{
				*arglistptr = NULL;
				return (arglist);
				}
			else *arglistptr++ = *args++;
		*arglistptr = NULL;
		generic = genericbuf;
		while (!endgeneric (*args))
			*generic++ = *args++;
		*generic++ = *args++;
		*generic = NULL;
		if (trueval ("highlight")) standout ();
		mvprintw (RESPLINE, 0, genericbuf);
		if (trueval ("highlight")) standend ();
		printw (": ");
		clrtoeol (); refresh ();
		if (initial) strcpy (response, initial);
		else *response = NULL;
		if (getresponse (response) == NULL) return (NULL);
		move (LINES-1, 0); clrtoeol (); refresh ();
		strcat (arglist, response);
		while (*arglistptr) arglistptr++;
		}
	}

char *
getresponse (s) char *s;
	{
	char	*linedit ();
	int	x, y;
	getyx (stdscr, y, x);
	return (linedit (s, y, x));
	}
SHAR_EOF
if test 2232 -ne "`wc -c 'input.c'`"
then
	echo shar: error transmitting "'input.c'" '(should have been 2232 characters)'
fi
echo shar: extracting "'menu.c'" '(2718 characters)'
if test -f 'menu.c'
then
	echo shar: over-writing existing file "'menu.c'"
fi
cat << \SHAR_EOF > 'menu.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include "menu.defs"
main (argc, argv) char **argv;
	{
	initial (argc, argv);
	process ();
	}

#include <signal.h>
char	*getenv ();
initial (argc, argv) char **argv;
	{
	int	i;
	struct	sgttyb ttystat;
	extern	finish (), howquit ();
	char	*term	=getenv ("TERM");
	WINDOW	*subwin ();
	if (!movecursor (term))
		{
		printf ("This terminal (%s) can't run menus\n");
		exit (1);
		}
	initscr ();
	signal (SIGINT, howquit);
	uid = getuid ();
	gid = getgid ();
	gtty (fileno (stdout), &ttystat);
	ttyspeed = ttystat.sg_ospeed;
	pwd (pwdname);
	nonames = newdir ();
	if (argc > 1) strcpy (menudir, argv[1]);
	readvar ();
	rootmenu = menu->parent = menu = readmenu ("UNIX", "UNIX");
	stdmenu = readmenu ("CONTROL", "CONTROL");
	lmenu = subwin (stdscr, MAXOPTION+1, RIGHTMENU-1, 0, 0);
	filewin = subwin (stdscr, PAGESIZE+1, COLS/2, 0, COLS/2);
	history = subwin (stdscr, INFOLINE-HISTORY-1, 0, HISTORY, 0);
	timewin = subwin (stdscr, 1, 0, NOTICES, RIGHTMENU);
	display (menu);
	crmode (); noecho ();
	}

process ()
	{
	int	c;
	int	chosen;
	for (;;)
		{
		if ((c = timegetc (1)) == 0)
			{
			if (newmenu) leftdisplay (menu);
			printtime ();
			}
		else if (isdigit (c) && c != '0')
			(fileprocess (c));
		else if ((chosen = choose (c, stdmenu)) != OUT_OF_RANGE)
			run (stdmenu, chosen);
		else if ((chosen = choose (c, menu)) == OUT_OF_RANGE)
			{
			mvprintw (INFOLINE, 0, "BREAK to quit.  Type & for [CONTROL] commands");
			clrtoeol ();
			refresh ();
			putchar (7);
			}
		else if (menu->nextmenu[chosen])
			{
			menu = menu->nextmenu[chosen];
			if (ttyspeed > B9600)
				leftdisplay (menu);
			else newmenu = 1;
			flipped = 0;
			}
		else run (menu, chosen);
		}
	}

finish ()
	{
	signal (SIGINT, SIG_IGN);
	alarm (0);
	clear ();
	refresh ();
	endwin ();
	exit (0);
	}

howquit ()
	{
	extern	finish (), howquit ();
	alarm (0);
	signal (SIGINT, finish);
	if (trueval ("highlight")) standout ();
	mvprintw (INFOLINE, 0, "Type RETURN to return to menu, BREAK to exit");
	signal (SIGINT, finish);
	if (trueval ("highlight")) standend ();
	clrtoeol (); refresh ();
	crmode ();
	while (getchar () != '\n') putchar (7);
	signal (SIGINT, howquit);
	move (INFOLINE, 0); clrtoeol (); refresh ();
	display (menu);
	process ();
	}

choose (ch, thismenu) struct MENU *thismenu;
	{
	int	i;
	int	chosen = OUT_OF_RANGE;
	for (i = 0; i < thismenu->noptions; i++)
		if (ch == thismenu->selector[i]) chosen = i;
	if (chosen == OUT_OF_RANGE) return (chosen);
	if (thismenu == stdmenu) return (chosen);
	for (i = 0; i < thismenu->noptions; i++)
		mvwprintw (lmenu, i + 1, 2, "  ");
	if (!newmenu) mvwprintw (lmenu, chosen + 1, 2, "<-");
	wrefresh (lmenu);
	return (chosen);
	}

SHAR_EOF
if test 2718 -ne "`wc -c 'menu.c'`"
then
	echo shar: error transmitting "'menu.c'" '(should have been 2718 characters)'
fi
echo shar: extracting "'CW'" '(211 characters)'
if test -f 'CW'
then
	echo shar: over-writing existing file "'CW'"
fi
cat << \SHAR_EOF > 'CW'
/* Copyright (c) 1981 Gary Perlman  All rights reserved */
/* Permission to copy this software is granted provided */
/* this notice accompanies all distributions and it is  */
/* not used for material gain. */
SHAR_EOF
if test 211 -ne "`wc -c 'CW'`"
then
	echo shar: error transmitting "'CW'" '(should have been 211 characters)'
fi
echo shar: extracting "'movecursor.c'" '(242 characters)'
if test -f 'movecursor.c'
then
	echo shar: over-writing existing file "'movecursor.c'"
fi
cat << \SHAR_EOF > 'movecursor.c'
movecursor (term) char *term;
	{
	char	bp[1024];
	char	*ptr = bp;
	if (tgetent (bp, term) != 1) return (0);
	while (*ptr)
		{
		while (*ptr && *ptr != ':') ptr++;
		if (ptr[1] == 'c' && ptr[2] == 'm') return (1);
		ptr++;
		}
	return (0);
	}
SHAR_EOF
if test 242 -ne "`wc -c 'movecursor.c'`"
then
	echo shar: error transmitting "'movecursor.c'" '(should have been 242 characters)'
fi
echo shar: extracting "'image.c'" '(592 characters)'
if test -f 'image.c'
then
	echo shar: over-writing existing file "'image.c'"
fi
cat << \SHAR_EOF > 'image.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
/* this function is used to create a screen image in a file */
/* I used it to make diagrams but it is not really useful */
#include <curses.h>
#include <ctype.h>
image ()
	{
	int i, j;
	char c;
	FILE *ioptr;
	char file[100];
	sprintf (file, "image.%d", getpid ());
	ioptr = fopen (file, "w");
	for (i = 0; i < 24; i++)
		{
		for (j = 0; j < 80; j++)
			{
			c = stdscr->_y[i][j];
			if (isascii (c))
			    fputc (stdscr->_y[i][j], ioptr);
			else fputc (' ', ioptr);
			}
		fputc ('\n', ioptr);
		}
	fclose (ioptr);
	putchar (7);
	}
SHAR_EOF
if test 592 -ne "`wc -c 'image.c'`"
then
	echo shar: error transmitting "'image.c'" '(should have been 592 characters)'
fi
echo shar: extracting "'Makefile'" '(474 characters)'
if test -f 'Makefile'
then
	echo shar: over-writing existing file "'Makefile'"
fi
cat << \SHAR_EOF > 'Makefile'
#Copyright (c) 1981 Gary Perlman  All rights reserved
#
# Be sure to change MENUDIR (where all menus are kept)
#
MENUDIR="/b/faculty/perlman/menunix/menus"
#
OBJS = menu.o init.o internalrun.o file.o display.o run.o\
	input.o linedit.o utility.o alias.o movecursor.o
LIBES = -lcurses -ltermlib
DESTDIR = .
menu: $(OBJS)
	cc -o $(DESTDIR)/menunix $(OBJS) $(LIBES)
$(OBJS): menu.h
menu.o: menu.defs
	@echo Menus should be in $(MENUDIR)
	cc -D'MENUDIR=$(MENUDIR)' -O -c menu.c
SHAR_EOF
if test 474 -ne "`wc -c 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 474 characters)'
fi
echo shar: extracting "'linedit.c'" '(6649 characters)'
if test -f 'linedit.c'
then
	echo shar: over-writing existing file "'linedit.c'"
fi
cat << \SHAR_EOF > 'linedit.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include "menu.h"
WINDOW	*subwin ();
WINDOW	*feedback;
int	neveredited = 1;
char *
linedit (s, y, x) char *s;
    {
    char	*cursormode ();
    if (neveredited)
	{
	if ((feedback = subwin (stdscr, 1, 0, LINES-1, 0)) == NULL)
	    return (NULL);
	neveredited = 0;
	}
    return (cursormode (s, y, x, feedback));
    }

char *
cursormode (s, y, base_x, feedback) char *s; WINDOW *feedback;
	{
	extern	char	varchar;
	char	command = 0;
	char	saved_s[BUFSIZ];
	char	saved[2][BUFSIZ];
	int	x = 0;
	int	answer;
	int	max_x = strlen (s) - 1;
	int	other = 0;
	strcpy (saved_s, s);
	strcpy (saved[0], s);
	strcpy (saved[1], s);
	if (*s == NULL) command = 'I'; /* auto insert */
	else
	    {
	    mvwprintw (feedback, 0, 0,
		"Cursor mode: quit with 'q', insert with 'i', undo with 'u'");
	    wclrtoeol (feedback); wrefresh (feedback);
	    }
	move (y, base_x);
	ctrlprintw (s);
	clrtoeol ();
	move (y, x+base_x);
	refresh ();
	do	{
		strcpy (saved[other], s);
		switch (command)
			{
			case 0: break;
			case ' ': /* forward one character */
			case 'l':
			case 12:
			case '+':
				if (++x > max_x) putchar (7);
				break;
			case '-': /* backward one character */
			case 'h':
			case 8: /* backspace ughh */
				 if (--x < 0) putchar (7);
				break;
			case '^':
			case 'H': /* all the way to left */
				x = 0;
				break;
			case '$':
			case 'L': /* all the way to right */
				x = max_x;
				break;
			case 'W': /* forward one word */
			case 'w':
				if (x == max_x)
					{
					putchar (7);
					break;
					}
				while (isspace (s[x])) x++;
				while (x < max_x && !isspace (s[x])) x++;
				while (isspace (s[x])) x++;
				break;
			case 'B': /* backward one word */
			case 'b':
				if (x == 0)
					{
					putchar (7);
					break;
					}
				while (x && !isspace (s[x])) x--;
				while (x && isspace (s[x])) x--;
				while (x && !isspace (s[x])) x--;
				if (isspace (s[x])) x++;
				break;
			case 'C': /*change to end of line */
				clrtoeol (); refresh ();
				s[x] = NULL;
				max_x = --x;
				if (max_x < 0) max_x = 0;
			case 'A': /* append after end */
				x = max_x;
			case 'a': /* append after cursor */
				other = !other;
				if (*s == NULL) x--;
				if ((answer = insert (s, y, base_x, feedback, x+1)) == RUN)
					return (s);
				x = answer - 1;
				max_x = strlen (s) - 1;
				break;
			case 'r': /* replace char */
				if (*s == NULL) putchar (7);
				else	{
					other = !other;
					s[x] = getchar ();
					}
				break;
			case 'D':
			case '0':
				other = !other;
				s[x] = NULL;
				max_x = --x;
				break;
			case 'x': /* delete character */
				other = !other;
				strcpy (s+x, s+x+1);
				max_x--;
				break;
			case 'X': /* delete line  and auto insert */
				*s = NULL;
				move (y, base_x);
				clrtoeol ();
				refresh ();
			case 'I': /* insert before start */
				x = 0;
			case 'i': /* insert before  cursor */
				other = !other;
				if ((answer = insert (s, y, base_x, feedback, x)) == RUN)
					return (s);
				x = answer;
				max_x = strlen (s) - 1;
				break;
			case 'U': /* undo all stuff on line */
				other = !other;
				strcpy (s, saved_s);
				max_x = strlen (s) - 1;
				x = 0;
				break;
			case 'u': /* undo last change */
				other = !other;
				strcpy (s, saved[other]);
				max_x = strlen (s) - 1;
				x = 0;
				break;
			case 'Q':
				wclear (feedback);
				wrefresh (feedback);
				mvprintw (y, base_x, "Line-edit escaped");
				clrtoeol ();
				refresh ();
				return (NULL);
			default: putchar (7);
			}
		if (max_x < 0) x = max_x = 0;
		else if (x > max_x) x = max_x;
		else if (x < 0) x = 0;
		move (y, base_x);
		ctrlprintw (s);
		clrtoeol ();
		move (y, x+base_x);
		refresh ();
		} while ((command = getchar ()) != 'q' && command != '\n');
	return (s);
	}

insert (s, y, base_x, feedback, x) char *s; WINDOW *feedback;
	{
	int	i;
	char	before_cursor[BUFSIZ], after_cursor[BUFSIZ];
	char	insert_cursor[BUFSIZ];
	char	*ptr = insert_cursor;
	int	max_x = strlen (s) - 1;
	before_cursor[0] = insert_cursor[0] = after_cursor[0] = NULL;
	mvwprintw (feedback, 0, 0,
	    "Adding text: quit with ESC, select files with '_'");
	wclrtoeol (feedback); wrefresh (feedback);
	if (*s)
		{
		sprintf (before_cursor, "%.*s", x, s);
		strcpy (after_cursor, s+x);
		}
	else max_x = 0;
	move (y, base_x);
	ctrlprintw (s);
	move (y, x+base_x);
	refresh ();
	while ((*ptr = getchar ()) != ESC && *ptr != '\n')
	    {
	    if (*ptr == modechar)
		{
		mvwprintw (feedback, 0, 0,
		    "Selecting files: quit with '_', select files by number");
		wclrtoeol (feedback);
		wrefresh (feedback);
		*ptr = NULL;
		while ((i = getfile ()) != MODECHANGE && i != RUN)
			{
			sprintf (ptr, "%s ", filent[i].f_name);
			i = strlen (filent[i].f_name) + 1;
			x += i;
			ptr += i;
			move (y, base_x);
			ctrlprintw (before_cursor);
			ctrlprintw (insert_cursor);
			ctrlprintw (after_cursor);
			clrtoeol ();
			move (y, x+base_x);
			refresh ();
			}
		mvwprintw (feedback, 0, 0, "Adding text: quit with ESC");
		wclrtoeol (feedback);
		wrefresh (feedback);
		}
	    else if (*ptr == 8) /* backspace */
		    {
		    if (ptr > insert_cursor)
			    {
			    *ptr = NULL;
			    ptr--;
			    *ptr = NULL;
			    x--;
			    }
		    else
			    {
			    putchar (7);
			    ptr = insert_cursor;
			    *ptr = NULL;
			    }
		    }
	    else if (*ptr == ESCAPE)
		    {
		    *ptr++ = getchar ();
		    *ptr = NULL;
		    x++;
		    }
	    else	{
		    ptr++;
		    *ptr = NULL;
		    x++;
		    }
	    move (y, base_x);
	    ctrlprintw (before_cursor);
	    ctrlprintw (insert_cursor);
	    ctrlprintw (after_cursor);
	    clrtoeol ();
	    move (y, x+base_x);
	    refresh ();
	    if (i == RUN) break;
	    }
	if (*ptr == '\n') i = RUN;
	*ptr = NULL;
	sprintf (s, "%s%s%s", before_cursor, insert_cursor, after_cursor);
	strcpy (s, interpolate (s));
	mvwprintw (feedback, 0, 0,"Cursor mode: quit with 'q', abort with 'Q'");
	wclrtoeol (feedback); wrefresh (feedback);
	if (i == RUN) return (RUN);
	return (x);
	}

getfile ()
	{
	char	c;
	int	i;
	for (;;)
		{
		c = getchar ();
		if (c == '+')
			page = vdir (++page, nonames);
		else if (c == '-')
			page = vdir (--page, nonames);
		else if (isdigit (c) && c != '0')
			if ((i = c - '1' + (page-1)*PAGESIZE) >= nonames)
				putchar (7);
			else	{
				mvwprintw (filewin, 1+c-'1', 2, "<-");
				wrefresh (filewin);
				return (i);
				}
		else if (c == RETURN) return (RUN);
		else if (c == modechar) return (MODECHANGE);
		else putchar (7);
		}
	}

ctrlprintw (s) char *s;
	{
	while (*s)
		{
		if (iscntrl (*s))
			{
			standout ();
			addch (*s-1+'A');
			standend ();
			}
		else addch (*s);
		s++;
		}
	}
SHAR_EOF
if test 6649 -ne "`wc -c 'linedit.c'`"
then
	echo shar: error transmitting "'linedit.c'" '(should have been 6649 characters)'
fi
echo shar: extracting "'alias.c'" '(889 characters)'
if test -f 'alias.c'
then
	echo shar: over-writing existing file "'alias.c'"
fi
cat << \SHAR_EOF > 'alias.c'
/*Copyright (c) 1981 Gary Perlman  All rights reserved*/
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
char *
alias (s, delim) char *s, *delim;
	{
	static	char	aliased[BUFSIZ];
	char	*alias = aliased;
	char	name[BUFSIZ], *nameptr = name;
	char	*getval (), *val;
	struct	stat status;
    checkalias:
	*alias = NULL;
	while (isspace (*s)) *alias++ = *s++;
	nameptr = name;
	*nameptr = NULL;
	while (isalnum (*s) || *s == '_')
		*nameptr++ = *s++;
	*nameptr = NULL;
	if (val = getval (name)) /* has a value */
	    if ((stat (val, &status) == 0) /* can get status */
		&& ((status.st_mode & S_IFMT) == S_IFDIR)) /* directory file */
		    strcpy (alias, name);
	    else strcpy (alias, val);
	else
	    strcpy (alias, name);
	while (*alias) alias++;
	while (*s)
		if (index (delim, *alias++ = *s++)) goto checkalias;
	*alias = NULL;
	return (aliased);
	}
SHAR_EOF
if test 889 -ne "`wc -c 'alias.c'`"
then
	echo shar: error transmitting "'alias.c'" '(should have been 889 characters)'
fi
echo shar: done with directory "'src'"
chdir ..
#	End of shell archive
exit 0

stevel@haddock.UUCP (01/23/85)

Is it true that the program posted from the wang institute, that
neuvo bastion of software engineering, has embeded control characters.

And dumb me has been us'in  \134 escape sequences.

Steve Ludlum, decvax!yale-co!ima!stevel, {amd|ihnp4!cbosgd}!ima!stevel