kfeature version 1.1 (Part 1 of 1)

Gil Kloepfer Jr. gil at limbic.ssdl.com
Wed Dec 12 04:26:42 AEST 1990


The following is an updated shar archive of kfeature, a program which
allows shell-level modification of some kernel features in the
UNIX-pc 3.51m kernel.  Many thanks to Bruce Lilly for sending his
patches along!

- Cut Here - - Cut Here - - Cut Here - - Cut Here - - Cut Here -

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README README.BRUCE kfeature.1 kfeature.c
# Wrapped by gil at limbic on Tue Dec 11 11:25:21 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(3648 characters\)
sed "s/^X//" >README <<'END_OF_README'
XREADME file for kfeature version 1.1  Tue Dec 11 11:08:45 CST 1990
X(C)1990 Gil Kloepfer, Jr.  ICUS Software Systems
X
XNew Features
X------------
X
XThanks to some patches mailed to me by Bruce Lilly, some bugs have been
Xfixed and some additional functionality has been added, as outlined below:
X
X	1.  Support has been added for ANSI-type compilers (specifically,
X	    GNU C).
X
X	2.  Bugs concerning the size and contents of certain kernel
X	    variables has been more thoroughly checked and they should
X	    now be in conformance with the actual symbols.  This caused
X	    kfeature not to do what it was supposed to do in some cases.
X
X	3.  Checking has been added to assure that the user is on the
X	    console.  This should probably be #ifdef'd .. if you agree,
X	    send me e-mail and I (or Bruce) will add that functionality
X
XI want to thank Bruce for sending along some very well-thought-out
Xpatches for the program.  I'm not able to test them not having a
X3B1 up-and-running anymore, but I will be happy to coordinate the
Xchanges and fixes to the program.
X
XSee INFO.BRUCE for information Bruce mailed along to me regarding
Xhis patches (as well as his e-mail address(es)).
X
X
XDescription & Operation
X-----------------------
X
Xkfeature is a program which allows one to enable/disable the "special"
Xkernel features under program control (rather than CAPS-CTL-SHIFT-f_key).
XThis allows the system to be booted in a more comfortable default condition
Xthan currently exists, if desired.
X
XNote that kfeature needs to be run as root.  Therefore, it is recommended
Xthat it be s-bitted to "root".  If you don't want users to run it, make
Xit s-bit root, but allow world no-access.  It will help save your sanity
Xlater, perhaps.
X
Xkfeature allows the modification of the following kernel features:
X
X	capctrl		Exchange the CAPS-LOCK and right control key's
X			functions
X
X	meta		Enable the left control key as a meta key
X
X	saveub		Save the screen unblanking character and enter
X			it into the input stream (rather than the default
X			action of discarding it)
X
X	fastrep		Enable the keyboard auto-repeat to get faster
X			as time goes on.
X
X	metermaid	Enable the "metermaid" debugging feature (a kernel
X			status meter in the right-hand corner of the
X			screen)
X
XAll of these kernel features are off by default.  If you wanted, say,
Xthe meta key and caps-control swap enabled upon bootup, you'd put:
X
X		/etc/kfeature capctrl meta
X
Xin your /etc/rc file (assuming that kfeature was in /etc).
X
XThe syntax of kfeature is similar to that of the stty command.
X
X
X** Known Limitations **
X
XKernel hackers will notice that I turn on the "metermaid" using the value
X255 decimal, rather than "1" like the keyboard method does.  It works
Xthis way, and it was cleaner, so I did it.  It might not always work,
Xand it doesn't account for other changes that might happen eventually in
Xthe kernel (changes?? :-).  There are ways this could be accomplished...
XI'll leave it this way, or leave it to someone else to fix, if it needs
Xto be.
X
XThere is one kernel feature which pertains to the kernel debugger which
XI have left out of this version of the program, primarily because I
Xhaven't used it yet.  A future update to kfeature might have this, or
Xit might not.  Drop me e-mail if it should, and specify how you'd like
Xit done.
X
X
XHopefully this program will be useful to many of you UNIX-pc people out
Xthere!
X
X--
XGil Kloepfer, Jr.              gil at limbic.ssdl.com   ...!ames!limbic!gil 
XSouthwest Systems Development Labs (Div of ICUS)   Houston, Texas
X"There are beautiful people I wish would have never opened their mouths,
Xbecause such ugliness oozes out."  Philosophy Prof. at NYIT
END_OF_README
if test 3648 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README.BRUCE -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README.BRUCE\"
else
echo shar: Extracting \"README.BRUCE\" \(1829 characters\)
sed "s/^X//" >README.BRUCE <<'END_OF_README.BRUCE'
XI came up with a better way to check if the program is invoked from the
X3b1 console (still not perfect, but greatly improved).
X
XI also double-checked the size and values of the kernel symbols.
XDisassembling the object modules and checking for the symbols, I found:
X
Xkbd.s:	mov.b	autoramp,%d0
Xkbd.s:	mov.b	savUBkey,%d0
Xkbd.s:	mov.b	metaLctl,%d0
Xkbd.s:	mov.b	cplk2ctl,%d0
Xkbd.s:	tst.b	cplk2ctl
Xkbd.s:	mov.b	%d0,cplk2ctl
Xkbd.s:	tst.b	metaLctl
Xkbd.s:	mov.b	%d0,metaLctl
Xkbd.s:	tst.b	savUBkey
Xkbd.s:	mov.b	%d0,savUBkey
Xkbd.s:	tst.b	autoramp
Xkbd.s:	mov.b	%d0,autoramp
Xkbd.s:	tst.w	metermade
Xkbd.s:	mov.w	%d0,metermade
Xkbd.s:	tst.b	cplk2ctl
Xkbd.s:	tst.b	metaLctl
Xkbd.s:	tst.b	cplk2ctl
Xkbd.s:	tst.b	autoramp
Xkbd.s:	tst.b	savUBkey
Xkbd.s:	global	cplk2ctl
Xkbd.s:cplk2ctl:
Xkbd.s:	global	metaLctl
Xkbd.s:metaLctl:
Xkbd.s:	global	autoramp
Xkbd.s:autoramp:
Xkbd.s:	global	savUBkey
Xkbd.s:savUBkey:
Xlp.s:	tst.w	metermade
X
XWhile it seems that some sections of the kernel code are writing/checking
Xbytes, at least metermade must be a full word.  Re-checking the symbols
Xusing sdb, I found:
X  symbol	  off		   on		  difference
X----------	--------	---------	--------------
Xautoramp	0x010101	0x1010101	bit 24 toggles
Xcplk2ctl	0x0		0x1000000	bit 24 toggles
XmetaLctl	0x0000101	0x1000101	bit 24 toggles
Xmetermade	0x000003	0x010003	bit 16 toggles
XsavUBkey	0x010000	0x1010000	bit 24 toggles
X
XWhen printing the symbol values as either a byte or half-word, no
Xdifference was apparent for some of these in the off/on states. The above
Xvalues were printed as long words, e.g. (in sdb)
X>autoramp/lx
X0x010101
X
XI am therefore certain that these symbols are 32 bit words.
X
XI revised the code to operate on the symbols the same as the multi-key
Xoperation, namely toggle only one bit in the 32-bit word.
X
X-- 
X	Bruce Lilly		blilly!balilly!bruce at sonyd1.Broadcast.Sony.COM
END_OF_README.BRUCE
if test 1829 -ne `wc -c <README.BRUCE`; then
    echo shar: \"README.BRUCE\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f kfeature.1 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"kfeature.1\"
