xref: /minix3/lib/libterminfo/term.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /* $NetBSD: term.c,v 1.17 2013/06/07 13:16:18 roy Exp $ */
251e66a47SVivek Prakash 
351e66a47SVivek Prakash /*
40c3ae37fSLionel Sambuc  * Copyright (c) 2009, 2010, 2011 The NetBSD Foundation, Inc.
551e66a47SVivek Prakash  *
651e66a47SVivek Prakash  * This code is derived from software contributed to The NetBSD Foundation
751e66a47SVivek Prakash  * by Roy Marples.
851e66a47SVivek Prakash  *
951e66a47SVivek Prakash  * Redistribution and use in source and binary forms, with or without
1051e66a47SVivek Prakash  * modification, are permitted provided that the following conditions
1151e66a47SVivek Prakash  * are met:
1251e66a47SVivek Prakash  * 1. Redistributions of source code must retain the above copyright
1351e66a47SVivek Prakash  *    notice, this list of conditions and the following disclaimer.
1451e66a47SVivek Prakash  * 2. Redistributions in binary form must reproduce the above copyright
1551e66a47SVivek Prakash  *    notice, this list of conditions and the following disclaimer in the
1651e66a47SVivek Prakash  *    documentation and/or other materials provided with the distribution.
1751e66a47SVivek Prakash  *
1851e66a47SVivek Prakash  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1951e66a47SVivek Prakash  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2051e66a47SVivek Prakash  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2151e66a47SVivek Prakash  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2251e66a47SVivek Prakash  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2351e66a47SVivek Prakash  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2451e66a47SVivek Prakash  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2551e66a47SVivek Prakash  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2651e66a47SVivek Prakash  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2751e66a47SVivek Prakash  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2851e66a47SVivek Prakash  */
2951e66a47SVivek Prakash 
3051e66a47SVivek Prakash #include <sys/cdefs.h>
31*84d9c625SLionel Sambuc __RCSID("$NetBSD: term.c,v 1.17 2013/06/07 13:16:18 roy Exp $");
3251e66a47SVivek Prakash 
3351e66a47SVivek Prakash #include <sys/stat.h>
3451e66a47SVivek Prakash 
3551e66a47SVivek Prakash #include <assert.h>
360c3ae37fSLionel Sambuc #include <cdbr.h>
3751e66a47SVivek Prakash #include <ctype.h>
3851e66a47SVivek Prakash #include <errno.h>
3951e66a47SVivek Prakash #include <fcntl.h>
4051e66a47SVivek Prakash #include <limits.h>
4151e66a47SVivek Prakash #include <stdio.h>
4251e66a47SVivek Prakash #include <stdlib.h>
4351e66a47SVivek Prakash #include <string.h>
4451e66a47SVivek Prakash #include <term_private.h>
4551e66a47SVivek Prakash #include <term.h>
4651e66a47SVivek Prakash 
47*84d9c625SLionel Sambuc #if !defined(__minix)
4851e66a47SVivek Prakash #define _PATH_TERMINFO		"/usr/share/misc/terminfo"
4939774435SBen Gras #else
5039774435SBen Gras #define _PATH_TERMINFO		"/usr/share/terminfo/terminfo"
51*84d9c625SLionel Sambuc #endif /* !defined(__minix) */
5251e66a47SVivek Prakash 
5351e66a47SVivek Prakash static char database[PATH_MAX];
5451e66a47SVivek Prakash static char pathbuf[PATH_MAX];
5551e66a47SVivek Prakash const char *_ti_database;
5651e66a47SVivek Prakash 
5751e66a47SVivek Prakash /* Include a generated list of pre-compiled terminfo descriptions. */
5851e66a47SVivek Prakash #include "compiled_terms.c"
5951e66a47SVivek Prakash 
6051e66a47SVivek Prakash static int
_ti_readterm(TERMINAL * term,const char * cap,size_t caplen,int flags)6151e66a47SVivek Prakash _ti_readterm(TERMINAL *term, const char *cap, size_t caplen, int flags)
6251e66a47SVivek Prakash {
6351e66a47SVivek Prakash 	uint8_t ver;
6451e66a47SVivek Prakash 	uint16_t ind, num;
6551e66a47SVivek Prakash 	size_t len;
6651e66a47SVivek Prakash 	TERMUSERDEF *ud;
6751e66a47SVivek Prakash 
6851e66a47SVivek Prakash 	ver = *cap++;
690c3ae37fSLionel Sambuc 	/* Only read version 1 structures */
700c3ae37fSLionel Sambuc 	if (ver != 1) {
7151e66a47SVivek Prakash 		errno = EINVAL;
7251e66a47SVivek Prakash 		return -1;
7351e66a47SVivek Prakash 	}
7451e66a47SVivek Prakash 
7551e66a47SVivek Prakash 	term->flags = calloc(TIFLAGMAX + 1, sizeof(char));
7651e66a47SVivek Prakash 	if (term->flags == NULL)
770c3ae37fSLionel Sambuc 		return -1;
7851e66a47SVivek Prakash 	term->nums = malloc((TINUMMAX + 1) * sizeof(short));
7951e66a47SVivek Prakash 	if (term->nums == NULL)
800c3ae37fSLionel Sambuc 		return -1;
8151e66a47SVivek Prakash 	memset(term->nums, (short)-1, (TINUMMAX + 1) * sizeof(short));
8251e66a47SVivek Prakash 	term->strs = calloc(TISTRMAX + 1, sizeof(char *));
8351e66a47SVivek Prakash 	if (term->strs == NULL)
840c3ae37fSLionel Sambuc 		return -1;
8551e66a47SVivek Prakash 	term->_arealen = caplen;
8651e66a47SVivek Prakash 	term->_area = malloc(term->_arealen);
8751e66a47SVivek Prakash 	if (term->_area == NULL)
880c3ae37fSLionel Sambuc 		return -1;
8951e66a47SVivek Prakash 	memcpy(term->_area, cap, term->_arealen);
9051e66a47SVivek Prakash 
9151e66a47SVivek Prakash 	cap = term->_area;
9251e66a47SVivek Prakash 	len = le16dec(cap);
9351e66a47SVivek Prakash 	cap += sizeof(uint16_t);
9451e66a47SVivek Prakash 	term->name = cap;
9551e66a47SVivek Prakash 	cap += len;
9651e66a47SVivek Prakash 	len = le16dec(cap);
9751e66a47SVivek Prakash 	cap += sizeof(uint16_t);
9851e66a47SVivek Prakash 	if (len == 0)
9951e66a47SVivek Prakash 		term->_alias = NULL;
10051e66a47SVivek Prakash 	else {
10151e66a47SVivek Prakash 		term->_alias = cap;
10251e66a47SVivek Prakash 		cap += len;
10351e66a47SVivek Prakash 	}
10451e66a47SVivek Prakash 	len = le16dec(cap);
10551e66a47SVivek Prakash 	cap += sizeof(uint16_t);
10651e66a47SVivek Prakash 	if (len == 0)
10751e66a47SVivek Prakash 		term->desc = NULL;
10851e66a47SVivek Prakash 	else {
10951e66a47SVivek Prakash 		term->desc = cap;
11051e66a47SVivek Prakash 		cap += len;
11151e66a47SVivek Prakash 	}
11251e66a47SVivek Prakash 
11351e66a47SVivek Prakash 	num = le16dec(cap);
11451e66a47SVivek Prakash 	cap += sizeof(uint16_t);
11551e66a47SVivek Prakash 	if (num != 0) {
11651e66a47SVivek Prakash 		num = le16dec(cap);
11751e66a47SVivek Prakash 		cap += sizeof(uint16_t);
11851e66a47SVivek Prakash 		for (; num != 0; num--) {
11951e66a47SVivek Prakash 			ind = le16dec(cap);
12051e66a47SVivek Prakash 			cap += sizeof(uint16_t);
12151e66a47SVivek Prakash 			term->flags[ind] = *cap++;
12251e66a47SVivek Prakash 			if (flags == 0 && !VALID_BOOLEAN(term->flags[ind]))
12351e66a47SVivek Prakash 				term->flags[ind] = 0;
12451e66a47SVivek Prakash 		}
12551e66a47SVivek Prakash 	}
12651e66a47SVivek Prakash 
12751e66a47SVivek Prakash 	num = le16dec(cap);
12851e66a47SVivek Prakash 	cap += sizeof(uint16_t);
12951e66a47SVivek Prakash 	if (num != 0) {
13051e66a47SVivek Prakash 		num = le16dec(cap);
13151e66a47SVivek Prakash 		cap += sizeof(uint16_t);
13251e66a47SVivek Prakash 		for (; num != 0; num--) {
13351e66a47SVivek Prakash 			ind = le16dec(cap);
13451e66a47SVivek Prakash 			cap += sizeof(uint16_t);
13551e66a47SVivek Prakash 			term->nums[ind] = le16dec(cap);
13651e66a47SVivek Prakash 			if (flags == 0 && !VALID_NUMERIC(term->nums[ind]))
13751e66a47SVivek Prakash 				term->nums[ind] = ABSENT_NUMERIC;
13851e66a47SVivek Prakash 			cap += sizeof(uint16_t);
13951e66a47SVivek Prakash 		}
14051e66a47SVivek Prakash 	}
14151e66a47SVivek Prakash 
14251e66a47SVivek Prakash 	num = le16dec(cap);
14351e66a47SVivek Prakash 	cap += sizeof(uint16_t);
14451e66a47SVivek Prakash 	if (num != 0) {
14551e66a47SVivek Prakash 		num = le16dec(cap);
14651e66a47SVivek Prakash 		cap += sizeof(uint16_t);
14751e66a47SVivek Prakash 		for (; num != 0; num--) {
14851e66a47SVivek Prakash 			ind = le16dec(cap);
14951e66a47SVivek Prakash 			cap += sizeof(uint16_t);
15051e66a47SVivek Prakash 			len = le16dec(cap);
15151e66a47SVivek Prakash 			cap += sizeof(uint16_t);
15251e66a47SVivek Prakash 			if (len > 0)
15351e66a47SVivek Prakash 				term->strs[ind] = cap;
15451e66a47SVivek Prakash 			else if (flags == 0)
15551e66a47SVivek Prakash 				term->strs[ind] = ABSENT_STRING;
15651e66a47SVivek Prakash 			else
15751e66a47SVivek Prakash 				term->strs[ind] = CANCELLED_STRING;
15851e66a47SVivek Prakash 			cap += len;
15951e66a47SVivek Prakash 		}
16051e66a47SVivek Prakash 	}
16151e66a47SVivek Prakash 
16251e66a47SVivek Prakash 	num = le16dec(cap);
16351e66a47SVivek Prakash 	cap += sizeof(uint16_t);
16451e66a47SVivek Prakash 	if (num != 0) {
16551e66a47SVivek Prakash 		term->_nuserdefs = le16dec(cap);
16651e66a47SVivek Prakash 		term->_userdefs = malloc(sizeof(*term->_userdefs) * num);
16751e66a47SVivek Prakash 		cap += sizeof(uint16_t);
16851e66a47SVivek Prakash 		for (num = 0; num < term->_nuserdefs; num++) {
16951e66a47SVivek Prakash 			ud = &term->_userdefs[num];
17051e66a47SVivek Prakash 			len = le16dec(cap);
17151e66a47SVivek Prakash 			cap += sizeof(uint16_t);
17251e66a47SVivek Prakash 			ud->id = cap;
17351e66a47SVivek Prakash 			cap += len;
17451e66a47SVivek Prakash 			ud->type = *cap++;
17551e66a47SVivek Prakash 			switch (ud->type) {
17651e66a47SVivek Prakash 			case 'f':
17751e66a47SVivek Prakash 				ud->flag = *cap++;
17851e66a47SVivek Prakash 				if (flags == 0 &&
17951e66a47SVivek Prakash 				    !VALID_BOOLEAN(ud->flag))
18051e66a47SVivek Prakash 					ud->flag = 0;
18151e66a47SVivek Prakash 				ud->num = ABSENT_NUMERIC;
18251e66a47SVivek Prakash 				ud->str = ABSENT_STRING;
18351e66a47SVivek Prakash 				break;
18451e66a47SVivek Prakash 			case 'n':
18551e66a47SVivek Prakash 				ud->flag = ABSENT_BOOLEAN;
18651e66a47SVivek Prakash 				ud->num = le16dec(cap);
18751e66a47SVivek Prakash 				if (flags == 0 &&
18851e66a47SVivek Prakash 				    !VALID_NUMERIC(ud->num))
18951e66a47SVivek Prakash 					ud->num = ABSENT_NUMERIC;
19051e66a47SVivek Prakash 				ud->str = ABSENT_STRING;
19151e66a47SVivek Prakash 				cap += sizeof(uint16_t);
19251e66a47SVivek Prakash 				break;
19351e66a47SVivek Prakash 			case 's':
19451e66a47SVivek Prakash 				ud->flag = ABSENT_BOOLEAN;
19551e66a47SVivek Prakash 				ud->num = ABSENT_NUMERIC;
19651e66a47SVivek Prakash 				len = le16dec(cap);
19751e66a47SVivek Prakash 				cap += sizeof(uint16_t);
19851e66a47SVivek Prakash 				if (len > 0)
19951e66a47SVivek Prakash 					ud->str = cap;
20051e66a47SVivek Prakash 				else if (flags == 0)
20151e66a47SVivek Prakash 					ud->str = ABSENT_STRING;
20251e66a47SVivek Prakash 				else
20351e66a47SVivek Prakash 					ud->str = CANCELLED_STRING;
20451e66a47SVivek Prakash 				cap += len;
20551e66a47SVivek Prakash 				break;
20651e66a47SVivek Prakash 			default:
20751e66a47SVivek Prakash 				errno = EINVAL;
2080c3ae37fSLionel Sambuc 				return -1;
20951e66a47SVivek Prakash 			}
21051e66a47SVivek Prakash 		}
21151e66a47SVivek Prakash 	}
21251e66a47SVivek Prakash 	return 1;
21351e66a47SVivek Prakash }
21451e66a47SVivek Prakash 
21551e66a47SVivek Prakash static int
_ti_dbgetterm(TERMINAL * term,const char * path,const char * name,int flags)21651e66a47SVivek Prakash _ti_dbgetterm(TERMINAL *term, const char *path, const char *name, int flags)
21751e66a47SVivek Prakash {
2180c3ae37fSLionel Sambuc 	struct cdbr *db;
2190c3ae37fSLionel Sambuc 	const void *data;
2200c3ae37fSLionel Sambuc 	char *db_name;
2210c3ae37fSLionel Sambuc 	const uint8_t *data8;
2220c3ae37fSLionel Sambuc 	size_t len, klen;
22351e66a47SVivek Prakash 	int r;
22451e66a47SVivek Prakash 
2250c3ae37fSLionel Sambuc 	if (asprintf(&db_name, "%s.cdb", path) < 0)
2260c3ae37fSLionel Sambuc 		return -1;
2270c3ae37fSLionel Sambuc 
2280c3ae37fSLionel Sambuc 	db = cdbr_open(db_name, CDBR_DEFAULT);
2290c3ae37fSLionel Sambuc 	free(db_name);
23051e66a47SVivek Prakash 	if (db == NULL)
23151e66a47SVivek Prakash 		return -1;
2320c3ae37fSLionel Sambuc 
2330c3ae37fSLionel Sambuc 	klen = strlen(name) + 1;
2340c3ae37fSLionel Sambuc 	if (cdbr_find(db, name, klen, &data, &len) == -1)
2350c3ae37fSLionel Sambuc 		goto fail;
2360c3ae37fSLionel Sambuc 	data8 = data;
2370c3ae37fSLionel Sambuc 	if (len == 0)
2380c3ae37fSLionel Sambuc 		goto fail;
2390c3ae37fSLionel Sambuc 	/* Check for alias first, fall through to processing normal entries. */
2400c3ae37fSLionel Sambuc 	if (data8[0] == 2) {
2410c3ae37fSLionel Sambuc 		if (klen + 7 > len || le16dec(data8 + 5) != klen)
2420c3ae37fSLionel Sambuc 			goto fail;
2430c3ae37fSLionel Sambuc 		if (memcmp(data8 + 7, name, klen))
2440c3ae37fSLionel Sambuc 			goto fail;
2450c3ae37fSLionel Sambuc 		if (cdbr_get(db, le32dec(data8 + 1), &data, &len))
2460c3ae37fSLionel Sambuc 			goto fail;
2470c3ae37fSLionel Sambuc 		data8 = data;
2480c3ae37fSLionel Sambuc 		if (data8[0] != 1)
2490c3ae37fSLionel Sambuc 			goto fail;
2500c3ae37fSLionel Sambuc 	} else if (data8[0] != 1)
2510c3ae37fSLionel Sambuc 		goto fail;
2520c3ae37fSLionel Sambuc 	else if (klen + 3 >= len || le16dec(data8 + 1) != klen)
2530c3ae37fSLionel Sambuc 		goto fail;
2540c3ae37fSLionel Sambuc 	else if (memcmp(data8 + 3, name, klen))
2550c3ae37fSLionel Sambuc 		goto fail;
2560c3ae37fSLionel Sambuc 
25751e66a47SVivek Prakash 	strlcpy(database, path, sizeof(database));
25851e66a47SVivek Prakash 	_ti_database = database;
25951e66a47SVivek Prakash 
2600c3ae37fSLionel Sambuc 	r = _ti_readterm(term, data, len, flags);
2610c3ae37fSLionel Sambuc 	cdbr_close(db);
26251e66a47SVivek Prakash 	return r;
2630c3ae37fSLionel Sambuc 
2640c3ae37fSLionel Sambuc  fail:
2650c3ae37fSLionel Sambuc 	cdbr_close(db);
2660c3ae37fSLionel Sambuc 	return 0;
26751e66a47SVivek Prakash }
26851e66a47SVivek Prakash 
26951e66a47SVivek Prakash static int
_ti_dbgettermp(TERMINAL * term,const char * path,const char * name,int flags)27051e66a47SVivek Prakash _ti_dbgettermp(TERMINAL *term, const char *path, const char *name, int flags)
27151e66a47SVivek Prakash {
27251e66a47SVivek Prakash 	const char *p;
27351e66a47SVivek Prakash 	size_t l;
27451e66a47SVivek Prakash 	int r, e;
27551e66a47SVivek Prakash 
27651e66a47SVivek Prakash 	e = -1;
27751e66a47SVivek Prakash 	r = 0;
27851e66a47SVivek Prakash 	do {
27951e66a47SVivek Prakash 		for (p = path; *path != '\0' && *path != ':'; path++)
28051e66a47SVivek Prakash 			continue;
28151e66a47SVivek Prakash 		l = path - p;
28251e66a47SVivek Prakash 		if (l != 0 && l + 1 < sizeof(pathbuf)) {
28351e66a47SVivek Prakash 			memcpy(pathbuf, p, l);
28451e66a47SVivek Prakash 			pathbuf[l] = '\0';
28551e66a47SVivek Prakash 			r = _ti_dbgetterm(term, pathbuf, name, flags);
28651e66a47SVivek Prakash 			if (r == 1)
28751e66a47SVivek Prakash 				return 1;
28851e66a47SVivek Prakash 			if (r == 0)
28951e66a47SVivek Prakash 				e = 0;
29051e66a47SVivek Prakash 		}
29151e66a47SVivek Prakash 	} while (*path++ == ':');
29251e66a47SVivek Prakash 	return e;
29351e66a47SVivek Prakash }
29451e66a47SVivek Prakash 
29551e66a47SVivek Prakash static int
ticcmp(const TIC * tic,const char * name)29651e66a47SVivek Prakash ticcmp(const TIC *tic, const char *name)
29751e66a47SVivek Prakash {
29851e66a47SVivek Prakash 	char *alias, *s;
29951e66a47SVivek Prakash 	size_t len, l;
30051e66a47SVivek Prakash 
30151e66a47SVivek Prakash 	if (strcmp(tic->name, name) == 0)
30251e66a47SVivek Prakash 		return 0;
30351e66a47SVivek Prakash 	if (tic->alias == NULL)
30451e66a47SVivek Prakash 		return -1;
30551e66a47SVivek Prakash 
30651e66a47SVivek Prakash 	len = strlen(name);
30751e66a47SVivek Prakash 	alias = tic->alias;
30851e66a47SVivek Prakash 	while (*alias != '\0') {
30951e66a47SVivek Prakash 		s = strchr(alias, '|');
31051e66a47SVivek Prakash 		if (s == NULL)
31151e66a47SVivek Prakash 			l = strlen(alias);
31251e66a47SVivek Prakash 		else
31351e66a47SVivek Prakash 			l = s - alias;
3140c3ae37fSLionel Sambuc 		if (len == l && memcmp(alias, name, l) == 0)
31551e66a47SVivek Prakash 			return 0;
31651e66a47SVivek Prakash 		if (s == NULL)
31751e66a47SVivek Prakash 			break;
31851e66a47SVivek Prakash 		alias = s + 1;
31951e66a47SVivek Prakash 	}
32051e66a47SVivek Prakash 	return 1;
32151e66a47SVivek Prakash }
32251e66a47SVivek Prakash 
32351e66a47SVivek Prakash static int
_ti_findterm(TERMINAL * term,const char * name,int flags)32451e66a47SVivek Prakash _ti_findterm(TERMINAL *term, const char *name, int flags)
32551e66a47SVivek Prakash {
32651e66a47SVivek Prakash 	int r;
32751e66a47SVivek Prakash 	char *c, *e, h[PATH_MAX];
32851e66a47SVivek Prakash 	TIC *tic;
32951e66a47SVivek Prakash 	uint8_t *f;
33051e66a47SVivek Prakash 	ssize_t len;
33151e66a47SVivek Prakash 
33251e66a47SVivek Prakash 	_DIAGASSERT(term != NULL);
33351e66a47SVivek Prakash 	_DIAGASSERT(name != NULL);
33451e66a47SVivek Prakash 
33551e66a47SVivek Prakash 	database[0] = '\0';
33651e66a47SVivek Prakash 	_ti_database = NULL;
33751e66a47SVivek Prakash 	r = 0;
33851e66a47SVivek Prakash 
33951e66a47SVivek Prakash 	if ((e = getenv("TERMINFO")) != NULL && *e != '\0')
34051e66a47SVivek Prakash 		if (e[0] == '/')
34151e66a47SVivek Prakash 			return _ti_dbgetterm(term, e, name, flags);
34251e66a47SVivek Prakash 
34351e66a47SVivek Prakash 	c = NULL;
34451e66a47SVivek Prakash 	if (e == NULL && (c = getenv("TERMCAP")) != NULL) {
34551e66a47SVivek Prakash 		if (*c != '\0' && *c != '/') {
34651e66a47SVivek Prakash 			c = strdup(c);
34751e66a47SVivek Prakash 			if (c != NULL) {
34851e66a47SVivek Prakash 				e = captoinfo(c);
34951e66a47SVivek Prakash 				free(c);
35051e66a47SVivek Prakash 			}
35151e66a47SVivek Prakash 		}
35251e66a47SVivek Prakash 	}
35351e66a47SVivek Prakash 
35451e66a47SVivek Prakash 	if (e != NULL) {
35551e66a47SVivek Prakash 		if (c == NULL)
35651e66a47SVivek Prakash 			e = strdup(e); /* So we don't destroy env */
35751e66a47SVivek Prakash 		if (e  == NULL)
35851e66a47SVivek Prakash 			tic = NULL;
35951e66a47SVivek Prakash 		else
36051e66a47SVivek Prakash 			tic = _ti_compile(e, TIC_WARNING |
36151e66a47SVivek Prakash 			    TIC_ALIAS | TIC_DESCRIPTION | TIC_EXTRA);
36251e66a47SVivek Prakash 		if (c == NULL && e != NULL)
36351e66a47SVivek Prakash 			free(e);
36451e66a47SVivek Prakash 		if (tic != NULL && ticcmp(tic, name) == 0) {
36551e66a47SVivek Prakash 			len = _ti_flatten(&f, tic);
36651e66a47SVivek Prakash 			if (len != -1) {
3670c3ae37fSLionel Sambuc 				r = _ti_readterm(term, (char *)f, (size_t)len,
3680c3ae37fSLionel Sambuc 				    flags);
36951e66a47SVivek Prakash 				free(f);
37051e66a47SVivek Prakash 			}
37151e66a47SVivek Prakash 		}
37251e66a47SVivek Prakash 		_ti_freetic(tic);
37351e66a47SVivek Prakash 		if (r == 1) {
37451e66a47SVivek Prakash 			if (c == NULL)
37551e66a47SVivek Prakash 				_ti_database = "$TERMINFO";
37651e66a47SVivek Prakash 			else
37751e66a47SVivek Prakash 				_ti_database = "$TERMCAP";
37851e66a47SVivek Prakash 			return r;
37951e66a47SVivek Prakash 		}
38051e66a47SVivek Prakash 	}
38151e66a47SVivek Prakash 
38251e66a47SVivek Prakash 	if ((e = getenv("TERMINFO_DIRS")) != NULL)
38351e66a47SVivek Prakash 		return _ti_dbgettermp(term, e, name, flags);
38451e66a47SVivek Prakash 
38551e66a47SVivek Prakash 	if ((e = getenv("HOME")) != NULL) {
38651e66a47SVivek Prakash 		snprintf(h, sizeof(h), "%s/.terminfo", e);
38751e66a47SVivek Prakash 		r = _ti_dbgetterm(term, h, name, flags);
38851e66a47SVivek Prakash 	}
38951e66a47SVivek Prakash 	if (r != 1)
39051e66a47SVivek Prakash 		r = _ti_dbgettermp(term, _PATH_TERMINFO, name, flags);
39151e66a47SVivek Prakash 
39251e66a47SVivek Prakash 	return r;
39351e66a47SVivek Prakash 
39451e66a47SVivek Prakash }
39551e66a47SVivek Prakash 
39651e66a47SVivek Prakash int
_ti_getterm(TERMINAL * term,const char * name,int flags)39751e66a47SVivek Prakash _ti_getterm(TERMINAL *term, const char *name, int flags)
39851e66a47SVivek Prakash {
39951e66a47SVivek Prakash 	int r;
40051e66a47SVivek Prakash 	size_t i;
40151e66a47SVivek Prakash 	const struct compiled_term *t;
40251e66a47SVivek Prakash 
40351e66a47SVivek Prakash 	r = _ti_findterm(term, name, flags);
40451e66a47SVivek Prakash 	if (r == 1)
40551e66a47SVivek Prakash 		return r;
40651e66a47SVivek Prakash 
40751e66a47SVivek Prakash 	for (i = 0; i < __arraycount(compiled_terms); i++) {
40851e66a47SVivek Prakash 		t = &compiled_terms[i];
40951e66a47SVivek Prakash 		if (strcmp(name, t->name) == 0) {
41051e66a47SVivek Prakash 			r = _ti_readterm(term, t->cap, t->caplen, flags);
41151e66a47SVivek Prakash 			break;
41251e66a47SVivek Prakash 		}
41351e66a47SVivek Prakash 	}
41451e66a47SVivek Prakash 
41551e66a47SVivek Prakash 	return r;
41651e66a47SVivek Prakash }
417