home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / libexec / getty / subr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-06  |  9.2 KB  |  507 lines

  1. /*
  2.  * Copyright (c) 1983 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)subr.c    5.10 (Berkeley) 2/26/91";
  36. #endif /* not lint */
  37.  
  38. /*
  39.  * Melbourne getty.
  40.  */
  41. #define USE_OLD_TTY
  42. #include <sgtty.h>
  43. #include <unistd.h>
  44. #include <string.h>
  45. #include "gettytab.h"
  46.  
  47. extern    struct sgttyb tmode;
  48. extern    struct tchars tc;
  49. extern    struct ltchars ltc;
  50.  
  51. /*
  52.  * Get a table entry.
  53.  */
  54. gettable(name, buf, area)
  55.     char *name, *buf, *area;
  56. {
  57.     register struct gettystrs *sp;
  58.     register struct gettynums *np;
  59.     register struct gettyflags *fp;
  60.     register n;
  61.  
  62.     hopcount = 0;        /* new lookup, start fresh */
  63.     if (getent(buf, name) != 1)
  64.         return;
  65.  
  66.     for (sp = gettystrs; sp->field; sp++)
  67.         sp->value = getstr(sp->field, &area);
  68.     for (np = gettynums; np->field; np++) {
  69.         n = getnum(np->field);
  70.         if (n == -1)
  71.             np->set = 0;
  72.         else {
  73.             np->set = 1;
  74.             np->value = n;
  75.         }
  76.     }
  77.     for (fp = gettyflags; fp->field; fp++) {
  78.         n = getflag(fp->field);
  79.         if (n == -1)
  80.             fp->set = 0;
  81.         else {
  82.             fp->set = 1;
  83.             fp->value = n ^ fp->invrt;
  84.         }
  85.     }
  86. }
  87.  
  88. gendefaults()
  89. {
  90.     register struct gettystrs *sp;
  91.     register struct gettynums *np;
  92.     register struct gettyflags *fp;
  93.  
  94.     for (sp = gettystrs; sp->field; sp++)
  95.         if (sp->value)
  96.             sp->defalt = sp->value;
  97.     for (np = gettynums; np->field; np++)
  98.         if (np->set)
  99.             np->defalt = np->value;
  100.     for (fp = gettyflags; fp->field; fp++)
  101.         if (fp->set)
  102.             fp->defalt = fp->value;
  103.         else
  104.             fp->defalt = fp->invrt;
  105. }
  106.  
  107. setdefaults()
  108. {
  109.     register struct gettystrs *sp;
  110.     register struct gettynums *np;
  111.     register struct gettyflags *fp;
  112.  
  113.     for (sp = gettystrs; sp->field; sp++)
  114.         if (!sp->value)
  115.             sp->value = sp->defalt;
  116.     for (np = gettynums; np->field; np++)
  117.         if (!np->set)
  118.             np->value = np->defalt;
  119.     for (fp = gettyflags; fp->field; fp++)
  120.         if (!fp->set)
  121.             fp->value = fp->defalt;
  122. }
  123.  
  124. static char **
  125. charnames[] = {
  126.     &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
  127.     &SU, &DS, &RP, &FL, &WE, &LN, 0
  128. };
  129.  
  130. static char *
  131. charvars[] = {
  132.     &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
  133.     &tc.t_quitc, &tc.t_startc, &tc.t_stopc,
  134.     &tc.t_eofc, &tc.t_brkc, <c.t_suspc,
  135.     <c.t_dsuspc, <c.t_rprntc, <c.t_flushc,
  136.     <c.t_werasc, <c.t_lnextc, 0
  137. };
  138.  
  139. setchars()
  140. {
  141.     register int i;
  142.     register char *p;
  143.  
  144.     for (i = 0; charnames[i]; i++) {
  145.         p = *charnames[i];
  146.         if (p && *p)
  147.             *charvars[i] = *p;
  148.         else
  149.             *charvars[i] = '\377';
  150.     }
  151. }
  152.  
  153. long
  154. setflags(n)
  155. {
  156.     register long f;
  157.  
  158.     switch (n) {
  159.     case 0:
  160.         if (F0set)
  161.             return(F0);
  162.         break;
  163.     case 1:
  164.         if (F1set)
  165.             return(F1);
  166.         break;
  167.     default:
  168.         if (F2set)
  169.             return(F2);
  170.         break;
  171.     }
  172.  
  173.     f = 0;
  174.  
  175.     if (AP)
  176.         f |= ANYP;
  177.     else if (OP)
  178.         f |= ODDP;
  179.     else if (EP)
  180.         f |= EVENP;
  181.  
  182.     if (UC)
  183.         f |= LCASE;
  184.  
  185.     if (NL)
  186.         f |= CRMOD;
  187.  
  188.     f |= delaybits();
  189.  
  190.     if (n == 1) {        /* read mode flags */
  191.         if (RW)
  192.             f |= RAW;
  193.         else
  194.             f |= CBREAK;
  195.         return (f);
  196.     }
  197.  
  198.     if (!HT)
  199.         f |= XTABS;
  200.  
  201.     if (n == 0)
  202.         return (f);
  203.  
  204.     if (CB)
  205.         f |= CRTBS;
  206.  
  207.     if (CE)
  208.         f |= CRTERA;
  209.  
  210.     if (CK)
  211.         f |= CRTKIL;
  212.  
  213.     if (PE)
  214.         f |= PRTERA;
  215.  
  216.     if (EC)
  217.         f |= ECHO;
  218.  
  219.     if (XC)
  220.         f |= CTLECH;
  221.  
  222.     if (DX)
  223.         f |= DECCTQ;
  224.  
  225.     return (f);
  226. }
  227.  
  228. struct delayval {
  229.     unsigned    delay;        /* delay in ms */
  230.     int        bits;
  231. };
  232.  
  233. /*
  234.  * below are random guesses, I can't be bothered checking
  235.  */
  236.  
  237. struct delayval    crdelay[] = {
  238.     1,        CR1,
  239.     2,        CR2,
  240.     3,        CR3,
  241.     83,        CR1,
  242.     166,        CR2,
  243.     0,        CR3,
  244. };
  245.  
  246. struct delayval nldelay[] = {
  247.     1,        NL1,        /* special, calculated */
  248.     2,        NL2,
  249.     3,        NL3,
  250.     100,        NL2,
  251.     0,        NL3,
  252. };
  253.  
  254. struct delayval    bsdelay[] = {
  255.     1,        BS1,
  256.     0,        0,
  257. };
  258.  
  259. struct delayval    ffdelay[] = {
  260.     1,        FF1,
  261.     1750,        FF1,
  262.     0,        FF1,
  263. };
  264.  
  265. struct delayval    tbdelay[] = {
  266.     1,        TAB1,
  267.     2,        TAB2,
  268.     3,        XTABS,        /* this is expand tabs */
  269.     100,        TAB1,
  270.     0,        TAB2,
  271. };
  272.  
  273. delaybits()
  274. {
  275.     register f;
  276.  
  277.     f  = adelay(CD, crdelay);
  278.     f |= adelay(ND, nldelay);
  279.     f |= adelay(FD, ffdelay);
  280.     f |= adelay(TD, tbdelay);
  281.     f |= adelay(BD, bsdelay);
  282.     return (f);
  283. }
  284.  
  285. adelay(ms, dp)
  286.     register ms;
  287.     register struct delayval *dp;
  288. {
  289.     if (ms == 0)
  290.         return (0);
  291.     while (dp->delay && ms > dp->delay)
  292.         dp++;
  293.     return (dp->bits);
  294. }
  295.  
  296. char    editedhost[32];
  297.  
  298. edithost(pat)
  299.     register char *pat;
  300. {
  301.     register char *host = HN;
  302.     register char *res = editedhost;
  303.  
  304.     if (!pat)
  305.         pat = "";
  306.     while (*pat) {
  307.         switch (*pat) {
  308.  
  309.         case '#':
  310.             if (*host)
  311.                 host++;
  312.             break;
  313.  
  314.         case '@':
  315.             if (*host)
  316.                 *res++ = *host++;
  317.             break;
  318.  
  319.         default:
  320.             *res++ = *pat;
  321.             break;
  322.  
  323.         }
  324.         if (res == &editedhost[sizeof editedhost - 1]) {
  325.             *res = '\0';
  326.             return;
  327.         }
  328.         pat++;
  329.     }
  330.     if (*host)
  331.         strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
  332.     else
  333.         *res = '\0';
  334.     editedhost[sizeof editedhost - 1] = '\0';
  335. }
  336.  
  337. struct speedtab {
  338.     int    speed;
  339.     int    uxname;
  340. } speedtab[] = {
  341.     50,    B50,
  342.     75,    B75,
  343.     110,    B110,
  344.     134,    B134,
  345.     150,    B150,
  346.     200,    B200,
  347.     300,    B300,
  348.     600,    B600,
  349.     1200,    B1200,
  350.     1800,    B1800,
  351.     2400,    B2400,
  352.     4800,    B4800,
  353.     9600,    B9600,
  354.     19200,    EXTA,
  355.     19,    EXTA,        /* for people who say 19.2K */
  356.     38400,    EXTB,
  357.     38,    EXTB,
  358.     7200,    EXTB,        /* alternative */
  359.     0
  360. };
  361.  
  362. speed(val)
  363. {
  364.     register struct speedtab *sp;
  365.  
  366.     if (val <= 15)
  367.         return (val);
  368.  
  369.     for (sp = speedtab; sp->speed; sp++)
  370.         if (sp->speed == val)
  371.             return (sp->uxname);
  372.     
  373.     return (B300);        /* default in impossible cases */
  374. }
  375.  
  376. makeenv(env)
  377.     char *env[];
  378. {
  379.     static char termbuf[128] = "TERM=";
  380.     register char *p, *q;
  381.     register char **ep;
  382.     char *index();
  383.  
  384.     ep = env;
  385.     if (TT && *TT) {
  386.         strcat(termbuf, TT);
  387.         *ep++ = termbuf;
  388.     }
  389.     if (p = EV) {
  390.         q = p;
  391.         while (q = index(q, ',')) {
  392.             *q++ = '\0';
  393.             *ep++ = p;
  394.             p = q;
  395.         }
  396.         if (*p)
  397.             *ep++ = p;
  398.     }
  399.     *ep = (char *)0;
  400. }
  401.  
  402. /*
  403.  * This speed select mechanism is written for the Develcon DATASWITCH.
  404.  * The Develcon sends a string of the form "B{speed}\n" at a predefined
  405.  * baud rate. This string indicates the user's actual speed.
  406.  * The routine below returns the terminal type mapped from derived speed.
  407.  */
  408. struct    portselect {
  409.     char    *ps_baud;
  410.     char    *ps_type;
  411. } portspeeds[] = {
  412.     { "B110",    "std.110" },
  413.     { "B134",    "std.134" },
  414.     { "B150",    "std.150" },
  415.     { "B300",    "std.300" },
  416.     { "B600",    "std.600" },
  417.     { "B1200",    "std.1200" },
  418.     { "B2400",    "std.2400" },
  419.     { "B4800",    "std.4800" },
  420.     { "B9600",    "std.9600" },
  421.     { "B19200",    "std.19200" },
  422.     { 0 }
  423. };
  424.  
  425. char *
  426. portselector()
  427. {
  428.     char c, baud[20], *type = "default";
  429.     register struct portselect *ps;
  430.     int len;
  431.  
  432.     alarm(5*60);
  433.     for (len = 0; len < sizeof (baud) - 1; len++) {
  434.         if (read(STDIN_FILENO, &c, 1) <= 0)
  435.             break;
  436.         c &= 0177;
  437.         if (c == '\n' || c == '\r')
  438.             break;
  439.         if (c == 'B')
  440.             len = 0;    /* in case of leading garbage */
  441.         baud[len] = c;
  442.     }
  443.     baud[len] = '\0';
  444.     for (ps = portspeeds; ps->ps_baud; ps++)
  445.         if (strcmp(ps->ps_baud, baud) == 0) {
  446.             type = ps->ps_type;
  447.             break;
  448.         }
  449.     sleep(2);    /* wait for connection to complete */
  450.     return (type);
  451. }
  452.  
  453. /*
  454.  * This auto-baud speed select mechanism is written for the Micom 600
  455.  * portselector. Selection is done by looking at how the character '\r'
  456.  * is garbled at the different speeds.
  457.  */
  458. #include <sys/time.h>
  459.  
  460. char *
  461. autobaud()
  462. {
  463.     int rfds;
  464.     struct timeval timeout;
  465.     char c, *type = "9600-baud";
  466.     int null = 0;
  467.  
  468.     ioctl(0, TIOCFLUSH, &null);
  469.     rfds = 1 << 0;
  470.     timeout.tv_sec = 5;
  471.     timeout.tv_usec = 0;
  472.     if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
  473.         (fd_set *)NULL, &timeout) <= 0)
  474.         return (type);
  475.     if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
  476.         return (type);
  477.     timeout.tv_sec = 0;
  478.     timeout.tv_usec = 20;
  479.     (void) select(32, (fd_set *)NULL, (fd_set *)NULL,
  480.         (fd_set *)NULL, &timeout);
  481.     ioctl(0, TIOCFLUSH, &null);
  482.     switch (c & 0377) {
  483.  
  484.     case 0200:        /* 300-baud */
  485.         type = "300-baud";
  486.         break;
  487.  
  488.     case 0346:        /* 1200-baud */
  489.         type = "1200-baud";
  490.         break;
  491.  
  492.     case  015:        /* 2400-baud */
  493.     case 0215:
  494.         type = "2400-baud";
  495.         break;
  496.  
  497.     default:        /* 4800-baud */
  498.         type = "4800-baud";
  499.         break;
  500.  
  501.     case 0377:        /* 9600-baud */
  502.         type = "9600-baud";
  503.         break;
  504.     }
  505.     return (type);
  506. }
  507.