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