File:  [MW Coherent from dump] / coherent / b / etc / Build_401 / kbdinstall.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:35 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * kbdinstall.c
 * 07/26/92
 * Keyboard support installation, including virtual console questions.
 *
 * cc kbdinstall.c -lcurses [-lterm]
 * Usage: kbdinstall [ -bu ]
 * Options:
 *	-b	invoked from build
 *	-u	invoked from update install, don't patch running system
 */

#include <stdio.h>
#include <string.h>
#include <curses.h>
#include "build0.h"

extern	char	*fgets();
extern	char	*malloc();

#define	VERSION	"3.4"			/* Version number.	*/
#define	KBDDIR	"/conf/kbd"		/* Keyboard directory.	*/
#define	KBDLIST	"/conf/kbd/.list"	/* List of keyboards.	*/
#define	KBDFILE	"/tmp/kbd"		/* File of driver object name(s) */
#define	KBDY	4			/* y-coordinate of keyboard list. */
#define	NLINE	512			/* Line length.		*/
#define	NKBDS	(24-KBDY)		/* Max number of keyboards */
#define	USAGE	"Usage: /etc/kbdinstall [-bu]\n"

/* Keyboard list file entries. */
typedef	struct	kline	{
	int	k_loadable;		/* True: loadable tables supported */
	char	*k_driver;		/* Name of keyboard driver object */
	char	*k_table;		/* Keyboard table name	*/
	char	*k_desc;		/* Keyboard description	*/
}	KLINE;

/* Forward */
char	*copystr();
void	display_line();
void	display_rev();
void	fatal();
void	my_fatal();			/* handles window cleanup */
void	format_error();
void	nonfatal();
void	my_nonfatal();			/* handles window cleanup */
void	read_klist();

/* Globals. */
int	bflag;				/* Invoked from build.	*/
char	buf[NBUF];			/* Input buffer.	*/
KLINE	klist[NKBDS];			/* Keyboard list.	*/
int	nkbds;				/* Number of keyboards.	*/
int	initflag;			/* Curses initialized.	*/
int	uflag;				/* Invoked from update.	*/
int	virtual;			/* Virtual consoles wanted */
int	default_entry = -1;		/* Which entry to default to */
int	color_sessions;			/* number of color sessions */
int	mono_sessions;			/* number of mono sessions */

