Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!nuchat!steve From: steve@nuchat.UUCP (Steve Nuchia) Newsgroups: comp.unix.xenix,alt.sources Subject: "friendly" autobauding getty Message-ID: <442@nuchat.UUCP> Date: Fri, 13-Nov-87 00:08:41 EST Article-I.D.: nuchat.442 Posted: Fri Nov 13 00:08:41 1987 Date-Received: Sun, 15-Nov-87 06:30:48 EST Organization: Public Access - Houston, Tx Lines: 247 Keywords: sysV, microport, bounced mail Xref: mnetor comp.unix.xenix:1134 alt.sources:32 I mentioned that I was working on a getty replacement, some people asked for it, I mailed it off, and it came back. What was that Elvis Presley song about a letter? He must have had the usenet in mind... Anyway, since it went out I've hacked on it some more, so even if you got the first one tou might want this one. It is still a bit rough around the edges, but its getting there. It spits out a short message at each baud rate and waits a short while for the user to say "hey, that looks like text!". Once it decides it has a good baud rate it punts to login(1). Included is a mini-init so you can run this on microbug systems. Even if you pay for unlimited users, their security keeps you from using your own getty. :-( Only good for sysV - the ioctl stuff needs translating for any other system. Bugs - It occasionally leaves an alarm pending, killing the login and leaving the user perplexed. Patches at 11:00. -- Steve Nuchia | [...] but the machine would probably be allowed no mercy. uunet!nuchat!steve | In other words then, if a machine is expected to be (713) 334 6720 | infallible, it cannot be intelligent. - Alan Turing, 1947 #! /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 init2.c <<'END_OF_init2.c' X/* X * init2.c - partial replacement for init, to spawn local getty X * on microport since their init won't. X * X * run by root after going multiuser to start things microport's X * getty refuses to start. actually works! X * X * Steve Nuchia * uunet!nuchat!steve * (713) 334 6720 X * 21 October 1987 X */ X Xstruct X{ X int pid; X char *f; X char *a[6]; X} proc[] = X{ X /* one of these for each "respawn"ed process */ X { 0, "/etc/lgetty", "getty", "ttyM1", "t1" }, X { 0, "/etc/lgetty", "getty", "ttyM0", "t0" } X}; X#define NPROC (sizeof(proc)/sizeof(proc[0])) X Xmain() X{ X int i, pid; X X setpgrp(); X if ( fork() ) exit(0); X while ( 1 ) X { X /* if any jobs are dead, (re)start them */ X for ( i = 0; i < NPROC; i++ ) X { X if ( !proc[i].pid && !(proc[i].pid = fork()) ) X { X execl ( proc[i].f, proc[i].a[0], proc[i].a[1], proc[i].a[2], X proc[i].a[3], proc[i].a[4], proc[i].a[5], (char *) 0 ); X perror ( proc[i].f ); X exit(0); X } X } X /* wait for some job to die */ X pid = wait ( &i ); X printf ( "%d returns %04x\n", pid, i ); X /* figure out which it was and mark it dead */ X for ( i = 0; i < NPROC; i++ ) X if ( proc[i].pid == pid ) proc[i].pid = 0; X } X} END_OF_init2.c if test 1169 -ne `wc -c getty.c <<'END_OF_getty.c' X/* X * getty.c - partial replacement for UNIX getty, designed X * to solve autobaud and line noise problems. X * X * sysV only - the ioctl stuff is not portable (but probably X * isn't too hard, if you know what you're doing). X * X * called with the /dev/%s device name as argv[1] and X * the init "slot id" as argv[2]. X * X * Steve Nuchia * uunet!nuchat!steve * (713) 334 6720 X * 21 October 1987 X */ X X#include X#include X#include X#include X X#define CFLAGS (CS8 | CSTOPB | CREAD | HUPCL) Xstruct termio tbuf = X{ X /*iflag*/ BRKINT | IGNPAR | ISTRIP | ICRNL | IXON, X /*oflag*/ OPOST | ONLCR | TAB3, X /*cflag*/ B2400 | CFLAGS, X /*lflag*/ ISIG | ICANON | ECHO | ECHOE, X /*cline*/ 0, X /*c_cc */ { 3, 034, 8, 024, 4, 0, 0, 032 } X}; X Xextern char **environ; X Xchar *envbuf[10], tname[30]; X X/* speeds to loop through */ X#define NSPEEDS 3 Xint speed[NSPEEDS] = { B2400, B1200, B300 }; X Xcatch() X{ X signal ( SIGINT, catch ); X signal ( SIGQUIT, catch ); X signal ( SIGALRM, catch ); X alarm(0); X} X Xchar buf[2048]; X Xmain ( argc, argv, envp ) X int argc; X char *argv[], *envp[]; X{ X int i = 0, c; X struct utmp ubuf; X int count = 5 * NSPEEDS; /* tries before giving up */ X X /* add TZ to the environment - Microport - more bugs for the buck! */ X environ = envbuf; X while ( envbuf[i] = *envp++ ) i++; X envbuf[i] = "TZ=CST6CDT"; X X /* X * the open should hang until carrier detect comes up. X * if you can't do that you'll have to use the uugetty strategy X * or some other punt. Microport has two interlocked device X * files for each port, which makes bidiertional use a breeze. X */ X sprintf ( tname, "/dev/%s", argv[1] ); X i = open ( UTMP_FILE, 2 ); X X /* open returns, fiddle with accounting files **INCOMPLETE** */ X while ( read ( i, &ubuf, sizeof(ubuf) ) == sizeof(ubuf) ) X { X if ( !strncmp ( ubuf.ut_line, argv[1], sizeof(ubuf.ut_line) ) ) X { X lseek ( i, (long) -sizeof(ubuf), 1 ); X break; X } X } X strcpy ( ubuf.ut_user, argv[0] ); X strcpy ( ubuf.ut_id, argv[2] ); X strcpy ( ubuf.ut_line, argv[1] ); X ubuf.ut_pid = getpid(); X ubuf.ut_type = LOGIN_PROCESS; X ubuf.ut_exit.e_termination = 0; X ubuf.ut_exit.e_exit = 0; X time ( &ubuf.ut_time ); X write ( i, &ubuf, sizeof(ubuf) ); X X /* start setting up the execution environment */ X for ( i = 0; i < 20; i++ ) close ( i ); X setpgrp(); X catch(); X open ( tname, 0 ); X open ( tname, 1 ); X open ( tname, 1 ); X X /* try to find the line speed */ X alarm(3); X pause(); X for ( i = 0; 1; i = (i+1) % NSPEEDS ) X { X if ( ! count-- ) exit ( 0 ); X tbuf.c_cflag = speed[i] | CFLAGS; X ioctl ( 0, TCSETAW, &tbuf ); X write ( 1, "\r\n\npress return: ", 17 ); X alarm ( 3 ); X ioctl ( 0, TCFLSH, 0 ); X /* icrnl is set - CR's get mapped to NL's */ X if ( read ( 0, &c, 1 ) == 1 && c == '\n' ) break; X alarm(0); X } X alarm(0); X X /* send login banner */ X if ( (i = open ( "/etc/issue", 0 )) > 0 ) X { X write ( 1, buf, read ( i, buf, sizeof(buf) ) ); X close ( i ); X } X X /* let login get the user name - "real" getty does it, but no need */ X execl ( "/bin/login", "login", (char *) 0 ); X close ( 2 ); open ( "/dev/console", 1 ); X perror ( "/bin/login" ); X} END_OF_getty.c if test 3246 -ne `wc -c