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