gil@limbic.ssdl.com (Gil Kloepfer Jr.) (12/12/90)
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@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@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@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@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@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@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