[net.sources] menunix sources reposted

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

#!/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	putchar (7);
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 putchar (7);
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			putchar (7);
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') putchar (7);
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	putchar (7);
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) putchar (7);
X				break;
X			case '-': /* backward one character */
X			case 'h':
X			case 8:
X				 if (--x < 0) putchar (7);
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					putchar (7);
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					putchar (7);
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) putchar (7);
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: putchar (7);
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			    putchar (7);
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				putchar (7);
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 putchar (7);
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