allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (02/04/89)
Posting-number: Volume 6, Issue 34 Submitted-by: wht@tridom.UUCP (Warren Tucker) Archive-name: gettyfe Here is yet-another-getty-front-end-for-autobauding, this one for SCO XENIX 286/386. It is likely to be portable to future releases. The source has the README built in. ---- Cut Here and unpack ---- #!/bin/sh # shar: Shell Archiver (v1.22) # # Run the following text with /bin/sh to create: # gettyfe.c # if test -f gettyfe.c; then echo "File gettyfe.c exists"; else echo "x - extracting gettyfe.c (Text)" sed 's/^X//' << 'SHAR_EOF' > gettyfe.c && X/* CHK=0x71AC */ X/* vi: set tabstop=4 shiftwidth=4: */ X/*+------------------------------------------------------------------------- X gettyfe.c - front end to SCO XENIX getty X by Warren Tucker ...!gatech!{emory,kd4nc}!wht X XAs exec'd by init, getty gets: Xargv[0] = "-" Xargv[1] = "ttyxx" Xargv[2] = "?" where ? is gettydefs character from /etc/ttys X XThis program becomes /etc/getty, the supplied getty being renamed X/etc/real-getty. My sole dial-in line is tty2D (your mileage may vary). XThus, if gettyfe sees that it is invoked for a tty other than tty2D, Xit immediately chains to "real-getty". X Xgettyfe counts on the following two gettydefs entries: X X2 # B1200 HUPCL OPOST CR0 ECHOE NL1 # X B1200 CS8 SANE HUPCL TAB3 ECHOE IXANY #@\r\nlogin: # 3 X X3 # B2400 HUPCL OPOST CR0 ECHOE NL1 # X B2400 CS8 SANE HUPCL TAB3 ECHOE IXANY #@\r\nlogin: # 2 X XThe port is opened and the file descriptor is dup(2)'d three times. XThis means that fd 0 (stdin), 1 (stdout) and 2 (stderr) is established Xas well as fd 3, the use of which is described below. X XThe port is set up for 2400 baud, NL mapping to CR and otherwise very Xraw. The caller is prompted to set to 8-N-1 and to press ENTER. If the Xcaller is calling at 2400 baud, if he/she/it presses either CR or NL X(via INLCR), then gettyfe executes "real-getty" such that it will prompt Xfor a login at 2400 baud. Otherwise, gettyfe changes the baud rate to X1200, repeats the prompt and so on until CR or NL is found at the proper Xbaud rate. X XWhen a chain to "real-getty" happens after the tty has been opened, fds X0-2 are closed since getty expects to be able to open them. fd 3 is Xleft open so that the tty will not be closed. I'm not sure if this Xis necessary or not, or whether or not the problem can be fixed by Xomitting HUPCL, but I didn't find out. X XFinally, an alarm(30) call gives the caller 30 seconds to start a getty. X XNotes for variations: Xwith port set at 2400 baud, a 1200 baud 8-N CR appears as 0xE6 Xwith port set at 1200 baud, a 2400 baud 8-N CR appears as 0xFE X XTo compile for XENIX 286 or 386: X% cc -O -i -s gettyfe.c -o gettyfe X XIt probably will work under BSD4 if you hacked the code to replace Xnap calls with select() calls of equivalent (I have put my copy in here) X X--------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:01-30-1989-20:08-wht-creation */ X X#include <fcntl.h> X#include <signal.h> X#include <termio.h> X Xint fdtty; Xstruct termio tty_termio; X X#if defined(DEBUG) X#include <stdio.h> X/*+------------------------------------------------------------------------- X debugit(cbaud,user_char) X--------------------------------------------------------------------------*/ Xdebugit(cbaud,user_char) Xint cbaud; Xunsigned char user_char; X{ XFILE *fp = fopen("/gettyfe.log","a"); X fprintf(fp,"baud %d user_char %02x\n",(cbaud == B2400) ? 2400 : 1200, X user_char); X fclose(fp); X} /* end of debugit */ X#endif X X#if defined(BSD4) X/*+------------------------------------------------------------------------- X nap(msec) - BSD4 nap(); needs <time.h> X--------------------------------------------------------------------------*/ Xlong Xnap(msec) Xlong msec; X{ Xstruct timeval tp; Xstruct timezone tzp; Xu_long start_sec; Xlong start_usec; Xlong target_usec; Xlong now_usec; X X gettimeofday(&tp,&tzp); X start_sec = tp.tv_sec; X start_usec = tp.tv_usec; X target_usec = start_usec + (msec * 1000L); X now_usec = start_usec; X while(now_usec < target_usec) X { X gettimeofday(&tp,&tzp); X now_usec = ((tp.tv_sec - start_sec) * 1000000L) + tp.tv_usec; X } X return((now_usec - start_usec) / 1000L); X} /* end of nap */ X#endif X X/*+------------------------------------------------------------------------- X bye(code) X--------------------------------------------------------------------------*/ Xvoid Xbye(code) Xint code; X{ X#if defined(DEBUG) XFILE *fp = fopen("/gettyfe.log","a"); X fprintf(fp,"exit(%d)\n",code); X fclose(fp); X#endif X exit(code); X} /* end of bye */ X X/*+------------------------------------------------------------------------- X login_timeout() X--------------------------------------------------------------------------*/ Xvoid Xlogin_timeout() X{ X bye(13); X} /* end of login_timeout */ X X/*+------------------------------------------------------------------------- X setline(cbaud) X--------------------------------------------------------------------------*/ Xsetline(cbaud) Xint cbaud; X{ X tty_termio.c_cflag &= ~CBAUD; X tty_termio.c_cflag |= cbaud; X ioctl(fdtty,TCSETA,(char *)&tty_termio); X nap(100L); X ioctl(fdtty,TCFLSH,0); X} /* end of setline */ X X/*+------------------------------------------------------------------------- X main(argc,argv,envp) X--------------------------------------------------------------------------*/ Xmain(argc,argv,envp) Xint argc; Xchar **argv; Xchar **envp; X{ Xint cbaud; Xunsigned char user_char; Xchar ttyname[64]; Xchar *prompt = "\r\nUse 8-N-1 and press ENTER: "; Xint promptlen = strlen(prompt); X X if(strcmp(argv[1],"tty2D")) X { X execv("/etc/real-getty",argv); X bye(1); X } X X strcpy(ttyname,"/dev/"); X strcat(ttyname,argv[1]); X X if((fdtty = open(ttyname,O_RDWR)) < 0) /* open stdin */ X bye(2); X X dup(0); /* create stdout */ X dup(0); /* create stderr */ X dup(0); /* create an extra we will not close on exec */ X X tty_termio.c_iflag = IGNPAR | IGNBRK | INLCR; X tty_termio.c_oflag = 0; X tty_termio.c_cflag = CREAD | HUPCL | CS8 | CSTOPB | B2400; X tty_termio.c_lflag = 0; X tty_termio.c_cc[VMIN] = 1; X tty_termio.c_cc[VTIME] = 0; X ioctl(fdtty,TCSETA,(char *)&tty_termio); X X nap(1750L); /* allow for other end carrier detect */ X X signal(SIGALRM,login_timeout); X alarm(30); /* 30 secs to finish this */ X X cbaud = B2400; X X while(1) X { X write(1,prompt,promptlen); X read(0,&user_char,1); X#if defined(DEBUG) X debugit(cbaud,user_char); X#endif X switch(user_char) X { X case 0x0D: X close(0); /* getty will re-open */ X close(1); X close(2); /* keep fd 3 open */ X alarm(0); X execl("/etc/real-getty","-",argv[1], X (cbaud == B2400) ? "3" : "2",(char *)0); X bye(3); X X default: X cbaud = (cbaud == B2400) ? B1200 : B2400; X setline(cbaud); X } X } X /*NOTREACHED*/ X X} /* end of main */ X SHAR_EOF chmod 0644 gettyfe.c || echo "restore of gettyfe.c fails" fi exit 0