From: pjc@pcbox.UUCP (Paul J. Condie) Newsgroups: alt.sources Subject: menu(1) part 3 of 11 Message-ID: <425@pcbox.UUCP> Date: 6 Apr 90 17:37:40 GMT #!/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 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 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 X#include 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 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 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 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