xref: /netbsd-src/lib/libterminfo/term.c (revision b6924e8af2776584be61d1d4e9a7b947af510445)
1*b6924e8aSmartin /* $NetBSD: term.c,v 1.34 2020/04/05 14:53:39 martin Exp $ */
24ca00e00Sroy 
34ca00e00Sroy /*
4aadfdb11Sroy  * Copyright (c) 2009, 2010, 2011, 2020 The NetBSD Foundation, Inc.
54ca00e00Sroy  *
64ca00e00Sroy  * This code is derived from software contributed to The NetBSD Foundation
74ca00e00Sroy  * by Roy Marples.
84ca00e00Sroy  *
94ca00e00Sroy  * Redistribution and use in source and binary forms, with or without
104ca00e00Sroy  * modification, are permitted provided that the following conditions
114ca00e00Sroy  * are met:
124ca00e00Sroy  * 1. Redistributions of source code must retain the above copyright
134ca00e00Sroy  *    notice, this list of conditions and the following disclaimer.
144ca00e00Sroy  * 2. Redistributions in binary form must reproduce the above copyright
154ca00e00Sroy  *    notice, this list of conditions and the following disclaimer in the
164ca00e00Sroy  *    documentation and/or other materials provided with the distribution.
174ca00e00Sroy  *
184ca00e00Sroy  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
194ca00e00Sroy  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
204ca00e00Sroy  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
214ca00e00Sroy  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
224ca00e00Sroy  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
234ca00e00Sroy  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
244ca00e00Sroy  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
254ca00e00Sroy  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
264ca00e00Sroy  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
274ca00e00Sroy  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
284ca00e00Sroy  */
294ca00e00Sroy 
304ca00e00Sroy #include <sys/cdefs.h>
31*b6924e8aSmartin __RCSID("$NetBSD: term.c,v 1.34 2020/04/05 14:53:39 martin Exp $");
324ca00e00Sroy 
334ca00e00Sroy #include <sys/stat.h>
344ca00e00Sroy 
354ca00e00Sroy #include <assert.h>
36fc67b0cdSjoerg #include <cdbr.h>
374ca00e00Sroy #include <ctype.h>
384ca00e00Sroy #include <errno.h>
394ca00e00Sroy #include <fcntl.h>
404ca00e00Sroy #include <limits.h>
414ca00e00Sroy #include <stdio.h>
424ca00e00Sroy #include <stdlib.h>
434ca00e00Sroy #include <string.h>
444ca00e00Sroy #include <term_private.h>
454ca00e00Sroy #include <term.h>
464ca00e00Sroy 
47aadfdb11Sroy /*
48aadfdb11Sroy  * Although we can read v1 structure (which includes v2 alias records)
49aadfdb11Sroy  * we really want a v3 structure to get numerics of type int rather than short.
50aadfdb11Sroy  */
513958d16aSchristos #define _PATH_TERMINFO	"/usr/share/misc/terminfo"
524ca00e00Sroy 
539e387da6Sroy #ifdef TERMINFO_DB
542678fcfdSroy static char __ti_database[PATH_MAX];
559e387da6Sroy #endif
564ca00e00Sroy const char *_ti_database;
574ca00e00Sroy 
58420f923aSroy /* Include a generated list of pre-compiled terminfo descriptions. */
59420f923aSroy #include "compiled_terms.c"
6090cead5eSroy 
614ca00e00Sroy static int
allocset(void * pp,int init,size_t nelem,size_t elemsize)62f464a786Schristos allocset(void *pp, int init, size_t nelem, size_t elemsize)
63f464a786Schristos {
64f464a786Schristos 	void **p = pp;
65f464a786Schristos 	if (*p) {
66f464a786Schristos 		memset(*p, init, nelem * elemsize);
67f464a786Schristos 		return 0;
68f464a786Schristos 	}
69f464a786Schristos 
70f464a786Schristos 	if ((*p = calloc(nelem, elemsize)) == NULL)
71f464a786Schristos 		return -1;
72f464a786Schristos 
73f464a786Schristos 	if (init != 0)
74f464a786Schristos 		memset(*p, init, nelem * elemsize);
75f464a786Schristos 	return 0;
76f464a786Schristos }
77f464a786Schristos 
78f464a786Schristos static int
_ti_readterm(TERMINAL * term,const char * cap,size_t caplen,int flags)7990cead5eSroy _ti_readterm(TERMINAL *term, const char *cap, size_t caplen, int flags)
804ca00e00Sroy {
81aadfdb11Sroy 	char rtype;
824ca00e00Sroy 	uint16_t ind, num;
834ca00e00Sroy 	size_t len;
844ca00e00Sroy 	TERMUSERDEF *ud;
854ca00e00Sroy 
86ee97ae6aSchristos 	if (caplen == 0)
87ee97ae6aSchristos 		goto out;
88aadfdb11Sroy 	rtype = *cap++;
89ee97ae6aSchristos 	caplen--;
90aadfdb11Sroy 	/* Only read type 1 or 3 records */
91aadfdb11Sroy 	if (rtype != TERMINFO_RTYPE && rtype != TERMINFO_RTYPE_O1)
92ee97ae6aSchristos 		goto out;
934ca00e00Sroy 
94f464a786Schristos 	if (allocset(&term->flags, 0, TIFLAGMAX+1, sizeof(*term->flags)) == -1)
9591ab69b0Sroy 		return -1;
96f464a786Schristos 
97f464a786Schristos 	if (allocset(&term->nums, -1, TINUMMAX+1, sizeof(*term->nums)) == -1)
9891ab69b0Sroy 		return -1;
99f464a786Schristos 
100f464a786Schristos 	if (allocset(&term->strs, 0, TISTRMAX+1, sizeof(*term->strs)) == -1)
10191ab69b0Sroy 		return -1;
102f464a786Schristos 
103f464a786Schristos 	if (term->_arealen != caplen) {
10490cead5eSroy 		term->_arealen = caplen;
105f464a786Schristos 		term->_area = realloc(term->_area, term->_arealen);
1064ca00e00Sroy 		if (term->_area == NULL)
10791ab69b0Sroy 			return -1;
108f464a786Schristos 	}
109f5cb16e7Schristos 	memcpy(term->_area, cap, term->_arealen);
1104ca00e00Sroy 
1114ca00e00Sroy 	cap = term->_area;
1121d30fdaeSchristos 	len = _ti_decode_16(&cap);
1134ca00e00Sroy 	term->name = cap;
1144ca00e00Sroy 	cap += len;
1151d30fdaeSchristos 	len = _ti_decode_16(&cap);
116ae351fabSroy 	if (len == 0)
117ae351fabSroy 		term->_alias = NULL;
118ae351fabSroy 	else {
119ae351fabSroy 		term->_alias = cap;
120ae351fabSroy 		cap += len;
121ae351fabSroy 	}
1221d30fdaeSchristos 	len = _ti_decode_16(&cap);
1230c02e7a2Sroy 	if (len == 0)
1240c02e7a2Sroy 		term->desc = NULL;
1250c02e7a2Sroy 	else {
1264ca00e00Sroy 		term->desc = cap;
1274ca00e00Sroy 		cap += len;
1280c02e7a2Sroy 	}
1294ca00e00Sroy 
1301d30fdaeSchristos 	num = _ti_decode_16(&cap);
1314ca00e00Sroy 	if (num != 0) {
1321d30fdaeSchristos 		num = _ti_decode_16(&cap);
1334ca00e00Sroy 		for (; num != 0; num--) {
1341d30fdaeSchristos 			ind = _ti_decode_16(&cap);
1354ca00e00Sroy 			term->flags[ind] = *cap++;
1364ca00e00Sroy 			if (flags == 0 && !VALID_BOOLEAN(term->flags[ind]))
1374ca00e00Sroy 				term->flags[ind] = 0;
1384ca00e00Sroy 		}
1394ca00e00Sroy 	}
1404ca00e00Sroy 
1411d30fdaeSchristos 	num = _ti_decode_16(&cap);
1424ca00e00Sroy 	if (num != 0) {
1431d30fdaeSchristos 		num = _ti_decode_16(&cap);
1444ca00e00Sroy 		for (; num != 0; num--) {
1451d30fdaeSchristos 			ind = _ti_decode_16(&cap);
1461d30fdaeSchristos 			term->nums[ind] = _ti_decode_num(&cap, rtype);
1474ca00e00Sroy 			if (flags == 0 && !VALID_NUMERIC(term->nums[ind]))
1484ca00e00Sroy 				term->nums[ind] = ABSENT_NUMERIC;
1494ca00e00Sroy 		}
1504ca00e00Sroy 	}
1514ca00e00Sroy 
1521d30fdaeSchristos 	num = _ti_decode_16(&cap);
1534ca00e00Sroy 	if (num != 0) {
1541d30fdaeSchristos 		num = _ti_decode_16(&cap);
1554ca00e00Sroy 		for (; num != 0; num--) {
1561d30fdaeSchristos 			ind = _ti_decode_16(&cap);
1571d30fdaeSchristos 			len = _ti_decode_16(&cap);
1584ca00e00Sroy 			if (len > 0)
1594ca00e00Sroy 				term->strs[ind] = cap;
1604ca00e00Sroy 			else if (flags == 0)
1614ca00e00Sroy 				term->strs[ind] = ABSENT_STRING;
1624ca00e00Sroy 			else
1634ca00e00Sroy 				term->strs[ind] = CANCELLED_STRING;
1644ca00e00Sroy 			cap += len;
1654ca00e00Sroy 		}
1664ca00e00Sroy 	}
1674ca00e00Sroy 
1681d30fdaeSchristos 	num = _ti_decode_16(&cap);
1694ca00e00Sroy 	if (num != 0) {
1701d30fdaeSchristos 		num = _ti_decode_16(&cap);
171f464a786Schristos 		if (num != term->_nuserdefs) {
172f464a786Schristos 			free(term->_userdefs);
173f464a786Schristos 			term->_userdefs = NULL;
174f464a786Schristos 			term->_nuserdefs = num;
175f464a786Schristos 		}
176f464a786Schristos 		if (allocset(&term->_userdefs, 0, term->_nuserdefs,
177f464a786Schristos 		    sizeof(*term->_userdefs)) == -1)
178f464a786Schristos 			return -1;
1794ca00e00Sroy 		for (num = 0; num < term->_nuserdefs; num++) {
1804ca00e00Sroy 			ud = &term->_userdefs[num];
1811d30fdaeSchristos 			len = _ti_decode_16(&cap);
1824ca00e00Sroy 			ud->id = cap;
1834ca00e00Sroy 			cap += len;
1844ca00e00Sroy 			ud->type = *cap++;
1854ca00e00Sroy 			switch (ud->type) {
1864ca00e00Sroy 			case 'f':
1874ca00e00Sroy 				ud->flag = *cap++;
1884ca00e00Sroy 				if (flags == 0 &&
1894ca00e00Sroy 				    !VALID_BOOLEAN(ud->flag))
1904ca00e00Sroy 					ud->flag = 0;
1914ca00e00Sroy 				ud->num = ABSENT_NUMERIC;
1924ca00e00Sroy 				ud->str = ABSENT_STRING;
1934ca00e00Sroy 				break;
1944ca00e00Sroy 			case 'n':
1954ca00e00Sroy 				ud->flag = ABSENT_BOOLEAN;
1961d30fdaeSchristos 				ud->num = _ti_decode_num(&cap, rtype);
1974ca00e00Sroy 				if (flags == 0 &&
1984ca00e00Sroy 				    !VALID_NUMERIC(ud->num))
1994ca00e00Sroy 					ud->num = ABSENT_NUMERIC;
2004ca00e00Sroy 				ud->str = ABSENT_STRING;
2014ca00e00Sroy 				break;
2024ca00e00Sroy 			case 's':
2034ca00e00Sroy 				ud->flag = ABSENT_BOOLEAN;
2044ca00e00Sroy 				ud->num = ABSENT_NUMERIC;
2051d30fdaeSchristos 				len = _ti_decode_16(&cap);
2064ca00e00Sroy 				if (len > 0)
2074ca00e00Sroy 					ud->str = cap;
2084ca00e00Sroy 				else if (flags == 0)
2094ca00e00Sroy 					ud->str = ABSENT_STRING;
2104ca00e00Sroy 				else
2114ca00e00Sroy 					ud->str = CANCELLED_STRING;
2124ca00e00Sroy 				cap += len;
2134ca00e00Sroy 				break;
2144ca00e00Sroy 			default:
215ee97ae6aSchristos 				goto out;
2164ca00e00Sroy 			}
2174ca00e00Sroy 		}
218f464a786Schristos 	} else {
219f464a786Schristos 		term->_nuserdefs = 0;
220f464a786Schristos 		if (term->_userdefs) {
221f464a786Schristos 			free(term->_userdefs);
222f464a786Schristos 			term->_userdefs = NULL;
2234ca00e00Sroy 		}
224f464a786Schristos 	}
225f464a786Schristos 
2264ca00e00Sroy 	return 1;
227ee97ae6aSchristos out:
228ee97ae6aSchristos 	errno = EINVAL;
229ee97ae6aSchristos 	return -1;
2304ca00e00Sroy }
2314ca00e00Sroy 
2329e387da6Sroy #if defined(TERMINFO_DB) || defined(TERMINFO_COMPILE)
2334ca00e00Sroy static int
_ti_checkname(const char * name,const char * termname,const char * termalias)2348e374e1bSroy _ti_checkname(const char *name, const char *termname, const char *termalias)
2352b9f5c3fSroy {
2368e374e1bSroy 	const char *alias, *s;
2378e374e1bSroy 	size_t len, l;
2382b9f5c3fSroy 
2392b9f5c3fSroy 	/* Check terminal name matches. */
2408e374e1bSroy 	if (strcmp(termname, name) == 0)
2412b9f5c3fSroy 		return 1;
2422b9f5c3fSroy 
2432b9f5c3fSroy 	/* Check terminal aliases match. */
2448e374e1bSroy 	if (termalias == NULL)
2458e374e1bSroy 		return 0;
2468e374e1bSroy 
2478e374e1bSroy 	len = strlen(name);
2488e374e1bSroy 	alias = termalias;
2498e374e1bSroy 	while (*alias != '\0') {
2508e374e1bSroy 		s = strchr(alias, '|');
2518e374e1bSroy 		if (s == NULL)
2528e374e1bSroy 			l = strlen(alias);
2538e374e1bSroy 		else
2548e374e1bSroy 			l = (size_t)(s - alias);
2558e374e1bSroy 		if (len == l && memcmp(alias, name, l) == 0)
2562b9f5c3fSroy 			return 1;
2578e374e1bSroy 		if (s == NULL)
2588e374e1bSroy 			break;
2598e374e1bSroy 		alias = s + 1;
2602b9f5c3fSroy 	}
2612b9f5c3fSroy 
2622b9f5c3fSroy 	/* No match. */
2632b9f5c3fSroy 	return 0;
2642b9f5c3fSroy }
2659e387da6Sroy #endif
2662b9f5c3fSroy 
2679e387da6Sroy #ifdef TERMINFO_DB
2682b9f5c3fSroy static int
_ti_dbgetterm(TERMINAL * term,const char * path,const char * name,int flags)2694ca00e00Sroy _ti_dbgetterm(TERMINAL *term, const char *path, const char *name, int flags)
2704ca00e00Sroy {
271fc67b0cdSjoerg 	struct cdbr *db;
272fc67b0cdSjoerg 	const void *data;
273fc67b0cdSjoerg 	const uint8_t *data8;
274fc67b0cdSjoerg 	size_t len, klen;
2754ca00e00Sroy 	int r;
2764ca00e00Sroy 
2777b8fbc2dSroy 	r = snprintf(__ti_database, sizeof(__ti_database), "%s.cdb", path);
2787b8fbc2dSroy 	if (r < 0 || (size_t)r > sizeof(__ti_database)) {
2797b8fbc2dSroy 		db = NULL;
2807b8fbc2dSroy 		errno = ENOENT; /* To fall back to a non extension. */
2817b8fbc2dSroy 	} else
2822678fcfdSroy 		db = cdbr_open(__ti_database, CDBR_DEFAULT);
2837b8fbc2dSroy 
2847b8fbc2dSroy 	/* Target file *may* be a cdb file without the extension. */
2857b8fbc2dSroy 	if (db == NULL && errno == ENOENT) {
2867b8fbc2dSroy 		len = strlcpy(__ti_database, path, sizeof(__ti_database));
2877b8fbc2dSroy 		if (len < sizeof(__ti_database))
2887b8fbc2dSroy 			db = cdbr_open(__ti_database, CDBR_DEFAULT);
2897b8fbc2dSroy 	}
2904ca00e00Sroy 	if (db == NULL)
2914ca00e00Sroy 		return -1;
292fc67b0cdSjoerg 
2932b9f5c3fSroy 	r = 0;
294fc67b0cdSjoerg 	klen = strlen(name) + 1;
295fc67b0cdSjoerg 	if (cdbr_find(db, name, klen, &data, &len) == -1)
2962b9f5c3fSroy 		goto out;
297fc67b0cdSjoerg 	data8 = data;
298fc67b0cdSjoerg 	if (len == 0)
2992b9f5c3fSroy 		goto out;
300fc67b0cdSjoerg 
3012b9f5c3fSroy 	/* If the entry is an alias, load the indexed terminfo description. */
3023958d16aSchristos 	if (data8[0] == TERMINFO_ALIAS) {
3032b9f5c3fSroy 		if (cdbr_get(db, le32dec(data8 + 1), &data, &len))
3042b9f5c3fSroy 			goto out;
3052b9f5c3fSroy 		data8 = data;
3062b9f5c3fSroy 	}
3074ca00e00Sroy 
308fc67b0cdSjoerg 	r = _ti_readterm(term, data, len, flags);
3092b9f5c3fSroy 	/* Ensure that this is the right terminfo description. */
3102b9f5c3fSroy         if (r == 1)
3118e374e1bSroy                 r = _ti_checkname(name, term->name, term->_alias);
3122b9f5c3fSroy 	/* Remember the database we read. */
3132b9f5c3fSroy         if (r == 1)
3142b9f5c3fSroy                 _ti_database = __ti_database;
3152b9f5c3fSroy 
3162b9f5c3fSroy out:
317fc67b0cdSjoerg 	cdbr_close(db);
3184ca00e00Sroy 	return r;
3194ca00e00Sroy }
3204ca00e00Sroy 
3214ca00e00Sroy static int
_ti_dbgettermp(TERMINAL * term,const char * path,const char * name,int flags)3224ca00e00Sroy _ti_dbgettermp(TERMINAL *term, const char *path, const char *name, int flags)
3234ca00e00Sroy {
3244ca00e00Sroy 	const char *p;
3253edb4adcSroy 	char pathbuf[PATH_MAX];
3264ca00e00Sroy 	size_t l;
3274ca00e00Sroy 	int r, e;
3284ca00e00Sroy 
3294ca00e00Sroy 	e = -1;
3304ca00e00Sroy 	r = 0;
3314ca00e00Sroy 	do {
3324ca00e00Sroy 		for (p = path; *path != '\0' && *path != ':'; path++)
3334ca00e00Sroy 			continue;
33404f58b48Sroy 		l = (size_t)(path - p);
3354ca00e00Sroy 		if (l != 0 && l + 1 < sizeof(pathbuf)) {
3364ca00e00Sroy 			memcpy(pathbuf, p, l);
3374ca00e00Sroy 			pathbuf[l] = '\0';
3384ca00e00Sroy 			r = _ti_dbgetterm(term, pathbuf, name, flags);
3394ca00e00Sroy 			if (r == 1)
3404ca00e00Sroy 				return 1;
3414ca00e00Sroy 			if (r == 0)
3424ca00e00Sroy 				e = 0;
3434ca00e00Sroy 		}
3444ca00e00Sroy 	} while (*path++ == ':');
3454ca00e00Sroy 	return e;
3464ca00e00Sroy }
3479e387da6Sroy #endif
3484ca00e00Sroy 
349b32b792eSroy static int
_ti_findterm(TERMINAL * term,const char * name,int flags)350b32b792eSroy _ti_findterm(TERMINAL *term, const char *name, int flags)
3514ca00e00Sroy {
352*b6924e8aSmartin #ifndef TERMINFO_DB
353*b6924e8aSmartin 	_ti_database = NULL;
354*b6924e8aSmartin 
355*b6924e8aSmartin 	return 0;
356*b6924e8aSmartin #else
3574ca00e00Sroy 	int r;
3582e0a9a1dSroy 	char *c, *e;
3594ca00e00Sroy 
3604ca00e00Sroy 	_DIAGASSERT(term != NULL);
3614ca00e00Sroy 	_DIAGASSERT(name != NULL);
3624ca00e00Sroy 
3634ca00e00Sroy 	_ti_database = NULL;
364fde317d2Sroy 	r = 0;
36590cead5eSroy 
3669e387da6Sroy 	e = getenv("TERMINFO");
3679e387da6Sroy 	if (e != NULL && *e == '/')
3684ca00e00Sroy 		return _ti_dbgetterm(term, e, name, flags);
369007ba6f7Sroy 
370007ba6f7Sroy 	c = NULL;
3719e387da6Sroy #ifdef TERMINFO_COMPILE
372007ba6f7Sroy 	if (e == NULL && (c = getenv("TERMCAP")) != NULL) {
373007ba6f7Sroy 		if (*c != '\0' && *c != '/') {
374007ba6f7Sroy 			c = strdup(c);
375007ba6f7Sroy 			if (c != NULL) {
376007ba6f7Sroy 				e = captoinfo(c);
377fde317d2Sroy 				free(c);
378007ba6f7Sroy 			}
379007ba6f7Sroy 		}
380007ba6f7Sroy 	}
381007ba6f7Sroy 
382007ba6f7Sroy 	if (e != NULL) {
3832e0a9a1dSroy 		TIC *tic;
3842e0a9a1dSroy 
385007ba6f7Sroy 		if (c == NULL)
386007ba6f7Sroy 			e = strdup(e); /* So we don't destroy env */
387007ba6f7Sroy 		if (e == NULL)
388007ba6f7Sroy 			tic = NULL;
389f464a786Schristos 		else {
390007ba6f7Sroy 			tic = _ti_compile(e, TIC_WARNING |
391007ba6f7Sroy 			    TIC_ALIAS | TIC_DESCRIPTION | TIC_EXTRA);
392007ba6f7Sroy 			free(e);
393f464a786Schristos 		}
3948e374e1bSroy 		if (tic != NULL &&
3958e374e1bSroy 		    _ti_checkname(name, tic->name, tic->alias) == 1)
3968e374e1bSroy 		{
3972e0a9a1dSroy 			uint8_t *f;
3982e0a9a1dSroy 			ssize_t len;
3992e0a9a1dSroy 
400fde317d2Sroy 			len = _ti_flatten(&f, tic);
401fde317d2Sroy 			if (len != -1) {
402ed684e08Sroy 				r = _ti_readterm(term, (char *)f, (size_t)len,
403ed684e08Sroy 				    flags);
404fde317d2Sroy 				free(f);
405fde317d2Sroy 			}
406fde317d2Sroy 		}
407fde317d2Sroy 		_ti_freetic(tic);
408fde317d2Sroy 		if (r == 1) {
409007ba6f7Sroy 			if (c == NULL)
410fde317d2Sroy 				_ti_database = "$TERMINFO";
411007ba6f7Sroy 			else
412007ba6f7Sroy 				_ti_database = "$TERMCAP";
413fde317d2Sroy 			return r;
414fde317d2Sroy 		}
4154ca00e00Sroy 	}
4164ca00e00Sroy 
417b32b792eSroy 	if ((e = getenv("TERMINFO_DIRS")) != NULL)
418b32b792eSroy 		return _ti_dbgettermp(term, e, name, flags);
419b32b792eSroy 
420b32b792eSroy 	if ((e = getenv("HOME")) != NULL) {
4212e0a9a1dSroy 		char homepath[PATH_MAX];
4222e0a9a1dSroy 
4232e0a9a1dSroy 		if (snprintf(homepath, sizeof(homepath), "%s/.terminfo", e) > 0)
4242e0a9a1dSroy 			r = _ti_dbgetterm(term, homepath, name, flags);
425b32b792eSroy 	}
426b32b792eSroy 	if (r != 1)
427b32b792eSroy 		r = _ti_dbgettermp(term, _PATH_TERMINFO, name, flags);
4289e387da6Sroy #endif
429b32b792eSroy 
430b32b792eSroy 	return r;
431*b6924e8aSmartin #endif
432b32b792eSroy }
433b32b792eSroy 
434b32b792eSroy int
_ti_getterm(TERMINAL * term,const char * name,int flags)435b32b792eSroy _ti_getterm(TERMINAL *term, const char *name, int flags)
436b32b792eSroy {
437b32b792eSroy 	int r;
438b32b792eSroy 	size_t i;
439b32b792eSroy 	const struct compiled_term *t;
4409e387da6Sroy #ifdef TERMINFO_COMPAT
4413958d16aSchristos 	char *namev3;
4423958d16aSchristos 
4433958d16aSchristos 	namev3 = _ti_getname(TERMINFO_RTYPE, name);
4443958d16aSchristos 	if (namev3 != NULL) {
4453958d16aSchristos 		r = _ti_findterm(term, namev3, flags);
4463958d16aSchristos 		free(namev3);
4473958d16aSchristos 		if (r == 1)
4483958d16aSchristos 			return r;
4493958d16aSchristos 	}
4509e387da6Sroy #endif
451b32b792eSroy 
452b32b792eSroy 	r = _ti_findterm(term, name, flags);
453298c3fd5Sroy 	if (r == 1)
454fde317d2Sroy 		return r;
455298c3fd5Sroy 
456a2e27dcdSroy 	for (i = 0; i < __arraycount(compiled_terms); i++) {
457a2e27dcdSroy 		t = &compiled_terms[i];
458a2e27dcdSroy 		if (strcmp(name, t->name) == 0) {
459a2e27dcdSroy 			r = _ti_readterm(term, t->cap, t->caplen, flags);
46090cead5eSroy 			break;
46190cead5eSroy 		}
462a2e27dcdSroy 	}
46390cead5eSroy 
464298c3fd5Sroy 	return r;
4654ca00e00Sroy }
466