main(argc, argv) int argc; char *argv[];
{
	register int n, c, i;
	char *s;

	/* Process command line options. */
	while (argc > 1 && argv[1][0] == '-') {
		for (s = &argv[1][1]; *s != '\0'; s++) {
			switch (*s) {
			case 'b':	++bflag;			break;
			case 'u':	++uflag;			break;
			case 'V':	nonfatal("V%s", VERSION);	break;
			default:
				fprintf(stderr, USAGE);
				exit(1);
			}
		}
		--argc;
		++argv;
	}

	if (bflag && uflag) {
		fprintf(stderr, USAGE);
		exit(1);
	}

	/* Initialize screen and terminal modes. */
	initscr();
	initflag = 1;
	noecho();
	raw();
	clear();

#if _I386
	if (bflag || uflag) {
		/*
		 * If 386 and invoked from "build" or "install", output some
		 * info about virtual consoles.  Prompt the user if he/she
		 * wants V.C. support and set variable "virtual" as needed.
		 */
		mvaddstr(0, 0,
"This release of COHERENT supports multiple simultaneous sessions on the");
		mvaddstr(1, 0,
"system console.  This feature, known as virtual consoles, supports both");
		mvaddstr(2, 0,
"monochrome and color video cards (text mode only) with multiple \"login\"");
		mvaddstr(3, 0,
"sessions on each, depending upon your hardware configuration.  If you have");
		mvaddstr(4, 0,
"both color and monochrome adapters on your system, you can run multiple");
		mvaddstr(5, 0,
"sessions on each of them at the same time.");
		mvaddstr(6, 0,
"Virtual console support only works with systems which have at least one");
		mvaddstr(7, 0,
"megabyte of usable system memory, and with keyboards which are 100% IBM AT");
		mvaddstr(8, 0,
"hardware compatible.  If you are using a low cost clone keyboard which is not");
		mvaddstr(9, 0,
"100% hardware compatible (i.e., does not correctly support scan code set 3");
		mvaddstr(10, 0,
"operation), you will not be able to use COHERENT's virtual console features,");
		mvaddstr(11, 0,
"nor will you be able to use COHERENT's \"loadable\" keyboard driver.");
		mvaddstr(13, 0,
"Do you wish to include support for virtual consoles? [y or n] ");
		refresh();
		echo();
		for (;;) {
			c = getch();
			switch (c) {
			case 'Y':
			case 'y':
				++virtual;
				break;
			case 'N':
			case 'n':
				break;
			default:
				continue;
			}
			noecho();
			refresh();
			mvaddstr(14, 0, "Please hit <Enter> ...");
			refresh();
			while ((c = getch()) != '\r' && c != '\n')
				;
			mvaddstr(14, 0, "One moment, please ....");
			refresh();
			break;
		}
		clear();
	}
#endif

	/* Read the keyboard list file. */
	read_klist();

	/* Display instructions at top of screen. */
	mvaddstr(0, 0,
"Select the entry below which indentifies your keyboard type.  Hit <Enter> to");
	mvaddstr(1, 0,
"select the highlighted entry.  Hit <space> to move to the next entry.");

	/* Display choices. */
	for (n = 0; n < nkbds; n++)
		display_line(n);

	/* Interactive input loop: display choice n highlighted. */
	for (n = (default_entry >= 0) ? default_entry : 0; ; ) {
		display_rev(n);		/* display default choice in reverse */
		refresh();
		switch (c = getch()) {
		case 'A':		/* n.b.:  ESC [ A is Up Arrow key */
			if (--n < 0)
				n = nkbds - 1;
			continue;
		case ' ':		/* space/Down Arrow: try next choice */
		case 'B':		/* n.b.:  ESC [ B is Down Arrow key */
			if (++n >= nkbds)
				n = 0;
			continue;
		case '\n':
		case '\r':		/* enter: take default value */
			break;
		default:
			continue;	/* ignore */
		}
		break;			/* done, choice is in n */
	}
	endwin();

	/*
	 * Execute the keyboard table file only if invoked by the user
	 * (i.e., not Build nor Update).
	 */
	if (!uflag && !bflag) {
		if (klist[n].k_loadable) {
			sprintf(buf, "%s/%s", KBDDIR, klist[n].k_table);
			if (system(buf) != 0)
			    fatal("Loadable keyboard tables not supported by this kernel", buf);
		} else {
			fatal("Selected entry is not a loadable keyboard table");
		}
		exit(0);
	}

	/*
	 * Build or Update:
	 *	Store keyboard driver name in file specified by KBDFILE.
	 *	If loadable keyboard table selected, store name of keyboard
	 *	table into /tmp/drvld.all (386),
	 *	or to /etc/drvld.all (286 update).
	 */

/*
 * COH 4.2 adds vt support with non-loadable tables. If such a keyboard is
 * selected by the user, then the table field will be "nl". In this instance,
 * we don't want to build a drvld entry.  bob h 7/14/93
 */
	if (klist[n].k_loadable) {
		sprintf(buf,"/bin/echo %s >%s",(virtual)?klist[n].k_driver : "nkb.a mm.a", KBDFILE);
		if(strcmp(klist[n].k_table,"nl")){
			sprintf(buf,"/bin/echo %s/%s >>%s/drvld.all",
				KBDDIR, klist[n].k_table,
#if _I386
				"/tmp");

#else
				(bflag) ? "/tmp" : "/etc");
#endif

		}
	} else {
		sprintf(buf, "/bin/echo %s mm.a >%s",
			klist[n].k_driver, KBDFILE);
	}
	sys(buf, S_FATAL);

	printf(	"Your keyboard selection will not take effect until after\n"
		"your system %s has completed and the system has rebooted!\n\n",
		bflag ? "installation" : "update");

	/*
	 * During installation, if V.C.'s are in use,
	 * don't provide the console device.
	 */
	if (bflag && !virtual) {
		sprintf(cmd, "/bin/echo \"1lPconsole\" >/tmp/ttys");
		sys(cmd, S_FATAL);
	}

