home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume1 / 8710 / 13 / prelog.c
Encoding:
C/C++ Source or Header  |  1990-07-13  |  13.7 KB  |  379 lines

  1. /*
  2.  *     prelog.c    Version 1.0    Glenn A. Emelko        10/10/87
  3.  *
  4.  *    First of all, I do hereby declare this code as a completely original
  5.  *    program, inspired by many but written by one (me).  I hereby grant
  6.  *    anyone permission to use this code as public domain, for the sole
  7.  *    purpose of understanding, learning, or simply implementation of any
  8.  *    or all of the concepts herein.  I hereby restrict the usage of this
  9.  *    code to NON-PROFIT purposes; no portions of this code should be used
  10.  *    by anyone in any way, shape, or form, in order to promote gain to
  11.  *    either self or others (except me, but I'll never do that).  This
  12.  *    restriction also stipulates that any of the above words, as well
  13.  *    these, shall be proliferated with this code until doomsday (or after).
  14.  *
  15.  *    Thank you.
  16.  *
  17.  *    This program was written and developed on a Charles River Data Systems
  18.  *    Universe 68/35 running UNOS 5.1.  The purpose was to provide a login
  19.  *    preprocessor similar to getty, which would automatically detect baud
  20.  *    rate, set the entry in the /etc/ttys file for the proper baud setting,
  21.  *    and then execute the original login processor to log in a user.  No
  22.  *    attempt has been made at this point to test this code with signals,
  23.  *    but it is my belief that it should work properly.
  24.  *
  25.  *
  26.  *    The file /etc/ttys must be maintained properly for the original UNOS
  27.  *    login procedure to set the baud rate during the login procedeure.  I
  28.  *    have added a field in /etc/ttys which will determine which baud table
  29.  *    is used for rotary baud selection.  Baud selection is accomplished by
  30.  *    sensing for two carriage returns, and if they are not found adjacent
  31.  *    to each other, waiting for no data, and then rotoring to the next baud
  32.  *    selection, and repeating.  During this time, either nothing, or a
  33.  *    message (see rotormsg) may be sent to the terminal as each rate is
  34.  *    rotored through.
  35.  *
  36.  *    Support in the code exists to start up and drive a "ATxx" compatable
  37.  *    modem, and it may be desirable to take advantage of the carrier
  38.  *    message to determine baud selection directly, rather than rotoring.
  39.  *
  40.  *    The /etc/ttys file has single line items for each tty device, with
  41.  *    the information fields delimited by colons.  I did not put in the
  42.  *    necessary support for continuation lines; it can be safely left as
  43.  *    an exercise to the guru [smile].  The format of the /etc/ttys file
  44.  *    is as follows:
  45.  *
  46.  *    state:lineno:devpath:devid:terminal:ttymodes:comments:extra
  47.  *
  48.  *    where [in brackets is the maximum field with allowed by prelog]:
  49.  *
  50.  *        state [12] -- either "on" or something else; on indicating an
  51.  *            active login port, and anything else indicating an
  52.  *            i/o port for other usage.
  53.  *
  54.  *        lineno [4] -- logical tty number, on the CRDS, it corresponds
  55.  *            to last number in the device path, whichhas a range
  56.  *            from 0 to 11.
  57.  *
  58.  *        dpath [12] -- the full path of the tty device.  Something like
  59.  *            "/dev/tty4" is valid.
  60.  *
  61.  *        devnum [6] -- The system major and minor device number.  On
  62.  *            the CRDS, this is 1/nn, where nn is the tty number.
  63.  *
  64.  *        ttyid [12] -- this is the terminal id assumed to be connected
  65.  *            to the line; it is looked up in the termcap entries
  66.  *            to set terminal parameters.  Something like "vt100"
  67.  *            is valid.
  68.  *
  69.  *        tbaud [20] -- this is the entry read to set terminal modes on
  70.  *            the tty device.  This entry is passed by the original
  71.  *            login program to an internal UNOS specific system call
  72.  *            called _ttymodes.  The standard /etc/ttys file only
  73.  *            sets the baud rate by this field, and this is where
  74.  *            prelog puts its speed setting after it has detected
  75.  *            the speed.  A standard UNOS entry in this field is
  76.  *            something like "speed=9600".
  77.  *            NOTE: THIS FIELD IS MODIFIED BY prelog.
  78.  *
  79.  *        tsetb [30] -- this field was the comment field associated with
  80.  *            the tty device.  I commandeered this field, and have
  81.  *            given it new meaning; the FIRST character of this
  82.  *            field shall be a '0' thru '9', identifying which table
  83.  *            prelog shall use to select its baud rates by, as well
  84.  *            as control a modem by.  The DEFAULT setting is 0 or
  85.  *            a non-numeric character, which are treated the same.
  86.  *            In this default mode, the baud rate will NOT be auto
  87.  *            selected, instead, the ttymodes field will be used
  88.  *            as is, without changing it.  See the tables for the
  89.  *            other possible values.  The REST of this field may
  90.  *            still be used for comments of any sort.
  91.  *            NOTE: THIS FIELD IS CHECKED BY prelog.
  92.  *
  93.  *        extra [30] -- Well, your guess is as good as mine.  This
  94.  *            field may or may not even exist on some of the
  95.  *            entries; in fact there are some extra colons at the
  96.  *            end of some lines in my own ttys file.  Anything
  97.  *            after the comments field is captured verbatim, so it
  98.  *            will be put back exactly the same way it came out.
  99.  *
  100.  *    One last thing, before we get on with the program....
  101.  *
  102.  *    INSTALLATION
  103.  *
  104.  *    To install this program on a CRDS under UNOS 5.1, compile it with cc,
  105.  *    move /sys/login to /sys/post_login, and move the compiled code to
  106.  *    /sys/login.  This is all that is needed, it will take over once you
  107.  *    log off.  For other versions of UNOS or other UNIX machines, I will
  108.  *    say that YOU ARE AT YOUR OWN RISK -- playing with /sys/login is a
  109.  *    very dangerous thing to do, and I do not recomment it for those who
  110.  *    are weak at heart.  I crashed my CRDS completely several times; even
  111.  *    though I had multiple ttys logged in to try to have recoverable
  112.  *    system problems, occasionally the WHOLE SYSTEM came to it's knees --
  113.  *    I get the feeling it really didn't like what I was doing.  Please
  114.  *    note that this was an experimental time, and NOW it works fine, I
  115.  *    have been running my new login procedure for several weeks.  You may
  116.  *    also wish to run "strip" on the new /sys/login file, to cut down its
  117.  *    storage requirements on the disk (strip removes symbolic information).
  118.  */
  119.  
  120. #include <fcntl.h>                /* For file i/o        */
  121. #include <sgtty.h>                /* For tty modes    */
  122. #include <signal.h>                /* for sigquit/sighup    */
  123. #include <stdio.h>                /* for fprintf        */
  124. #include <sys/utsname.h>            /* for uname call    */
  125. #include <termio.h>                /* for terminal setting    */
  126.  
  127. int at_init();
  128.  
  129. int no_init(){};
  130.  
  131. struct ttyentry {
  132.     char state[12];                /* state "on" or other    */
  133.     char lineno[4];                /* lineno (range 0-11)    */
  134.     char dpath[12];                /* device path /dev/tty    */
  135.     char devnum[6];                /* major/minor, 1/nn    */
  136.     char ttyid[12];                /* tty type, i.e. vt100    */
  137.     char tbaud[20];                /* baud, speed=9600    */
  138.     char tsetb[30];                /* table (0-9), remark    */
  139.     char extra[30];                /* anything else ?    */
  140. } ttys[20];                    /* NOTE max 20 entries    */
  141.  
  142. int ttys_count;                    /* count of entries    */
  143. int myttyentry;                    /* which entry am I?    */
  144.  
  145. FILE *ttysfile;                    /* fildes for /etc/ttys */
  146.  
  147. int tty_lun;                    /* login terminal unit    */
  148. FILE *indev;                    /* stdin/stdout        */
  149. FILE *outdev;
  150.  
  151. struct sgttyb tty_mode;                /* tty settings struct    */
  152.  
  153. char post_login[] = "/sys/post_login";        /* orig. login program    */
  154.  
  155. char s110[]    = "speed=110";            /* Text for ttymodes    */
  156. char s300[]    = "speed=300";
  157. char s1200[]    = "speed=1200";
  158. char s9600[]    = "speed=9600";
  159. char s38400[]    = "speed=38400";
  160.  
  161. char ttymatch[] = "/dev/tty?? ";        /* reserve space    */
  162.  
  163. char rotormsg[] = "\007";
  164.  
  165. struct tset {
  166.     char    tableid;            /* table name ('0'-'9')    */
  167.     int    (*Line_init)();            /* anything to do first    */
  168.     char    rotori;                /* rotor name ('A'-'Z')    */
  169. } tsets[] = {
  170.  
  171.     '0',no_init,\0,        /* tset 0, no init, use /etc/ttys    */
  172.  
  173.     '1',no_init,'A',    /* tset 1, no init, use rotor A        */
  174.  
  175.     '2',at_init,'B',    /* tset 2, "ATxx" init, use rotor B    */
  176.  
  177.     \0,no_init,\0        /* End of table, no init, use /etc/ttys */
  178. };
  179.  
  180. #define NUMTSETS sizeof tsets/sizeof tsets[0]
  181.  
  182. struct rotor {
  183.     char    rotorid;            /* rotor name ('A'-'Z')    */
  184.     int    flags;                /* Sense setup flags    */
  185.     int    speed;                /* Baud flags        */
  186.     char    *tbaudset;            /* ttys tbaud setting    */
  187. } rotors[] = {
  188.  
  189.     'A',CR1+NL1+CRMOD+RAW,B9600,s9600,    /*A, flags, ibaud, text    */
  190.     'A',CR1+NL1+CRMOD+RAW,B38400,s38400,    /*A, flags, ibaud, text    */
  191.     'A',CR1+NL1+CRMOD+RAW,B1200,s1200,    /*A, flags, ibaud, text    */
  192.     'A',CR1+NL1+CRMOD+RAW,B1200,s1200,    /*A, flags, ibaud, text    */
  193.  
  194.     'B',CR1+NL1+CRMOD+RAW,B300,s300,    /*A, flags, ibaud, text    */
  195.     'B',CR1+NL1+CRMOD+RAW,B1200,s1200,    /*A, flags, ibaud, text    */
  196.  
  197.     \0,0,0,(char *)\0        /* End of table */
  198. };
  199.  
  200. main(argc,argv)
  201. int argc;
  202. char **argv;
  203. {
  204.     struct utsname sysname;            /* utsname definition    */
  205.     char tsetgo;                /* default use table 0    */
  206.     char rotorgo;                /* search character    */
  207.     int i,j;                    /* general purpose    */
  208.     int tsetnum, rotornum;            /* pointer counts    */
  209.     char chr;                    /* general purpuse    */
  210.  
  211.     uname(&sysname);                /* Get system name    */
  212.  
  213.     if (argc==1) {
  214.     tty_lun = fdown(outdev=stdout);        /* get tty logical unit    */
  215.     indev = stdin;                /* get i/o devices    */
  216.     } else {
  217.     tty_lun = fdown(outdev=fileopen(argv[1],"w"));
  218.                         /* get tty logical unit */
  219.     indev = fileopen(argv[1],"r");        /* and get i/o devices    */
  220.     }
  221.  
  222.     setbuf(indev,NULL);                /* no i/o buffering    */
  223.     setbuf(outdev,NULL);
  224.     
  225.     strcpy(ttymatch,ttyname(tty_lun));        /* save device path    */
  226.     setctlterm(tty_lun);            /* set controlling term    */
  227.     tty_lun=open(ttymatch,O_RDWR);        /* reopen device for us    */
  228.  
  229.     ttys_count = 0;
  230.     ttysfile = fopen("/etc/ttys","r");        /* get /etc/ttys info    */
  231.     while (fread(&chr,1,1,ttysfile)>0)        /* if chr, get entry    */
  232.     getentry(chr);
  233.     fclose(ttysfile);                /* have ttys information*/
  234.  
  235.     for(i=0;i<ttys_count;i++) {            /* scan ttys entries    */
  236.     if (0==strcmp(ttymatch,ttys[i].dpath)) {/* if it matches...    */
  237.         tsetgo = *ttys[i].tsetb;        /* get character    */
  238.         if ((tsetgo<'0') || (tsetgo>'9'))    /* resort to default?    */
  239.         tsetgo='0';
  240.     }
  241.     }
  242.  
  243.     for(tsetnum=0;tsetnum<(NUMTSETS);tsetnum++)    /* find tsetgo in tsets*/
  244.     if (tsets[tsetnum].tableid==tsetgo) break;
  245.  
  246.     (*tsets[tsetnum].Line_init)();        /* Initialize the line    */
  247.  
  248.     rotorgo = tsets[tsetnum].rotori;        /* get the rotor ident    */
  249.  
  250.     while (rotorgo!=\0) {            /* do until cr detect    */
  251.                         /* unless rotorgo is 0    */
  252.     rotornum=0;                /* start at first rotor    */
  253.     while (rotors[rotornum].rotorid!=rotorgo) {/* scan list for match*/
  254.         rotornum++;                /* go to next if not    */
  255.         if (rotors[rotornum].rotorid==\0)    /* did we not find it?    */
  256.         rotorgo = \0;            /* Not found, GET OUT!    */
  257.     }
  258.     if (rotorgo!=\0) {            /* now scan good ones    */
  259.         while (rotors[rotornum].rotorid==rotorgo) {
  260.                         /* for each valid entry    */
  261.         tty_mode.sg_erase = CERASE;    /* prepare parameters    */
  262.         tty_mode.sg_kill = CKILL;
  263.         tty_mode.sg_flags = rotors[rotornum].flags;
  264.         tty_mode.sg_ispeed = rotors[rotornum].speed;
  265.         tty_mode.sg_ospeed = rotors[rotornum].speed;
  266.         stty(tty_lun,&tty_mode);    /* set tty parameters    */
  267.         delay(1);
  268.         j=0;                /* count of cr's    */
  269.         while ((j<2) && (read(tty_lun,&chr,1)>0)) {
  270.         /* go until 2 cr's, eof, or we get a bad chr        */
  271.             if ((chr=='\n') || (chr=='\r')) {
  272.             fprintf(outdev,rotormsg);
  273.             j++;            /* count them        */
  274.             }
  275.             else
  276.             break;
  277.         }
  278.  
  279.         if (j==2) {            /* we got 2 cr's, GO!    */
  280.  
  281.             ttys_count = 0;
  282.             ttysfile = fopen("/etc/ttys","r");    /* do it again    */
  283.             while (fread(&chr,1,1,ttysfile)>0)    /* get entry    */
  284.             getentry(chr);
  285.             fclose(ttysfile);        /* have ttys information*/
  286.  
  287.             ttysfile = fopen("/etc/ttys","w");    /* now update    */
  288.             for(i=0;i<ttys_count;i++) {
  289.             if (0==strcmp(ttymatch,ttys[i].dpath))
  290.                 strcpy(ttys[i].tbaud,rotors[rotornum].tbaudset);
  291.                         /* match entry & change    */
  292.             fprintf(ttysfile,"%s:%s:%s:%s:%s:%s:%s:%s\n",
  293.                 ttys[i].state,
  294.                 ttys[i].lineno,
  295.                 ttys[i].dpath,
  296.                 ttys[i].devnum,
  297.                 ttys[i].ttyid,
  298.                 ttys[i].tbaud,
  299.                 ttys[i].tsetb,
  300.                 ttys[i].extra
  301.             );            /* put back in file    */
  302.             };
  303.             fclose(ttysfile);
  304.             rotorgo = \0;        /* done, exit        */
  305.         } else {
  306.             rotornum++;            /* otherwise next entry    */
  307.         }
  308.         } /* end while matching rotorgo */
  309.     } /* end if (rotorgo) */
  310.     } /* end while (rotorgo) */
  311.  
  312.     fprintf(outdev,"\n\nCharles River Data Systems 68/35");
  313.     if (*sysname.nodename)            /* if nodename, print it*/
  314.     fprintf(outdev," (%s)",sysname.nodename);
  315.     fprintf(outdev,"\n\015");
  316.  
  317.     fexecl(post_login, indev, outdev, outdev, "login", ttymatch, 0);
  318.     exit(1);                    /* Never get here???    */
  319. }
  320.  
  321. getentry(a) /* parse entry from /etc/ttys file, increment ttys_count */
  322. char a;
  323. {
  324.     char *ptr;                /* field pointer in record    */
  325.     char *tbl[8];            /* ttys record field pointers    */
  326.     int i;                /* field number, general purpose*/
  327.  
  328.     tbl[0]=ttys[ttys_count].state;        /* point to fields     */
  329.     tbl[1]=ttys[ttys_count].lineno;
  330.     tbl[2]=ttys[ttys_count].dpath;
  331.     tbl[3]=ttys[ttys_count].devnum;
  332.     tbl[4]=ttys[ttys_count].ttyid;
  333.     tbl[5]=ttys[ttys_count].tbaud;
  334.     tbl[6]=ttys[ttys_count].tsetb;
  335.     tbl[7]=ttys[ttys_count].extra;
  336.  
  337.     for(i=0;i<8;i++) *tbl[i]=0;            /* init fields to null    */
  338.  
  339.     i = 0;                    /* start at first field    */
  340.     while (a!=10) {                /* watch for EOL    */
  341.     ptr=tbl[i];                /* point at field    */
  342.     while ((a!=10) && ((i==7) || (a!=58))) {
  343.         *ptr++=a;                /* save chr if valid    */
  344.         if (fread(&a,1,1,ttysfile)==0) a=10;/* EOF, terminate    */
  345.     }
  346.     if (a!=10)
  347.         if (fread(&a,1,1,ttysfile)==0) a=10;/* is there next field?    */
  348.     *ptr=0;                    /* mark end of string    */
  349.     if (i<7) i++;                /* next field ptr    */
  350.     }
  351.     ttys_count++;                /* count line-item    */
  352. }
  353.  
  354. at_init()
  355. {
  356.     int awake = 0;
  357.     char junk;
  358.  
  359.     tty_mode.sg_erase = CERASE;            /* prepare parameters    */
  360.     tty_mode.sg_kill = CKILL;
  361.     tty_mode.sg_flags = CR1+NL1+CRMOD+RAW;
  362.     tty_mode.sg_ispeed = B1200;
  363.     tty_mode.sg_ospeed = B1200;
  364.     stty(tty_lun,&tty_mode);            /* set tty parameters    */
  365.  
  366.     sleep(4);
  367.     fprintf(outdev,"+++");            /* get modems attention    */
  368.     sleep(4);
  369.     fprintf(outdev,"\r");
  370.     sleep(1);
  371.     fprintf(outdev,"ATZ\r");            /* reset modem        */
  372.     sleep(1);
  373.     fprintf(outdev,"ATS0=1\r");            /* auto answer        */
  374.     sleep(1);
  375.     junk=' ';
  376.     while(junk!='1') read(tty_lun,&junk,1);    /* flush input buffer    */
  377.     while(junk!='\r') read(tty_lun,&junk,1);
  378. }
  379.