386BSD 0.0 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Mon, 6 May 1991 23:31:44 +0000 (15:31 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Mon, 6 May 1991 23:31:44 +0000 (15:31 -0800)
Work on file usr/src/libexec/getty/gettytab.c
Work on file usr/src/libexec/getty/gettytab.h
Work on file usr/src/libexec/getty/init.c
Work on file usr/src/libexec/getty/pathnames.h
Work on file usr/src/libexec/getty/main.c
Work on file usr/src/libexec/getty/ttydefaults.c
Work on file usr/src/libexec/getty/subr.c

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.0/src

usr/src/libexec/getty/gettytab.c [new file with mode: 0644]
usr/src/libexec/getty/gettytab.h [new file with mode: 0644]
usr/src/libexec/getty/init.c [new file with mode: 0644]
usr/src/libexec/getty/main.c [new file with mode: 0644]
usr/src/libexec/getty/pathnames.h [new file with mode: 0644]
usr/src/libexec/getty/subr.c [new file with mode: 0644]
usr/src/libexec/getty/ttydefaults.c [new file with mode: 0644]

diff --git a/usr/src/libexec/getty/gettytab.c b/usr/src/libexec/getty/gettytab.c
new file mode 100644 (file)
index 0000000..cfdddc0
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)gettytab.c 5.5 (Berkeley) 2/25/91";
+#endif /* not lint */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include "pathnames.h"
+
+#define        TABBUFSIZ       512
+
+static char *tbuf;
+int    hopcount;       /* detect infinite loops in termcap, init 0 */
+char   *skip();
+char   *getstr();
+char   *decode();
+
+/*
+ * Get an entry for terminal name in buffer bp,
+ * from the termcap file.  Parse is very rudimentary;
+ * we just notice escaped newlines.
+ */
+getent(bp, name)
+       char *bp, *name;
+{
+       register char *cp;
+       register int c;
+       register int i = 0, cnt = 0;
+       char ibuf[TABBUFSIZ];
+       char *cp2;
+       int tf;
+
+       tbuf = bp;
+       tf = open(_PATH_GETTYTAB, O_RDONLY, 0);
+       if (tf < 0)
+               return (-1);
+       for (;;) {
+               cp = bp;
+               for (;;) {
+                       if (i == cnt) {
+                               cnt = read(tf, ibuf, TABBUFSIZ);
+                               if (cnt <= 0) {
+                                       close(tf);
+                                       return (0);
+                               }
+                               i = 0;
+                       }
+                       c = ibuf[i++];
+                       if (c == '\n') {
+                               if (cp > bp && cp[-1] == '\\'){
+                                       cp--;
+                                       continue;
+                               }
+                               break;
+                       }
+                       if (cp >= bp+TABBUFSIZ) {
+                               write(2,"Gettytab entry too long\n", 24);
+                               break;
+                       } else
+                               *cp++ = c;
+               }
+               *cp = 0;
+
+               /*
+                * The real work for the match.
+                */
+               if (namatch(name)) {
+                       close(tf);
+                       return(nchktc());
+               }
+       }
+}
+
+/*
+ * tnchktc: check the last entry, see if it's tc=xxx. If so,
+ * recursively find xxx and append that entry (minus the names)
+ * to take the place of the tc=xxx entry. This allows termcap
+ * entries to say "like an HP2621 but doesn't turn on the labels".
+ * Note that this works because of the left to right scan.
+ */
+#define        MAXHOP  32
+nchktc()
+{
+       register char *p, *q;
+       char tcname[16];        /* name of similar terminal */
+       char tcbuf[TABBUFSIZ];
+       char *holdtbuf = tbuf;
+       int l;
+
+       p = tbuf + strlen(tbuf) - 2;    /* before the last colon */
+       while (*--p != ':')
+               if (p<tbuf) {
+                       write(2, "Bad gettytab entry\n", 19);
+                       return (0);
+               }
+       p++;
+       /* p now points to beginning of last field */
+       if (p[0] != 't' || p[1] != 'c')
+               return(1);
+       strcpy(tcname,p+3);
+       q = tcname;
+       while (q && *q != ':')
+               q++;
+       *q = 0;
+       if (++hopcount > MAXHOP) {
+               write(2, "Getty: infinite tc= loop\n", 25);
+               return (0);
+       }
+       if (getent(tcbuf, tcname) != 1)
+               return(0);
+       for (q=tcbuf; *q != ':'; q++)
+               ;
+       l = p - holdtbuf + strlen(q);
+       if (l > TABBUFSIZ) {
+               write(2, "Gettytab entry too long\n", 24);
+               q[TABBUFSIZ - (p-tbuf)] = 0;
+       }
+       strcpy(p, q+1);
+       tbuf = holdtbuf;
+       return(1);
+}
+
+/*
+ * Tnamatch deals with name matching.  The first field of the termcap
+ * entry is a sequence of names separated by |'s, so we compare
+ * against each such name.  The normal : terminator after the last
+ * name (before the first field) stops us.
+ */
+namatch(np)
+       char *np;
+{
+       register char *Np, *Bp;
+
+       Bp = tbuf;
+       if (*Bp == '#')
+               return(0);
+       for (;;) {
+               for (Np = np; *Np && *Bp == *Np; Bp++, Np++)
+                       continue;
+               if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0))
+                       return (1);
+               while (*Bp && *Bp != ':' && *Bp != '|')
+                       Bp++;
+               if (*Bp == 0 || *Bp == ':')
+                       return (0);
+               Bp++;
+       }
+}
+
+/*
+ * Skip to the next field.  Notice that this is very dumb, not
+ * knowing about \: escapes or any such.  If necessary, :'s can be put
+ * into the termcap file in octal.
+ */
+static char *
+skip(bp)
+       register char *bp;
+{
+
+       while (*bp && *bp != ':')
+               bp++;
+       if (*bp == ':')
+               bp++;
+       return (bp);
+}
+
+/*
+ * Return the (numeric) option id.
+ * Numeric options look like
+ *     li#80
+ * i.e. the option string is separated from the numeric value by
+ * a # character.  If the option is not found we return -1.
+ * Note that we handle octal numbers beginning with 0.
+ */
+long
+getnum(id)
+       char *id;
+{
+       register long i, base;
+       register char *bp = tbuf;
+
+       for (;;) {
+               bp = skip(bp);
+               if (*bp == 0)
+                       return (-1);
+               if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
+                       continue;
+               if (*bp == '@')
+                       return(-1);
+               if (*bp != '#')
+                       continue;
+               bp++;
+               base = 10;
+               if (*bp == '0')
+                       base = 8;
+               i = 0;
+               while (isdigit(*bp))
+                       i *= base, i += *bp++ - '0';
+               return (i);
+       }
+}
+
+/*
+ * Handle a flag option.
+ * Flag options are given "naked", i.e. followed by a : or the end
+ * of the buffer.  Return 1 if we find the option, or 0 if it is
+ * not given.
+ */
+getflag(id)
+       char *id;
+{
+       register char *bp = tbuf;
+
+       for (;;) {
+               bp = skip(bp);
+               if (!*bp)
+                       return (-1);
+               if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) {
+                       if (!*bp || *bp == ':')
+                               return (1);
+                       else if (*bp == '!')
+                               return (0);
+                       else if (*bp == '@')
+                               return(-1);
+               }
+       }
+}
+
+/*
+ * Get a string valued option.
+ * These are given as
+ *     cl=^Z
+ * Much decoding is done on the strings, and the strings are
+ * placed in area, which is a ref parameter which is updated.
+ * No checking on area overflow.
+ */
+char *
+getstr(id, area)
+       char *id, **area;
+{
+       register char *bp = tbuf;
+
+       for (;;) {
+               bp = skip(bp);
+               if (!*bp)
+                       return (0);
+               if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1])
+                       continue;
+               if (*bp == '@')
+                       return(0);
+               if (*bp != '=')
+                       continue;
+               bp++;
+               return (decode(bp, area));
+       }
+}
+
+/*
+ * Tdecode does the grung work to decode the
+ * string capability escapes.
+ */
+static char *
+decode(str, area)
+       register char *str;
+       char **area;
+{
+       register char *cp;
+       register int c;
+       register char *dp;
+       int i;
+
+       cp = *area;
+       while ((c = *str++) && c != ':') {
+               switch (c) {
+
+               case '^':
+                       c = *str++ & 037;
+                       break;
+
+               case '\\':
+                       dp = "E\033^^\\\\::n\nr\rt\tb\bf\f";
+                       c = *str++;
+nextc:
+                       if (*dp++ == c) {
+                               c = *dp++;
+                               break;
+                       }
+                       dp++;
+                       if (*dp)
+                               goto nextc;
+                       if (isdigit(c)) {
+                               c -= '0', i = 2;
+                               do
+                                       c <<= 3, c |= *str++ - '0';
+                               while (--i && isdigit(*str));
+                       }
+                       break;
+               }
+               *cp++ = c;
+       }
+       *cp++ = 0;
+       str = *area;
+       *area = cp;
+       return (str);
+}
diff --git a/usr/src/libexec/getty/gettytab.h b/usr/src/libexec/getty/gettytab.h
new file mode 100644 (file)
index 0000000..33f797a
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)gettytab.h  5.5 (Berkeley) 3/27/91
+ */
+
+/*
+ * Getty description definitions.
+ */
+struct gettystrs {
+       char    *field;         /* name to lookup in gettytab */
+       char    *defalt;        /* value we find by looking in defaults */
+       char    *value;         /* value that we find there */
+};
+
+struct gettynums {
+       char    *field;         /* name to lookup */
+       long    defalt;         /* number we find in defaults */
+       long    value;          /* number we find there */
+       int     set;            /* we actually got this one */
+};
+
+struct gettyflags {
+       char    *field;         /* name to lookup */
+       char    invrt;          /* name existing in gettytab --> false */
+       char    defalt;         /* true/false in defaults */
+       char    value;          /* true/false flag */
+       char    set;            /* we found it */
+};
+
+/*
+ * String values.
+ */
+#define        NX      gettystrs[0].value
+#define        CL      gettystrs[1].value
+#define IM     gettystrs[2].value
+#define        LM      gettystrs[3].value
+#define        ER      gettystrs[4].value
+#define        KL      gettystrs[5].value
+#define        ET      gettystrs[6].value
+#define        PC      gettystrs[7].value
+#define        TT      gettystrs[8].value
+#define        EV      gettystrs[9].value
+#define        LO      gettystrs[10].value
+#define HN     gettystrs[11].value
+#define HE     gettystrs[12].value
+#define IN     gettystrs[13].value
+#define QU     gettystrs[14].value
+#define XN     gettystrs[15].value
+#define XF     gettystrs[16].value
+#define BK     gettystrs[17].value
+#define SU     gettystrs[18].value
+#define DS     gettystrs[19].value
+#define RP     gettystrs[20].value
+#define FL     gettystrs[21].value
+#define WE     gettystrs[22].value
+#define LN     gettystrs[23].value
+
+/*
+ * Numeric definitions.
+ */
+#define        IS      gettynums[0].value
+#define        OS      gettynums[1].value
+#define        SP      gettynums[2].value
+#define        ND      gettynums[3].value
+#define        CD      gettynums[4].value
+#define        TD      gettynums[5].value
+#define        FD      gettynums[6].value
+#define        BD      gettynums[7].value
+#define        TO      gettynums[8].value
+#define        F0      gettynums[9].value
+#define        F0set   gettynums[9].set
+#define        F1      gettynums[10].value
+#define        F1set   gettynums[10].set
+#define        F2      gettynums[11].value
+#define        F2set   gettynums[11].set
+#define        PF      gettynums[12].value
+
+/*
+ * Boolean values.
+ */
+#define        HT      gettyflags[0].value
+#define        NL      gettyflags[1].value
+#define        EP      gettyflags[2].value
+#define        EPset   gettyflags[2].set
+#define        OP      gettyflags[3].value
+#define        OPset   gettyflags[2].set
+#define        AP      gettyflags[4].value
+#define        APset   gettyflags[2].set
+#define        EC      gettyflags[5].value
+#define        CO      gettyflags[6].value
+#define        CB      gettyflags[7].value
+#define        CK      gettyflags[8].value
+#define        CE      gettyflags[9].value
+#define        PE      gettyflags[10].value
+#define        RW      gettyflags[11].value
+#define        XC      gettyflags[12].value
+#define        LC      gettyflags[13].value
+#define        UC      gettyflags[14].value
+#define        IG      gettyflags[15].value
+#define        PS      gettyflags[16].value
+#define        HC      gettyflags[17].value
+#define UB     gettyflags[18].value
+#define AB     gettyflags[19].value
+#define DX     gettyflags[20].value
+#define        NP      gettyflags[21].value
+
+int    getent();
+long   getnum();
+int    getflag();
+char   *getstr();
+
+extern struct gettyflags gettyflags[];
+extern struct gettynums gettynums[];
+extern struct gettystrs gettystrs[];
+extern int hopcount;
diff --git a/usr/src/libexec/getty/init.c b/usr/src/libexec/getty/init.c
new file mode 100644 (file)
index 0000000..ac7112f
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)init.c     5.6 (Berkeley) 3/27/91";
+#endif /* not lint */
+
+/*
+ * Getty table initializations.
+ *
+ * Melbourne getty.
+ */
+#include <sgtty.h>
+#include "gettytab.h"
+#include "pathnames.h"
+
+extern struct sgttyb tmode;
+extern struct tchars tc;
+extern struct ltchars ltc;
+extern char hostname[];
+
+struct gettystrs gettystrs[] = {
+       { "nx" },                       /* next table */
+       { "cl" },                       /* screen clear characters */
+       { "im" },                       /* initial message */
+       { "lm", "login: " },            /* login message */
+       { "er", &tmode.sg_erase },      /* erase character */
+       { "kl", &tmode.sg_kill },       /* kill character */
+       { "et", &tc.t_eofc },           /* eof chatacter (eot) */
+       { "pc", "" },                   /* pad character */
+       { "tt" },                       /* terminal type */
+       { "ev" },                       /* enviroment */
+       { "lo", _PATH_LOGIN },          /* login program */
+       { "hn", hostname },             /* host name */
+       { "he" },                       /* host name edit */
+       { "in", &tc.t_intrc },          /* interrupt char */
+       { "qu", &tc.t_quitc },          /* quit char */
+       { "xn", &tc.t_startc },         /* XON (start) char */
+       { "xf", &tc.t_stopc },          /* XOFF (stop) char */
+       { "bk", &tc.t_brkc },           /* brk char (alt \n) */
+       { "su", &ltc.t_suspc },         /* suspend char */
+       { "ds", &ltc.t_dsuspc },        /* delayed suspend */
+       { "rp", &ltc.t_rprntc },        /* reprint char */
+       { "fl", &ltc.t_flushc },        /* flush output */
+       { "we", &ltc.t_werasc },        /* word erase */
+       { "ln", &ltc.t_lnextc },        /* literal next */
+       { 0 }
+};
+
+struct gettynums gettynums[] = {
+       { "is" },                       /* input speed */
+       { "os" },                       /* output speed */
+       { "sp" },                       /* both speeds */
+       { "nd" },                       /* newline delay */
+       { "cd" },                       /* carriage-return delay */
+       { "td" },                       /* tab delay */
+       { "fd" },                       /* form-feed delay */
+       { "bd" },                       /* backspace delay */
+       { "to" },                       /* timeout */
+       { "f0" },                       /* output flags */
+       { "f1" },                       /* input flags */
+       { "f2" },                       /* user mode flags */
+       { "pf" },                       /* delay before flush at 1st prompt */
+       { 0 }
+};
+
+struct gettyflags gettyflags[] = {
+       { "ht", 0 },                    /* has tabs */
+       { "nl", 1 },                    /* has newline char */
+       { "ep", 0 },                    /* even parity */
+       { "op", 0 },                    /* odd parity */
+       { "ap", 0 },                    /* any parity */
+       { "ec", 1 },                    /* no echo */
+       { "co", 0 },                    /* console special */
+       { "cb", 0 },                    /* crt backspace */
+       { "ck", 0 },                    /* crt kill */
+       { "ce", 0 },                    /* crt erase */
+       { "pe", 0 },                    /* printer erase */
+       { "rw", 1 },                    /* don't use raw */
+       { "xc", 1 },                    /* don't ^X ctl chars */
+       { "lc", 0 },                    /* terminal las lower case */
+       { "uc", 0 },                    /* terminal has no lower case */
+       { "ig", 0 },                    /* ignore garbage */
+       { "ps", 0 },                    /* do port selector speed select */
+       { "hc", 1 },                    /* don't set hangup on close */
+       { "ub", 0 },                    /* unbuffered output */
+       { "ab", 0 },                    /* auto-baud detect with '\r' */
+       { "dx", 0 },                    /* set decctlq */
+       { "np", 0 },                    /* no parity at all (8bit chars) */
+       { 0 }
+};
diff --git a/usr/src/libexec/getty/main.c b/usr/src/libexec/getty/main.c
new file mode 100644 (file)
index 0000000..e95bdb1
--- /dev/null
@@ -0,0 +1,499 @@
+/*-
+ * Copyright (c) 1980 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c     5.16 (Berkeley) 3/27/91";
+#endif /* not lint */
+
+#define USE_OLD_TTY
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sgtty.h>
+#include <time.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gettytab.h"
+#include "pathnames.h"
+
+struct sgttyb tmode = {
+       0, 0, CERASE, CKILL, 0
+};
+struct tchars tc = {
+       CINTR, CQUIT, CSTART,
+       CSTOP, CEOF, CBRK,
+};
+struct ltchars ltc = {
+       CSUSP, CDSUSP, CRPRNT,
+       CFLUSH, CWERASE, CLNEXT
+};
+
+int crmod, digit, lower, upper;
+
+char   hostname[MAXHOSTNAMELEN];
+char   name[16];
+char   dev[] = _PATH_DEV;
+char   ttyn[32];
+char   *portselector();
+char   *ttyname();
+
+#define        OBUFSIZ         128
+#define        TABBUFSIZ       512
+
+char   defent[TABBUFSIZ];
+char   defstrs[TABBUFSIZ];
+char   tabent[TABBUFSIZ];
+char   tabstrs[TABBUFSIZ];
+
+char   *env[128];
+
+char partab[] = {
+       0001,0201,0201,0001,0201,0001,0001,0201,
+       0202,0004,0003,0205,0005,0206,0201,0001,
+       0201,0001,0001,0201,0001,0201,0201,0001,
+       0001,0201,0201,0001,0201,0001,0001,0201,
+       0200,0000,0000,0200,0000,0200,0200,0000,
+       0000,0200,0200,0000,0200,0000,0000,0200,
+       0000,0200,0200,0000,0200,0000,0000,0200,
+       0200,0000,0000,0200,0000,0200,0200,0000,
+       0200,0000,0000,0200,0000,0200,0200,0000,
+       0000,0200,0200,0000,0200,0000,0000,0200,
+       0000,0200,0200,0000,0200,0000,0000,0200,
+       0200,0000,0000,0200,0000,0200,0200,0000,
+       0000,0200,0200,0000,0200,0000,0000,0200,
+       0200,0000,0000,0200,0000,0200,0200,0000,
+       0200,0000,0000,0200,0000,0200,0200,0000,
+       0000,0200,0200,0000,0200,0000,0000,0201
+};
+
+#define        ERASE   tmode.sg_erase
+#define        KILL    tmode.sg_kill
+#define        EOT     tc.t_eofc
+
+jmp_buf timeout;
+
+static void
+dingdong()
+{
+
+       alarm(0);
+       signal(SIGALRM, SIG_DFL);
+       longjmp(timeout, 1);
+}
+
+jmp_buf        intrupt;
+
+static void
+interrupt()
+{
+
+       signal(SIGINT, interrupt);
+       longjmp(intrupt, 1);
+}
+
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       extern  char **environ;
+       char *tname;
+       long allflags;
+       int repcnt = 0;
+
+       signal(SIGINT, SIG_IGN);
+/*
+       signal(SIGQUIT, SIG_DFL);
+*/
+       openlog("getty", LOG_ODELAY|LOG_CONS, LOG_AUTH);
+       gethostname(hostname, sizeof(hostname));
+       if (hostname[0] == '\0')
+               strcpy(hostname, "Amnesiac");
+       /*
+        * The following is a work around for vhangup interactions
+        * which cause great problems getting window systems started.
+        * If the tty line is "-", we do the old style getty presuming
+        * that the file descriptors are already set up for us. 
+        * J. Gettys - MIT Project Athena.
+        */
+       if (argc <= 2 || strcmp(argv[2], "-") == 0)
+           strcpy(ttyn, ttyname(0));
+       else {
+           int i;
+
+           strcpy(ttyn, dev);
+           strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev));
+           if (strcmp(argv[0], "+") != 0) {
+               chown(ttyn, 0, 0);
+               chmod(ttyn, 0600);
+               revoke(ttyn);
+               /*
+                * Delay the open so DTR stays down long enough to be detected.
+                */
+               sleep(2);
+               while ((i = open(ttyn, O_RDWR)) == -1) {
+                       if (repcnt % 10 == 0) {
+                               syslog(LOG_ERR, "%s: %m", ttyn);
+                               closelog();
+                       }
+                       repcnt++;
+                       sleep(60);
+               }
+               login_tty(i);
+           }
+       }
+
+       gettable("default", defent, defstrs);
+       gendefaults();
+       tname = "default";
+       if (argc > 1)
+               tname = argv[1];
+       for (;;) {
+               int ldisp = OTTYDISC;
+               int off = 0;
+
+               gettable(tname, tabent, tabstrs);
+               if (OPset || EPset || APset)
+                       APset++, OPset++, EPset++;
+               setdefaults();
+               ioctl(0, TIOCFLUSH, 0);         /* clear out the crap */
+               ioctl(0, FIONBIO, &off);        /* turn off non-blocking mode */
+               ioctl(0, FIOASYNC, &off);       /* ditto for async mode */
+               if (IS)
+                       tmode.sg_ispeed = speed(IS);
+               else if (SP)
+                       tmode.sg_ispeed = speed(SP);
+               if (OS)
+                       tmode.sg_ospeed = speed(OS);
+               else if (SP)
+                       tmode.sg_ospeed = speed(SP);
+               tmode.sg_flags = setflags(0);
+               ioctl(0, TIOCSETP, &tmode);
+               setchars();
+               ioctl(0, TIOCSETC, &tc);
+               if (HC)
+                       ioctl(0, TIOCHPCL, 0);
+               if (AB) {
+                       extern char *autobaud();
+
+                       tname = autobaud();
+                       continue;
+               }
+               if (PS) {
+                       tname = portselector();
+                       continue;
+               }
+               if (CL && *CL)
+                       putpad(CL);
+               edithost(HE);
+               if (IM && *IM)
+                       putf(IM);
+               if (setjmp(timeout)) {
+                       tmode.sg_ispeed = tmode.sg_ospeed = 0;
+                       ioctl(0, TIOCSETP, &tmode);
+                       exit(1);
+               }
+               if (TO) {
+                       signal(SIGALRM, dingdong);
+                       alarm(TO);
+               }
+               if (getname()) {
+                       register int i;
+
+                       oflush();
+                       alarm(0);
+                       signal(SIGALRM, SIG_DFL);
+                       if (name[0] == '-') {
+                               puts("user names may not start with '-'.");
+                               continue;
+                       }
+                       if (!(upper || lower || digit))
+                               continue;
+                       allflags = setflags(2);
+                       tmode.sg_flags = allflags & 0xffff;
+                       allflags >>= 16;
+                       if (crmod || NL)
+                               tmode.sg_flags |= CRMOD;
+                       if (upper || UC)
+                               tmode.sg_flags |= LCASE;
+                       if (lower || LC)
+                               tmode.sg_flags &= ~LCASE;
+                       ioctl(0, TIOCSETP, &tmode);
+                       ioctl(0, TIOCSLTC, &ltc);
+                       ioctl(0, TIOCLSET, &allflags);
+                       signal(SIGINT, SIG_DFL);
+                       for (i = 0; environ[i] != (char *)0; i++)
+                               env[i] = environ[i];
+                       makeenv(&env[i]);
+
+                       /* 
+                        * this is what login was doing anyway.
+                        * soon we rewrite getty completely.
+                        */
+                       set_ttydefaults(0);
+                       execle(LO, "login", "-p", name, (char *) 0, env);
+                       syslog(LOG_ERR, "%s: %m", LO);
+                       exit(1);
+               }
+               alarm(0);
+               signal(SIGALRM, SIG_DFL);
+               signal(SIGINT, SIG_IGN);
+               if (NX && *NX)
+                       tname = NX;
+       }
+}
+
+getname()
+{
+       register int c;
+       register char *np;
+       char cs;
+
+       /*
+        * Interrupt may happen if we use CBREAK mode
+        */
+       if (setjmp(intrupt)) {
+               signal(SIGINT, SIG_IGN);
+               return (0);
+       }
+       signal(SIGINT, interrupt);
+       tmode.sg_flags = setflags(0);
+       ioctl(0, TIOCSETP, &tmode);
+       tmode.sg_flags = setflags(1);
+       prompt();
+       if (PF > 0) {
+               oflush();
+               sleep(PF);
+               PF = 0;
+       }
+       ioctl(0, TIOCSETP, &tmode);
+       crmod = digit = lower = upper = 0;
+       np = name;
+       for (;;) {
+               oflush();
+               if (read(STDIN_FILENO, &cs, 1) <= 0)
+                       exit(0);
+               if ((c = cs&0177) == 0)
+                       return (0);
+               if (c == EOT)
+                       exit(1);
+               if (c == '\r' || c == '\n' || np >= &name[sizeof name]) {
+                       putf("\r\n");
+                       break;
+               }
+               if (islower(c))
+                       lower = 1;
+               else if (isupper(c))
+                       upper = 1;
+               else if (c == ERASE || c == '#' || c == '\b') {
+                       if (np > name) {
+                               np--;
+                               if (tmode.sg_ospeed >= B1200)
+                                       puts("\b \b");
+                               else
+                                       putchr(cs);
+                       }
+                       continue;
+               } else if (c == KILL || c == '@') {
+                       putchr(cs);
+                       putchr('\r');
+                       if (tmode.sg_ospeed < B1200)
+                               putchr('\n');
+                       /* this is the way they do it down under ... */
+                       else if (np > name)
+                               puts("                                     \r");
+                       prompt();
+                       np = name;
+                       continue;
+               } else if (isdigit(c))
+                       digit++;
+               if (IG && (c <= ' ' || c > 0176))
+                       continue;
+               *np++ = c;
+               putchr(cs);
+       }
+       signal(SIGINT, SIG_IGN);
+       *np = 0;
+       if (c == '\r')
+               crmod = 1;
+       if (upper && !lower && !LC || UC)
+               for (np = name; *np; np++)
+                       if (isupper(*np))
+                               *np = tolower(*np);
+       return (1);
+}
+
+static
+short  tmspc10[] = {
+       0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15
+};
+
+putpad(s)
+       register char *s;
+{
+       register pad = 0;
+       register mspc10;
+
+       if (isdigit(*s)) {
+               while (isdigit(*s)) {
+                       pad *= 10;
+                       pad += *s++ - '0';
+               }
+               pad *= 10;
+               if (*s == '.' && isdigit(s[1])) {
+                       pad += s[1] - '0';
+                       s += 2;
+               }
+       }
+
+       puts(s);
+       /*
+        * If no delay needed, or output speed is
+        * not comprehensible, then don't try to delay.
+        */
+       if (pad == 0)
+               return;
+       if (tmode.sg_ospeed <= 0 ||
+           tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0]))
+               return;
+
+       /*
+        * Round up by a half a character frame, and then do the delay.
+        * Too bad there are no user program accessible programmed delays.
+        * Transmitting pad characters slows many terminals down and also
+        * loads the system.
+        */
+       mspc10 = tmspc10[tmode.sg_ospeed];
+       pad += mspc10 / 2;
+       for (pad /= mspc10; pad > 0; pad--)
+               putchr(*PC);
+}
+
+puts(s)
+       register char *s;
+{
+       while (*s)
+               putchr(*s++);
+}
+
+char   outbuf[OBUFSIZ];
+int    obufcnt = 0;
+
+putchr(cc)
+{
+       char c;
+
+       c = cc;
+       if (!NP) {
+               c |= partab[c&0177] & 0200;
+               if (OP)
+                       c ^= 0200;
+       }
+       if (!UB) {
+               outbuf[obufcnt++] = c;
+               if (obufcnt >= OBUFSIZ)
+                       oflush();
+       } else
+               write(STDOUT_FILENO, &c, 1);
+}
+
+oflush()
+{
+       if (obufcnt)
+               write(STDOUT_FILENO, outbuf, obufcnt);
+       obufcnt = 0;
+}
+
+prompt()
+{
+
+       putf(LM);
+       if (CO)
+               putchr('\n');
+}
+
+putf(cp)
+       register char *cp;
+{
+       extern char editedhost[];
+       time_t t;
+       char *slash, db[100];
+
+       while (*cp) {
+               if (*cp != '%') {
+                       putchr(*cp++);
+                       continue;
+               }
+               switch (*++cp) {
+
+               case 't':
+                       slash = rindex(ttyn, '/');
+                       if (slash == (char *) 0)
+                               puts(ttyn);
+                       else
+                               puts(&slash[1]);
+                       break;
+
+               case 'h':
+                       puts(editedhost);
+                       break;
+
+               case 'd': {
+                       static char fmt[] = "%l:% %P on %A, %d %B %Y";
+
+                       fmt[4] = 'M';           /* I *hate* SCCS... */
+                       (void)time(&t);
+                       (void)strftime(db, sizeof(db), fmt, localtime(&t));
+                       puts(db);
+                       break;
+               }
+
+               case '%':
+                       putchr('%');
+                       break;
+               }
+               cp++;
+       }
+}
diff --git a/usr/src/libexec/getty/pathnames.h b/usr/src/libexec/getty/pathnames.h
new file mode 100644 (file)
index 0000000..e02b8b9
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)pathnames.h 5.3 (Berkeley) 6/1/90
+ */
+
+#include <paths.h>
+
+#define        _PATH_GETTYTAB  "/etc/gettytab"
+#define        _PATH_LOGIN     "/usr/bin/login"
diff --git a/usr/src/libexec/getty/subr.c b/usr/src/libexec/getty/subr.c
new file mode 100644 (file)
index 0000000..8970cef
--- /dev/null
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)subr.c     5.10 (Berkeley) 2/26/91";
+#endif /* not lint */
+
+/*
+ * Melbourne getty.
+ */
+#define USE_OLD_TTY
+#include <sgtty.h>
+#include <unistd.h>
+#include <string.h>
+#include "gettytab.h"
+
+extern struct sgttyb tmode;
+extern struct tchars tc;
+extern struct ltchars ltc;
+
+/*
+ * Get a table entry.
+ */
+gettable(name, buf, area)
+       char *name, *buf, *area;
+{
+       register struct gettystrs *sp;
+       register struct gettynums *np;
+       register struct gettyflags *fp;
+       register n;
+
+       hopcount = 0;           /* new lookup, start fresh */
+       if (getent(buf, name) != 1)
+               return;
+
+       for (sp = gettystrs; sp->field; sp++)
+               sp->value = getstr(sp->field, &area);
+       for (np = gettynums; np->field; np++) {
+               n = getnum(np->field);
+               if (n == -1)
+                       np->set = 0;
+               else {
+                       np->set = 1;
+                       np->value = n;
+               }
+       }
+       for (fp = gettyflags; fp->field; fp++) {
+               n = getflag(fp->field);
+               if (n == -1)
+                       fp->set = 0;
+               else {
+                       fp->set = 1;
+                       fp->value = n ^ fp->invrt;
+               }
+       }
+}
+
+gendefaults()
+{
+       register struct gettystrs *sp;
+       register struct gettynums *np;
+       register struct gettyflags *fp;
+
+       for (sp = gettystrs; sp->field; sp++)
+               if (sp->value)
+                       sp->defalt = sp->value;
+       for (np = gettynums; np->field; np++)
+               if (np->set)
+                       np->defalt = np->value;
+       for (fp = gettyflags; fp->field; fp++)
+               if (fp->set)
+                       fp->defalt = fp->value;
+               else
+                       fp->defalt = fp->invrt;
+}
+
+setdefaults()
+{
+       register struct gettystrs *sp;
+       register struct gettynums *np;
+       register struct gettyflags *fp;
+
+       for (sp = gettystrs; sp->field; sp++)
+               if (!sp->value)
+                       sp->value = sp->defalt;
+       for (np = gettynums; np->field; np++)
+               if (!np->set)
+                       np->value = np->defalt;
+       for (fp = gettyflags; fp->field; fp++)
+               if (!fp->set)
+                       fp->value = fp->defalt;
+}
+
+static char **
+charnames[] = {
+       &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK,
+       &SU, &DS, &RP, &FL, &WE, &LN, 0
+};
+
+static char *
+charvars[] = {
+       &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc,
+       &tc.t_quitc, &tc.t_startc, &tc.t_stopc,
+       &tc.t_eofc, &tc.t_brkc, &ltc.t_suspc,
+       &ltc.t_dsuspc, &ltc.t_rprntc, &ltc.t_flushc,
+       &ltc.t_werasc, &ltc.t_lnextc, 0
+};
+
+setchars()
+{
+       register int i;
+       register char *p;
+
+       for (i = 0; charnames[i]; i++) {
+               p = *charnames[i];
+               if (p && *p)
+                       *charvars[i] = *p;
+               else
+                       *charvars[i] = '\377';
+       }
+}
+
+long
+setflags(n)
+{
+       register long f;
+
+       switch (n) {
+       case 0:
+               if (F0set)
+                       return(F0);
+               break;
+       case 1:
+               if (F1set)
+                       return(F1);
+               break;
+       default:
+               if (F2set)
+                       return(F2);
+               break;
+       }
+
+       f = 0;
+
+       if (AP)
+               f |= ANYP;
+       else if (OP)
+               f |= ODDP;
+       else if (EP)
+               f |= EVENP;
+
+       if (UC)
+               f |= LCASE;
+
+       if (NL)
+               f |= CRMOD;
+
+       f |= delaybits();
+
+       if (n == 1) {           /* read mode flags */
+               if (RW)
+                       f |= RAW;
+               else
+                       f |= CBREAK;
+               return (f);
+       }
+
+       if (!HT)
+               f |= XTABS;
+
+       if (n == 0)
+               return (f);
+
+       if (CB)
+               f |= CRTBS;
+
+       if (CE)
+               f |= CRTERA;
+
+       if (CK)
+               f |= CRTKIL;
+
+       if (PE)
+               f |= PRTERA;
+
+       if (EC)
+               f |= ECHO;
+
+       if (XC)
+               f |= CTLECH;
+
+       if (DX)
+               f |= DECCTQ;
+
+       return (f);
+}
+
+struct delayval {
+       unsigned        delay;          /* delay in ms */
+       int             bits;
+};
+
+/*
+ * below are random guesses, I can't be bothered checking
+ */
+
+struct delayval        crdelay[] = {
+       1,              CR1,
+       2,              CR2,
+       3,              CR3,
+       83,             CR1,
+       166,            CR2,
+       0,              CR3,
+};
+
+struct delayval nldelay[] = {
+       1,              NL1,            /* special, calculated */
+       2,              NL2,
+       3,              NL3,
+       100,            NL2,
+       0,              NL3,
+};
+
+struct delayval        bsdelay[] = {
+       1,              BS1,
+       0,              0,
+};
+
+struct delayval        ffdelay[] = {
+       1,              FF1,
+       1750,           FF1,
+       0,              FF1,
+};
+
+struct delayval        tbdelay[] = {
+       1,              TAB1,
+       2,              TAB2,
+       3,              XTABS,          /* this is expand tabs */
+       100,            TAB1,
+       0,              TAB2,
+};
+
+delaybits()
+{
+       register f;
+
+       f  = adelay(CD, crdelay);
+       f |= adelay(ND, nldelay);
+       f |= adelay(FD, ffdelay);
+       f |= adelay(TD, tbdelay);
+       f |= adelay(BD, bsdelay);
+       return (f);
+}
+
+adelay(ms, dp)
+       register ms;
+       register struct delayval *dp;
+{
+       if (ms == 0)
+               return (0);
+       while (dp->delay && ms > dp->delay)
+               dp++;
+       return (dp->bits);
+}
+
+char   editedhost[32];
+
+edithost(pat)
+       register char *pat;
+{
+       register char *host = HN;
+       register char *res = editedhost;
+
+       if (!pat)
+               pat = "";
+       while (*pat) {
+               switch (*pat) {
+
+               case '#':
+                       if (*host)
+                               host++;
+                       break;
+
+               case '@':
+                       if (*host)
+                               *res++ = *host++;
+                       break;
+
+               default:
+                       *res++ = *pat;
+                       break;
+
+               }
+               if (res == &editedhost[sizeof editedhost - 1]) {
+                       *res = '\0';
+                       return;
+               }
+               pat++;
+       }
+       if (*host)
+               strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
+       else
+               *res = '\0';
+       editedhost[sizeof editedhost - 1] = '\0';
+}
+
+struct speedtab {
+       int     speed;
+       int     uxname;
+} speedtab[] = {
+       50,     B50,
+       75,     B75,
+       110,    B110,
+       134,    B134,
+       150,    B150,
+       200,    B200,
+       300,    B300,
+       600,    B600,
+       1200,   B1200,
+       1800,   B1800,
+       2400,   B2400,
+       4800,   B4800,
+       9600,   B9600,
+       19200,  EXTA,
+       19,     EXTA,           /* for people who say 19.2K */
+       38400,  EXTB,
+       38,     EXTB,
+       7200,   EXTB,           /* alternative */
+       0
+};
+
+speed(val)
+{
+       register struct speedtab *sp;
+
+       if (val <= 15)
+               return (val);
+
+       for (sp = speedtab; sp->speed; sp++)
+               if (sp->speed == val)
+                       return (sp->uxname);
+       
+       return (B300);          /* default in impossible cases */
+}
+
+makeenv(env)
+       char *env[];
+{
+       static char termbuf[128] = "TERM=";
+       register char *p, *q;
+       register char **ep;
+       char *index();
+
+       ep = env;
+       if (TT && *TT) {
+               strcat(termbuf, TT);
+               *ep++ = termbuf;
+       }
+       if (p = EV) {
+               q = p;
+               while (q = index(q, ',')) {
+                       *q++ = '\0';
+                       *ep++ = p;
+                       p = q;
+               }
+               if (*p)
+                       *ep++ = p;
+       }
+       *ep = (char *)0;
+}
+
+/*
+ * This speed select mechanism is written for the Develcon DATASWITCH.
+ * The Develcon sends a string of the form "B{speed}\n" at a predefined
+ * baud rate. This string indicates the user's actual speed.
+ * The routine below returns the terminal type mapped from derived speed.
+ */
+struct portselect {
+       char    *ps_baud;
+       char    *ps_type;
+} portspeeds[] = {
+       { "B110",       "std.110" },
+       { "B134",       "std.134" },
+       { "B150",       "std.150" },
+       { "B300",       "std.300" },
+       { "B600",       "std.600" },
+       { "B1200",      "std.1200" },
+       { "B2400",      "std.2400" },
+       { "B4800",      "std.4800" },
+       { "B9600",      "std.9600" },
+       { "B19200",     "std.19200" },
+       { 0 }
+};
+
+char *
+portselector()
+{
+       char c, baud[20], *type = "default";
+       register struct portselect *ps;
+       int len;
+
+       alarm(5*60);
+       for (len = 0; len < sizeof (baud) - 1; len++) {
+               if (read(STDIN_FILENO, &c, 1) <= 0)
+                       break;
+               c &= 0177;
+               if (c == '\n' || c == '\r')
+                       break;
+               if (c == 'B')
+                       len = 0;        /* in case of leading garbage */
+               baud[len] = c;
+       }
+       baud[len] = '\0';
+       for (ps = portspeeds; ps->ps_baud; ps++)
+               if (strcmp(ps->ps_baud, baud) == 0) {
+                       type = ps->ps_type;
+                       break;
+               }
+       sleep(2);       /* wait for connection to complete */
+       return (type);
+}
+
+/*
+ * This auto-baud speed select mechanism is written for the Micom 600
+ * portselector. Selection is done by looking at how the character '\r'
+ * is garbled at the different speeds.
+ */
+#include <sys/time.h>
+
+char *
+autobaud()
+{
+       int rfds;
+       struct timeval timeout;
+       char c, *type = "9600-baud";
+       int null = 0;
+
+       ioctl(0, TIOCFLUSH, &null);
+       rfds = 1 << 0;
+       timeout.tv_sec = 5;
+       timeout.tv_usec = 0;
+       if (select(32, (fd_set *)&rfds, (fd_set *)NULL,
+           (fd_set *)NULL, &timeout) <= 0)
+               return (type);
+       if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char))
+               return (type);
+       timeout.tv_sec = 0;
+       timeout.tv_usec = 20;
+       (void) select(32, (fd_set *)NULL, (fd_set *)NULL,
+           (fd_set *)NULL, &timeout);
+       ioctl(0, TIOCFLUSH, &null);
+       switch (c & 0377) {
+
+       case 0200:              /* 300-baud */
+               type = "300-baud";
+               break;
+
+       case 0346:              /* 1200-baud */
+               type = "1200-baud";
+               break;
+
+       case  015:              /* 2400-baud */
+       case 0215:
+               type = "2400-baud";
+               break;
+
+       default:                /* 4800-baud */
+               type = "4800-baud";
+               break;
+
+       case 0377:              /* 9600-baud */
+               type = "9600-baud";
+               break;
+       }
+       return (type);
+}
diff --git a/usr/src/libexec/getty/ttydefaults.c b/usr/src/libexec/getty/ttydefaults.c
new file mode 100644 (file)
index 0000000..cb0fbc1
--- /dev/null
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ttydefaults.c      5.1 (Berkeley) 1/19/91";
+#endif /* not lint */
+
+#include <sys/termios.h>
+
+set_ttydefaults(fd)
+       int fd;
+{
+       struct termios term;
+
+       tcgetattr(fd, &term);
+       term.c_iflag = TTYDEF_IFLAG;
+       term.c_oflag = TTYDEF_OFLAG;
+       term.c_lflag = TTYDEF_LFLAG;
+       term.c_cflag = TTYDEF_CFLAG;
+       tcsetattr(fd, TCSAFLUSH, &term);
+}