rsalz@bbn.com (Rich Salz) (06/03/88)
Submitted-by: michael@stb.UUCP (Michael Gersten) Posting-number: Volume 15, Issue 26 Archive-name: newgetty [ This plays around with the inside of the FILE structure. I wrote the Makefile and edited Michael's manual page. -r$ ] This is an alternative front end to getty. It does not replace getty; it will call getty if needed (assumed to be placed in /etc/lib/getty). It does have the following features: 1. Automatic recognition of 300/1200/2400/9600 baud 2. The ability to run any program or shell script, not just /etc/login. 3. Variable prompting. Here I have a public access BBS on the same line. Most of my users wouldn't know what to do if told "Login:" (even though bbs, help, and "?" all work). If an upper case letter is given, this program sets the LCASE bit before going to the next program. : Michael Gersten : ihnp4!hermix!ucla-an!denwa!stb!michael : sdcsvax!crash!gryphon!denwa!stb!michael : "A hacker lives forever, but not so his free time" #! /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: Makefile newgetty.man newgetty.c # Wrapped by rsalz@fig.bbn.com on Thu Jun 2 14:59:18 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(240 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X## X## X X# Apparently this is needed for Xenix: X#LIBS=-lx CFLAGS=-O X all: newgetty newgetty.man install: all X @echo Install according to local convention X newgetty: newgetty.c X @rm -f newgetty X $(CC) -o newgetty $(CFLAGS) newgetty.c $(LIBS) END_OF_FILE if test 240 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'newgetty.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'newgetty.man'\" else echo shar: Extracting \"'newgetty.man'\" \(1700 characters\) sed "s/^X//" >'newgetty.man' <<'END_OF_FILE' X.TH NEWGETTY 8 X.SH NAME newgetty \- baud rate detecting version of getty (and more) X.SH SYNTAX X.B "getty b" X.br X.B "getty <anything else>" X.SH DESCRIPTION X.I newgetty is a front end to X.IR /etc/getty . It assumes that the old system supplied getty is in X.IR /etc/lib/getty ; if the argument is anything other than X.B b it calls that program with the argument. X.PP If the argument is X.BR b , it trys to open X.IR /etc/default/getty , which must contain a line like: X.RS prompt=Any string that you want to output X.RE X.PP XFor example, X.RS prompt=<b>bs or <u>nix X.RE It will then wait for a character (with a timeout, currently of 3 seconds), at which point it will change baud rates (currently 9600/2400/1200/300), and try again. X.PP XEventually it will get a character, which it will then try to find a line for in X.IR /etc/default/getty . This line should contain the name of the program or shell script to execute. As an example: X.RS X.nf prompt=<b>bs or <u>nix b=/bbs/login B=/bbs/login u=/etc/login U=/etc/login x=/etc/login XX=/etc/login X.fi X.RE X.PP X.I Newgetty is smart enough to set the uppercase flag if an uppercase letter comes in; other than that it assumes a normal (return/newline exchange, etc) terminal. It does not do as much checking as the standard getty, but it's only looking at one character. X.PP X.I Newgetty assumes a fairly standard stdio, and uses one nonportable call. The routine X.IR finkey () returns a single character from a standard I/O FILE; it uses X.IR rdchk () to see if a character is available. BSD users can substitute FIONREAD; pure System\-5 users will have to change the terminal codes used anyways, so they can put the timeout codes in. V7 should just forget this. END_OF_FILE if test 1700 -ne `wc -c <'newgetty.man'`; then echo shar: \"'newgetty.man'\" unpacked with wrong size! fi # end of 'newgetty.man' fi if test -f 'newgetty.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'newgetty.c'\" else echo shar: Extracting \"'newgetty.c'\" \(2660 characters\) sed "s/^X//" >'newgetty.c' <<'END_OF_FILE' X/* @(#)newgetty.c 2.2 4/18/88 17:55:29 ( 4/18/88 17:33:01 ) */ X/* New getty program. If called with an argument other than 'b', it invokes X the old getty program (assumed to be at /etc/lib/getty), otherwise X it reads the default file (/etc/defaults/getty) for 'prompt=', X displays the result, reads a character, loops if non-ascii, checks X the default file for <char>=, executes that program if found, otherwise X loops. */ X X/* 0.4 Sys 3 mods: set echo, cooked */ X/* Gave up on getting it to work with the sys3 structures. Will work fine for BSD systems, or Xenix systems. If you are pure USG, either link for version 7 mode (the kernel still has the version 7 stuff hidden inside for compatibility), or convert it yourself. X*/ X X#include <ctype.h> X#include <stdio.h> X#include <sgtty.h> X X/* 0.3 Does not actually pass arg to next program */ X/* Will not work at 2400 */ X#define SPEED (term.sg_ispeed >= B1200 ? "3":"5") X#define fnsleep(x) (3) /* Return time for sleep */ X char *defread(), *mkstr(); main(argc, argv) char *argv[]; X{ X int c; X char *x; X struct sgttyb term; X if (argc != 2 || strcmp (argv[1], "b") != 0) error: execv ("/etc/lib/getty", argv); X if (defopen("/etc/default/getty") != 0) X { X perror("new getty:"); X goto error; X } X ioctl (1, TIOCGETP, &term); X term.sg_ispeed = term.sg_ospeed = B9600; X term.sg_flags |= CBREAK | ECHO | CRMOD; X term.sg_flags &= ~RAW; X ioctl (1, TIOCNXCL); X for (;;) X { X ioctl (1, TIOCSETP, &term); X puts ("\r"); X fputs(defread("prompt="), stdout); X /* Flush input */ X while ((c=finkey(stdin)) != '\0' && c!= EOF) X ; X sleep(fnsleep(term.sg_ispeed)); X if (isalpha(c=finkey(stdin)) && (x=defread(mkstr(c))) !=NULL) X { X putchar('\n'); X term.sg_flags = term.sg_flags &~ CBREAK; X if (isupper(c)) X term.sg_flags |= LCASE; X ioctl (1, TIOCSETP, &term); X /* No more alarm clock */ X execlp (x, x, NULL); X /* Speed is no longer passed */ X perror (x); X term.sg_flags |= CBREAK; X } X term.sg_ispeed = term.sg_ospeed = nextspeed (term.sg_ispeed); X /* Change speed & try again */ X } X} X char *mkstr(c) char c; X{ X static char chr[]="x="; X chr[0]=c; X return chr; X} X nextspeed(oldspeed) X{ X switch (oldspeed) X { case B300: return B9600; X case B1200: return B300; X case B2400: return B1200; X case B9600: return B2400; X } X} X X/* @(#)inkey.c 1.1 4/18/88 17:57:48 ( 10/2/86 18:51:54 ) */ X# include <stdio.h> inkey(fd) int fd; X{ X char c; X int temp; X if (temp=rdchk(fd) > 0) X if (read (fd, &c, 1) >0) X return c; X else return (char) -1; X else return (temp == 0 ? 0 : -1); X} X finkey(fp) XFILE *fp; X{ X if ((fp->_cnt > 0) || rdchk(fileno(fp)) > 0) X return getc (fp); X if feof(fp) X return EOF; X return 0; X} END_OF_FILE if test 2660 -ne `wc -c <'newgetty.c'`; then echo shar: \"'newgetty.c'\" unpacked with wrong size! fi # end of 'newgetty.c' fi echo shar: End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.