PageRenderTime 24ms CodeModel.GetById 11ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/usr.bin/tset/term.c

https://bitbucket.org/freebsd/freebsd-head/
C | 156 lines | 90 code | 19 blank | 47 comment | 29 complexity | 9626b23856ecbee02aff453bed85159c MD5 | raw file
  1/*-
  2 * Copyright (c) 1991, 1993
  3 *	The Regents of the University of California.  All rights reserved.
  4 *
  5 * Redistribution and use in source and binary forms, with or without
  6 * modification, are permitted provided that the following conditions
  7 * are met:
  8 * 1. Redistributions of source code must retain the above copyright
  9 *    notice, this list of conditions and the following disclaimer.
 10 * 2. Redistributions in binary form must reproduce the above copyright
 11 *    notice, this list of conditions and the following disclaimer in the
 12 *    documentation and/or other materials provided with the distribution.
 13 * 4. Neither the name of the University nor the names of its contributors
 14 *    may be used to endorse or promote products derived from this software
 15 *    without specific prior written permission.
 16 *
 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 27 * SUCH DAMAGE.
 28 */
 29
 30#include <sys/cdefs.h>
 31
 32__FBSDID("$FreeBSD$");
 33
 34#ifndef lint
 35static const char sccsid[] = "@(#)term.c	8.1 (Berkeley) 6/9/93";
 36#endif
 37
 38#include <sys/types.h>
 39#include <err.h>
 40#include <errno.h>
 41#include <stdio.h>
 42#include <stdlib.h>
 43#include <string.h>
 44#include <termcap.h>
 45#include <unistd.h>
 46#include <ttyent.h>
 47#include "extern.h"
 48
 49char    tbuf[1024];      		/* Termcap entry. */
 50
 51const char *askuser(const char *);
 52char	*ttys(char *);
 53
 54/*
 55 * Figure out what kind of terminal we're dealing with, and then read in
 56 * its termcap entry.
 57 */
 58const char *
 59get_termcap_entry(char *userarg, char **tcapbufp)
 60{
 61	struct ttyent *t;
 62	int rval;
 63	char *p, *ttypath;
 64	const char *ttype;
 65
 66	if (userarg) {
 67		ttype = userarg;
 68		goto found;
 69	}
 70
 71	/* Try the environment. */
 72	if ((ttype = getenv("TERM")))
 73		goto map;
 74
 75	/* Try ttyname(3); check for dialup or other mapping. */
 76	if ((ttypath = ttyname(STDERR_FILENO))) {
 77		if ((p = strrchr(ttypath, '/')))
 78			++p;
 79		else
 80			p = ttypath;
 81		if ((t = getttynam(p))) {
 82			ttype = t->ty_type;
 83			goto map;
 84		}
 85	}
 86
 87	/* If still undefined, use "unknown". */
 88	ttype = "unknown";
 89
 90map:	ttype = mapped(ttype);
 91
 92	/*
 93	 * If not a path, remove TERMCAP from the environment so we get a
 94	 * real entry from /etc/termcap.  This prevents us from being fooled
 95	 * by out of date stuff in the environment.
 96	 */
 97found:	if ((p = getenv("TERMCAP")) != NULL && *p != '/')
 98		unsetenv("TERMCAP");
 99
100	/*
101	 * ttype now contains a pointer to the type of the terminal.
102	 * If the first character is '?', ask the user.
103	 */
104	if (ttype[0] == '?') {
105		if (ttype[1] != '\0')
106			ttype = askuser(ttype + 1);
107		else
108			ttype = askuser(NULL);
109	}
110
111	/* Find the termcap entry.  If it doesn't exist, ask the user. */
112	while ((rval = tgetent(tbuf, ttype)) == 0) {
113		warnx("terminal type %s is unknown", ttype);
114		ttype = askuser(NULL);
115	}
116	if (rval == -1)
117		errx(1, "termcap: %s", strerror(errno ? errno : ENOENT));
118	*tcapbufp = tbuf;
119	return (ttype);
120}
121
122/* Prompt the user for a terminal type. */
123const char *
124askuser(const char *dflt)
125{
126	static char answer[256];
127	char *p;
128
129	/* We can get recalled; if so, don't continue uselessly. */
130	if (feof(stdin) || ferror(stdin)) {
131		(void)fprintf(stderr, "\n");
132		exit(1);
133	}
134	for (;;) {
135		if (dflt)
136			(void)fprintf(stderr, "Terminal type? [%s] ", dflt);
137		else
138			(void)fprintf(stderr, "Terminal type? ");
139		(void)fflush(stderr);
140
141		if (fgets(answer, sizeof(answer), stdin) == NULL) {
142			if (dflt == NULL) {
143				(void)fprintf(stderr, "\n");
144				exit(1);
145			}
146			return (dflt);
147		}
148
149		if ((p = strchr(answer, '\n')))
150			*p = '\0';
151		if (answer[0])
152			return (answer);
153		if (dflt != NULL)
154			return (dflt);
155	}
156}