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