menu(1) part 3 of 11
Paul J. Condie
pjc at pcbox.UUCP
Sat Apr 7 03:37:40 AEST 1990
#!/bin/sh
# this is part 3 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file Main.c continued
#
CurArch=3
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file Main.c"
sed 's/^X//' << 'SHAR_EOF' >> Main.c
X** 1 = sub menu 2 = sub sub menu etc.
X** menuname[mptr--] = previous menu
X*/
X char menuname[MAXMENU][15]; /* filenames */
X char filename[80];
X int menuoption[MAXMENU]; /* what option to highlight */
X int i, exitkey, mptr=0, rc;
X int j; /* loop variable */
X char gnames[MAXGNAME][15]; /* goto menu names */
X char gfiles[MAXGNAME][15]; /* goto file names */
X int gindex = 0; /* goto index */
X char *ws;
X extern int optind;
X extern char *optarg;
X int gotorow = 6; /* default goto menu row */
X int gotocol = 8; /* default goto menu col */
X int keys = 0; /* show keyboard values */
X int parse_rc = 0; /* parsedriver return code */
X
X
X
X TrapSignal (shutdown);
X signal (SIGALRM, SIG_IGN); /* to fix bug in curses */
X while ((rc = getopt (argc, argv, "dp:vk:")) != EOF)
X switch (rc)
X {
X case 'd':
X /* Get debug excited */
X debug++;
X break;
X
X case 'p':
X /* Set row and column for ^g */
X sscanf (optarg, "%d,%d", &gotorow, &gotocol);
X break;
X
X case 'v':
X /* Show Version */
X fprintf (stderr, "%s Version %s\n", argv[0], VERSION);
X exit (0);
X break;
X case 'k':
X /* Show keyboard key values - for .menuinit */
X keys++;
X break;
X }
X if (argc == optind && (!keys))
X {
X fprintf (stderr,
X "\nUsage: %s [-v] [-p row,col] [ -keyboard ] menufile\n",
X argv[0]);
X exit (1);
X }
X if (!keys)
X sscanf (argv[optind], "%s", menuname[0]);
X menuoption[0] = 1;
X
X /* curses stuff */
X initscr ();
X cbreak ();
X noecho ();
X nonl ();
X#ifdef SYS5
X keypad (stdscr, TRUE);
X#endif
X
X SetTerm (); /* set terminal keyboard */
X if (keys)
X {
X keyboard ();
X shutdown ();
X }
X
X LoadKeys (KeyWord, ParseKey, ShowKey, RunKey);
X
X
X /*
X ** Parse, Show and Run each menu selected until exit program.
X */
X do
X {
X move (0,0);
X clrtobot (); /* clear screen */
X
X /*
X ** Check the parse return code from the last parse
X ** to determine what message to display.
X */
X switch (parse_rc)
X {
X case NOWAYJOSE:
X BEEP;
X attrset (A_REVERSE|A_BOLD);
X mvprintw (ErrRow, 0,
X "You have not been authorized to run that menu.");
X attrset (A_NORMAL);
X break;
X }
X
X initmenu (&menu); /* init menu defaults */
X
X /* open menu script file */
X strcpy (filename, findfile (menuname[mptr], ".",
X getenv("MENUDIR"), ""));
X if ((menufile = fopen (filename, "r")) == NULL)
X {
X BEEP;
X mvprintw (20, 0, "Unable to locate (%s) file.",
X menuname[mptr]);
X shutdown ();
X }
X
X
X /*
X ** Return Codes from parsedriver:
X ** NOWAYJOSE - not authorized for this menu.
X */
X parse_rc = parsedriver (menufile, KeyWord, ParseKey, &menu,
X gnames, gfiles, &gindex);
X fclose (menufile);
X
X switch (parse_rc)
X {
X case 0:
X /* success */
X break;
X
X case QUIT:
X shutdown ();
X break;
X
X case MAINMENU:
X /* not tested */
X mptr = 0;
X break;
X
X default:
X if (mptr > 0)
X {
X mptr--; /* return to previous menu */
X continue;
X }
X else
X {
X BEEP;
X attrset (A_REVERSE|A_BOLD);
X mvprintw (ErrRow, 0,
X "You have not been authorized to run that menu.");
X attrset (A_NORMAL);
X shutdown (); /* not authorized for main menu */
X }
X break;
X } /* end switch (parse_rc) */
X
X /* display menu */
X showdriver (KeyWord, ShowKey, &menu);
X
X /*
X ** rundriver will return:
X ** MAINMENU go directly to main menu
X ** PREVIOUSMENU go to previous menu
X ** REPARSE reparse & display current menu
X ** QUIT quit program.
X ** 0 - 99 option number containing sub menu
X ** filename.
X ** GNAMEOFFSET-199 go directly to menu
X ** gnames[exitkey%GNAMEOFFSET]
X */
X exitkey = rundriver (KeyWord, RunKey, ShowKey, ParseKey, &menu,
X &menuoption[mptr], gnames, gfiles, gindex,
X gotorow, gotocol);
X
X clean_menu (&menu); /* free menu space */
X
X
X switch (exitkey)
X {
X case MAINMENU:
X mptr = 0;
X break;
X case PREVIOUSMENU:
X if (mptr > 0) mptr--;
X break;
X case REPARSE:
X break;
X case QUIT:
X break;
X /*
X ** A submenu option has been selected or a goto menu.
X ** exitkey is the option # selected (which is a submenu)
X ** The submenu filename is in menu.option[exitkey]->command
X */
X default:
X if (exitkey >= GNAMEOFFSET) /* goto gname menu */
X strcpy (menuname[++mptr],
X gfiles[exitkey % GNAMEOFFSET]);
X else
X sscanf (menu.option[exitkey]->command, "%s",
X menuname[++mptr]);
X
X menuoption[mptr] = 1;
X break;
X }
X } while (exitkey != QUIT);
X shutdown ();
X}
X
X
X
Xshutdown ()
X{
X refresh ();
X endwin ();
X exit (1);
X}
SHAR_EOF
echo "File Main.c is complete"
chmod 0444 Main.c || echo "restore of Main.c fails"
echo "x - extracting LoadKeys.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > LoadKeys.c &&
Xstatic char Sccsid[] = "@(#)LoadKeys.c 1.7 DeltaDate 1/22/90 ExtrDate 1/22/90";
X
X/* FUNCTION: LoadKeys()
X** Identifies all the recognizable keywords and the
X** function(s) 2b called to process the keyword.
X** ARGS: KeyWord array to hold keywords
X** ParseKey array to hold parse functions
X** ShowKey array to hold display functions
X** RunKey array to hold run functions
X** RETURNS: zilch
X*/
X
X#include "menu.h"
X
XLoadKeys (KeyWord, ParseKey, ShowKey, RunKey)
X
X char KeyWord[][MAXKEYLENGTH];
X int (*ParseKey[])(), (*ShowKey[])(), (*RunKey[])();
X{
X int ParseTitle(), ParseOption(), ParseBanner(), ParseBox(),
X ParseLine(), ParseWindow(), ParseComnt(), ParseUnix(),
X ParseGname(), ParseAuthr(), ParseText(), ParseCursor(),
X ParseSpace(), ParseDefineScreen(), ParInclude(), ParAssign();
X int ShowOption();
X int RunSystem(), RunExit(), RunSetenv(), RunMenu(), RunPopMenu(),
X RunGetInput();
X
X
X/*
X** SECTION 1:
X** Starting with base 1.
X** Identify keywords to be acted upon when found in your
X** menu file.
X** Make sure MAXKEYS is >= the number of entries here.
X*/
X
X strcpy (KeyWord[1], ".TITLE"); /* title line */
X strcpy (KeyWord[2], ".MENU"); /* submenu option */
X strcpy (KeyWord[3], ".SYSTEM"); /* system call option */
X strcpy (KeyWord[4], ".BOX"); /* encase menu in a box */
X strcpy (KeyWord[5], ".BANNER"); /* welcome banner screen */
X strcpy (KeyWord[6], ".LINE"); /* line between title & options */
X strcpy (KeyWord[7], ".WINDOW"); /* window area for options */
X strcpy (KeyWord[8], "###"); /* comment line */
X strcpy (KeyWord[9], ".UNIX"); /* unix command line */
X strcpy (KeyWord[10], ".GNAME"); /* menu name (used in goto menu) */
X strcpy (KeyWord[11], ".AUTHORIZE"); /* login's authorized to run menu */
X strcpy (KeyWord[12], ".TEXT"); /* display text at row and column */
X strcpy (KeyWord[13], ".CURSOR"); /* where to put the cursor */
X strcpy (KeyWord[14], ".EXIT"); /* exit menu program */
X strcpy (KeyWord[15], ".SETENV"); /* set enviroment variable */
X strcpy (KeyWord[16], ".SPACE"); /* put a space between options */
X strcpy (KeyWord[17], ".POPMENU"); /* pop menu option */
X strcpy (KeyWord[18], ".DEFINE_SCREEN");/* define a prompt screen */
X strcpy (KeyWord[19], ".GETINPUT"); /* prompt screen */
X strcpy (KeyWord[20], ".INCLUDE"); /* include a menu file */
X strcpy (KeyWord[21], "*=*"); /* assignment - variable=value */
X
X strcpy (KeyWord[22], ""); /* END OF LIST */
X
X
X/*
X** SECTION 2:
X** Starting with base 1.
X** Identify function names to correspond with above keywords.
X** These functions describe what is to be done when above keyword
X** is found while parsing the "menu file".
X** Every keyword needs a Parse??? function.
X*/
X
X ParseKey[1] = ParseTitle;
X ParseKey[2] = ParseOption;
X ParseKey[3] = ParseOption;
X ParseKey[4] = ParseBox;
X ParseKey[5] = ParseBanner;
X ParseKey[6] = ParseLine;
X ParseKey[7] = ParseWindow;
X ParseKey[8] = ParseComnt;
X ParseKey[9] = ParseUnix;
X ParseKey[10] = ParseGname;
X ParseKey[11] = ParseAuthr;
X ParseKey[12] = ParseText;
X ParseKey[13] = ParseCursor;
X ParseKey[14] = ParseOption;
X ParseKey[15] = ParseOption;
X ParseKey[16] = ParseSpace;
X ParseKey[17] = ParseOption;
X ParseKey[18] = ParseDefineScreen;
X ParseKey[19] = ParseOption;
X ParseKey[20] = ParInclude;
X ParseKey[21] = ParAssign;
X
X
X/*
X** SECTION 3:
X** These functions describe what is to be done to display the
X** option to the screen. The option you loaded into OptionInfo.
X** If set to NULL then the option is not displayed.
X*/
X
X ShowKey[1] = NULL;
X ShowKey[2] = ShowOption;
X ShowKey[3] = ShowOption;
X ShowKey[4] = NULL;
X ShowKey[5] = NULL;
X ShowKey[6] = NULL;
X ShowKey[7] = NULL;
X ShowKey[8] = NULL;
X ShowKey[9] = NULL;
X ShowKey[10] = NULL;
X ShowKey[11] = NULL;
X ShowKey[12] = NULL;
X ShowKey[13] = NULL;
X ShowKey[14] = ShowOption;
X ShowKey[15] = ShowOption;
X ShowKey[16] = NULL;
X ShowKey[17] = ShowOption;
X ShowKey[18] = NULL;
X ShowKey[19] = ShowOption;
X ShowKey[20] = NULL;
X ShowKey[21] = NULL;
X
X
X/*
X** SECTION 4:
X** These functions explain what you want done when the user
X** selects the option on the screen with the corresponding
X** keyword.
X** If set to NULL the keyword becomes unselectable.
X*/
X
X RunKey[1] = NULL;
X RunKey[2] = RunMenu;
X RunKey[3] = RunSystem;
X RunKey[4] = NULL;
X RunKey[5] = NULL;
X RunKey[6] = NULL;
X RunKey[7] = NULL;
X RunKey[8] = NULL;
X RunKey[9] = NULL;
X RunKey[10] = NULL;
X RunKey[11] = NULL;
X RunKey[12] = NULL;
X RunKey[13] = NULL;
X RunKey[14] = RunExit;
X RunKey[15] = RunSetenv;
X RunKey[16] = NULL;
X RunKey[17] = RunPopMenu;
X RunKey[18] = NULL;
X RunKey[19] = RunGetInput;
X RunKey[20] = NULL;
X RunKey[21] = NULL;
X}
SHAR_EOF
chmod 0444 LoadKeys.c || echo "restore of LoadKeys.c fails"
echo "x - extracting parsedrive.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > parsedrive.c &&
Xstatic char Sccsid[] = "@(#)parsedrive.c 1.5 DeltaDate 1/22/90 ExtrDate 1/22/90";
X
X/* FUNCTION: parsedriver()
X** This is the driver routine in parseing the menu
X** file. This function calls the appropriate parse
X** function for that keyword.
X** ARGS: keyword the keyword "AUTHORIZE"
X** menufile the unix menu file
X** menu menu structure
X** gnames holder of goto menu names
X** gfiles holder of goto menu names (menu file)
X** gindex # of gnames
X** RETURNS: 0 success
X*/
X
X#include <curses.h>
X#include "menu.h"
X
X int swin, ewin, longest;
X
Xparsedriver (menufile, KeyWord, ParseKey, menu, gname, gfile, gindex)
X
X FILE *menufile;
X char KeyWord[][MAXKEYLENGTH];
X int (*ParseKey[])();
X struct MenuInfo *menu;
X char gname[][15], gfile[][15];
X int *gindex;
X{
X char keyword[80];
X int rcde, I, KEYFOUND;
X int opnumber = 0; /* last option number */
X
X
X /* Set default .WINDOW area */
X menu->wfcol = 0;
X menu->wlcol = COLS-1;
X menu->wfrow = 0;
X menu->wlrow = LINES-1;
X menu->titlecount = 0;
X menu->optioncount = 0;
X swin = ewin = longest = 0;
X
X /* loop through each keyword */
X rcde = fscanf (menufile, "%s", keyword);
X while (rcde != EOF)
X {
X if (strlen (keyword) >= 80-2)
X {
X BEEP;
X mvprintw (ErrRow-2, 0,
X "Your keyword <%s> is toooo looong. Max = %d",
X keyword, 80-2);
X shutdown ();
X }
X /*
X ** Check if we found a defined keyword
X */
X KEYFOUND = FALSE;
X for (I = 1; I <= MAXKEYS; I++)
X {
X /*
X if (strcmp (keyword, KeyWord[I]) == 0)
X */
X if (strmatch (keyword, KeyWord[I]))
X {
X KEYFOUND = TRUE;
X if (ParseKey[I] != NULL)
X {
X rcde = (*ParseKey[I]) (keyword,
X menufile, menu, KeyWord,
X ParseKey, gname, gfile, gindex,
X &opnumber);
X /*
X ** The return code from each parse
X ** function must be 0 in order to
X ** continue.
X */
X if (rcde != 0) return (rcde);
X }
X break;
X }
X }
X if (!KEYFOUND)
X {
X BEEP;
X mvprintw (ErrRow-2, 0, "ERROR: (%s) Key not found.",
X keyword);
X shutdown ();
X }
X rcde = fscanf (menufile, "%s", keyword);
X }
X
X EndWindow (menu);
X return (0);
X}
SHAR_EOF
chmod 0444 parsedrive.c || echo "restore of parsedrive.c fails"
echo "x - extracting showdriver.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > showdriver.c &&
Xstatic char Sccsid[] = "@(#)showdriver.c 1.2 DeltaDate 10/16/88 ExtrDate 1/22/90";
X
X/* FUNCTION: showdriver()
X** The driver module to initially display the options
X** to the screen.
X** ARGS: keyword the keyword found
X** ShowKey show functions
X** menu menu structure
X** RETURNS: none
X*/
X
X#include <curses.h>
X#include "menu.h"
X
X
Xshowdriver (KeyWord, ShowKey, menu)
X
X char KeyWord[][MAXKEYLENGTH];
X int (*ShowKey[])();
X struct MenuInfo *menu;
X{
X int i, j;
X
X
X
X /*
X ** Loop through options and call apropriate function.
X */
X
X for (i = 0; i < menu->optioncount; i++)
X for (j = 1; j <= MAXKEYS; j++)
X if (strcmp (menu->option[i]->keyword, KeyWord[j]) == 0)
X {
X if (ShowKey[j] != NULL)
X (*ShowKey[j]) (menu, i);
X break;
X }
X refresh ();
X}
SHAR_EOF
chmod 0444 showdriver.c || echo "restore of showdriver.c fails"
echo "x - extracting rundriver.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > rundriver.c &&
Xstatic char Sccsid[] = "@(#)rundriver.c 1.11 DeltaDate 1/22/90 ExtrDate 1/22/90";
X
X/* FUNCTION: rundriver()
X** The driver module to run each selectable option.
X** Runmenu will call the appropriate run function
X** for that keyword.
X** ARGS: keyword the keyword "AUTHORIZE"
X** menufile the unix menu file
X** menu menu structure
X** gnames holder of goto menu names
X** gfiles holder of goto menu names (menu file)
X** gindex # of gnames
X** RETURNS: QUIT exit pgm
X** MAIN go to main menu
X** PREVIOUS go to previous menu
X** index to submenu
X*/
X
X#include <curses.h>
X#include <signal.h>
X#include "menu.h"
X#include "terminal.h"
X
X#define INITMENU 0
X#define GOTOMENU 1
X
Xextern int MAILCALL;
X
X
Xrundriver (KeyWord, RunKey, ShowKey, ParseKey, menu, option, gnames,
X gfiles, gindex, gotorow, gotocol)
X
X char KeyWord[][MAXKEYLENGTH];
X int (*RunKey[])(), *option;
X int (*ShowKey[])();
X int (*ParseKey[])();
X struct MenuInfo *menu;
X char gnames[][15], gfiles[][15];
X int gindex;
X int gotorow;
X int gotocol;
X{
X FILE *fopen(), *fp;
X char *findfile();
X char select[78], command[200];
X char matchstr[60];
X int exitkey, index;
X int i, j;
X int lastopnumber = 0; /* last option # */
X int MATCHED; /* char match flag */
X int ch;
X
X
X /*
X ** What is the last option number ?
X */
X for (i = menu->optioncount-1; i >= 0; i--)
X if (menu->option[i]->opnumber != 0)
X {
X lastopnumber = menu->option[i]->opnumber;
X break;
X }
X
X if (lastopnumber <= 0) return (QUIT); /* no options */
X select[0] = '\0';
X matchstr[0] = '\0';
X
X /*
X ** Loop through options untill user exits menu or selects
X ** another menu.
X */
X for (;;)
X {
X#ifndef ALARM
X if (MAILCALL)
X checkmail ();
X#endif
X
X /* highlight current option */
X/*
X#ifdef BSD
X standout ();
X#else
X attrset (A_REVERSE);
X#endif
X*/
X
X for (i = 1; i <= MAXKEYS && KeyWord[i] != NULL; i++)
X if (strcmp (menu->option[*option-1]->keyword,
X KeyWord[i]) == 0)
X {
X if (ShowKey[i] != NULL)
X {
X /* display option */
X (*ShowKey[i]) (menu, (*option)-1);
X mvaddch (menu->option[(*option)-1]->row,
X menu->option[(*option)-1]->col-1,
X ' ');
X /*
X ** turn on reverse video
X ** maintaining current attributes
X */
X exitkey = slength(menu->option[(*option)-1]->description) + menu->option[(*option)-1]->col + 5;
X for (j = menu->option[(*option)-1]->col-1; j <= exitkey; j++)
X {
X ch = mvinch (menu->option[(*option)-1]->row, j);
X ch |= A_REVERSE;
X mvaddch (menu->option[(*option)-1]->row, j, ch);
X }
X
X }
X break;
X }
X
X#ifdef BSD
X standend ();
X#else
X attrset (A_NORMAL);
X#endif
X
X if (RunKey[i] != NULL)
X exitkey = GetOption (menu->row_cursor, menu->col_cursor,
X select);
X else
X /* so we don't go in a loop */
X exitkey = (exitkey == KEY_UP ||
X exitkey == KeyUp) ? KEY_UP : KEY_DOWN;
X
X if (exitkey == KeyDown) exitkey = KEY_DOWN;
X if (exitkey == KeyUp) exitkey = KEY_UP;
X if (exitkey == KeyTab) exitkey = KEY_TAB;
X if (exitkey == KeyBTab) exitkey = KEY_BTAB;
X if (exitkey == KeyReturn) exitkey = KEY_RETURN;
X if (exitkey == KeyMainMenu) exitkey = KEY_MAINMENU;
X if (exitkey == KeyPrevMenu) exitkey = KEY_PREVMENU;
X if (exitkey == KeyExitMenu) exitkey = KEY_EXITMENU;
X if (exitkey == KeyGname) exitkey = KEY_GNAME;
X
X /* unhighlight current option */
X if (ShowKey[i] != NULL)
X {
X mvaddch (menu->option[(*option)-1]->row,
X menu->option[(*option)-1]->col-1, ' ');
X strcat (menu->option[(*option)-1]->description, " ");
X (*ShowKey[i]) (menu, *option-1);
X menu->option[(*option)-1]->description[strlen(menu->option[(*option)-1]->description)-1] = '\0';
X
X /*
X mvaddch (menu->option[(*option)-1]->row,
X menu->option[(*option)-1]->col +
X strlen (menu->option[(*option)-1]->description)+5,
X ' ');
X */
X }
X
X
X switch (exitkey)
X {
X case KEY_DOWN:
X case 'j':
X *option =*option >= menu->optioncount ? 1 : ++(*option);
X break;
X
X case KEY_UP:
X case 'k':
X *option =*option <= 1 ? menu->optioncount : --(*option);
X break;
X
X case KEY_TAB:
X /* A tab will hop forward four options at a time. */
X if (menu->optioncount > 4)
X {
X *option += 4;
X if (*option > menu->optioncount)
X *option = 1 + *option -
X menu->optioncount - 1;
X }
X else
X *option = *option >= menu->optioncount ? 1 :
X ++(*option);
X break;
X
X case KEY_BTAB:
X /* A back tab will hop backward 4 options at a time. */
X if (menu->optioncount > 4)
X {
X *option -= 4;
X if (*option < 0)
X *option = menu->optioncount - abs(*option);
X }
X else
X *option = *option <= 1 ? menu->optioncount:--(*option);
X break;
X
X /*
X ** This section is to highlight the selected option
X ** before the user presses the return_key to select it.
X */
X case '0':
X case '1':
X case '2':
X case '3':
X case '4':
X case '5':
X case '6':
X case '7':
X case '8':
X case '9':
X sprintf (select, "%s%c", select, exitkey);
X if (matoi (select) < 1 ||
X matoi (select) > lastopnumber)
X {
X /* Invalid Option */
X attrset (A_REVERSE);
X mvprintw (ErrRow, 0, "To select an option enter the option number and press return.");
X attrset (A_NORMAL);
X select[0] = '\0';
X }
X else
X {
X /* find the element cooresponding to opnumber */
X for (i = 0; i < menu->optioncount; i++)
X if (matoi(select) == menu->option[i]->opnumber)
X {
X *option = i+1;
X break;
X }
X }
X break;
X
X case 'A':
X case 'B':
X case 'C':
X case 'D':
X case 'E':
X case 'F':
X case 'G':
X case 'H':
X case 'I':
X case 'J':
X case 'K':
X case 'L':
X case 'M':
X case 'N':
X case 'O':
X case 'P':
X case 'Q':
X case 'R':
X case 'S':
X case 'T':
X case 'U':
X case 'V':
X case 'W':
X case 'X':
X case 'Y':
X case 'Z':
X case ' ':
X /* character matching */
X sprintf (matchstr, "%s%c", matchstr, exitkey);
X MATCHED = FALSE;
X for (i = 0; i < menu->optioncount; i++)
X {
X strcpy (command, menu->option[i]->description);
X upper (command);
X if (strncmp (command, matchstr,
X strlen(matchstr)) == 0)
X {
X MATCHED = TRUE;
X sprintf (select, "%d",
X menu->option[i]->opnumber);
X *option = i + 1;
X break;
X }
X }
X if (!MATCHED)
X strcpy (matchstr, "");
X break;
X
X case KEY_EXITMENU:
X /* check if we have a .EXIT option */
X for (i = 0; i < menu->optioncount; i++)
X if (strcmp (menu->option[i]->keyword, ".EXIT") == 0)
X RunExit (menu, i, KeyWord, ParseKey, ShowKey,
X RunKey, gnames, gfiles, gindex);
X return (QUIT);
X
X case KEY_MAINMENU:
X return (MAINMENU);
X
X case KEY_PREVMENU:
X return (PREVIOUSMENU);
X
X case '!':
X /*
X ** Shell Option.
X ** Prompt user for a command to be executed within a
X ** shell (system(1)).
X */
X select[0] = '\0';
X mvaddch (ErrRow, 0, '!');
X move (ErrRow, 1);
X echo ();
X refresh ();
X#ifdef ALARM
X alarm (0); /* turn off mail check */
X signal (SIGALRM, SIG_IGN);
X#endif
X getstr (select);
X#ifdef ALARM
X if (MAILCALL)
X checkmail ();
X#endif
X noecho ();
X sprintf (command, "%s;runrealid \"%s\";%s;%s",
X#if BSD || SUN
X "clear",
X#else
X "tput clear",
X#endif
X select,
X "echo \"\\n[Press return to continue]\\c\"",
X "read reply");
X reset_shell_mode ();
X system (command);
X reset_prog_mode ();
X move (ErrRow,0);
X clrtoeol ();
X select[0] = '\0';
X matchstr[0] = '\0';
X clearok (stdscr, TRUE);
X break;
X
X case KEY_HELP:
X /*
X ** Show Help Screen Option.
X ** Search directories for a menu.hlp file.
X ** If found display to screen.
X */
X strcpy (command, findfile ("menu.hlp", ".",
X getenv("HELPDIR"), getenv("MENUDIR"),
X ""));
X#ifdef ALARM
X alarm (0); /* turn off mail check */
X signal (SIGALRM, SIG_IGN);
X#endif
X ShowHelp (command, "menu", ErrRow);
X#ifdef ALARM
X if (MAILCALL)
X checkmail ();
X#endif
X clearok (stdscr, TRUE);
X select[0] ='\0';
X matchstr[0] ='\0';
X break;
X
X case KEY_GNAME:
X /*
X ** Goto Menu option
X ** Prompt user for the Gname (goto menu name)
X ** that the user wants to go to.
X ** And then return GNAMEOFFSET + gindex to main.
X ** The > GNAMEOFFSET indicates a goto menu option.
X */
X select[0] = '\0';
X echo ();
X mvprintw (ErrRow, 0, "Goto ");
X#ifdef ALARM
X alarm (0); /* turn off mail check */
X signal (SIGALRM, SIG_IGN);
X#endif
X getstr (select);
X#ifdef ALARM
X if (MAILCALL)
X checkmail ();
X#endif
X noecho ();
X for (i = 0; i < gindex; i++)
X {
X if (strcmp (select, gnames[i]) == 0)
X return (GNAMEOFFSET + i);
X }
X BEEP;
X attrset (A_REVERSE);
X mvprintw (ErrRow, 0, "[%s] not found.", select);
X attrset (A_NORMAL);
X select[0] = '\0';
X matchstr[0] ='\0';
X break;
X
X case KEY_RETURN:
X case KEY_LINEFEED:
X /*
X ** We now take an action based upon what is in
X ** select - that which the user typed in.
X */
X if (select[0] == KeyExitMenu)
X {
X /* check if we have a .EXIT option */
X for (i = 0; i < menu->optioncount; i++)
X if (strcmp (menu->option[i]->keyword,
X ".EXIT") == 0)
X {
X RunExit (menu, i, KeyWord,
X ParseKey, ShowKey, RunKey,
X gnames, gfiles, gindex);
X break;
X }
X return (QUIT);
X }
X if (select[0] == KeyMainMenu) return (MAINMENU);
X if (select[0] == KeyPrevMenu) return (PREVIOUSMENU);
X
X /*
X ** Goto Menu option
X ** Prompt user for the Gname (goto menu name)
X ** that the user wants to go to.
X ** And then return GNAMEOFFSET + gindex to main.
X ** The > GNAMEOFFSET indicates a goto menu option.
X */
X if (select[0] == KeyGname)
X {
X select[0] = '\0';
X echo ();
X mvprintw (ErrRow, 0, "Goto ");
X#ifdef ALARM
X alarm (0); /* turn off mail check */
X signal (SIGALRM, SIG_IGN);
X#endif
X getstr (select);
X#ifdef ALARM
X if (MAILCALL)
X checkmail ();
X#endif
X noecho ();
X for (i = 0; i < gindex; i++)
X {
X if (strcmp (select, gnames[i]) == 0)
X return (GNAMEOFFSET + i);
X }
X BEEP;
X attrset (A_REVERSE);
X mvprintw (ErrRow, 0, "[%s] not found.", select);
X attrset (A_NORMAL);
X select[0] = '\0';
X matchstr[0] ='\0';
X break;
X }
X
X /*
X ** Show Help Screen Option.
X ** Search directories for a menu.hlp file.
X ** If found display to screen.
X */
X if (select[0] == KeyHelp)
X {
X strcpy (command, findfile ("menu.hlp",
X ".", getenv("HELPDIR"),
X getenv("MENUDIR"), ""));
X#ifdef ALARM
X alarm (0); /* turn off mail check */
X signal (SIGALRM, SIG_IGN);
X#endif
X ShowHelp (command, "menu", ErrRow);
X#ifdef ALARM
X if (MAILCALL)
X checkmail ();
X#endif
X clearok (stdscr, TRUE);
X select[0] ='\0';
X matchstr[0] ='\0';
X break;
X }
X
X
X /*
X ** The user has manually typed in a option to be
X ** executed. Execute the appropriate option.
X */
X if (strlen (select) > 0)
X {
X index = matoi (select);
X if (index < 1 || index > lastopnumber)
X {
X /* Invalid Option */
X attrset (A_REVERSE);
X mvprintw (ErrRow, 0, "To select an option enter the option number and press return.");
X attrset (A_NORMAL);
X select[0] = '\0';
X break;
X }
X /* find the element cooresponding to opnumber */
X for (i = 0; i < menu->optioncount; i++)
X if (index == menu->option[i]->opnumber)
X {
X *option = i+1;
X break;
X }
X }
X
X /*
X ** Run the option the user selected.
X */
X for (i = 1; i <= MAXKEYS; i++)
X if (strcmp (menu->option[*option-1]->keyword,
X KeyWord[i]) == 0)
X {
X if (RunKey[i] != NULL)
X {
X#ifdef ALARM
X alarm (0); /* turn off mail */
X signal (SIGALRM, SIG_IGN);
X#endif
X exitkey = (*RunKey[i]) (menu, *option-1, KeyWord,
X ParseKey, ShowKey, RunKey,
X gnames, gfiles, gindex);
X /* .MENU is a special case */
X if (exitkey == SUBMENU)
X return (*option-1);
X if (exitkey == MAINMENU)
X return (MAINMENU);
X if (exitkey == PREVIOUSMENU)
X return (PREVIOUSMENU);
X if (exitkey == QUIT)
X return (QUIT);
X if (exitkey == REPARSE)
X return (REPARSE);
X if (exitkey >= GNAMEOFFSET &&
X exitkey <= GNAMEOFFSET + gindex)
X return (exitkey);
X#ifdef ALARM
X if (MAILCALL)
X checkmail ();
X#endif
X }
X break;
X }
X select[0] = '\0';
X matchstr[0] = '\0';
X break;
X
X default:
X if (exitkey == KeyPopGname && gindex > 0)
X {
X /*
X ** Popup menu for goto names.
X */
X#ifdef ALARM
X alarm (0); /* turn off mail check */
X signal (SIGALRM, SIG_IGN);
X#endif
X popmenu (INITMENU, GOTOMENU, gotorow, gotocol,
X "GOTO MENU", HELPFILE, LINES-2,
X sizeof(gnames[0]), gnames);
X
X move (ErrRow,0);
X clrtoeol ();
X BEEP;
X mvprintw (ErrRow, 0, "Goto what menu ?");
X refresh ();
X exitkey = popmenu (GOTOMENU);
X touchwin (stdscr);
X refresh ();
X#ifdef ALARM
X if (MAILCALL)
X checkmail ();
X#endif
X if (exitkey >= 1 && exitkey <= gindex)
X return (GNAMEOFFSET + exitkey-1);
X }
X
X move (ErrRow,0);
X clrtoeol ();
X mvprintw (ErrRow, 0, "Say What.");
X select[0] = '\0';
X matchstr[0] = '\0';
X break;
X }
X }
X}
X
X
X
X/*
X** My ascii to integer
X** Return -1 if string contains more than digits.
X*/
Xmatoi (s)
X char *s;
X{
X int value;
X
X value = atoi (s);
X while (*s)
X {
X if (*s < '0' || *s > '9')
X return (-1);
X s++;
X }
X return (value);
X}
SHAR_EOF
chmod 0444 rundriver.c || echo "restore of rundriver.c fails"
echo "x - extracting ParseOpton.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ParseOpton.c &&
Xstatic char Sccsid[] = "@(#)ParseOpton.c 1.7 DeltaDate 1/22/90 ExtrDate 1/22/90";
X
X/* FUNCTION: ParseOption()
X** This function parses user selectable options.
X** ARGS: keyword the keyword found
X** menufile the unix menu file
X** menu menu structure
X** gnames holder of goto menu names
X** gfiles holder of goto menu names (menu file)
X** gindex # of gnames
X** RETURNS: 0
X*/
X
X#include <curses.h>
X#include "menu.h"
X
Xextern int swin, ewin, longest;
Xextern int debug;
X
X
XParseOption (keyword, menufile, menu, KeyWord, ParseKey, gnames, gfiles,
Xgindex, opnumber)
X
X char keyword[];
X FILE *menufile;
X struct MenuInfo *menu;
X char KeyWord[][MAXKEYLENGTH];
X int (*ParseKey[])();
X char gnames[][15], gfiles[][15];
X int *gindex;
X int *opnumber;
X{
X struct OptionInfo *malloc();
X char *getval();
X char *fgets(), line[MAXLEN+100];
X int i = 0;
X int j;
X char *ws;
X
X
X if (menu->optioncount >= MAXOPTION)
X {
X BEEP;
X mvprintw (ErrRow-2, 0, "Exceeded maximum allowable options.");
X shutdown ();
X }
X menu->option[menu->optioncount] = malloc (sizeof (struct OptionInfo));
X if (menu->option[menu->optioncount] == NULL)
X {
X BEEP;
X mvprintw (ErrRow-2, 0, "Unable to allocate memory for option.");
X shutdown ();
X }
X
X strcpy (menu->option[menu->optioncount]->keyword, keyword);
X
X /*
X ** Read in option command
X ** strcat continuation lines
X */
X fgets (line, BUFSIZE, menufile);
X line[strlen(line)-1] = '\0'; /* get rid of \n */
X while (line[strlen(line)-1] == '\\')
X {
X if (strlen(line) >= MAXLEN)
X {
X BEEP;
X mvprintw (ErrRow-2, 0,
X "Option command is too long. Max = %d",MAXLEN);
X shutdown ();
X }
X line[strlen(line)-1] = '\n'; /* replace \ with \n */
X fgets (line+strlen(line), BUFSIZE, menufile);
X line[strlen(line)-1] = '\0'; /* get rid of \n */
X }
X strcpy (menu->option[menu->optioncount]->command, line);
X if (debug)
X {
X fprintf (stderr, "\n[ParseOpton] <%s> command=:%s:",
X keyword, menu->option[menu->optioncount]->command);
X fflush (stderr);
X }
X
X /*
X ** Read in option description
X */
X fgets (line, BUFSIZE+1, menufile);
X line[strlen(line)-1] = '\0';
X for (j = 0, i = 0; i < strlen (line); j++, i++)
X if (line[i] == '$')
X {
X char *sptr, *b4ptr;
X
X sptr = b4ptr = line+i;
X strcpy (menu->option[menu->optioncount]->description+j,
X getval (&sptr, '$'));
X i += (int)(sptr - b4ptr);
X j += strlen (menu->option[menu->optioncount]->description+j) - 1;
X i--;
X }
X else
X {
X menu->option[menu->optioncount]->description[j] = line[i];
X }
X menu->option[menu->optioncount]->description[j] = '\0';
X
X
X /*
X ** Determine length of longest option
X */
X if (slength (menu->option[menu->optioncount]->description) > longest)
X longest = slength(menu->option[menu->optioncount]->description);
X
X /* set option number 2b displayed */
X (*opnumber)++;
X menu->option[menu->optioncount]->opnumber = *opnumber;
X
X menu->optioncount++;
X ewin++;
X return (0);
X}
SHAR_EOF
chmod 0444 ParseOpton.c || echo "restore of ParseOpton.c fails"
echo "x - extracting ParseBaner.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ParseBaner.c &&
Xstatic char Sccsid[] = "@(#)ParseBaner.c 1.4 DeltaDate 11/13/88 ExtrDate 1/22/90";
X
X/* FUNCTION: ParseBanner()
X** Parses the "BANNER" keyword.
X** RETURNS: 0
X*/
X
X#include <curses.h>
X#include "menu.h"
X
X
XParseBanner (keyword, menufile, menu, KeyWord, ParseKey, gnames, gfiles,
X gindex, opnumber)
X
X char keyword[];
X FILE *menufile;
X struct MenuInfo *menu;
X char KeyWord[][MAXKEYLENGTH];
X int (*ParseKey[])();
X char gnames[][15], gfiles[][15];
X int *gindex;
X int *opnumber;
X{
X static int onetime = FALSE; /* show only 1 time */
X int row, col, rstart, rstop, cstart, cstop;
X int ulc=0, llc=0, linecount, increment;
X char flag[5], upper[4][30], lower[4][30];
X
X
X fscanf (menufile, "%d", &linecount);
X
X/*
X** Load the input banner text into upper and lower arrays.
X*/
X
X for (row = 1; row <= linecount; row++)
X {
X fscanf (menufile, "%s", flag);
X if (strncmp (flag, ".U", 2) == 0)
X {
X fgets (upper[ulc], 80, menufile);
X upper[ulc][strlen(upper[ulc])-1] = '\0';
X ulc++;
X }
X else
X {
X fgets (lower[llc], 80, menufile);
X lower[llc][strlen(lower[llc])-1] = '\0';
X llc++;
X }
X }
X
X if (onetime)
X return (0);
X onetime++;
X
X#ifdef BSD
X standout ();
X#else
X attrset (A_STANDOUT);
X#endif
X for (rstart = 24/2-1, rstop = 24/2+1,
X cstart = COLS/2-2, cstop = COLS/2+1;
X rstart >= 0 && rstop <= 23 && cstart >= 0 && cstop <= COLS-1;
X rstart--, rstop++, cstart-=3, cstop+=3)
X {
X for (row = rstart; row <= rstop; row++)
X {
X if (row == rstart || row == rstop)
X {
X for (col = cstart; col <= cstop; col++)
X mvaddch (row, col, BORDERCHAR);
X }
X else
X {
X mvaddch (row, cstart, BORDERCHAR);
X mvaddch (row, cstop, BORDERCHAR);
X }
X }
X refresh ();
X }
X
X increment = 2;
X for (rstart = rstart+3, rstop=rstop-2, cstart = cstart+1, cstop = cstop-1;
X cstart >= 0 && cstop <= COLS-1;
X rstart++, rstop--, cstart-=increment, cstop+=increment)
X {
X for (row = 1; row <= 23; row++)
X {
X if (row < rstart || row > rstop)
X {
X for (col = cstart; col <= cstart+increment; col++)
X mvaddch (row, col, BORDERCHAR);
X for (col = cstop-increment; col <= cstop; col++)
X mvaddch (row, col, BORDERCHAR);
X }
X else
X {
X mvaddch (row, cstart, BORDERCHAR);
X mvaddch (row, cstop, BORDERCHAR);
X }
X }
X refresh ();
X }
X
X#ifdef BSD
X standout ();
X#else
X attrset (A_REVERSE);
X#endif
X for (row = 0; ulc > 0; row++, ulc--)
X mvprintw (row+4, COLS/2-strlen(upper[row])/2-1, "%s", upper[row]);
X for (row = 0; llc > 0; row++, llc--)
X mvprintw (row+17, COLS/2-strlen(lower[row])/2-1, "%s", lower[row]);
X
X mvprintw (23, 27, "Press return to continue");
X move (23,0);
X getch ();
X refresh ();
X#ifdef BSD
X standend ();
X#else
X attrset (A_NORMAL);
X#endif
X move (0,0); clrtobot ();
X return (0);
X}
SHAR_EOF
chmod 0444 ParseBaner.c || echo "restore of ParseBaner.c fails"
echo "x - extracting ParseTitle.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ParseTitle.c &&
Xstatic char Sccsid[] = "@(#)ParseTitle.c 1.8 DeltaDate 1/22/90 ExtrDate 1/22/90";
X
X/* FUNCTION: ParseTitle()
X** Parses keyword "TITLE".
X** ARGS: keyword the keyword "TITLE"
X** menufile the unix menu file
X** menu menu structure
X** gnames holder of goto menu names
X** gfiles holder of goto menu names (menu file)
X** gindex # of gnames
X** RETURNS: 0
X*/
X
X#include <curses.h>
X#include "menu.h"
X
X
Xextern int MAILCALL;
Xextern int mailrow;
Xextern int mailcol;
X
X
XParseTitle (keyword, menufile, menu, KeyWord, ParseKey, gnames, gfiles,
X gindex, opnumber)
X
X char keyword[];
X FILE *menufile;
X struct MenuInfo *menu;
X char KeyWord[][MAXKEYLENGTH];
X int (*ParseKey[])();
X char gnames[][15], gfiles[][15];
X int *gindex;
X int *opnumber;
X{
X char *fgets(), line[201];
X char *getenv();
X char *getval();
X char section[3][201]; /* section[0] = left justified */
X /* section[1] = centered */
X /* section[2] = right justified */
X int i = 0; /* index into line */
X int j; /* index into section */
X int k, row, col;
X char *ws;
X int mailsection=999; /* section $MAIL was found */
X /* we set to 999 so sub menus */
X /* that don't have a $MAIL wont */
X /* recalculate mailcol */
X
X
X
X fgets (line, 200, menufile);
X
X/*
X** Get title line
X*/
X fgets (line, 200, menufile);
X line[strlen(line)-1] = '\0';
X
X section[0][0] = section[1][0] = section[2][0] = '\0';
X
X/*
X** Now we break input line into left, center, and right sections
X** Loop through each section.
X*/
X
X for (k = 0; k <= 2; k++)
X {
X /* Loop through each character of line until we find next section */
X for (j = 0; i < strlen (line) && strncmp (line+i, "...", 3) != 0;
X i++, j++)
X {
X if (strncmp (line+i, "$DATE", 5) == 0)
X {
X sysdate (section[k]+j, "mm/dd/yy");
X j += 7;
X i += 4;
X }
X else
X if (strncmp (line+i, "$TIME", 5) == 0)
X {
X systime (section[k]+j, "HH:MM zz");
X j += 7;
X i += 4;
X }
X else
X if (strncmp (line+i, "$MAIL", 5) == 0)
X {
X /*
X ** User wants 2b notified when mail arrives.
X ** The mailfile is located in enviroment $MAIL
X ** if the mailfile exists and size is greater than zero
X ** mailfile = getenv("$MAIL")
X ** We need to process entire line b4 we find mailcol
X */
X MAILCALL = TRUE;
X strcpy (section[k]+j, "mAiL"); /* unique ? */
X mailrow = menu->titlecount;
X mailsection = k;
X i += 4; /* get past $MAIL */
X j += 3; /* for "MAIL" */
X }
X else
X /*
X ** A environment variable
X */
X if (line[i] == '$')
X {
X char *sptr, *b4ptr;
X
X sptr = b4ptr = line+i;
X strcpy (section[k]+j, getval (&sptr, '$'));
X i += (int)(sptr - b4ptr);
X j += strlen (section[k]+j) - 1;
X i--;
X }
X else
X section[k][j] = line[i];
X }
X section[k][j] = '\0';
X i += 3;
X }
X
X if (menu->titlecount >= MAXTITLE)
X {
X BEEP;
X mvprintw (ErrRow, 0, "Number of Title lines exceed the maximim.");
X shutdown ();
X }
X (menu->titlecount)++;
X (menu->wfrow)++; /* reduce window size to center in */
X
X
X/*
X** Now we display the three sections to the screen
X*/
X
X for (k = 0; k <= 2; k++)
X {
X/*
X** First we must find out what column to start displaying on.
X** Taking into account the terminal attribute characters.
X*/
X switch (k)
X {
X case 0:
X /* left justified */
X row = menu->titlecount - 1;
X col = 0;
X break;
X case 1:
X /* center */
X for (i = 0, j = 0; section[k][i] != '\0'; i++)
X if (section[k][i] == '\\') j++;
X col = COLS/2-(strlen(section[k])-j*2)/2;
X col -= (((strlen(section[k])-j*2) % 2) == 0) ? 0 : 1;
X row = menu->titlecount - 1;
X move (menu->titlecount-1, i);
X break;
X case 2:
X /* right justify */
X for (i = 0, j = 0; section[k][i] != '\0'; i++)
X if (section[k][i] == '\\') j++;
X row = menu->titlecount - 1;
X col = COLS-strlen(section[k])+j*2;
X break;
X } /* end switch */
X
X if (MAILCALL && mailsection == k)
X {
X /* find mailcol - remember the attributes */
X for (i = 0, j = 0; section[k][i] != '\0' &&
X strncmp (section[k]+i, "mAiL", 4) != 0; i++)
X if (section[k][i] == '\\') j++;
X mailcol = i - j*2 + col; /* for \R */
X memcpy (section[k]+i, " ", 4); /* get rid of mAiL */
X }
X
X displaytext (row, col, section[k]);
X } /* end for loop */
SHAR_EOF
echo "End of part 3"
echo "File ParseTitle.c is continued in part 4"
echo "4" > s2_seq_.tmp
exit 0
More information about the Alt.sources
mailing list