again:
	mono_sessions = 0;
	if (virtual && yes_no("\nDoes this system have a monochrome (i.e., MDA) video adapter")) {
		mono_sessions = get_int(1, 4,
		"How many active virtual console sessions would you like on your\n"
		"monochrome video adapter card [1-4]?");
		for (i = 0; i < mono_sessions; ++i) {
			sprintf(cmd, "/bin/echo \"1lPmono%d\" >>%s/ttys",
#if _I386
				i, "/tmp");
#else
				i, (bflag) ? "/tmp" : "/etc");
#endif
			sys(cmd, S_FATAL);
		}
	}

	color_sessions = 0;
	if (virtual && yes_no("\nDoes this system have a color (i.e., CGA/EGA/VGA) video adapter")) {
		color_sessions = get_int(1, 4,
		"How many active virtual console sessions would you like on your\n"
		"color video adapter card [1-4]?");
		for (i = 0; i < color_sessions; ++i) {
			sprintf(cmd, "/bin/echo \"1lPcolor%d\" >>%s/ttys",
#if _I386
				i, "/tmp");
#else
				i, (bflag) ? "/tmp" : "/etc");
#endif
			sys(cmd, S_FATAL);
		}
	}

	if (virtual && (mono_sessions + color_sessions) == 0) {
		printf("\nYou must select either a monochrome or a color video adapter!\n");
		goto again;
	}

	/*
	 * After linking new kernel, will patch it for number of mono
	 * and color sessions.  Do the patch even if number of sessions
	 * for the given type is zero.
	 */
	if (virtual) {
		sprintf(cmd,
	  "echo /conf/patch /mnt/coherent VTMONO=%d:c VTVGA=%d:c >> %s\n",
		  mono_sessions, color_sessions, PATCHFILE);
		sys(cmd, S_FATAL);
	}

	/* Done. */
	exit(0);
}

/*
 * Allocate a copy of a string and return a pointer to it.
 */
char *
copystr(s) register char *s;
{
	register char *cp;

	if ((cp = malloc(strlen(s) + 1)) == NULL)
		my_fatal("no space for string \"%s\"");
	strcpy(cp, s);
	return cp;
}

/*
 * Display choice n.
 */
void
display_line(n) register int n;
{
	mvaddstr(KBDY+n, 12, klist[n].k_desc);
}

/*
 * Display choice n in reverse video.
 */
void
display_rev(n) int n;
{
	static int last = -1;

	if (last != -1)
		display_line(last);	/* redisplay last in normal */
	standout();
	display_line(n);		/* display n in reverse */
	standend();
	last = n;
}

/*
 * Cry and die.
 */
/* VARARGS */
void
my_fatal(s) char *s;
{
	if (initflag)
		endwin();
	fprintf(stderr, "kbdinstall: %r\n", &s);
	exit(1);
}

/*
 * Issue nonfatal informative message.
 */
/* VARARGS */
void
my_nonfatal(s) char *s;
{
	if (initflag)
		endwin();
	fprintf(stderr, "kbdinstall: %r\n", &s);
}

/*
 * Read a file containing keyboard file names and descriptions,
 * build a keyboard list.
 *
 * Format of input is:
 *	# Comment line
 * or
 *	Default <tab> Loadable <tab> Driver <tab> Table <tab> Descr.
 */
void
read_klist()
{
	register FILE *fp;
	register unsigned char *s, *s1;

	if ((fp = fopen(KBDLIST, "r")) == NULL)
		my_fatal("cannot open \"%s\"", KBDLIST);
	while (fgets(buf, sizeof buf, fp) != NULL) {
		if (buf[0] == '#')
			continue;		/* ignore comments */
		if (nkbds == NKBDS) {
			my_nonfatal("more than %d keyboard entries", NKBDS-1);
			continue;
		}

		/*
		 * Parse input lines and emit error messages if input bad.
		 */
		if (buf[0] == 'Y' || buf[0] == 'y')
			default_entry = nkbds;
		if ((s = strchr(buf, '\t')) == NULL) {
			format_error(buf);
			continue;
		}

		switch (*++s) {
		case 'Y': case 'y':
			klist[nkbds].k_loadable = TRUE;
			break;
		case 'N': case 'n':
			if ((!bflag && !uflag) || virtual)
				continue;	/* ignore if interactive ... */
			break;			/* ... or if VC's desired */
		default:
			format_error(buf);
			continue;
		}
		if ((s = strchr(++s, '\t')) == NULL) {
			format_error(buf);
			continue;
		}
		if ((s1 = strchr(++s, '\t')) == NULL) {
			format_error(buf);
			continue;
		}
		*s1++ = '\0';
		klist[nkbds].k_driver = copystr(s);	/* keyboard driver */
		if ((s = strchr(s1, '\t')) == NULL) {
			format_error(s1);
			continue;
		}
		*s++ = '\0';
		klist[nkbds].k_table = copystr(s1);	/* keyboard table */
		if ((s1 = strchr(s, '\n')) == NULL) {
			my_nonfatal("no newline in \"%s\"", s);
			continue;
		}
		*s1 = '\0';
		klist[nkbds].k_desc = copystr(s);	/* kbd description */

		nkbds++;
	}
	fclose(fp);
}

/*
 * Input error found: display an error message and continue.
 */
void
format_error(line)
char *line;
{
	my_nonfatal("Input format error found in \"%s\" -- ignored.", line);
}

/* end of kbdinstall.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.