#ifndef __GNO__ /*- * Copyright (c) 1991, 1993 * 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. */ #include #ifndef lint #if 0 static char sccsid[] = "@(#)getent.c 8.2 (Berkeley) 12/15/93"; #endif #endif /* not lint */ #include #include #include "misc-proto.h" static char *area; static char gettytab[] = "/etc/gettytab"; /*ARGSUSED*/ int getent(char *cp __unused, const char *name) { int retval; char *tempnam, *dba[2] = { gettytab, NULL }; tempnam = strdup(name); retval = cgetent(&area, dba, tempnam) == 0 ? 1 : 0; free(tempnam); return(retval); } /*ARGSUSED*/ char * Getstr(const char *id, char **cpp __unused) { int retval; char *answer, *tempid; tempid = strdup(id); retval = cgetstr(area, tempid, &answer); free(tempid); return((retval > 0) ? answer : NULL); } #else /* On GNO, use code for this taken from GNO's getty. */ /* * 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 __GNO__ #ifndef lint static char sccsid[] = "@(#)gettytab.c 5.5 (Berkeley) 2/25/91"; #endif /* not lint */ #endif #include #include #include #include #include #include #include #ifndef _PATH_GETTYTAB #define _PATH_GETTYTAB "/etc/gettytab" #endif #define TABBUFSIZ 512 static char *tbuf; int hopcount; /* detect infinite loops in termcap, init 0 */ int nchktc(void); int namatch(char *np); static char * skip (register char *bp); static char * decode (register char *str, char **area); /* * Get an entry for terminal name in buffer bp, * from the termcap file. Parse is very rudimentary; * we just notice escaped newlines. */ int getent(char *bp, char *name) { register char *cp; register int c; register int i = 0, cnt = 0; static char ibuf[TABBUFSIZ]; char *cp2; int tf; tbuf = bp; tf = open(_PATH_GETTYTAB, O_RDONLY); 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' || c == '\r') { if (cp > bp && cp[-1] == '\\'){ cp--; continue; } break; } if (cp >= bp+TABBUFSIZ) { write(STDERR_FILENO,"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 int nchktc(void) { register char *p, *q; char tcname[16]; /* name of similar terminal */ char *tcbuf; /*char tcbuf[TABBUFSIZ];*/ char *holdtbuf = tbuf; int l; tcbuf = malloc(TABBUFSIZ); p = tbuf + strlen(tbuf) - 2; /* before the last colon */ while (*--p != ':') if (p MAXHOP) { write(STDERR_FILENO, "Getty: infinite tc= loop\n", 25); free(tcbuf); return (0); } if (getent(tcbuf, tcname) != 1) { free(tcbuf); return(0); } for (q=tcbuf; *q != ':'; q++) ; l = p - holdtbuf + strlen(q); if (l > TABBUFSIZ) { write(STDERR_FILENO, "Gettytab entry too long\n", 24); q[TABBUFSIZ - (p-tbuf)] = 0; } strcpy(p, q+1); tbuf = holdtbuf; free(tcbuf); 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. */ int namatch(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(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(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. */ int getflag (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(char *id, char **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(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); } #endif