"Fossies" - the Fresh Open Source Software Archive

Member "xterm-379/resize.c" (26 Jan 2023, 16700 Bytes) of package /linux/misc/xterm-379.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "resize.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 377_vs_379.

    1 /* $XTermId: resize.c,v 1.149 2023/01/26 00:43:18 tom Exp $ */
    2 
    3 /*
    4  * Copyright 2003-2022,2023 by Thomas E. Dickey
    5  *
    6  *                         All Rights Reserved
    7  *
    8  * Permission is hereby granted, free of charge, to any person obtaining a
    9  * copy of this software and associated documentation files (the
   10  * "Software"), to deal in the Software without restriction, including
   11  * without limitation the rights to use, copy, modify, merge, publish,
   12  * distribute, sublicense, and/or sell copies of the Software, and to
   13  * permit persons to whom the Software is furnished to do so, subject to
   14  * the following conditions:
   15  *
   16  * The above copyright notice and this permission notice shall be included
   17  * in all copies or substantial portions of the Software.
   18  *
   19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   20  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   22  * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
   23  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   24  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   25  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   26  *
   27  * Except as contained in this notice, the name(s) of the above copyright
   28  * holders shall not be used in advertising or otherwise to promote the
   29  * sale, use or other dealings in this Software without prior written
   30  * authorization.
   31  *
   32  *
   33  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
   34  *
   35  *                         All Rights Reserved
   36  *
   37  * Permission to use, copy, modify, and distribute this software and its
   38  * documentation for any purpose and without fee is hereby granted,
   39  * provided that the above copyright notice appear in all copies and that
   40  * both that copyright notice and this permission notice appear in
   41  * supporting documentation, and that the name of Digital Equipment
   42  * Corporation not be used in advertising or publicity pertaining to
   43  * distribution of the software without specific, written prior permission.
   44  *
   45  *
   46  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
   47  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
   48  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
   49  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   50  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
   51  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   52  * SOFTWARE.
   53  */
   54 
   55 /* resize.c */
   56 
   57 #include <stdio.h>
   58 #include <ctype.h>
   59 
   60 #include <xterm.h>
   61 #include <version.h>
   62 #include <xstrings.h>
   63 #include <xtermcap.h>
   64 #include <xterm_io.h>
   65 
   66 #ifndef USE_TERMINFO        /* avoid conflict with configure script */
   67 #if defined(__QNX__) || defined(__SCO__) || defined(linux) || defined(__OpenBSD__) || defined(__UNIXWARE__)
   68 #define USE_TERMINFO
   69 #endif
   70 #endif
   71 
   72 #if defined(__QNX__)
   73 #include <unix.h>
   74 #endif
   75 
   76 /*
   77  * Some OS's may want to use both, like SCO for example.  We catch here anyone
   78  * who hasn't decided what they want.
   79  */
   80 #if !defined(USE_TERMCAP) && !defined(USE_TERMINFO)
   81 #define USE_TERMINFO
   82 #endif
   83 
   84 #include <signal.h>
   85 #include <pwd.h>
   86 
   87 #ifdef USE_IGNORE_RC
   88 int ignore_unused;
   89 #endif
   90 
   91 #ifdef __MVS__
   92 #define ESCAPE(string) "\047" string
   93 #else
   94 #define ESCAPE(string) "\033" string
   95 #endif
   96 
   97 #define EMULATIONS  2
   98 #define SUN     1
   99 #define VT100       0
  100 
  101 #define TIMEOUT     3
  102 
  103 #define SHELL_UNKNOWN   0
  104 #define SHELL_C     1
  105 #define SHELL_BOURNE    2
  106 /* *INDENT-OFF* */
  107 static struct {
  108     const char *name;
  109     int type;
  110 } shell_list[] = {
  111     { "csh",    SHELL_C },  /* vanilla cshell */
  112     { "jcsh",   SHELL_C },
  113     { "tcsh",   SHELL_C },
  114     { "sh", SHELL_BOURNE }, /* vanilla Bourne shell */
  115     { "ash",    SHELL_BOURNE },
  116     { "bash",   SHELL_BOURNE }, /* GNU Bourne again shell */
  117     { "dash",   SHELL_BOURNE },
  118     { "jsh",    SHELL_BOURNE },
  119     { "ksh",    SHELL_BOURNE }, /* Korn shell (from AT&T toolchest) */
  120     { "ksh-i",  SHELL_BOURNE }, /* another name for Korn shell */
  121     { "ksh93",  SHELL_BOURNE }, /* Korn shell */
  122     { "mksh",   SHELL_BOURNE },
  123     { "pdksh",  SHELL_BOURNE },
  124     { "zsh",    SHELL_BOURNE },
  125     { NULL, SHELL_BOURNE }  /* default (same as xterm's) */
  126 };
  127 /* *INDENT-ON* */
  128 
  129 static const char *const emuname[EMULATIONS] =
  130 {
  131     "VT100",
  132     "Sun",
  133 };
  134 static char *myname;
  135 static int shell_type = SHELL_UNKNOWN;
  136 static const char *const getattr[EMULATIONS] =
  137 {
  138     ESCAPE("[c"),
  139     NULL,
  140 };
  141 static const char *const getsize[EMULATIONS] =
  142 {
  143     ESCAPE("7") ESCAPE("[r") ESCAPE("[9999;9999H") ESCAPE("[6n"),
  144     ESCAPE("[18t"),
  145 };
  146 #if defined(USE_STRUCT_WINSIZE)
  147 static const char *const getwsize[EMULATIONS] =
  148 {               /* size in pixels */
  149     0,
  150     ESCAPE("[14t"),
  151 };
  152 #endif /* USE_STRUCT_WINSIZE */
  153 static const char *const restore[EMULATIONS] =
  154 {
  155     ESCAPE("8"),
  156     0,
  157 };
  158 static const char *const setsize[EMULATIONS] =
  159 {
  160     0,
  161     ESCAPE("[8;%s;%st"),
  162 };
  163 
  164 #ifdef USE_ANY_SYSV_TERMIO
  165 static struct termio tioorig;
  166 #elif defined(USE_TERMIOS)
  167 static struct termios tioorig;
  168 #else
  169 static struct sgttyb sgorig;
  170 #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
  171 
  172 static const char *const reply_attr[EMULATIONS] =
  173 {
  174     ESCAPE("[?%d;%dc"),
  175     NULL,
  176 };
  177 static const char *const reply_size[EMULATIONS] =
  178 {
  179     ESCAPE("[%d;%dR"),
  180     ESCAPE("[8;%d;%dt"),
  181 };
  182 static const char sunname[] = "sunsize";
  183 static int tty;
  184 static FILE *ttyfp;
  185 
  186 #if defined(USE_STRUCT_WINSIZE)
  187 static const char *wsize[EMULATIONS] =
  188 {
  189     0,
  190     ESCAPE("[4;%hd;%hdt"),
  191 };
  192 #endif /* USE_STRUCT_WINSIZE */
  193 
  194 static GCC_NORETURN void failed(const char *);
  195 static GCC_NORETURN void onintr(int);
  196 static GCC_NORETURN void resize_timeout(int);
  197 static GCC_NORETURN void Usage(void);
  198 
  199 static void
  200 failed(const char *s)
  201 {
  202     int save = errno;
  203     IGNORE_RC(write(2, myname, strlen(myname)));
  204     IGNORE_RC(write(2, ": ", (size_t) 2));
  205     errno = save;
  206     perror(s);
  207     exit(EXIT_FAILURE);
  208 }
  209 
  210 /* ARGSUSED */
  211 static void
  212 onintr(int sig GCC_UNUSED)
  213 {
  214 #ifdef USE_ANY_SYSV_TERMIO
  215     (void) ioctl(tty, TCSETAW, &tioorig);
  216 #elif defined(USE_TERMIOS)
  217     (void) tcsetattr(tty, TCSADRAIN, &tioorig);
  218 #else /* not USE_TERMIOS */
  219     (void) ioctl(tty, TIOCSETP, &sgorig);
  220 #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
  221     exit(EXIT_FAILURE);
  222 }
  223 
  224 const char *timeout_message = "?";
  225 
  226 static void
  227 resize_timeout(int sig)
  228 {
  229     fprintf(stderr, "\n%s: %s\r\n", myname, timeout_message);
  230     onintr(sig);
  231 }
  232 
  233 static void
  234 Usage(void)
  235 {
  236     fprintf(stderr, strcmp(myname, sunname) == 0 ?
  237         "Usage: %s [rows cols]\n" :
  238         "Usage: %s [-v] [-u] [-c] [-s [rows cols]]\n", myname);
  239     exit(EXIT_FAILURE);
  240 }
  241 
  242 #ifdef USE_TERMCAP
  243 static void
  244 print_termcap(const char *termcap)
  245 {
  246     int ch;
  247 
  248     putchar('\'');
  249     while ((ch = *termcap++) != '\0') {
  250     switch (ch & 0xff) {
  251     case 127:       /* undo bug in GNU termcap */
  252         printf("^?");
  253         break;
  254     case '\'':      /* must escape anyway (unlikely) */
  255         /* FALLTHRU */
  256     case '!':       /* must escape for SunOS csh */
  257         putchar('\\');
  258         /* FALLTHRU */
  259     default:
  260         putchar(ch);
  261         break;
  262     }
  263     }
  264     putchar('\'');
  265 }
  266 #endif /* USE_TERMCAP */
  267 
  268 static int
  269 checkdigits(char *str)
  270 {
  271     while (*str) {
  272     if (!isdigit(CharOf(*str)))
  273         return (0);
  274     str++;
  275     }
  276     return (1);
  277 }
  278 
  279 static void
  280 unexpected_char(int c)
  281 {
  282     fprintf(stderr, "%s: unknown character %#x, exiting.\r\n", myname, c);
  283     onintr(0);
  284 }
  285 
  286 static void
  287 readstring(FILE *fp, char *buf, const char *str)
  288 {
  289     int last, c;
  290 #if HAVE_SETITIMER
  291     struct itimerval it;
  292 #endif
  293     int limit = (BUFSIZ - 3);
  294 
  295     signal(SIGALRM, resize_timeout);
  296 #if HAVE_SETITIMER
  297     memset((char *) &it, 0, sizeof(struct itimerval));
  298     it.it_value.tv_sec = TIMEOUT;
  299     setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
  300 #else
  301     alarm(TIMEOUT);
  302 #endif
  303     if ((c = getc(fp)) == 0233) {   /* meta-escape, CSI */
  304     c = ESCAPE("")[0];
  305     *buf++ = (char) c;
  306     *buf++ = '[';
  307     } else {
  308     *buf++ = (char) c;
  309     }
  310     if (c != *str) {
  311     unexpected_char(c);
  312     }
  313     last = str[strlen(str) - 1];
  314     while ((c = getc(fp)) != EOF) {
  315     if (--limit <= 0) {
  316         fprintf(stderr, "%s: unexpected response\n", myname);
  317         onintr(0);
  318     }
  319     if (c < 32 || c > 126) {
  320         unexpected_char(c);
  321     }
  322     *buf++ = (char) c;
  323     if (c == last)
  324         break;
  325     }
  326 #if HAVE_SETITIMER
  327     memset((char *) &it, 0, sizeof(struct itimerval));
  328     setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
  329 #else
  330     alarm(0);
  331 #endif
  332     *buf = 0;
  333 }
  334 
  335 /*
  336    resets termcap string to reflect current screen size
  337  */
  338 int
  339 main(int argc, char **argv ENVP_ARG)
  340 {
  341 #ifdef USE_TERMCAP
  342     char *env;
  343 #endif
  344     char *ptr;
  345     int emu = VT100;
  346     char *shell;
  347     int i;
  348     int rc;
  349     int rows, cols;
  350 #ifdef USE_ANY_SYSV_TERMIO
  351     struct termio tio;
  352 #elif defined(USE_TERMIOS)
  353     struct termios tio;
  354 #else
  355     struct sgttyb sg;
  356 #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
  357 #ifdef USE_TERMCAP
  358     int ok_tcap = 1;
  359     char termcap[TERMCAP_SIZE];
  360     char newtc[TERMCAP_SIZE];
  361 #endif /* USE_TERMCAP */
  362     char buf[BUFSIZ];
  363 #ifdef TTYSIZE_STRUCT
  364     TTYSIZE_STRUCT ts;
  365 #endif
  366     char *name_of_tty;
  367 #ifdef CANT_OPEN_DEV_TTY
  368     extern char *ttyname();
  369 #endif
  370     const char *setname = "";
  371 
  372     myname = x_basename(argv[0]);
  373     if (strcmp(myname, sunname) == 0)
  374     emu = SUN;
  375     for (argv++, argc--; argc > 0 && **argv == '-'; argv++, argc--) {
  376     switch ((*argv)[1]) {
  377     case 's':       /* Sun emulation */
  378         if (emu == SUN)
  379         Usage();    /* Never returns */
  380         emu = SUN;
  381         break;
  382     case 'u':       /* Bourne (Unix) shell */
  383         shell_type = SHELL_BOURNE;
  384         break;
  385     case 'c':       /* C shell */
  386         shell_type = SHELL_C;
  387         break;
  388     case 'v':
  389         printf("%s\n", xtermVersion());
  390         exit(EXIT_SUCCESS);
  391     default:
  392         Usage();        /* Never returns */
  393     }
  394     }
  395 
  396     if (SHELL_UNKNOWN == shell_type) {
  397     /* Find out what kind of shell this user is running.
  398      * This is the same algorithm that xterm uses.
  399      */
  400     if ((ptr = x_getenv("SHELL")) == NULL) {
  401         uid_t uid = getuid();
  402         struct passwd pw;
  403 
  404         if (x_getpwuid(uid, &pw)) {
  405         (void) x_getlogin(uid, &pw);
  406         }
  407         if (!OkPasswd(&pw)
  408         || *(ptr = pw.pw_shell) == 0) {
  409         /* this is the same default that xterm uses */
  410         ptr = x_strdup("/bin/sh");
  411         }
  412     }
  413 
  414     shell = x_basename(ptr);
  415 
  416     /* now that we know, what kind is it? */
  417     for (i = 0; shell_list[i].name; i++) {
  418         if (!strcmp(shell_list[i].name, shell)) {
  419         break;
  420         }
  421     }
  422     shell_type = shell_list[i].type;
  423     }
  424 
  425     if (argc == 2) {
  426     if (!setsize[emu]) {
  427         fprintf(stderr,
  428             "%s: Can't set window size under %s emulation\n",
  429             myname, emuname[emu]);
  430         exit(EXIT_FAILURE);
  431     }
  432     if (!checkdigits(argv[0]) || !checkdigits(argv[1])) {
  433         Usage();        /* Never returns */
  434     }
  435     } else if (argc != 0) {
  436     Usage();        /* Never returns */
  437     }
  438 #ifdef CANT_OPEN_DEV_TTY
  439     if ((name_of_tty = ttyname(fileno(stderr))) == NULL)
  440 #endif
  441     name_of_tty = x_strdup("/dev/tty");
  442 
  443     if ((ttyfp = fopen(name_of_tty, "r+")) == NULL) {
  444     fprintf(stderr, "%s:  can't open terminal %s\n",
  445         myname, name_of_tty);
  446     exit(EXIT_FAILURE);
  447     }
  448     tty = fileno(ttyfp);
  449 #ifdef USE_TERMCAP
  450     if ((env = x_getenv("TERM")) == 0) {
  451     env = x_strdup(DFT_TERMTYPE);
  452     if (SHELL_BOURNE == shell_type) {
  453         setname = "TERM=" DFT_TERMTYPE ";\nexport TERM;\n";
  454     } else {
  455         setname = "setenv TERM " DFT_TERMTYPE ";\n";
  456     }
  457     }
  458     termcap[0] = 0;     /* ...just in case we've accidentally gotten terminfo */
  459     if (tgetent(termcap, env) <= 0 || termcap[0] == 0) {
  460     ok_tcap = 0;
  461     }
  462 #endif /* USE_TERMCAP */
  463 #ifdef USE_TERMINFO
  464     if (x_getenv("TERM") == 0) {
  465     if (SHELL_BOURNE == shell_type) {
  466         setname = "TERM=" DFT_TERMTYPE ";\nexport TERM;\n";
  467     } else {
  468         setname = "setenv TERM " DFT_TERMTYPE ";\n";
  469     }
  470     }
  471 #endif /* USE_TERMINFO */
  472 
  473 #ifdef USE_ANY_SYSV_TERMIO
  474     rc = ioctl(tty, TCGETA, &tioorig);
  475     tio = tioorig;
  476     UIntClr(tio.c_iflag, (ICRNL | IUCLC));
  477     UIntClr(tio.c_lflag, (ICANON | ECHO));
  478     tio.c_cflag |= CS8;
  479     tio.c_cc[VMIN] = 6;
  480     tio.c_cc[VTIME] = 1;
  481 #elif defined(USE_TERMIOS)
  482     rc = tcgetattr(tty, &tioorig);
  483     tio = tioorig;
  484     UIntClr(tio.c_iflag, ICRNL);
  485     UIntClr(tio.c_lflag, (ICANON | ECHO));
  486     tio.c_cflag |= CS8;
  487     tio.c_cc[VMIN] = 6;
  488     tio.c_cc[VTIME] = 1;
  489 #else /* not USE_TERMIOS */
  490     rc = ioctl(tty, TIOCGETP, &sgorig);
  491     sg = sgorig;
  492     sg.sg_flags |= RAW;
  493     UIntClr(sg.sg_flags, ECHO);
  494 #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
  495     if (rc != 0)
  496     failed("get tty settings");
  497 
  498     signal(SIGINT, onintr);
  499     signal(SIGQUIT, onintr);
  500     signal(SIGTERM, onintr);
  501 
  502 #ifdef USE_ANY_SYSV_TERMIO
  503     rc = ioctl(tty, TCSETAW, &tio);
  504 #elif defined(USE_TERMIOS)
  505     rc = tcsetattr(tty, TCSADRAIN, &tio);
  506 #else /* not USE_TERMIOS */
  507     rc = ioctl(tty, TIOCSETP, &sg);
  508 #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
  509     if (rc != 0)
  510     failed("set tty settings");
  511 
  512     if (argc == 2) {        /* look for optional parameters of "-s" */
  513     char *tmpbuf = TypeMallocN(char,
  514                    strlen(setsize[emu]) +
  515                    strlen(argv[0]) +
  516                    strlen(argv[1]) +
  517                    1);
  518     if (tmpbuf == 0) {
  519         fprintf(stderr, "%s: Cannot query size\n", myname);
  520         onintr(0);
  521     } else {
  522         sprintf(tmpbuf, setsize[emu], argv[0], argv[1]);
  523         IGNORE_RC(write(tty, tmpbuf, strlen(tmpbuf)));
  524         free(tmpbuf);
  525     }
  526     }
  527     if (getattr[emu]) {
  528     timeout_message = "Terminal is not VT100-compatible";
  529     IGNORE_RC(write(tty, getattr[emu], strlen(getattr[emu])));
  530     readstring(ttyfp, buf, reply_attr[emu]);
  531     }
  532     timeout_message = "Time out occurred";
  533     IGNORE_RC(write(tty, getsize[emu], strlen(getsize[emu])));
  534     readstring(ttyfp, buf, reply_size[emu]);
  535     if (sscanf(buf, reply_size[emu], &rows, &cols) != 2) {
  536     fprintf(stderr, "%s: Can't get rows and columns\r\n", myname);
  537     onintr(0);
  538     }
  539     if (restore[emu])
  540     IGNORE_RC(write(tty, restore[emu], strlen(restore[emu])));
  541 #if defined(USE_STRUCT_WINSIZE)
  542     /* finally, set the tty's window size */
  543     if (getwsize[emu]) {
  544     /* get the window size in pixels */
  545     IGNORE_RC(write(tty, getwsize[emu], strlen(getwsize[emu])));
  546     readstring(ttyfp, buf, wsize[emu]);
  547     if (sscanf(buf, wsize[emu], &ts.ws_xpixel, &ts.ws_ypixel) != 2) {
  548         fprintf(stderr, "%s: Can't get window size\r\n", myname);
  549         onintr(0);
  550     }
  551     setup_winsize(ts, rows, cols, 0, 0);
  552     SET_TTYSIZE(tty, ts);
  553     } else if (ioctl(tty, TIOCGWINSZ, &ts) != -1) {
  554     /* we don't have any way of directly finding out
  555        the current height & width of the window in pixels.  We try
  556        our best by computing the font height and width from the "old"
  557        window-size values, and multiplying by these ratios... */
  558 #define scaled(old,new,len) (old)?((unsigned)(new)*(len)/(old)):(len)
  559     setup_winsize(ts, rows, cols,
  560               scaled(TTYSIZE_ROWS(ts), rows, ts.ws_ypixel),
  561               scaled(TTYSIZE_COLS(ts), cols, ts.ws_xpixel));
  562     SET_TTYSIZE(tty, ts);
  563     }
  564 #endif /* USE_STRUCT_WINSIZE */
  565 
  566 #ifdef USE_ANY_SYSV_TERMIO
  567     rc = ioctl(tty, TCSETAW, &tioorig);
  568 #elif defined(USE_TERMIOS)
  569     rc = tcsetattr(tty, TCSADRAIN, &tioorig);
  570 #else /* not USE_TERMIOS */
  571     rc = ioctl(tty, TIOCSETP, &sgorig);
  572 #endif /* USE_ANY_SYSV_TERMIO/USE_TERMIOS */
  573     if (rc != 0)
  574     failed("set tty settings");
  575 
  576     signal(SIGINT, SIG_DFL);
  577     signal(SIGQUIT, SIG_DFL);
  578     signal(SIGTERM, SIG_DFL);
  579 
  580 #ifdef USE_TERMCAP
  581     if (ok_tcap) {
  582     /* update termcap string */
  583     /* first do columns */
  584     if ((ptr = x_strindex(termcap, "co#")) == NULL) {
  585         fprintf(stderr, "%s: No `co#'\n", myname);
  586         exit(EXIT_FAILURE);
  587     }
  588 
  589     i = (int) (ptr - termcap) + 3;
  590     strncpy(newtc, termcap, (size_t) i);
  591     sprintf(newtc + i, "%d", cols);
  592     if ((ptr = strchr(ptr, ':')) != 0)
  593         strcat(newtc, ptr);
  594 
  595     /* now do lines */
  596     if ((ptr = x_strindex(newtc, "li#")) == NULL) {
  597         fprintf(stderr, "%s: No `li#'\n", myname);
  598         exit(EXIT_FAILURE);
  599     }
  600 
  601     i = (int) (ptr - newtc) + 3;
  602     strncpy(termcap, newtc, (size_t) i);
  603     sprintf(termcap + i, "%d", rows);
  604     if ((ptr = strchr(ptr, ':')) != 0)
  605         strcat(termcap, ptr);
  606     }
  607 #endif /* USE_TERMCAP */
  608 
  609     if (SHELL_BOURNE == shell_type) {
  610 
  611 #ifdef USE_TERMCAP
  612     if (ok_tcap) {
  613         printf("%sTERMCAP=", setname);
  614         print_termcap(termcap);
  615         printf(";\nexport TERMCAP;\n");
  616     }
  617 #endif /* USE_TERMCAP */
  618 #ifdef USE_TERMINFO
  619     printf("%sCOLUMNS=%d;\nLINES=%d;\nexport COLUMNS LINES;\n",
  620            setname, cols, rows);
  621 #endif /* USE_TERMINFO */
  622 
  623     } else {            /* not Bourne shell */
  624 
  625 #ifdef USE_TERMCAP
  626     if (ok_tcap) {
  627         printf("set noglob;\n%ssetenv TERMCAP ", setname);
  628         print_termcap(termcap);
  629         printf(";\nunset noglob;\n");
  630     }
  631 #endif /* USE_TERMCAP */
  632 #ifdef USE_TERMINFO
  633     printf("set noglob;\n%ssetenv COLUMNS '%d';\nsetenv LINES '%d';\nunset noglob;\n",
  634            setname, cols, rows);
  635 #endif /* USE_TERMINFO */
  636     }
  637     exit(EXIT_SUCCESS);
  638 }