else
echo shar: Extracting \"kfeature.1\" \(1289 characters\)
sed "s/^X//" >kfeature.1 <<'END_OF_kfeature.1'
X.TH KFEATURE 1A "UNIX-pc utilities" "ICUS Software Systems"
X.ad b
X.SH NAME
Xkfeature - enable/disable kernel special features
X.SH SYNOPSIS
X.B kfeature
X{[+|-][modes]}
X.SH DESCRIPTION
X.I Kfeature
Xis a program which allows one to enable/disable the "special"
Xkernel features under program control (rather than CAPS-CTL-SHIFT-f_key).
XThis allows the system to be booted in a more comfortable default condition
Xthan currently exists, if desired.
X.PP
X\fIkfeature\fR allows the modification of the following kernel features:
X.PP
X.BR \fIcapctrl\fR\ -
XExchange the CAPS-LOCK and right control key's functions
X.PP
X.BR \fImeta\fR\ -
XEnable the left control key as a meta key
X.PP
X.BR \fIsaveub\fR\ -
XSave the screen unblanking character and enter it into the
Xinput stream (rather than the default action of discarding it)
X.PP
X.BR \fIfastrep\fR\ -
XEnable the keyboard auto-repeat to get faster as time goes on.
X.PP
X.BR \fImetermaid\fR\ -
XEnable the "metermaid" debugging feature (a kernel status meter in
Xthe right-hand corner of the screen)
X.SH AUTHOR
XGil\ Kloepfer,\ Jr,\ ICUS\ Software\ Systems\n
Xgil%limbic at ames.arc.nasa.gov
X.SH SEE\ ALSO
Xadb(1)
X.SH BUGS
X\fIkfeature\fR writes 0xff into metermade when a 0x01 is written there
Xnormally.  No ill effects have been observed, but it could be a problem.
END_OF_kfeature.1
if test 1289 -ne `wc -c <kfeature.1`; then
    echo shar: \"kfeature.1\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f kfeature.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"kfeature.c\"
