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