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