else
echo shar: Extracting \"kfeature.c\" \(9462 characters\)
sed "s/^X//" >kfeature.c <<'END_OF_kfeature.c'
X/*	%W%	%G%	%U%	*/
X/***************************************************************************\
X * File name:		kfeature.c				   	   *
X *									   *
X * Purpose:		Enable/disable special kernel features in the	   *
X *			3.51m UNIX-pc kernel				   *
X *									   *
X * Programmer:		Gil Kloepfer, Jr.  ICUS Software Systems	   *
X *									   *
X * Revision history:	29-Jan-90  1.0	 Program created		   *
X * 			11-Dec-90  1.1	 Patches from Bruce Lilly added    *
X *									   *
X * Restrictions:	Program will only work on the UNIX-pc, and only	   *
X *			with the 3.51m (and maybe higher) kernel.  If	   *
X *			an attempt is made to use this program with a	   *
X *			different kernel version SERIOUS DAMAGE TO YOUR	   *
X *			FILES COULD RESULT!				   *
X *									   *
X *			Because of the nature of this program, it needs to *
X *			be s-bitted to "root" so that it can modify the    *
X *			running kernel.					   *
X *									   *
X * Usage:		Invoked from the shell or a script by:		   *
X *				$ kfeature [features]			   *
X *									   *
X *			A list of available features can be obtained by	   *
X *			typing 'kfeature' with no args.  Prior knowledge   *
X *			of the available kernel features is useful...	   *
X *									   *
X * Compiled by:		$ cc -v -O -o kfeature kfeature.c -s		   *
X *									   *
X * Copyright/		(C) 1990 Gil Kloepfer, Jr., ICUS Software Systems  *
X * Disclaimer:		All Rights Reserved				   *
X *									   *
X *			Thanks to Lenny Tropiano for providing his clist   *
X *			reading program as a model.  Thanks also to Bruce  *
X *			Lilly for sending along his bugfixes and           *
X *			enhancements                                       *
X *									   *
X *			Permission is granted to use, copy, or redistribute*
X *			this software provided that this header in its     *
X *			entirety is kept in the source code, that all      *
X *			copyright notices are left intact, and that it is  *
X *			not distributed or used for monetary gain of any   *
X *			kind without the express, written permission of    *
X *			the copyright holder(s).  Furthermore, if this     *
X *			software is modified, all changes should be mailed *
X *			to gil at limbic.ssdl.com                             *
X *									   *
X *			The user of this program agrees and understands    *
X *			that this software is distributed on an "as-is"    *
X *			basis, and shall not use this program as the basis *
X *			for any claims, now or in the future, against      *
X *			any individual, organization, or entity.	   *
X\***************************************************************************/
X
X#ifndef	lint
Xstatic	char	sccs_id[] = "%W%";
X#ifdef	__GNUC__
Xstatic	char	compiled[] = "%Z%compiled by gcc "__VERSION__;
X#endif
X#endif
X
X#include	<sys/types.h>
X#include	<utmp.h>
X#include	<termio.h>
X#include	<sys/window.h>
X#include <stdio.h>
X#include <nlist.h>
X#include <fcntl.h>
X#include	<string.h>
X
X#define UNIX	"/unix"			/* Path to current /unix */
X#define KMEM	"/dev/kmem"		/* Path to current kernel memory */
X
Xextern	int	close();
Xextern	void	endutent();
Xextern	void	exit();
Xextern	void	free();
Xextern	int	fprintf();
Xextern	struct	utmp	*getutent();
Xextern	long	lseek();
X#ifdef	__STDC__
Xextern	void	*malloc();
X#else
Xextern	char	*malloc();
X#endif
Xextern	int	nlist();
Xextern	int	open();
Xextern	void	perror();
Xextern	int	read();
Xextern	void	setutent();
Xextern	void	sync();
Xextern	int	ttyslot();
Xextern	void	utmpname();
Xextern	int	write();
X
X/*
X * The following table defines the valid keywords, their corresponding
X * kernel symbol names, and will ultimately hold any modified kernel
X * feature parameters
X */
X
Xstatic struct {
X	char		*kf_featname;
X	char		*kf_kernsym;
X	unsigned char	bit;	/* bit in kf_value to change */
X	unsigned char	kf_modified;	/* true/false */
X	unsigned int	kf_value;
X} ftable[] = {
X	{ "capctrl",	"cplk2ctl",	24, 0, 0 },
X	{ "meta",	"metaLctl",	24, 0, 0 },
X	{ "saveub",	"savUBkey",	24, 0, 0 },
X	{ "metermaid",	"metermade",	16, 0, 0 },
X	{ "fastrep",	"autoramp",	24, 0, 0 },
X	{ NULL,		NULL,		0, 0, 0 } };
X
X
Xint	main(argc,argv)
Xint argc;
Xchar *argv[];
X{
X	int	isconsole();
X	void		parseargs(), usage(), setkern();
X
X
X	if (! isconsole()) {
X		fprintf(stderr, "%s: useful only from the 3b1 console\n", argv[0]);
X		exit(1);
X	}
X
X	if (argc < 2) {
X		usage(argv[0]);
X		exit(1);
X	}
X
X	parseargs(argc,argv);
X	setkern();
X	exit(0);
X}
X
X
Xvoid parseargs(argc,argv)
Xint argc;
Xchar **argv;
X{
X	int		carg, foundfeat, fc;
X	unsigned char	seton; /* on/off = 1/0 */
X	char		*symp;
X	void		usage();
X	int		getkern();
X
X	for (carg=1; carg<argc; carg++) {
X		/*
X		 * Find on/off status of current argument
X		 */
X		switch(*argv[carg]) {
X		case '+':	/* Turn on feature */
X			seton = 1;
X			symp = &(argv[carg][1]);
X			break;
X
X		case '-':	/* Turn off feature */
X			seton = 0;
X			symp = &(argv[carg][1]);
X			break;
X
X		default:	/* If no mode, assume "ON" */
X			seton = 1;
X			symp = argv[carg];
X			break;
X		}
X		/*
X		 * Find feature in the table
X		 */
X		for (fc=0, foundfeat=0; *ftable[fc].kf_featname && !foundfeat; fc++) {
X			if (strcmp(symp,ftable[fc].kf_featname) == 0) {
X				foundfeat = 1;
X				ftable[fc].kf_modified = 1;
X				/* find current value */
X				ftable[fc].kf_value = getkern(ftable[fc].kf_kernsym);
X				if (seton)
X					ftable[fc].kf_value |= (0x1 << ftable[fc].bit);
X				else
X					ftable[fc].kf_value &= ~(0x1 << ftable[fc].bit);
X			}
X		}
X		/*
X		 * If symbol not found, tell user what was wrong, then
X		 * exit with usage statement
X		 */
X		if (!foundfeat) {
X			fprintf(stderr,"%s: undefined feature \"%s\"\n",
X					argv[0], symp);
X			usage(argv[0]);
X			exit(2);
X		}
X	}
X}
X
X
Xvoid usage(progname)
Xchar *progname;
X{
X	int		i;
X
X	fprintf(stderr,"usage: %s {[+|-][modes]}  where modes are:\n",progname);
X	fprintf(stderr,"       ");
X	for (i=0; *ftable[i].kf_featname; i++)
X		fprintf(stderr,"%s  ",ftable[i].kf_featname);
X	fprintf(stderr,"\n");
X}
X 
X
Xint getkern(name)
Xchar	*name;
X{
X	int		return_value;
X	int		kmemfd;
X	struct nlist	*unixsym;
X
X	/*
X	 * Malloc two nlist structs to nlist the symbol we
X	 * want to find.  Initialize the name.
X	 */
X
X	unixsym = (struct nlist *)malloc(sizeof(struct nlist)*2);
X	unixsym[0].n_name = name;
X	unixsym[1].n_name = NULL;
X
X	/*
X	 * Namelist the kernel and get the symbol
X	 */
X
X	if (nlist(UNIX, unixsym) < 0) {
X		fprintf(stderr, "%s: (nlist) symbols unavailable (are you running 3.51m?)\n",
X				UNIX);
X		free(unixsym);
X		exit(2);
X	}
X
X	/*
X	 * Now open the kernel memory so that the offset obtained above
X	 * may be accessed, and the data value read from the running
X	 * kernel
X	 */
X
X	if ((kmemfd=open(KMEM,O_RDONLY)) < 0) {
X		perror(KMEM);
X		free(unixsym);
X		exit(2);
X	}
X
X	/*
X	 * Sync for safety...
X	 */
X
X	sync();
X
X	/*
X	 * ** NOTE **  The following section of code most certainly has
X	 * kernel-version specific assumptions in it.  If the kernel really
X	 * does change, and the size of symbols change, the code should be
X	 * modified here
X	 */
X
X	lseek(kmemfd,unixsym[0].n_value,0);
X	if (read(kmemfd, &return_value, sizeof(return_value)) < 0) {
X		perror("read");
X		fprintf(stderr,"    error when reading symbol %s\n",
X			unixsym[0].n_name);
X		return_value = 0;
X	}
X
X	close(kmemfd);
X	free(unixsym);
X	return(return_value);
X}
X 
X
Xvoid setkern()
X{
X	int		kmemfd, nsyms, cs;
X	struct nlist	*unixsym;
X
X	/*
X	 * Malloc enough nlist structs to nlist all the symbols we
X	 * could possibly be setting.  Initialize all the names to
X	 * the ones in our feature table
X	 */
X
X	for (nsyms=0; *ftable[nsyms].kf_featname; nsyms++);
X
X	unixsym = (struct nlist *)malloc(sizeof(struct nlist)*(nsyms+1));
X	for (cs=0; cs<nsyms; cs++)
X		unixsym[cs].n_name = ftable[cs].kf_kernsym;
X	unixsym[cs].n_name = NULL;
X
X	/*
X	 * Namelist the kernel and get the symbols we'll be setting
X	 */
X
X	if (nlist(UNIX, unixsym) < 0) {
X		fprintf(stderr, "%s: (nlist) symbols unavailable (are you running 3.51m?)\n",
X				UNIX);
X		free(unixsym);
X		exit(2);
X	}
X
X	/*
X	 * Now open the kernel memory so that the offsets obtained above
X	 * may be accessed, and the data values written into the running
X	 * kernel
X	 */
X
X	if ((kmemfd=open(KMEM,O_RDWR)) < 0) {
X		perror(KMEM);
X		free(unixsym);
X		exit(2);
X	}
X
X	/*
X	 * Sync for safety...
X	 */
X
X	sync();
X
X	/*
X	 * Loop through all the values and set them
X	 *
X	 * ** NOTE **  The following section of code most certainly has
X	 * kernel-version specific assumptions in it.  If the kernel really
X	 * does change, and the size of symbols change, the code should be
X	 * modified here
X	 */
X
X	for (cs=0; cs<nsyms; cs++) {
X		if (ftable[cs].kf_modified) {
X			lseek(kmemfd,unixsym[cs].n_value,0);
X			/*
X			 * NOTE: This writes 32 bits -- if future
X			 * kernels have different sizes for these symbols,
X			 * logic will need to be placed here to handle the
X			 * situation
X			 */
X			if (write(kmemfd,&ftable[cs].kf_value,4) < 0) {
X				perror("write");
X				fprintf(stderr,"    error when writing symbol %s\n",
X					unixsym[cs].n_name);
X			}
X		}
X	}
X
X	close(kmemfd);
X	free(unixsym);
X}
X
Xint	isconsole()
X{
X	int	n;
X
X	if ((n = ttyslot()) >= 0) {
X		struct	utmp	*utmp_ptr = (struct utmp *)NULL;
X
X		utmpname("/etc/utmp"); /* insurance */
X		setutent();
X		for (; n >= 0 ; n--)
X			if ((utmp_ptr = getutent()) == (struct utmp *)NULL)
X				break;
X		if ((utmp_ptr)
X		&& ((*(utmp_ptr->ut_line) == 'w')  /* true - is a window on the console */
X		|| (strcmp(utmp_ptr->ut_line, "syscon") == 0) /* /dev/syscon */
X		|| (strcmp(utmp_ptr->ut_line, "console") == 0) /* /dev/console */
X		)) {
X			endutent();
X			return(1);
X		}
X		endutent();
X	}
X	return(0); /* not on console, can't find stdin, stdout, stderr, or problem with /etc/utmp */
X}
END_OF_kfeature.c
if test 9462 -ne `wc -c <kfeature.c`; then
    echo shar: \"kfeature.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
-- 
Gil Kloepfer, Jr.              gil at limbic.ssdl.com   ...!ames!limbic!gil 
Southwest Systems Development Labs (Div of ICUS)   Houston, Texas
"There are beautiful people I wish would have never opened their mouths,
because such ugliness oozes out."  Philosophy Prof. at NYIT



More information about the Comp.sys.att mailing list