term.c revision 216370
1243750Srwatson/*- 2186545Srwatson * Copyright (c) 1991, 1993 3186545Srwatson * The Regents of the University of California. All rights reserved. 4243750Srwatson * 5243750Srwatson * Redistribution and use in source and binary forms, with or without 6186545Srwatson * modification, are permitted provided that the following conditions 7186545Srwatson * are met: 8186545Srwatson * 1. Redistributions of source code must retain the above copyright 9186545Srwatson * notice, this list of conditions and the following disclaimer. 10186545Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11186545Srwatson * notice, this list of conditions and the following disclaimer in the 12186545Srwatson * documentation and/or other materials provided with the distribution. 13186545Srwatson * 4. Neither the name of the University nor the names of its contributors 14186545Srwatson * may be used to endorse or promote products derived from this software 15186545Srwatson * without specific prior written permission. 16186545Srwatson * 17186545Srwatson * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18243750Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19243750Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20243750Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21243750Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22243750Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23243750Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24243750Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25243750Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26243750Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27243750Srwatson * SUCH DAMAGE. 28243750Srwatson */ 29243750Srwatson 30243750Srwatson#include <sys/cdefs.h> 31243750Srwatson 32243750Srwatson__FBSDID("$FreeBSD: head/usr.bin/tset/term.c 216370 2010-12-11 08:32:16Z joel $"); 33243750Srwatson 34243750Srwatson#ifndef lint 35186545Srwatsonstatic const char sccsid[] = "@(#)term.c 8.1 (Berkeley) 6/9/93"; 36243750Srwatson#endif 37186545Srwatson 38243750Srwatson#include <sys/types.h> 39186545Srwatson#include <err.h> 40186545Srwatson#include <errno.h> 41186545Srwatson#include <stdio.h> 42186545Srwatson#include <stdlib.h> 43186545Srwatson#include <string.h> 44186545Srwatson#include <termcap.h> 45186545Srwatson#include <unistd.h> 46186545Srwatson#include <ttyent.h> 47186545Srwatson#include "extern.h" 48186545Srwatson 49186545Srwatsonchar tbuf[1024]; /* Termcap entry. */ 50186545Srwatson 51186545Srwatsonconst char *askuser(const char *); 52186545Srwatsonchar *ttys(char *); 53186545Srwatson 54243750Srwatson/* 55243750Srwatson * Figure out what kind of terminal we're dealing with, and then read in 56186545Srwatson * its termcap entry. 57186545Srwatson */ 58186545Srwatsonconst char * 59186545Srwatsonget_termcap_entry(char *userarg, char **tcapbufp) 60186545Srwatson{ 61186545Srwatson struct ttyent *t; 62186545Srwatson int rval; 63243750Srwatson char *p, *ttypath; 64186545Srwatson const char *ttype; 65186545Srwatson 66186545Srwatson if (userarg) { 67186545Srwatson ttype = userarg; 68186545Srwatson goto found; 69243750Srwatson } 70243750Srwatson 71243750Srwatson /* Try the environment. */ 72243750Srwatson if ((ttype = getenv("TERM"))) 73243750Srwatson goto map; 74243750Srwatson 75243750Srwatson /* Try ttyname(3); check for dialup or other mapping. */ 76243750Srwatson if ((ttypath = ttyname(STDERR_FILENO))) { 77243750Srwatson if ((p = rindex(ttypath, '/'))) 78243750Srwatson ++p; 79243750Srwatson else 80243750Srwatson p = ttypath; 81243750Srwatson if ((t = getttynam(p))) { 82243750Srwatson ttype = t->ty_type; 83243750Srwatson goto map; 84243750Srwatson } 85243750Srwatson } 86243750Srwatson 87243750Srwatson /* If still undefined, use "unknown". */ 88243750Srwatson ttype = "unknown"; 89243750Srwatson 90243750Srwatsonmap: ttype = mapped(ttype); 91187214Srwatson 92186545Srwatson /* 93186545Srwatson * If not a path, remove TERMCAP from the environment so we get a 94186545Srwatson * real entry from /etc/termcap. This prevents us from being fooled 95186545Srwatson * by out of date stuff in the environment. 96191273Srwatson */ 97186545Srwatsonfound: if ((p = getenv("TERMCAP")) != NULL && *p != '/') 98186545Srwatson unsetenv("TERMCAP"); 99243750Srwatson 100186545Srwatson /* 101186545Srwatson * ttype now contains a pointer to the type of the terminal. 102186545Srwatson * If the first character is '?', ask the user. 103186545Srwatson */ 104186545Srwatson if (ttype[0] == '?') { 105186545Srwatson if (ttype[1] != '\0') 106186545Srwatson ttype = askuser(ttype + 1); 107186545Srwatson else 108186545Srwatson ttype = askuser(NULL); 109186545Srwatson } 110186545Srwatson 111243750Srwatson /* Find the termcap entry. If it doesn't exist, ask the user. */ 112243750Srwatson while ((rval = tgetent(tbuf, ttype)) == 0) { 113243750Srwatson warnx("terminal type %s is unknown", ttype); 114243750Srwatson ttype = askuser(NULL); 115243750Srwatson } 116187214Srwatson if (rval == -1) 117187214Srwatson errx(1, "termcap: %s", strerror(errno ? errno : ENOENT)); 118187214Srwatson *tcapbufp = tbuf; 119186545Srwatson return (ttype); 120186545Srwatson} 121186545Srwatson 122186545Srwatson/* Prompt the user for a terminal type. */ 123186545Srwatsonconst char * 124186545Srwatsonaskuser(const char *dflt) 125186545Srwatson{ 126186545Srwatson static char answer[256]; 127186545Srwatson char *p; 128186545Srwatson 129186545Srwatson /* We can get recalled; if so, don't continue uselessly. */ 130186545Srwatson if (feof(stdin) || ferror(stdin)) { 131186545Srwatson (void)fprintf(stderr, "\n"); 132186545Srwatson exit(1); 133186545Srwatson } 134186545Srwatson for (;;) { 135186545Srwatson if (dflt) 136186545Srwatson (void)fprintf(stderr, "Terminal type? [%s] ", dflt); 137243750Srwatson else 138191273Srwatson (void)fprintf(stderr, "Terminal type? "); 139243750Srwatson (void)fflush(stderr); 140186545Srwatson 141186545Srwatson if (fgets(answer, sizeof(answer), stdin) == NULL) { 142186545Srwatson if (dflt == NULL) { 143186545Srwatson (void)fprintf(stderr, "\n"); 144186545Srwatson exit(1); 145243750Srwatson } 146186545Srwatson return (dflt); 147186545Srwatson } 148186545Srwatson 149186545Srwatson if ((p = index(answer, '\n'))) 150186545Srwatson *p = '\0'; 151186545Srwatson if (answer[0]) 152243750Srwatson return (answer); 153186545Srwatson if (dflt != NULL) 154243750Srwatson return (dflt); 155243750Srwatson } 156243750Srwatson} 157186545Srwatson