Annotation of src/lib/libterm/termcap.c, Revision 1.5
1.1 cgd 1: /*
2: * Copyright (c) 1980 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
1.2 mycroft 35: /*static char sccsid[] = "from: @(#)termcap.c 5.5 (Berkeley) 6/1/90";*/
1.5 ! deraadt 36: static char rcsid[] = "$Id: termcap.c,v 1.4 1994/01/24 23:40:10 cgd Exp $";
1.1 cgd 37: #endif /* not lint */
38:
39: #define PBUFSIZ 512 /* max length of filename path */
40: #define PVECSIZ 32 /* max number of names in path */
41:
1.4 cgd 42: #include <stdio.h>
1.1 cgd 43: #include <ctype.h>
1.4 cgd 44: #include <stdlib.h>
45: #include <string.h>
1.1 cgd 46: #include "pathnames.h"
47:
48: /*
49: * termcap - routines for dealing with the terminal capability data base
50: *
51: * BUG: Should use a "last" pointer in tbuf, so that searching
52: * for capabilities alphabetically would not be a n**2/2
53: * process when large numbers of capabilities are given.
54: * Note: If we add a last pointer now we will screw up the
55: * tc capability. We really should compile termcap.
56: *
57: * Essentially all the work here is scanning and decoding escapes
58: * in string capabilities. We don't use stdio because the editor
59: * doesn't, and because living w/o it is not hard.
60: */
61:
62: static char *tbuf;
63:
64: /*
65: * Get an entry for terminal name in buffer bp from the termcap file.
66: */
1.4 cgd 67: int
1.1 cgd 68: tgetent(bp, name)
69: char *bp, *name;
70: {
71: register char *p;
72: register char *cp;
1.4 cgd 73: int i;
1.5 ! deraadt 74: char *dummy = NULL, *home, *termpath;
1.4 cgd 75: char **fname, **pvec;
76: char pathbuf[PBUFSIZ], *pathvec[PVECSIZ];
1.1 cgd 77:
1.4 cgd 78: fname = pvec = pathvec;
1.1 cgd 79: tbuf = bp;
80: p = pathbuf;
81: cp = getenv("TERMCAP");
82: /*
83: * TERMCAP can have one of two things in it. It can be the
84: * name of a file to use instead of /etc/termcap. In this
85: * case it better start with a "/". Or it can be an entry to
86: * use so we don't have to read the file. In this case it
87: * has to already have the newlines crunched out. If TERMCAP
88: * does not hold a file name then a path of names is searched
89: * instead. The path is found in the TERMPATH variable, or
90: * becomes "$HOME/.termcap /etc/termcap" if no TERMPATH exists.
91: */
92: if (!cp || *cp != '/') { /* no TERMCAP or it holds an entry */
93: if (termpath = getenv("TERMPATH"))
94: strncpy(pathbuf, termpath, PBUFSIZ);
95: else {
96: if (home = getenv("HOME")) { /* set up default */
97: p += strlen(home); /* path, looking in */
98: strcpy(pathbuf, home); /* $HOME first */
99: *p++ = '/';
100: } /* if no $HOME look in current directory */
101: strncpy(p, _PATH_DEF, PBUFSIZ - (p - pathbuf));
102: }
103: }
104: else /* user-defined name in TERMCAP */
105: strncpy(pathbuf, cp, PBUFSIZ); /* still can be tokenized */
106:
107: *fname++ = pathbuf; /* tokenize path into vector of names */
108: while (*++p)
109: if (*p == ' ' || *p == ':') {
110: *p = '\0';
111: while (*++p)
112: if (*p != ' ' && *p != ':')
113: break;
114: if (*p == '\0')
115: break;
116: *fname++ = p;
117: if (fname >= pathvec + PVECSIZ) {
118: fname--;
119: break;
120: }
121: }
122: *fname = (char *) 0; /* mark end of vector */
1.4 cgd 123: if (cp && *cp && *cp != '/')
124: if (cgetset(cp) < 0)
125: return -2;
126:
127: i = cgetent(&dummy, pathvec, name);
128:
129: if (i == 0)
130: strcpy(bp, dummy);
131:
132: if (dummy != NULL)
133: free(dummy);
134:
135: /* no way to return "loop" */
136: if (i == -3)
137: return -1;
138: return(i + 1);
1.1 cgd 139: }
140:
141: /*
142: * Return the (numeric) option id.
143: * Numeric options look like
144: * li#80
145: * i.e. the option string is separated from the numeric value by
146: * a # character. If the option is not found we return -1.
147: * Note that we handle octal numbers beginning with 0.
148: */
1.4 cgd 149: int
1.1 cgd 150: tgetnum(id)
151: char *id;
152: {
1.4 cgd 153: long num;
1.1 cgd 154:
1.4 cgd 155: if (cgetnum(tbuf, id, &num) == 0)
156: return(num);
157: else
158: return -1;
1.1 cgd 159: }
160:
161: /*
162: * Handle a flag option.
163: * Flag options are given "naked", i.e. followed by a : or the end
164: * of the buffer. Return 1 if we find the option, or 0 if it is
165: * not given.
166: */
167: tgetflag(id)
168: char *id;
169: {
1.4 cgd 170: return(cgetcap(tbuf, id, ':') != NULL);
1.1 cgd 171: }
172:
173: /*
174: * Get a string valued option.
175: * These are given as
176: * cl=^Z
177: * Much decoding is done on the strings, and the strings are
178: * placed in area, which is a ref parameter which is updated.
179: * No checking on area overflow.
180: */
181: char *
182: tgetstr(id, area)
183: char *id, **area;
184: {
1.4 cgd 185: char ids[3];
186: char *s;
1.1 cgd 187: int i;
188:
1.4 cgd 189: /*
190: * XXX
191: * This is for all the boneheaded programs that relied on tgetstr
192: * to look only at the first 2 characters of the string passed...
193: */
194: *ids = *id;
195: ids[1] = id[1];
196: ids[2] = '\0';
197:
198: if ((i = cgetstr(tbuf, ids, &s)) < 0)
199: return NULL;
200:
201: strcpy(*area, s);
202: *area += i + 1;
203: return(s);
1.1 cgd 204: }
CVSweb <webmaster@jp.NetBSD.org>