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 * 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 * 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