crds@t.UUCP (Who Am I) (10/15/87)
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# prelog.c
# This archive created: Sun Oct 11 06:12:11 1987
export PATH; PATH=/bin:$PATH
if test -f 'prelog.c'
then
echo shar: over-writing existing file "'prelog.c'"
fi
cat << \SHAR_EOF > 'prelog.c'
/*
* prelog.c Version 1.0 Glenn A. Emelko 10/10/87
*
* First of all, I do hereby declare this code as a completely original
* program, inspired by many but written by one (me). I hereby grant
* anyone permission to use this code as public domain, for the sole
* purpose of understanding, learning, or simply implementation of any
* or all of the concepts herein. I hereby restrict the usage of this
* code to NON-PROFIT purposes; no portions of this code should be used
* by anyone in any way, shape, or form, in order to promote gain to
* either self or others (except me, but I'll never do that). This
* restriction also stipulates that any of the above words, as well
* these, shall be proliferated with this code until doomsday (or after).
*
* Thank you.
*
* This program was written and developed on a Charles River Data Systems
* Universe 68/35 running UNOS 5.1. The purpose was to provide a login
* preprocessor similar to getty, which would automatically detect baud
* rate, set the entry in the /etc/ttys file for the proper baud setting,
* and then execute the original login processor to log in a user. No
* attempt has been made at this point to test this code with signals,
* but it is my belief that it should work properly.
*
*
* The file /etc/ttys must be maintained properly for the original UNOS
* login procedure to set the baud rate during the login procedeure. I
* have added a field in /etc/ttys which will determine which baud table
* is used for rotary baud selection. Baud selection is accomplished by
* sensing for two carriage returns, and if they are not found adjacent
* to each other, waiting for no data, and then rotoring to the next baud
* selection, and repeating. During this time, either nothing, or a
* message (see rotormsg) may be sent to the terminal as each rate is
* rotored through.
*
* Support in the code exists to start up and drive a "ATxx" compatable
* modem, and it may be desirable to take advantage of the carrier
* message to determine baud selection directly, rather than rotoring.
*
* The /etc/ttys file has single line items for each tty device, with
* the information fields delimited by colons. I did not put in the
* necessary support for continuation lines; it can be safely left as
* an exercise to the guru [smile]. The format of the /etc/ttys file
* is as follows:
*
* state:lineno:devpath:devid:terminal:ttymodes:comments:extra
*
* where [in brackets is the maximum field with allowed by prelog]:
*
* state [12] -- either "on" or something else; on indicating an
* active login port, and anything else indicating an
* i/o port for other usage.
*
* lineno [4] -- logical tty number, on the CRDS, it corresponds
* to last number in the device path, whichhas a range
* from 0 to 11.
*
* dpath [12] -- the full path of the tty device. Something like
* "/dev/tty4" is valid.
*
* devnum [6] -- The system major and minor device number. On
* the CRDS, this is 1/nn, where nn is the tty number.
*
* ttyid [12] -- this is the terminal id assumed to be connected
* to the line; it is looked up in the termcap entries
* to set terminal parameters. Something like "vt100"
* is valid.
*
* tbaud [20] -- this is the entry read to set terminal modes on
* the tty device. This entry is passed by the original
* login program to an internal UNOS specific system call
* called _ttymodes. The standard /etc/ttys file only
* sets the baud rate by this field, and this is where
* prelog puts its speed setting after it has detected
* the speed. A standard UNOS entry in this field is
* something like "speed=9600".
* NOTE: THIS FIELD IS MODIFIED BY prelog.
*
* tsetb [30] -- this field was the comment field associated with
* the tty device. I commandeered this field, and have
* given it new meaning; the FIRST character of this
* field shall be a '0' thru '9', identifying which table
* prelog shall use to select its baud rates by, as well
* as control a modem by. The DEFAULT setting is 0 or
* a non-numeric character, which are treated the same.
* In this default mode, the baud rate will NOT be auto
* selected, instead, the ttymodes field will be used
* as is, without changing it. See the tables for the
* other possible values. The REST of this field may
* still be used for comments of any sort.
* NOTE: THIS FIELD IS CHECKED BY prelog.
*
* extra [30] -- Well, your guess is as good as mine. This
* field may or may not even exist on some of the
* entries; in fact there are some extra colons at the
* end of some lines in my own ttys file. Anything
* after the comments field is captured verbatim, so it
* will be put back exactly the same way it came out.
*
* One last thing, before we get on with the program....
*
* INSTALLATION
*
* To install this program on a CRDS under UNOS 5.1, compile it with cc,
* move /sys/login to /sys/post_login, and move the compiled code to
* /sys/login. This is all that is needed, it will take over once you
* log off. For other versions of UNOS or other UNIX machines, I will
* say that YOU ARE AT YOUR OWN RISK -- playing with /sys/login is a
* very dangerous thing to do, and I do not recomment it for those who
* are weak at heart. I crashed my CRDS completely several times; even
* though I had multiple ttys logged in to try to have recoverable
* system problems, occasionally the WHOLE SYSTEM came to it's knees --
* I get the feeling it really didn't like what I was doing. Please
* note that this was an experimental time, and NOW it works fine, I
* have been running my new login procedure for several weeks. You may
* also wish to run "strip" on the new /sys/login file, to cut down its
* storage requirements on the disk (strip removes symbolic information).
*/
#include <fcntl.h> /* For file i/o */
#include <sgtty.h> /* For tty modes */
#include <signal.h> /* for sigquit/sighup */
#include <stdio.h> /* for fprintf */
#include <sys/utsname.h> /* for uname call */
#include <termio.h> /* for terminal setting */
int at_init();
int no_init(){};
struct ttyentry {
char state[12]; /* state "on" or other */
char lineno[4]; /* lineno (range 0-11) */
char dpath[12]; /* device path /dev/tty */
char devnum[6]; /* major/minor, 1/nn */
char ttyid[12]; /* tty type, i.e. vt100 */
char tbaud[20]; /* baud, speed=9600 */
char tsetb[30]; /* table (0-9), remark */
char extra[30]; /* anything else ? */
} ttys[20]; /* NOTE max 20 entries */
int ttys_count; /* count of entries */
int myttyentry; /* which entry am I? */
FILE *ttysfile; /* fildes for /etc/ttys */
int tty_lun; /* login terminal unit */
FILE *indev; /* stdin/stdout */
FILE *outdev;
struct sgttyb tty_mode; /* tty settings struct */
char post_login[] = "/sys/post_login"; /* orig. login program */
char s110[] = "speed=110"; /* Text for ttymodes */
char s300[] = "speed=300";
char s1200[] = "speed=1200";
char s9600[] = "speed=9600";
char s38400[] = "speed=38400";
char ttymatch[] = "/dev/tty?? "; /* reserve space */
char rotormsg[] = "\007";
struct tset {
char tableid; /* table name ('0'-'9') */
int (*Line_init)(); /* anything to do first */
char rotori; /* rotor name ('A'-'Z') */
} tsets[] = {
'0',no_init,\0, /* tset 0, no init, use /etc/ttys */
'1',no_init,'A', /* tset 1, no init, use rotor A */
'2',at_init,'B', /* tset 2, "ATxx" init, use rotor B */
\0,no_init,\0 /* End of table, no init, use /etc/ttys */
};
#define NUMTSETS sizeof tsets/sizeof tsets[0]
struct rotor {
char rotorid; /* rotor name ('A'-'Z') */
int flags; /* Sense setup flags */
int speed; /* Baud flags */
char *tbaudset; /* ttys tbaud setting */
} rotors[] = {
'A',CR1+NL1+CRMOD+RAW,B9600,s9600, /*A, flags, ibaud, text */
'A',CR1+NL1+CRMOD+RAW,B38400,s38400, /*A, flags, ibaud, text */
'A',CR1+NL1+CRMOD+RAW,B1200,s1200, /*A, flags, ibaud, text */
'A',CR1+NL1+CRMOD+RAW,B1200,s1200, /*A, flags, ibaud, text */
'B',CR1+NL1+CRMOD+RAW,B300,s300, /*A, flags, ibaud, text */
'B',CR1+NL1+CRMOD+RAW,B1200,s1200, /*A, flags, ibaud, text */
\0,0,0,(char *)\0 /* End of table */
};
main(argc,argv)
int argc;
char **argv;
{
struct utsname sysname; /* utsname definition */
char tsetgo; /* default use table 0 */
char rotorgo; /* search character */
int i,j; /* general purpose */
int tsetnum, rotornum; /* pointer counts */
char chr; /* general purpuse */
uname(&sysname); /* Get system name */
if (argc==1) {
tty_lun = fdown(outdev=stdout); /* get tty logical unit */
indev = stdin; /* get i/o devices */
} else {
tty_lun = fdown(outdev=fileopen(argv[1],"w"));
/* get tty logical unit */
indev = fileopen(argv[1],"r"); /* and get i/o devices */
}
setbuf(indev,NULL); /* no i/o buffering */
setbuf(outdev,NULL);
strcpy(ttymatch,ttyname(tty_lun)); /* save device path */
setctlterm(tty_lun); /* set controlling term */
tty_lun=open(ttymatch,O_RDWR); /* reopen device for us */
ttys_count = 0;
ttysfile = fopen("/etc/ttys","r"); /* get /etc/ttys info */
while (fread(&chr,1,1,ttysfile)>0) /* if chr, get entry */
getentry(chr);
fclose(ttysfile); /* have ttys information*/
for(i=0;i<ttys_count;i++) { /* scan ttys entries */
if (0==strcmp(ttymatch,ttys[i].dpath)) {/* if it matches... */
tsetgo = *ttys[i].tsetb; /* get character */
if ((tsetgo<'0') || (tsetgo>'9')) /* resort to default? */
tsetgo='0';
}
}
for(tsetnum=0;tsetnum<(NUMTSETS);tsetnum++) /* find tsetgo in tsets*/
if (tsets[tsetnum].tableid==tsetgo) break;
(*tsets[tsetnum].Line_init)(); /* Initialize the line */
rotorgo = tsets[tsetnum].rotori; /* get the rotor ident */
while (rotorgo!=\0) { /* do until cr detect */
/* unless rotorgo is 0 */
rotornum=0; /* start at first rotor */
while (rotors[rotornum].rotorid!=rotorgo) {/* scan list for match*/
rotornum++; /* go to next if not */
if (rotors[rotornum].rotorid==\0) /* did we not find it? */
rotorgo = \0; /* Not found, GET OUT! */
}
if (rotorgo!=\0) { /* now scan good ones */
while (rotors[rotornum].rotorid==rotorgo) {
/* for each valid entry */
tty_mode.sg_erase = CERASE; /* prepare parameters */
tty_mode.sg_kill = CKILL;
tty_mode.sg_flags = rotors[rotornum].flags;
tty_mode.sg_ispeed = rotors[rotornum].speed;
tty_mode.sg_ospeed = rotors[rotornum].speed;
stty(tty_lun,&tty_mode); /* set tty parameters */
delay(1);
j=0; /* count of cr's */
while ((j<2) && (read(tty_lun,&chr,1)>0)) {
/* go until 2 cr's, eof, or we get a bad chr */
if ((chr=='\n') || (chr=='\r')) {
fprintf(outdev,rotormsg);
j++; /* count them */
}
else
break;
}
if (j==2) { /* we got 2 cr's, GO! */
ttys_count = 0;
ttysfile = fopen("/etc/ttys","r"); /* do it again */
while (fread(&chr,1,1,ttysfile)>0) /* get entry */
getentry(chr);
fclose(ttysfile); /* have ttys information*/
ttysfile = fopen("/etc/ttys","w"); /* now update */
for(i=0;i<ttys_count;i++) {
if (0==strcmp(ttymatch,ttys[i].dpath))
strcpy(ttys[i].tbaud,rotors[rotornum].tbaudset);
/* match entry & change */
fprintf(ttysfile,"%s:%s:%s:%s:%s:%s:%s:%s\n",
ttys[i].state,
ttys[i].lineno,
ttys[i].dpath,
ttys[i].devnum,
ttys[i].ttyid,
ttys[i].tbaud,
ttys[i].tsetb,
ttys[i].extra
); /* put back in file */
};
fclose(ttysfile);
rotorgo = \0; /* done, exit */
} else {
rotornum++; /* otherwise next entry */
}
} /* end while matching rotorgo */
} /* end if (rotorgo) */
} /* end while (rotorgo) */
fprintf(outdev,"\n\nCharles River Data Systems 68/35");
if (*sysname.nodename) /* if nodename, print it*/
fprintf(outdev," (%s)",sysname.nodename);
fprintf(outdev,"\n\015");
fexecl(post_login, indev, outdev, outdev, "login", ttymatch, 0);
exit(1); /* Never get here??? */
}
getentry(a) /* parse entry from /etc/ttys file, increment ttys_count */
char a;
{
char *ptr; /* field pointer in record */
char *tbl[8]; /* ttys record field pointers */
int i; /* field number, general purpose*/
tbl[0]=ttys[ttys_count].state; /* point to fields */
tbl[1]=ttys[ttys_count].lineno;
tbl[2]=ttys[ttys_count].dpath;
tbl[3]=ttys[ttys_count].devnum;
tbl[4]=ttys[ttys_count].ttyid;
tbl[5]=ttys[ttys_count].tbaud;
tbl[6]=ttys[ttys_count].tsetb;
tbl[7]=ttys[ttys_count].extra;
for(i=0;i<8;i++) *tbl[i]=0; /* init fields to null */
i = 0; /* start at first field */
while (a!=10) { /* watch for EOL */
ptr=tbl[i]; /* point at field */
while ((a!=10) && ((i==7) || (a!=58))) {
*ptr++=a; /* save chr if valid */
if (fread(&a,1,1,ttysfile)==0) a=10;/* EOF, terminate */
}
if (a!=10)
if (fread(&a,1,1,ttysfile)==0) a=10;/* is there next field? */
*ptr=0; /* mark end of string */
if (i<7) i++; /* next field ptr */
}
ttys_count++; /* count line-item */
}
at_init()
{
int awake = 0;
char junk;
tty_mode.sg_erase = CERASE; /* prepare parameters */
tty_mode.sg_kill = CKILL;
tty_mode.sg_flags = CR1+NL1+CRMOD+RAW;
tty_mode.sg_ispeed = B1200;
tty_mode.sg_ospeed = B1200;
stty(tty_lun,&tty_mode); /* set tty parameters */
sleep(4);
fprintf(outdev,"+++"); /* get modems attention */
sleep(4);
fprintf(outdev,"\r");
sleep(1);
fprintf(outdev,"ATZ\r"); /* reset modem */
sleep(1);
fprintf(outdev,"ATS0=1\r"); /* auto answer */
sleep(1);
junk=' ';
while(junk!='1') read(tty_lun,&junk,1); /* flush input buffer */
while(junk!='\r') read(tty_lun,&junk,1);
}
SHAR_EOF
chmod +x 'prelog.c'
# End of shell archive
exit 0