|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 6487 (0x1957)
Types: TextFile
Notes: UNIX file
Names: »main.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »unimenu/src/menu/main.c«
#define MAINLINE
/*
* Copyright (c) 1984
*
* LANTECH Systems, Incoroporated
*
* All rights reserved
*/
/* Program: Menu
*
* Purpose: UNIX(tm)-style command interpreters have long been
* accused of being "expert-friendly", and inaccessable
* to novice users. This menu-driven shell attempts
* to provide a useful, easy-to-use, easy-to-maintain
* interface to what Micheal McChesney calls "the Operating
* System." (I.e. all the software other than applications
* one may purchase.)
*
* History: Original Coding June 84, Robert Adams
* Added "prompt" support July 84. -Rha
* Added "dump" support July 84. -Rha
*
* Code Files: This file (main.c) includes the main routine, and all
* mainline data declarations required. (Hopefully few.)
* parse.c contains code to accept RFC-822 style input.
* input.c decides which option the user has selected
* based upon a minimally unique abbreviation.
* (Not implemented yet. -- Rha, July 84)
* io.c contains special-purpose i/o routines.
* subs.c contains general-purpose i/o routines.
* July 84 Removed parse.c (it was too monolithic.)
* Added parslin.c init.c and getlin.c. They perform
* the memory initialization. Added uninit.c It frees
* all the memory alloc-ed for a given menu pointer.
*
* Include Files:
* defs.h contains exact definition of data structures.
* return codes from the RFC-822 parser, and return
* values from get_choice() (located in input.c)
*/
/*
* Function: main(argc,argv)
*
* Purpose: Initialize data structures, process arguments
* provide operational loop.
*
* Passed: Information is passed to this code two ways.
* First, (and the firstly) through argv[] from the
* O/S. Secondly, when this code is a child of fork(),
* then information is passed through the data elements.
* See "Notes: " below and also execute() in xqt.c
*
* Returns: Three possible values (via exit()):
* (-1): It is time to get out. ALL levels of "fork"
* need to exit(-1). If you have received
* a -1 from a child, then exit() with a -1.
* This comes from certain fatal errors, and
* a "get me the hell out of here" request
* from the user.
* (0): Normal exit, i.e. the user requested that he
* not view this menu any more.
* (1): Exactly the same as 0.
* (value): Normal exit again, but this time the
* user asked to go back "this many" levels".
* (Not supported.)
* This will be in the range of 2 - oo
*
* Called by: O/S.
*
* Calls: Just about everybody. List to be compiled.
*
* Notes: main() is not the only entry point to this code.
* Most everything is implicity re-started (in execute)
* if we are the child of a fork.
* Check out execute() for more info.
*
* History: Original Coding June 1984 by Robert Adams
* Prompt user for menu name: July 84, Robert Adams
* Changed screen display mechanism: March 85, Dan Mitchell
*/
#include "defs.h" /* get definitions */
#include <signal.h>
#include <setjmp.h>
char *MCFile = NULL; /* Menu Control File */
int *Scrnbuf = NULL;
char DefMCF[] = "/usr/local/menus/start"; /* default MCF */
W2B SCR_SIZ;
main (argc, argv)
int argc; /* arg count from O/S */
char *argv[]; /* arg array from same */
{
struct menu_f *menu = NULL; /* current menu to deal with */
struct menu_f *init (); /* set up data-structure */
struct menu_f *execute (); /* re-set data structure */
char *charp; /* scratch */
char buf[55]; /* storage for same */
char *strchr (); /* acquire same */
char *sbrk();
char *getenv();
int choice; /* user's choice */
int onintr(); /* what to do? */
Scrnbuf = (int *) sbrk((SCR_WID * SCR_LEN) * sizeof(int));
if ( Scrnbuf == (int *) -1 )
{
printf("Not enough memory for screen buffer\n");
_exit(1);
}
SCR_SIZ.bytes.low = SCR_WID;
SCR_SIZ.bytes.high = SCR_LEN;
if ( setwin() < 0 )
{
printf("This version of menu must run in a window\n");
_exit(1);
}
/*
* Looking for MC File. If not entered, prompt for it.
*/
if (argc < 2)
{
if ( (MCFile = getenv("MENU")) == NULL)
MCFile = DefMCF;
}
else
MCFile = argv[1];
menu = init (MCFile);
if (menu == NULL)
{
printf ("Invalid Input File.\n");
_exit (-1);
}
/* When we come back, come back here. */
/* don't do it. we could wind up without a valid menu control
* block if they interrupt within init() - drm
* besides, we're now doing all keyboard input in raw mode...
*
* setjmp(restart);
*/
signal(SIGINT, onintr);
/* Start of operational loop */
while (1)
{
/* Display menu choices. */
screen (menu);
/* User must choose a menu selection. */
/* if ( menu->m_prompt )
* status(menu->m_row + 8, menu -> m_prompt);
* else
* status(menu->m_row + 8, sel_msg);
*/
pcurs(24, 80);
while ((choice = get_choice (menu)) == CHINVLD)
{
if (menu -> m_bad)
status(menu->m_row + 8, menu->m_bad);
}
switch (choice)
{
/* exec and help are really the same thing */
case CHEXEC:
case CHHELP:
menu = execute (menu);
/* we might now be a child, and menu
pointing to new data. */
continue;
#ifdef DUMPS
case CHDUMP:
{
char *cp;
int i;
charp = menu -> m_current;
if (charp == NULL || *charp == EOS
|| *charp == '\n')
{
printf ("File to save to? ");
i = read(0, buf, 50);
if (i <= 0 || buf[0] == '\n' )
continue;
buf[i-1] = '\0';
charp = buf;
}
dump (charp, menu, 1);
continue;
}
#endif
case CHRPLOT: /* just wants to do it again. */
continue;
case CHBACK: /* back one level, back
more levels not
supported yet. */
cls();
#ifdef DEBUG
printf("main: exiting");
read(0, buf, 1);
#endif
_exit (0); /* get_choice itself may
exit, instead of
passing the info back
up. I havent decided
yet. */
default: /* shouldnt get here. */
x (TRUE, "main: switch (choice)");
/* will exit(-1); */
}
}
}
/*
* Function: onintr()
*
* Called by: Signal routine.
*
* Purpose: Restart loop.
*/
static int onintr()
{
char buf;
signal(SIGINT,onintr);
printf("\nInterrupt.\nQuit? [y or n] ");
to_raw();
read(0, &buf, 1);
to_cooked();
if ( buf == 'y' || buf == 'Y' )
_exit(0);
/* see note in main() - drm
longjmp(restart, 0);
*/
}
abort()
{
kill(getpid(), SIGQUIT); /* commit suicide, force a core dump */
_exit(-1); /* justin case */
}