2017-07-15 13:20:51 -06:00
|
|
|
/* $XTermId: resize.c,v 1.139 2017/05/31 08:58:56 tom Exp $ */
|
2006-11-26 04:11:12 -07:00
|
|
|
|
|
|
|
/*
|
2017-07-15 13:20:51 -06:00
|
|
|
* Copyright 2003-2015,2017 by Thomas E. Dickey
|
2006-11-26 04:11:12 -07:00
|
|
|
*
|
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the
|
|
|
|
* "Software"), to deal in the Software without restriction, including
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
* the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included
|
|
|
|
* in all copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
|
|
* IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
|
|
|
|
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
|
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*
|
|
|
|
* Except as contained in this notice, the name(s) of the above copyright
|
|
|
|
* holders shall not be used in advertising or otherwise to promote the
|
|
|
|
* sale, use or other dealings in this Software without prior written
|
|
|
|
* authorization.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
|
|
|
|
*
|
|
|
|
* All Rights Reserved
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and distribute this software and its
|
|
|
|
* documentation for any purpose and without fee is hereby granted,
|
|
|
|
* provided that the above copyright notice appear in all copies and that
|
|
|
|
* both that copyright notice and this permission notice appear in
|
|
|
|
* supporting documentation, and that the name of Digital Equipment
|
|
|
|
* Corporation not be used in advertising or publicity pertaining to
|
|
|
|
* distribution of the software without specific, written prior permission.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
|
|
|
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
|
|
|
* DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
|
|
|
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
|
|
|
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
|
|
|
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
|
|
* SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* resize.c */
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <ctype.h>
|
2013-03-09 07:45:38 -07:00
|
|
|
|
|
|
|
#include <xterm.h>
|
|
|
|
#include <version.h>
|
2006-11-26 04:11:12 -07:00
|
|
|
#include <xstrings.h>
|
2008-02-16 02:34:45 -07:00
|
|
|
#include <xtermcap.h>
|
2006-11-26 04:11:12 -07:00
|
|
|
#include <xterm_io.h>
|
|
|
|
|
|
|
|
#ifndef USE_TERMINFO /* avoid conflict with configure script */
|
|
|
|
#if defined(__QNX__) || defined(__SCO__) || defined(linux) || defined(__OpenBSD__) || defined(__UNIXWARE__)
|
|
|
|
#define USE_TERMINFO
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(__QNX__)
|
|
|
|
#include <unix.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Some OS's may want to use both, like SCO for example. We catch here anyone
|
|
|
|
* who hasn't decided what they want.
|
|
|
|
*/
|
|
|
|
#if !defined(USE_TERMCAP) && !defined(USE_TERMINFO)
|
|
|
|
#define USE_TERMINFO
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <signal.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
|
2009-10-31 08:11:57 -06:00
|
|
|
#ifdef USE_IGNORE_RC
|
|
|
|
int ignore_unused;
|
|
|
|
#endif
|
|
|
|
|
2006-11-26 04:11:12 -07:00
|
|
|
#ifdef __MVS__
|
|
|
|
#define ESCAPE(string) "\047" string
|
|
|
|
#else
|
|
|
|
#define ESCAPE(string) "\033" string
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define EMULATIONS 2
|
|
|
|
#define SUN 1
|
|
|
|
#define VT100 0
|
|
|
|
|
|
|
|
#define TIMEOUT 10
|
|
|
|
|
|
|
|
#define SHELL_UNKNOWN 0
|
|
|
|
#define SHELL_C 1
|
|
|
|
#define SHELL_BOURNE 2
|
|
|
|
/* *INDENT-OFF* */
|
|
|
|
static struct {
|
2009-10-31 08:11:57 -06:00
|
|
|
const char *name;
|
2006-11-26 04:11:12 -07:00
|
|
|
int type;
|
|
|
|
} shell_list[] = {
|
|
|
|
{ "csh", SHELL_C }, /* vanilla cshell */
|
|
|
|
{ "jcsh", SHELL_C },
|
2011-09-17 05:51:57 -06:00
|
|
|
{ "tcsh", SHELL_C },
|
2006-11-26 04:11:12 -07:00
|
|
|
{ "sh", SHELL_BOURNE }, /* vanilla Bourne shell */
|
2011-09-17 05:51:57 -06:00
|
|
|
{ "ash", SHELL_BOURNE },
|
2006-11-26 04:11:12 -07:00
|
|
|
{ "bash", SHELL_BOURNE }, /* GNU Bourne again shell */
|
2011-09-17 05:51:57 -06:00
|
|
|
{ "dash", SHELL_BOURNE },
|
2006-11-26 04:11:12 -07:00
|
|
|
{ "jsh", SHELL_BOURNE },
|
2011-09-17 05:51:57 -06:00
|
|
|
{ "ksh", SHELL_BOURNE }, /* Korn shell (from AT&T toolchest) */
|
|
|
|
{ "ksh-i", SHELL_BOURNE }, /* another name for Korn shell */
|
|
|
|
{ "ksh93", SHELL_BOURNE }, /* Korn shell */
|
|
|
|
{ "mksh", SHELL_BOURNE },
|
|
|
|
{ "pdksh", SHELL_BOURNE },
|
|
|
|
{ "zsh", SHELL_BOURNE },
|
2006-11-26 04:11:12 -07:00
|
|
|
{ NULL, SHELL_BOURNE } /* default (same as xterm's) */
|
|
|
|
};
|
|
|
|
/* *INDENT-ON* */
|
|
|
|
|
2015-09-05 08:11:45 -06:00
|
|
|
static const char *const emuname[EMULATIONS] =
|
2006-11-26 04:11:12 -07:00
|
|
|
{
|
|
|
|
"VT100",
|
|
|
|
"Sun",
|
|
|
|
};
|
|
|
|
static char *myname;
|
|
|
|
static int shell_type = SHELL_UNKNOWN;
|
2015-09-05 08:11:45 -06:00
|
|
|
static const char *const getsize[EMULATIONS] =
|
2006-11-26 04:11:12 -07:00
|
|
|
{
|
2017-07-15 13:20:51 -06:00
|
|
|
ESCAPE("7") ESCAPE("[r") ESCAPE("[9999;9999H") ESCAPE("[6n"),
|
2006-11-26 04:11:12 -07:00
|
|
|
ESCAPE("[18t"),
|
|
|
|
};
|
2013-03-09 07:45:38 -07:00
|
|
|
#if defined(USE_STRUCT_WINSIZE)
|
2015-09-05 08:11:45 -06:00
|
|
|
static const char *const getwsize[EMULATIONS] =
|
2006-11-26 04:11:12 -07:00
|
|
|
{ /* size in pixels */
|
|
|
|
0,
|
|
|
|
ESCAPE("[14t"),
|
|
|
|
};
|
2013-03-09 07:45:38 -07:00
|
|
|
#endif /* USE_STRUCT_WINSIZE */
|
2015-09-05 08:11:45 -06:00
|
|
|
static const char *const restore[EMULATIONS] =
|
2006-11-26 04:11:12 -07:00
|
|
|
{
|
|
|
|
ESCAPE("8"),
|
|
|
|
0,
|
|
|
|
};
|
2015-09-05 08:11:45 -06:00
|
|
|
static const char *const setsize[EMULATIONS] =
|
2006-11-26 04:11:12 -07:00
|
|
|
{
|
|
|
|
0,
|
|
|
|
ESCAPE("[8;%s;%st"),
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef USE_ANY_SYSV_TERMIO
|
|
|
|
static struct termio tioorig;
|
|
|
|
#elif defined(USE_TERMIOS)
|
|
|
|
static struct termios tioorig;
|
|
|
|
#else
|
|
|
|
static struct sgttyb sgorig;
|
|
|
|
#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
|
|
|
|
|
2015-09-05 08:11:45 -06:00
|
|
|
static const char *const size[EMULATIONS] =
|
2006-11-26 04:11:12 -07:00
|
|
|
{
|
|
|
|
ESCAPE("[%d;%dR"),
|
|
|
|
ESCAPE("[8;%d;%dt"),
|
|
|
|
};
|
2015-09-05 08:11:45 -06:00
|
|
|
static const char sunname[] = "sunsize";
|
2006-11-26 04:11:12 -07:00
|
|
|
static int tty;
|
|
|
|
static FILE *ttyfp;
|
|
|
|
|
2013-03-09 07:45:38 -07:00
|
|
|
#if defined(USE_STRUCT_WINSIZE)
|
2009-10-31 08:11:57 -06:00
|
|
|
static const char *wsize[EMULATIONS] =
|
2006-11-26 04:11:12 -07:00
|
|
|
{
|
|
|
|
0,
|
|
|
|
ESCAPE("[4;%hd;%hdt"),
|
|
|
|
};
|
2013-03-09 07:45:38 -07:00
|
|
|
#endif /* USE_STRUCT_WINSIZE */
|
2006-11-26 04:11:12 -07:00
|
|
|
|
2013-03-09 07:45:38 -07:00
|
|
|
static void
|
|
|
|
failed(const char *s)
|
|
|
|
{
|
|
|
|
int save = errno;
|
|
|
|
IGNORE_RC(write(2, myname, strlen(myname)));
|
|
|
|
IGNORE_RC(write(2, ": ", (size_t) 2));
|
|
|
|
errno = save;
|
|
|
|
perror(s);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ARGSUSED */
|
|
|
|
static void
|
|
|
|
onintr(int sig GCC_UNUSED)
|
|
|
|
{
|
|
|
|
#ifdef USE_ANY_SYSV_TERMIO
|
|
|
|
(void) ioctl(tty, TCSETAW, &tioorig);
|
|
|
|
#elif defined(USE_TERMIOS)
|
|
|
|
(void) tcsetattr(tty, TCSADRAIN, &tioorig);
|
|
|
|
#else /* not USE_TERMIOS */
|
|
|
|
(void) ioctl(tty, TIOCSETP, &sgorig);
|
|
|
|
#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
resize_timeout(int sig)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "\n%s: Time out occurred\r\n", myname);
|
|
|
|
onintr(sig);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
Usage(void)
|
|
|
|
{
|
|
|
|
fprintf(stderr, strcmp(myname, sunname) == 0 ?
|
|
|
|
"Usage: %s [rows cols]\n" :
|
|
|
|
"Usage: %s [-v] [-u] [-c] [-s [rows cols]]\n", myname);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2006-11-26 04:11:12 -07:00
|
|
|
|
|
|
|
#ifdef USE_TERMCAP
|
|
|
|
static void
|
|
|
|
print_termcap(const char *termcap)
|
|
|
|
{
|
|
|
|
int ch;
|
|
|
|
|
|
|
|
putchar('\'');
|
|
|
|
while ((ch = *termcap++) != '\0') {
|
|
|
|
switch (ch & 0xff) {
|
|
|
|
case 127: /* undo bug in GNU termcap */
|
|
|
|
printf("^?");
|
|
|
|
break;
|
|
|
|
case '\'': /* must escape anyway (unlikely) */
|
|
|
|
/* FALLTHRU */
|
|
|
|
case '!': /* must escape for SunOS csh */
|
|
|
|
putchar('\\');
|
|
|
|
/* FALLTHRU */
|
|
|
|
default:
|
|
|
|
putchar(ch);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
putchar('\'');
|
|
|
|
}
|
|
|
|
#endif /* USE_TERMCAP */
|
|
|
|
|
2013-03-09 07:45:38 -07:00
|
|
|
static int
|
|
|
|
checkdigits(char *str)
|
|
|
|
{
|
|
|
|
while (*str) {
|
|
|
|
if (!isdigit(CharOf(*str)))
|
|
|
|
return (0);
|
|
|
|
str++;
|
|
|
|
}
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
readstring(FILE *fp, char *buf, const char *str)
|
|
|
|
{
|
|
|
|
int last, c;
|
2014-10-05 10:39:19 -06:00
|
|
|
#if !defined(USG) && !defined(__minix)
|
2013-03-09 07:45:38 -07:00
|
|
|
/* What is the advantage of setitimer() over alarm()? */
|
|
|
|
struct itimerval it;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
signal(SIGALRM, resize_timeout);
|
2014-10-05 10:39:19 -06:00
|
|
|
#if defined(USG) || defined(__minix)
|
2013-03-09 07:45:38 -07:00
|
|
|
alarm(TIMEOUT);
|
|
|
|
#else
|
|
|
|
memset((char *) &it, 0, sizeof(struct itimerval));
|
|
|
|
it.it_value.tv_sec = TIMEOUT;
|
|
|
|
setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
|
|
|
|
#endif
|
|
|
|
if ((c = getc(fp)) == 0233) { /* meta-escape, CSI */
|
|
|
|
c = ESCAPE("")[0];
|
|
|
|
*buf++ = (char) c;
|
|
|
|
*buf++ = '[';
|
|
|
|
} else {
|
|
|
|
*buf++ = (char) c;
|
|
|
|
}
|
|
|
|
if (c != *str) {
|
|
|
|
fprintf(stderr, "%s: unknown character, exiting.\r\n", myname);
|
|
|
|
onintr(0);
|
|
|
|
}
|
|
|
|
last = str[strlen(str) - 1];
|
|
|
|
while ((*buf++ = (char) getc(fp)) != last) {
|
|
|
|
;
|
|
|
|
}
|
2014-10-05 10:39:19 -06:00
|
|
|
#if defined(USG) || defined(__minix)
|
2013-03-09 07:45:38 -07:00
|
|
|
alarm(0);
|
|
|
|
#else
|
|
|
|
memset((char *) &it, 0, sizeof(struct itimerval));
|
|
|
|
setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
|
|
|
|
#endif
|
|
|
|
*buf = 0;
|
|
|
|
}
|
|
|
|
|
2006-11-26 04:11:12 -07:00
|
|
|
/*
|
|
|
|
resets termcap string to reflect current screen size
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
main(int argc, char **argv ENVP_ARG)
|
|
|
|
{
|
2007-08-25 12:53:27 -06:00
|
|
|
#ifdef USE_TERMCAP
|
2009-01-06 13:10:20 -07:00
|
|
|
char *env;
|
2007-08-25 12:53:27 -06:00
|
|
|
#endif
|
2009-01-06 13:10:20 -07:00
|
|
|
char *ptr;
|
|
|
|
int emu = VT100;
|
2006-11-26 04:11:12 -07:00
|
|
|
char *shell;
|
|
|
|
int i;
|
2013-03-09 07:45:38 -07:00
|
|
|
int rc;
|
2006-11-26 04:11:12 -07:00
|
|
|
int rows, cols;
|
|
|
|
#ifdef USE_ANY_SYSV_TERMIO
|
|
|
|
struct termio tio;
|
|
|
|
#elif defined(USE_TERMIOS)
|
|
|
|
struct termios tio;
|
|
|
|
#else
|
|
|
|
struct sgttyb sg;
|
|
|
|
#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
|
|
|
|
#ifdef USE_TERMCAP
|
|
|
|
int ok_tcap = 1;
|
|
|
|
char termcap[TERMCAP_SIZE];
|
|
|
|
char newtc[TERMCAP_SIZE];
|
|
|
|
#endif /* USE_TERMCAP */
|
|
|
|
char buf[BUFSIZ];
|
|
|
|
#ifdef TTYSIZE_STRUCT
|
|
|
|
TTYSIZE_STRUCT ts;
|
|
|
|
#endif
|
|
|
|
char *name_of_tty;
|
|
|
|
#ifdef CANT_OPEN_DEV_TTY
|
|
|
|
extern char *ttyname();
|
|
|
|
#endif
|
2015-09-05 08:11:45 -06:00
|
|
|
const char *setname = "";
|
2006-11-26 04:11:12 -07:00
|
|
|
|
|
|
|
myname = x_basename(argv[0]);
|
|
|
|
if (strcmp(myname, sunname) == 0)
|
|
|
|
emu = SUN;
|
|
|
|
for (argv++, argc--; argc > 0 && **argv == '-'; argv++, argc--) {
|
|
|
|
switch ((*argv)[1]) {
|
|
|
|
case 's': /* Sun emulation */
|
|
|
|
if (emu == SUN)
|
|
|
|
Usage(); /* Never returns */
|
|
|
|
emu = SUN;
|
|
|
|
break;
|
|
|
|
case 'u': /* Bourne (Unix) shell */
|
|
|
|
shell_type = SHELL_BOURNE;
|
|
|
|
break;
|
|
|
|
case 'c': /* C shell */
|
|
|
|
shell_type = SHELL_C;
|
|
|
|
break;
|
2013-03-09 07:45:38 -07:00
|
|
|
case 'v':
|
|
|
|
printf("%s\n", xtermVersion());
|
|
|
|
exit(EXIT_SUCCESS);
|
2006-11-26 04:11:12 -07:00
|
|
|
default:
|
|
|
|
Usage(); /* Never returns */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SHELL_UNKNOWN == shell_type) {
|
|
|
|
/* Find out what kind of shell this user is running.
|
|
|
|
* This is the same algorithm that xterm uses.
|
|
|
|
*/
|
2011-09-17 05:51:57 -06:00
|
|
|
if ((ptr = x_getenv("SHELL")) == NULL) {
|
|
|
|
uid_t uid = getuid();
|
|
|
|
struct passwd pw;
|
|
|
|
|
|
|
|
if (x_getpwuid(uid, &pw)) {
|
|
|
|
(void) x_getlogin(uid, &pw);
|
|
|
|
}
|
|
|
|
if (!OkPasswd(&pw)
|
|
|
|
|| *(ptr = pw.pw_shell) == 0) {
|
|
|
|
/* this is the same default that xterm uses */
|
|
|
|
ptr = x_strdup("/bin/sh");
|
|
|
|
}
|
|
|
|
}
|
2006-11-26 04:11:12 -07:00
|
|
|
|
|
|
|
shell = x_basename(ptr);
|
|
|
|
|
|
|
|
/* now that we know, what kind is it? */
|
2013-03-09 07:45:38 -07:00
|
|
|
for (i = 0; shell_list[i].name; i++) {
|
|
|
|
if (!strcmp(shell_list[i].name, shell)) {
|
2006-11-26 04:11:12 -07:00
|
|
|
break;
|
2013-03-09 07:45:38 -07:00
|
|
|
}
|
|
|
|
}
|
2006-11-26 04:11:12 -07:00
|
|
|
shell_type = shell_list[i].type;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (argc == 2) {
|
|
|
|
if (!setsize[emu]) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"%s: Can't set window size under %s emulation\n",
|
|
|
|
myname, emuname[emu]);
|
2013-03-09 07:45:38 -07:00
|
|
|
exit(EXIT_FAILURE);
|
2006-11-26 04:11:12 -07:00
|
|
|
}
|
2013-03-09 07:45:38 -07:00
|
|
|
if (!checkdigits(argv[0]) || !checkdigits(argv[1])) {
|
2006-11-26 04:11:12 -07:00
|
|
|
Usage(); /* Never returns */
|
2013-03-09 07:45:38 -07:00
|
|
|
}
|
|
|
|
} else if (argc != 0) {
|
2006-11-26 04:11:12 -07:00
|
|
|
Usage(); /* Never returns */
|
2013-03-09 07:45:38 -07:00
|
|
|
}
|
2006-11-26 04:11:12 -07:00
|
|
|
#ifdef CANT_OPEN_DEV_TTY
|
|
|
|
if ((name_of_tty = ttyname(fileno(stderr))) == NULL)
|
|
|
|
#endif
|
2009-10-31 08:11:57 -06:00
|
|
|
name_of_tty = x_strdup("/dev/tty");
|
2006-11-26 04:11:12 -07:00
|
|
|
|
|
|
|
if ((ttyfp = fopen(name_of_tty, "r+")) == NULL) {
|
|
|
|
fprintf(stderr, "%s: can't open terminal %s\n",
|
|
|
|
myname, name_of_tty);
|
2013-03-09 07:45:38 -07:00
|
|
|
exit(EXIT_FAILURE);
|
2006-11-26 04:11:12 -07:00
|
|
|
}
|
|
|
|
tty = fileno(ttyfp);
|
|
|
|
#ifdef USE_TERMCAP
|
2007-08-25 12:53:27 -06:00
|
|
|
if ((env = x_getenv("TERM")) == 0) {
|
2006-11-26 04:11:12 -07:00
|
|
|
env = DFT_TERMTYPE;
|
2013-03-09 07:45:38 -07:00
|
|
|
if (SHELL_BOURNE == shell_type) {
|
2007-08-25 12:53:27 -06:00
|
|
|
setname = "TERM=" DFT_TERMTYPE ";\nexport TERM;\n";
|
2013-03-09 07:45:38 -07:00
|
|
|
} else {
|
2007-08-25 12:53:27 -06:00
|
|
|
setname = "setenv TERM " DFT_TERMTYPE ";\n";
|
2013-03-09 07:45:38 -07:00
|
|
|
}
|
2006-11-26 04:11:12 -07:00
|
|
|
}
|
|
|
|
termcap[0] = 0; /* ...just in case we've accidentally gotten terminfo */
|
2013-03-09 07:45:38 -07:00
|
|
|
if (tgetent(termcap, env) <= 0 || termcap[0] == 0) {
|
2006-11-26 04:11:12 -07:00
|
|
|
ok_tcap = 0;
|
2013-03-09 07:45:38 -07:00
|
|
|
}
|
2006-11-26 04:11:12 -07:00
|
|
|
#endif /* USE_TERMCAP */
|
|
|
|
#ifdef USE_TERMINFO
|
2007-08-25 12:53:27 -06:00
|
|
|
if (x_getenv("TERM") == 0) {
|
2013-03-09 07:45:38 -07:00
|
|
|
if (SHELL_BOURNE == shell_type) {
|
2007-08-25 12:53:27 -06:00
|
|
|
setname = "TERM=" DFT_TERMTYPE ";\nexport TERM;\n";
|
2013-03-09 07:45:38 -07:00
|
|
|
} else {
|
2007-08-25 12:53:27 -06:00
|
|
|
setname = "setenv TERM " DFT_TERMTYPE ";\n";
|
2013-03-09 07:45:38 -07:00
|
|
|
}
|
2006-11-26 04:11:12 -07:00
|
|
|
}
|
|
|
|
#endif /* USE_TERMINFO */
|
|
|
|
|
|
|
|
#ifdef USE_ANY_SYSV_TERMIO
|
2013-03-09 07:45:38 -07:00
|
|
|
rc = ioctl(tty, TCGETA, &tioorig);
|
2006-11-26 04:11:12 -07:00
|
|
|
tio = tioorig;
|
2010-05-08 06:20:46 -06:00
|
|
|
UIntClr(tio.c_iflag, (ICRNL | IUCLC));
|
|
|
|
UIntClr(tio.c_lflag, (ICANON | ECHO));
|
2006-11-26 04:11:12 -07:00
|
|
|
tio.c_cflag |= CS8;
|
|
|
|
tio.c_cc[VMIN] = 6;
|
|
|
|
tio.c_cc[VTIME] = 1;
|
|
|
|
#elif defined(USE_TERMIOS)
|
2013-03-09 07:45:38 -07:00
|
|
|
rc = tcgetattr(tty, &tioorig);
|
2006-11-26 04:11:12 -07:00
|
|
|
tio = tioorig;
|
2010-05-08 06:20:46 -06:00
|
|
|
UIntClr(tio.c_iflag, ICRNL);
|
|
|
|
UIntClr(tio.c_lflag, (ICANON | ECHO));
|
2006-11-26 04:11:12 -07:00
|
|
|
tio.c_cflag |= CS8;
|
|
|
|
tio.c_cc[VMIN] = 6;
|
|
|
|
tio.c_cc[VTIME] = 1;
|
|
|
|
#else /* not USE_TERMIOS */
|
2013-03-09 07:45:38 -07:00
|
|
|
rc = ioctl(tty, TIOCGETP, &sgorig);
|
2006-11-26 04:11:12 -07:00
|
|
|
sg = sgorig;
|
|
|
|
sg.sg_flags |= RAW;
|
2010-05-08 06:20:46 -06:00
|
|
|
UIntClr(sg.sg_flags, ECHO);
|
2006-11-26 04:11:12 -07:00
|
|
|
#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
|
2013-03-09 07:45:38 -07:00
|
|
|
if (rc != 0)
|
|
|
|
failed("get tty settings");
|
|
|
|
|
2006-11-26 04:11:12 -07:00
|
|
|
signal(SIGINT, onintr);
|
|
|
|
signal(SIGQUIT, onintr);
|
|
|
|
signal(SIGTERM, onintr);
|
2013-03-09 07:45:38 -07:00
|
|
|
|
2006-11-26 04:11:12 -07:00
|
|
|
#ifdef USE_ANY_SYSV_TERMIO
|
2013-03-09 07:45:38 -07:00
|
|
|
rc = ioctl(tty, TCSETAW, &tio);
|
2006-11-26 04:11:12 -07:00
|
|
|
#elif defined(USE_TERMIOS)
|
2013-03-09 07:45:38 -07:00
|
|
|
rc = tcsetattr(tty, TCSADRAIN, &tio);
|
2006-11-26 04:11:12 -07:00
|
|
|
#else /* not USE_TERMIOS */
|
2013-03-09 07:45:38 -07:00
|
|
|
rc = ioctl(tty, TIOCSETP, &sg);
|
2006-11-26 04:11:12 -07:00
|
|
|
#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
|
2013-03-09 07:45:38 -07:00
|
|
|
if (rc != 0)
|
|
|
|
failed("set tty settings");
|
2006-11-26 04:11:12 -07:00
|
|
|
|
2013-03-09 07:45:38 -07:00
|
|
|
if (argc == 2) { /* look for optional parameters of "-s" */
|
2008-02-16 02:34:45 -07:00
|
|
|
char *tmpbuf = TypeMallocN(char,
|
|
|
|
strlen(setsize[emu]) +
|
|
|
|
strlen(argv[0]) +
|
|
|
|
strlen(argv[1]) +
|
|
|
|
1);
|
2007-08-25 12:53:27 -06:00
|
|
|
if (tmpbuf == 0) {
|
|
|
|
fprintf(stderr, "%s: Cannot query size\n", myname);
|
|
|
|
onintr(0);
|
2010-08-22 07:38:11 -06:00
|
|
|
} else {
|
|
|
|
sprintf(tmpbuf, setsize[emu], argv[0], argv[1]);
|
|
|
|
IGNORE_RC(write(tty, tmpbuf, strlen(tmpbuf)));
|
|
|
|
free(tmpbuf);
|
2007-08-25 12:53:27 -06:00
|
|
|
}
|
2006-11-26 04:11:12 -07:00
|
|
|
}
|
2009-10-31 08:11:57 -06:00
|
|
|
IGNORE_RC(write(tty, getsize[emu], strlen(getsize[emu])));
|
2006-11-26 04:11:12 -07:00
|
|
|
readstring(ttyfp, buf, size[emu]);
|
|
|
|
if (sscanf(buf, size[emu], &rows, &cols) != 2) {
|
|
|
|
fprintf(stderr, "%s: Can't get rows and columns\r\n", myname);
|
|
|
|
onintr(0);
|
|
|
|
}
|
|
|
|
if (restore[emu])
|
2009-10-31 08:11:57 -06:00
|
|
|
IGNORE_RC(write(tty, restore[emu], strlen(restore[emu])));
|
2013-03-09 07:45:38 -07:00
|
|
|
#if defined(USE_STRUCT_WINSIZE)
|
2006-11-26 04:11:12 -07:00
|
|
|
/* finally, set the tty's window size */
|
|
|
|
if (getwsize[emu]) {
|
|
|
|
/* get the window size in pixels */
|
2009-10-31 08:11:57 -06:00
|
|
|
IGNORE_RC(write(tty, getwsize[emu], strlen(getwsize[emu])));
|
2006-11-26 04:11:12 -07:00
|
|
|
readstring(ttyfp, buf, wsize[emu]);
|
|
|
|
if (sscanf(buf, wsize[emu], &ts.ws_xpixel, &ts.ws_ypixel) != 2) {
|
|
|
|
fprintf(stderr, "%s: Can't get window size\r\n", myname);
|
|
|
|
onintr(0);
|
|
|
|
}
|
2017-07-15 13:20:51 -06:00
|
|
|
setup_winsize(ts, rows, cols, 0, 0);
|
2006-11-26 04:11:12 -07:00
|
|
|
SET_TTYSIZE(tty, ts);
|
|
|
|
} else if (ioctl(tty, TIOCGWINSZ, &ts) != -1) {
|
|
|
|
/* we don't have any way of directly finding out
|
|
|
|
the current height & width of the window in pixels. We try
|
|
|
|
our best by computing the font height and width from the "old"
|
|
|
|
window-size values, and multiplying by these ratios... */
|
2017-07-15 13:20:51 -06:00
|
|
|
#define scaled(old,new,len) (old)?((unsigned)(new)*(len)/(old)):(len)
|
|
|
|
setup_winsize(ts, rows, cols,
|
|
|
|
scaled(TTYSIZE_ROWS(ts), rows, ts.ws_ypixel),
|
|
|
|
scaled(TTYSIZE_COLS(ts), cols, ts.ws_xpixel));
|
2006-11-26 04:11:12 -07:00
|
|
|
SET_TTYSIZE(tty, ts);
|
|
|
|
}
|
2013-03-09 07:45:38 -07:00
|
|
|
#endif /* USE_STRUCT_WINSIZE */
|
2006-11-26 04:11:12 -07:00
|
|
|
|
|
|
|
#ifdef USE_ANY_SYSV_TERMIO
|
2013-03-09 07:45:38 -07:00
|
|
|
rc = ioctl(tty, TCSETAW, &tioorig);
|
2006-11-26 04:11:12 -07:00
|
|
|
#elif defined(USE_TERMIOS)
|
2013-03-09 07:45:38 -07:00
|
|
|
rc = tcsetattr(tty, TCSADRAIN, &tioorig);
|
2006-11-26 04:11:12 -07:00
|
|
|
#else /* not USE_TERMIOS */
|
2013-03-09 07:45:38 -07:00
|
|
|
rc = ioctl(tty, TIOCSETP, &sgorig);
|
2006-11-26 04:11:12 -07:00
|
|
|
#endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
|
2013-03-09 07:45:38 -07:00
|
|
|
if (rc != 0)
|
|
|
|
failed("set tty settings");
|
|
|
|
|
2006-11-26 04:11:12 -07:00
|
|
|
signal(SIGINT, SIG_DFL);
|
|
|
|
signal(SIGQUIT, SIG_DFL);
|
|
|
|
signal(SIGTERM, SIG_DFL);
|
|
|
|
|
|
|
|
#ifdef USE_TERMCAP
|
|
|
|
if (ok_tcap) {
|
|
|
|
/* update termcap string */
|
|
|
|
/* first do columns */
|
|
|
|
if ((ptr = x_strindex(termcap, "co#")) == NULL) {
|
|
|
|
fprintf(stderr, "%s: No `co#'\n", myname);
|
2013-03-09 07:45:38 -07:00
|
|
|
exit(EXIT_FAILURE);
|
2006-11-26 04:11:12 -07:00
|
|
|
}
|
|
|
|
|
2014-05-09 13:56:40 -06:00
|
|
|
i = (int) (ptr - termcap) + 3;
|
2010-05-08 06:20:46 -06:00
|
|
|
strncpy(newtc, termcap, (size_t) i);
|
2006-11-26 04:11:12 -07:00
|
|
|
sprintf(newtc + i, "%d", cols);
|
2015-01-18 13:24:39 -07:00
|
|
|
if ((ptr = strchr(ptr, ':')) != 0)
|
|
|
|
strcat(newtc, ptr);
|
2006-11-26 04:11:12 -07:00
|
|
|
|
|
|
|
/* now do lines */
|
|
|
|
if ((ptr = x_strindex(newtc, "li#")) == NULL) {
|
|
|
|
fprintf(stderr, "%s: No `li#'\n", myname);
|
2013-03-09 07:45:38 -07:00
|
|
|
exit(EXIT_FAILURE);
|
2006-11-26 04:11:12 -07:00
|
|
|
}
|
|
|
|
|
2014-05-09 13:56:40 -06:00
|
|
|
i = (int) (ptr - newtc) + 3;
|
2010-05-08 06:20:46 -06:00
|
|
|
strncpy(termcap, newtc, (size_t) i);
|
2006-11-26 04:11:12 -07:00
|
|
|
sprintf(termcap + i, "%d", rows);
|
2015-01-18 13:24:39 -07:00
|
|
|
if ((ptr = strchr(ptr, ':')) != 0)
|
|
|
|
strcat(termcap, ptr);
|
2006-11-26 04:11:12 -07:00
|
|
|
}
|
|
|
|
#endif /* USE_TERMCAP */
|
|
|
|
|
|
|
|
if (SHELL_BOURNE == shell_type) {
|
|
|
|
|
|
|
|
#ifdef USE_TERMCAP
|
|
|
|
if (ok_tcap) {
|
|
|
|
printf("%sTERMCAP=", setname);
|
|
|
|
print_termcap(termcap);
|
|
|
|
printf(";\nexport TERMCAP;\n");
|
|
|
|
}
|
|
|
|
#endif /* USE_TERMCAP */
|
|
|
|
#ifdef USE_TERMINFO
|
|
|
|
printf("%sCOLUMNS=%d;\nLINES=%d;\nexport COLUMNS LINES;\n",
|
|
|
|
setname, cols, rows);
|
|
|
|
#endif /* USE_TERMINFO */
|
|
|
|
|
|
|
|
} else { /* not Bourne shell */
|
|
|
|
|
|
|
|
#ifdef USE_TERMCAP
|
|
|
|
if (ok_tcap) {
|
|
|
|
printf("set noglob;\n%ssetenv TERMCAP ", setname);
|
|
|
|
print_termcap(termcap);
|
|
|
|
printf(";\nunset noglob;\n");
|
|
|
|
}
|
|
|
|
#endif /* USE_TERMCAP */
|
|
|
|
#ifdef USE_TERMINFO
|
|
|
|
printf("set noglob;\n%ssetenv COLUMNS '%d';\nsetenv LINES '%d';\nunset noglob;\n",
|
|
|
|
setname, cols, rows);
|
|
|
|
#endif /* USE_TERMINFO */
|
|
|
|
}
|
2013-03-09 07:45:38 -07:00
|
|
|
exit(EXIT_SUCCESS);
|
2006-11-26 04:11:12 -07:00
|
|
|
}
|