tgetent.c (7749B)
1 /************************************************************************ 2 * * 3 * Copyright (c) 1982, Fred Fish * 4 * All Rights Reserved * 5 * * 6 * This software and/or documentation is released for public * 7 * distribution for personal, non-commercial use only. * 8 * Limited rights to use, modify, and redistribute are hereby * 9 * granted for non-commercial purposes, provided that all * 10 * copyright notices remain intact and all changes are clearly * 11 * documented. The author makes no warranty of any kind with * 12 * respect to this product and explicitly disclaims any implied * 13 * warranties of merchantability or fitness for any particular * 14 * purpose. * 15 * * 16 ************************************************************************ 17 */ 18 19 20 /* 21 * LIBRARY FUNCTION 22 * 23 * tgetent load buffer with entry for specified terminal 24 * 25 * KEY WORDS 26 * 27 * termcap functions 28 * utility routines 29 * 30 * SYNOPSIS 31 * 32 * int tgetent(bp,name) 33 * char *bp; 34 * char *name; 35 * 36 * DESCRIPTION 37 * 38 * Extracts the entry for terminal <name> from the termcap file 39 * and places it in the character buffer <bp>. It is currently 40 * assumed that bp is at least 1024 characters. If the entry in 41 * the termcap file is larger than 1023 characters the excess 42 * characters will be discarded and appropriate status will 43 * be returned. 44 * 45 * Also note that since bp is used by other termcap 46 * routines, the storage associated with the termcap entry 47 * cannot be freed until all termcap calls are completed. 48 * 49 * Tgetent can be directed to look in a file other than 50 * the default (/etc/termcap) by defining an environment 51 * variable called TERMCAP to be the pathname of the desired 52 * termcap file. This is useful for debugging new entries. 53 * NOTE: the pathname MUST begin with a '/' character. 54 * 55 * Also, if the string assigned to TERMCAP does not begin with 56 * a '/' and if the environment variable TERM matches <name> then 57 * the string assigned to TERMCAP is copied to buffer <bp> 58 * instead of reading a termcap file. 59 * 60 * RETURNS 61 * 62 * -1 if the termcap file cannot be opened 63 * 0 if no entry in termcap file matches <name> 64 * 1 if extraction is successful with no errors 65 * 2 if extraction is successful but entry truncated 66 * 67 * SEE ALSO 68 * 69 * tgetnum extract numeric type capability 70 * tgetflag test boolean type capability 71 * tgetstr get string value of capability 72 * 73 * AUTHOR 74 * 75 * Fred Fish 76 * 77 */ 78 79 #include <stdio.h> 80 81 #define TRUE 1 82 #define FALSE 0 83 #define BUFSIZE 1024 /* Assumed size of external buffer */ 84 85 #define NO_FILE -1 /* Returned if can't open file */ 86 #define NO_ENTRY 0 /* Returned if can't find entry */ 87 #define SUCCESS 1 /* Returned if entry found ok */ 88 #define TRUNCATED 2 /* Returned if entry found but trunc */ 89 90 # ifdef DGK 91 # define DEFAULT_ROOT "termcap" /* name without path component */ 92 FILE *fopenp(); 93 # endif 94 # define DEFAULT_FILE "/etc/termcap" /* default termcap filename */ 95 96 char *_tcpbuf; /* Place to remember buffer pointer */ 97 98 /* 99 * PSEUDO CODE 100 * 101 * Begin tgetent 102 * Erase any previous buffer contents. 103 * Remember the buffer pointer. 104 * If termcap file is not found then 105 * If buffer was filled anyway then 106 * Return SUCCESS. 107 * Else 108 * Return NO_FILE. 109 * End if 110 * Else 111 * While records left to process 112 * If this is entry is what we want then 113 * Close the termcap file. 114 * If entry was truncated then 115 * Return TRUNCATED status 116 * Else 117 * Return SUCCESS status. 118 * End if 119 * End if 120 * End while 121 * Return NO_ENTRY status. 122 * End if 123 * End tgetent 124 * 125 */ 126 127 int tgetent(bp,name) 128 char *bp; /* Pointer to buffer (1024 char min) */ 129 char *name; /* Pointer to terminal entry to find */ 130 { 131 FILE *fp, *find_file(); 132 133 *bp = NULL; 134 _tcpbuf = bp; 135 if ((fp = find_file(bp)) == NULL) { 136 if (*bp != NULL) { 137 return(SUCCESS); 138 } else { 139 return(NO_FILE); 140 } 141 } else { 142 while (fgetlr(bp,BUFSIZE,fp)) { 143 if (gotcha(bp,name)) { 144 fclose(fp); 145 if (bp[strlen(bp)-1] != '\n') { 146 return(TRUNCATED); 147 } else { 148 return(SUCCESS); 149 } 150 } 151 } 152 return(NO_ENTRY); 153 } 154 } 155 156 /* 157 * INTERNAL FUNCTION 158 * 159 * find_file find the termcap file and open it if possible 160 * 161 * KEY WORDS 162 * 163 * internal functions 164 * find_file 165 * 166 * SYNOPSIS 167 * 168 * static FILE *find_file(bp) 169 * char *bp; 170 * 171 * DESCRIPTION 172 * 173 * Attempts to locate and open the termcap file. Also handles 174 * using the environment TERMCAP string as the actual buffer 175 * (that's why bp has to be an input parameter). 176 * 177 * If TERMCAP is defined an begins with a '/' character then 178 * it is taken to be the pathname of the termcap file and 179 * an attempt is made to open it. If this fails then 180 * the default termcap file is used instead. 181 * 182 * If TERMCAP is defined but does not begin with a '/' then 183 * it is assumed to be the actual buffer contents provided 184 * that <name> matches the environment variable TERM. 185 * 186 * BUGS 187 * 188 * There is currently no way to be sure which termcap 189 * file was opened since the default will always be 190 * tried. 191 * 192 */ 193 194 /* 195 * PSEUDO CODE 196 * 197 * Begin find_file 198 * If there is a TERMCAP environment string then 199 * If the string is not null then 200 * If the string is a pathname then 201 * If that file is opened successfully then 202 * Return its pointer. 203 * End if 204 * Else 205 * If there is a TERM environment string then 206 * If TERM matches <name> then 207 * Copy TERMCAP string to buffer. 208 * Return NULL for no file. 209 * End if 210 * End if 211 * End if 212 * End if 213 * End if 214 * Open default termcap file and return results. 215 * End find_file 216 * 217 */ 218 219 static FILE *find_file(bp) 220 char *bp; 221 { 222 FILE *fp, *fopen(); 223 char *cp, *ncp, *getenv(); 224 225 if ((cp = getenv("TERMCAP")) != NULL) { 226 if (*cp != NULL) { 227 if (*cp == '/' || *cp == '\\') { 228 if ((fp = fopen(cp,"r")) != NULL) { 229 return(fp); 230 } 231 } else { 232 if ((ncp = getenv("TERM")) != NULL) { 233 if (strcmp(cp,ncp) == 0) { 234 strcpy(bp,cp); 235 return((FILE *)NULL); 236 } 237 } 238 } 239 } 240 } 241 # ifdef DGK 242 /* Try current directory, then /etc/termcap, then along the path 243 */ 244 if (fp = fopen(DEFAULT_ROOT, "r")) 245 return fp; 246 else if (fp = fopen(DEFAULT_FILE, "r")) 247 return fp; 248 else 249 return fopenp(DEFAULT_ROOT, "r", NULL); 250 # else 251 return(fopen(DEFAULT_FILE,"r")); 252 # endif 253 } 254 255 /* 256 * INTERNAL FUNCTION 257 * 258 * gotcha test to see if entry is for specified terminal 259 * 260 * SYNOPSIS 261 * 262 * gotcha(bp,name) 263 * char *bp; 264 * char *name; 265 * 266 * DESCRIPTION 267 * 268 * Tests to see if the entry in buffer bp matches the terminal 269 * specified by name. Returns TRUE if match is detected, FALSE 270 * otherwise. 271 * 272 */ 273 274 /* 275 * PSEUDO CODE 276 * 277 * Begin gotcha 278 * If buffer character is comment character then 279 * Return FALSE since remainder is comment 280 * Else 281 * Initialize name scan pointer. 282 * Compare name and buffer until end or mismatch. 283 * If valid terminators for both name and buffer strings 284 * Return TRUE since a match was found. 285 * Else 286 * Find next non-name character in buffer. 287 * If not an alternate name separater character 288 * Return FALSE since no more names to check. 289 * Else 290 * Test next name and return results. 291 * End if 292 * End if 293 * End if 294 * End gotcha 295 * 296 */ 297 298 gotcha(bp,name) 299 char *bp; 300 char *name; 301 { 302 char *np; 303 304 if (*bp == '#') { 305 return(FALSE); 306 } else { 307 np = name; 308 while (*np == *bp && *np != NULL) {np++; bp++;} 309 if (*np == NULL && (*bp == NULL || *bp == '|' || *bp == ':')) { 310 return(TRUE); 311 } else { 312 while (*bp != NULL && *bp != ':' && *bp != '|') {bp++;} 313 if (*bp != '|') { 314 return(FALSE); 315 } else { 316 return(gotcha(++bp,name)); 317 } 318 } 319 } 320 }