Expand PMF_FN_* macros.
[netbsd-mini2440.git] / usr.bin / tset / term.c
blobba10419b7440c1e8802be2e45d5553dce47ef9ad
1 /* $NetBSD: term.c,v 1.14 2000/05/31 05:50:06 blymn Exp $ */
3 /*-
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)term.c 8.1 (Berkeley) 6/9/93";
36 #endif
37 __RCSID("$NetBSD: term.c,v 1.14 2000/05/31 05:50:06 blymn Exp $");
38 #endif /* not lint */
40 #include <sys/types.h>
41 #include <err.h>
42 #include <errno.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <termcap.h>
47 #include <ttyent.h>
48 #include <unistd.h>
49 #include "extern.h"
51 char *tbuf; /* Termcap entry. */
53 const char *askuser __P((const char *));
54 char *ttys __P((char *));
57 * Figure out what kind of terminal we're dealing with, and then read in
58 * its termcap entry.
60 const char *
61 get_termcap_entry(userarg, tcapbufp, extended)
62 const char *userarg;
63 char **tcapbufp;
64 int extended;
66 struct ttyent *t;
67 int rval;
68 char *p, *ttypath;
69 const char *ttype;
70 char zz[1024], *zz_ptr;
71 char *ext_tc, *newptr;
73 if (userarg) {
74 ttype = userarg;
75 goto found;
78 /* Try the environment. */
79 if ((ttype = getenv("TERM")) != NULL)
80 goto map;
82 /* Try ttyname(3); check for dialup or other mapping. */
83 if ((ttypath = ttyname(STDERR_FILENO)) != NULL) {
84 if ((p = strrchr(ttypath, '/')) != NULL)
85 ++p;
86 else
87 p = ttypath;
88 if ((t = getttynam(p))) {
89 ttype = t->ty_type;
90 goto map;
94 /* If still undefined, use "unknown". */
95 ttype = "unknown";
97 map: ttype = mapped(ttype);
100 * If not a path, remove TERMCAP from the environment so we get a
101 * real entry from /etc/termcap. This prevents us from being fooled
102 * by out of date stuff in the environment.
104 found: if ((p = getenv("TERMCAP")) != NULL && *p != '/')
105 unsetenv("TERMCAP");
108 * ttype now contains a pointer to the type of the terminal.
109 * If the first character is '?', ask the user.
111 if (ttype[0] == '?') {
112 if (ttype[1] != '\0')
113 ttype = askuser(ttype + 1);
114 else
115 ttype = askuser(NULL);
117 /* Find the termcap entry. If it doesn't exist, ask the user. */
118 if ((tbuf = (char *) malloc(1024)) == NULL) {
119 fprintf(stderr, "Could not malloc termcap buffer\n");
120 exit(1);
123 while ((rval = tgetent(tbuf, ttype)) == 0) {
124 warnx("terminal type %s is unknown", ttype);
125 ttype = askuser(NULL);
127 if (rval == -1) {
128 if (!errno)
129 errno = ENOENT;
130 err(1, NULL);
133 /* check if we get a truncated termcap entry, fish back the full
134 * one if need be and the user has asked for it.
136 zz_ptr = zz;
137 if ((extended == 1) && (tgetstr("ZZ", &zz_ptr) != NULL)) {
138 /* it was, fish back the full termcap */
139 sscanf(zz, "%p", &ext_tc);
140 if ((newptr = (char *) realloc(tbuf, strlen(ext_tc) + 1))
141 == NULL) {
142 fprintf(stderr,
143 "reallocate of termcap falied\n");
144 exit (1);
147 strcpy(newptr, ext_tc);
148 tbuf = newptr;
151 *tcapbufp = tbuf;
152 return (ttype);
155 /* Prompt the user for a terminal type. */
156 const char *
157 askuser(dflt)
158 const char *dflt;
160 static char answer[256];
161 char *p;
163 /* We can get recalled; if so, don't continue uselessly. */
164 if (feof(stdin) || ferror(stdin)) {
165 (void)fprintf(stderr, "\n");
166 exit(1);
168 for (;;) {
169 if (dflt)
170 (void)fprintf(stderr, "Terminal type? [%s] ", dflt);
171 else
172 (void)fprintf(stderr, "Terminal type? ");
173 (void)fflush(stderr);
175 if (fgets(answer, sizeof(answer), stdin) == NULL) {
176 if (dflt == NULL) {
177 (void)fprintf(stderr, "\n");
178 exit(1);
180 return (dflt);
183 if ((p = strchr(answer, '\n')) != NULL)
184 *p = '\0';
185 if (answer[0])
186 return (answer);
187 if (dflt != NULL)
188 return (dflt);