Commit | Line | Data |
---|---|---|
8856c09d KB |
1 | /*- |
2 | * Copyright (c) 1991 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * %sccs.include.redist.c% | |
6 | */ | |
7 | ||
8 | #ifndef lint | |
8ac08362 | 9 | static char sccsid[] = "@(#)term.c 5.5 (Berkeley) %G%"; |
8856c09d KB |
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 * | |
31 | get_termcap_entry(userarg, tcapbufp) | |
32 | char *userarg, **tcapbufp; | |
33 | { | |
34 | struct ttyent *t; | |
35 | int rval; | |
8e64664b | 36 | char *p, *ttype, *ttypath; |
8856c09d KB |
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)) { | |
8e64664b KB |
49 | if (p = rindex(ttypath, '/')) |
50 | ++p; | |
8856c09d | 51 | else |
8e64664b KB |
52 | p = ttypath; |
53 | if ((t = getttynam(p))) { | |
8856c09d KB |
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 | /* | |
8e64664b KB |
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. | |
8856c09d | 68 | */ |
8e64664b KB |
69 | found: if ((p = getenv("TERMCAP")) != NULL && *p != '/') |
70 | unsetenv("TERMCAP"); | |
8856c09d KB |
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] == '?') | |
8ac08362 KB |
77 | if (ttype[1] != '\0') |
78 | ttype = askuser(ttype + 1); | |
79 | else | |
80 | ttype = askuser(NULL); | |
8856c09d KB |
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 * | |
96 | askuser(dflt) | |
97 | char *dflt; | |
98 | { | |
99 | static char answer[256]; | |
100 | char *p; | |
101 | ||
646ffb51 KB |
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 | } | |
8856c09d KB |
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 | ||
646ffb51 KB |
114 | if (fgets(answer, sizeof(answer), stdin) == NULL) { |
115 | if (dflt == NULL) { | |
116 | (void)fprintf(stderr, "\n"); | |
117 | exit(1); | |
118 | } | |
2eb98b4d | 119 | return (dflt); |
646ffb51 | 120 | } |
8856c09d KB |
121 | |
122 | if (p = index(answer, '\n')) | |
123 | *p = '\0'; | |
8ac08362 KB |
124 | if (answer[0]) |
125 | return (answer); | |
126 | if (dflt != NULL) | |
127 | return (dflt); | |
8856c09d KB |
128 | } |
129 | } |