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 | |
8e64664b | 9 | static char sccsid[] = "@(#)term.c 5.2 (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] == '?') | |
77 | ttype = askuser(ttype + 1); | |
78 | ||
79 | /* Find the termcap entry. If it doesn't exist, ask the user. */ | |
80 | while ((rval = tgetent(tbuf, ttype)) == 0) { | |
81 | (void)fprintf(stderr, | |
82 | "tset: terminal type %s is unknown\n", ttype); | |
83 | ttype = askuser(NULL); | |
84 | } | |
85 | if (rval == -1) | |
86 | err("termcap: %s", strerror(errno ? errno : ENOENT)); | |
87 | *tcapbufp = tbuf; | |
88 | return (ttype); | |
89 | } | |
90 | ||
91 | /* Prompt the user for a terminal type. */ | |
92 | char * | |
93 | askuser(dflt) | |
94 | char *dflt; | |
95 | { | |
96 | static char answer[256]; | |
97 | char *p; | |
98 | ||
99 | for (;;) { | |
100 | if (dflt) | |
101 | (void)fprintf(stderr, "Terminal type? [%s] ", dflt); | |
102 | else | |
103 | (void)fprintf(stderr, "Terminal type? "); | |
104 | (void)fflush(stderr); | |
105 | ||
106 | if (fgets(answer, sizeof(answer), stdin) == NULL) | |
107 | continue; | |
108 | ||
109 | if (p = index(answer, '\n')) | |
110 | *p = '\0'; | |
111 | return (answer[0] ? answer : dflt); | |
112 | } | |
113 | } |