1 /*-
2 * Copyright (c) 1991, 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[] = "@(#)term.c 8.1 (Berkeley) 06/09/93";
10 #endif /* not lint */
11
12 #include <sys/types.h>
13 #include <errno.h>
14 #include <ttyent.h>
15 #include <unistd.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include "extern.h"
20
21 char tbuf[1024]; /* Termcap entry. */
22
23 char *askuser __P((char *));
24 char *ttys __P((char *));
25
26 /*
27 * Figure out what kind of terminal we're dealing with, and then read in
28 * its termcap entry.
29 */
30 char *
get_termcap_entry(userarg,tcapbufp)31 get_termcap_entry(userarg, tcapbufp)
32 char *userarg, **tcapbufp;
33 {
34 struct ttyent *t;
35 int rval;
36 char *p, *ttype, *ttypath;
37
38 if (userarg) {
39 ttype = userarg;
40 goto found;
41 }
42
43 /* Try the environment. */
44 if (ttype = getenv("TERM"))
45 goto map;
46
47 /* Try ttyname(3); check for dialup or other mapping. */
48 if (ttypath = ttyname(STDERR_FILENO)) {
49 if (p = rindex(ttypath, '/'))
50 ++p;
51 else
52 p = ttypath;
53 if ((t = getttynam(p))) {
54 ttype = t->ty_type;
55 goto map;
56 }
57 }
58
59 /* If still undefined, use "unknown". */
60 ttype = "unknown";
61
62 map: ttype = mapped(ttype);
63
64 /*
65 * If not a path, remove TERMCAP from the environment so we get a
66 * real entry from /etc/termcap. This prevents us from being fooled
67 * by out of date stuff in the environment.
68 */
69 found: if ((p = getenv("TERMCAP")) != NULL && *p != '/')
70 unsetenv("TERMCAP");
71
72 /*
73 * ttype now contains a pointer to the type of the terminal.
74 * If the first character is '?', ask the user.
75 */
76 if (ttype[0] == '?')
77 if (ttype[1] != '\0')
78 ttype = askuser(ttype + 1);
79 else
80 ttype = askuser(NULL);
81
82 /* Find the termcap entry. If it doesn't exist, ask the user. */
83 while ((rval = tgetent(tbuf, ttype)) == 0) {
84 (void)fprintf(stderr,
85 "tset: terminal type %s is unknown\n", ttype);
86 ttype = askuser(NULL);
87 }
88 if (rval == -1)
89 err("termcap: %s", strerror(errno ? errno : ENOENT));
90 *tcapbufp = tbuf;
91 return (ttype);
92 }
93
94 /* Prompt the user for a terminal type. */
95 char *
askuser(dflt)96 askuser(dflt)
97 char *dflt;
98 {
99 static char answer[256];
100 char *p;
101
102 /* We can get recalled; if so, don't continue uselessly. */
103 if (feof(stdin) || ferror(stdin)) {
104 (void)fprintf(stderr, "\n");
105 exit(1);
106 }
107 for (;;) {
108 if (dflt)
109 (void)fprintf(stderr, "Terminal type? [%s] ", dflt);
110 else
111 (void)fprintf(stderr, "Terminal type? ");
112 (void)fflush(stderr);
113
114 if (fgets(answer, sizeof(answer), stdin) == NULL) {
115 if (dflt == NULL) {
116 (void)fprintf(stderr, "\n");
117 exit(1);
118 }
119 return (dflt);
120 }
121
122 if (p = index(answer, '\n'))
123 *p = '\0';
124 if (answer[0])
125 return (answer);
126 if (dflt != NULL)
127 return (dflt);
128 }
129 }
130