DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦981f66693⟧ TextFile

    Length: 6487 (0x1957)
    Types: TextFile
    Notes: UNIX file
    Names: »main.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦f4b8d8c84⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »unimenu/src/menu/main.c« 

TextFile


#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 */
}