1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1988 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 /*
  31  *      tput - print terminal attribute
  32  *
  33  *  return-codes - command line arguments:
  34  *      0: ok if boolean capname -> TRUE
  35  *      1: for boolean capname -> FALSE
  36  *
  37  *  return-codes - standard input arguments:
  38  *      0: ok; tput for all lines was successful
  39  *
  40  *  return-codes - both cases:
  41  *      2       usage error
  42  *      3       bad terminal type given or no terminfo database
  43  *      4       unknown capname
  44  *      -1      capname is a numeric variable that is not specified in the
  45  *              terminfo database(E.g. tpu -T450 lines).
  46  *
  47  *  tput printfs a value if an INT capname was given; e.g. cols.
  48  *      putp's a string if a STRING capname was given; e.g. clear. and
  49  *  for BOOLEAN capnames, e.g. hard-copy, just returns the boolean value.
  50  */
  51 
  52 #include <curses.h>
  53 #include <term.h>
  54 #include <fcntl.h>
  55 #include <ctype.h>
  56 #include <stdlib.h>
  57 #include <string.h>
  58 #include <sys/types.h>
  59 #include <unistd.h>
  60 #include <locale.h>
  61 
  62 /* externs from libcurses */
  63 extern int tigetnum();
  64 
  65 static int outputcap(char *cap, int argc, char **argv);
  66 static int allnumeric(char *string);
  67 static int getpad(char *cap);
  68 static void setdelay();
  69 static void settabs();
  70 static void cat(char *file);
  71 static void initterm();
  72 static void reset_term();
  73 
  74 static char *progname;          /* argv[0] */
  75 static int CurrentBaudRate;     /* current baud rate */
  76 static int reset = 0;           /* called as reset_term */
  77 static int fildes = 1;
  78 
  79 int
  80 main(int argc, char **argv)
  81 {
  82         int i, std_argc;
  83         char *term = getenv("TERM");
  84         char *cap, std_input = FALSE;
  85         int setuperr;
  86 
  87         (void) setlocale(LC_ALL, "");
  88 #if !defined(TEXT_DOMAIN)
  89 #define TEXT_DOMAIN "SYS_TEST"
  90 #endif
  91         (void) textdomain(TEXT_DOMAIN);
  92 
  93         progname = argv[0];
  94 
  95         while ((i = getopt(argc, argv, "ST:")) != EOF) {
  96                 switch (i) {
  97                 case 'T':
  98                         fildes = -1;
  99                         (void) putenv("LINES=");
 100                         (void) putenv("COLUMNS=");
 101                         term = optarg;
 102                         break;
 103 
 104                 case 'S':
 105                         std_input = TRUE;
 106                         break;
 107 
 108                 case '?':                       /* FALLTHROUGH          */
 109                 usage:                          /* FALLTHROUGH          */
 110                 default:
 111                         (void) fprintf(stderr, gettext(
 112                             "usage:\t%s [-T [term]] capname "
 113                             "[parm argument...]\n"), progname);
 114                         (void) fprintf(stderr, gettext("OR:\t%s -S <<\n"),
 115                             progname);
 116                         exit(2);
 117                 }
 118         }
 119 
 120         if (!term || !*term) {
 121                 (void) fprintf(stderr,
 122                     gettext("%s: No value for $TERM and no -T specified\n"),
 123                     progname);
 124                 exit(2);
 125         }
 126 
 127         (void) setupterm(term, fildes, &setuperr);
 128 
 129         switch (setuperr) {
 130         case -2:
 131                 (void) fprintf(stderr,
 132                     gettext("%s: unreadable terminal descriptor \"%s\"\n"),
 133                     progname, term);
 134                 exit(3);
 135                 break;
 136 
 137         case -1:
 138                 (void) fprintf(stderr,
 139                     gettext("%s: no terminfo database\n"), progname);
 140                 exit(3);
 141                 break;
 142 
 143         case 0:
 144                 (void) fprintf(stderr,
 145                     gettext("%s: unknown terminal \"%s\"\n"),
 146                     progname, term);
 147                 exit(3);
 148         }
 149 
 150         reset_shell_mode();
 151 
 152         /* command line arguments */
 153         if (!std_input) {
 154                 if (argc == optind)
 155                         goto usage;
 156 
 157                 cap = argv[optind++];
 158 
 159                 if (strcmp(cap, "init") == 0)
 160                         initterm();
 161                 else if (strcmp(cap, "reset") == 0)
 162                         reset_term();
 163                 else if (strcmp(cap, "longname") == 0)
 164                         (void) printf("%s\n", longname());
 165                 else
 166                         exit(outputcap(cap, argc, argv));
 167                 return (0);
 168         } else {                        /* standard input argumets      */
 169                 char buff[128];
 170                 char **v;
 171 
 172                 /* allocate storage for the 'faked' argv[] array        */
 173                 v = (char **)malloc(10 * sizeof (char *));
 174                 for (i = 0; i < 10; i++)
 175                         v[i] = (char *)malloc(32 * sizeof (char));
 176 
 177                 while (gets(buff) != NULL) {
 178                         /* read standard input line; skip over empty lines */
 179                         if ((std_argc =
 180                             sscanf(buff, "%s %s %s %s %s %s %s %s %s %s",
 181                             v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7],
 182                             v[8], v[9])) < 1) {
 183                                 continue;
 184                         }
 185 
 186                         cap = v[0];
 187                         optind = 1;
 188 
 189                         if (strcmp(cap, "init") == 0) {
 190                                 initterm();
 191                         } else if (strcmp(cap, "reset") == 0) {
 192                                 reset_term();
 193                         } else if (strcmp(cap, "longname") == 0) {
 194                                 (void) printf("%s\n", longname());
 195                         } else {
 196                                 (void) outputcap(cap, std_argc, v);
 197                         }
 198                         (void) fflush(stdout);
 199                 }
 200 
 201                 return (0);
 202         }
 203 }
 204 
 205 static long parm[9] = {
 206     0, 0, 0, 0, 0, 0, 0, 0, 0
 207 };
 208 
 209 static int
 210 outputcap(char *cap, int argc, char **argv)
 211 {
 212         int parmset = 0;
 213         char *thisstr;
 214         int i;
 215 
 216         if ((i = tigetflag(cap)) >= 0)
 217                 return (1 - i);
 218 
 219         if ((i = tigetnum(cap)) >= -1) {
 220                 (void) printf("%d\n", i);
 221                 return (0);
 222         }
 223 
 224         if ((thisstr = tigetstr(cap)) != (char *)-1) {
 225                 if (!thisstr) {
 226                         return (1);
 227                 }
 228                 for (parmset = 0; optind < argc; optind++, parmset++)
 229                         if (allnumeric(argv[optind]))
 230                                 parm[parmset] = atoi(argv[optind]);
 231                         else
 232                                 parm[parmset] = (int)argv[optind];
 233 
 234                 if (parmset)
 235                         putp(tparm(thisstr,
 236                             parm[0], parm[1], parm[2], parm[3],
 237                             parm[4], parm[5], parm[6], parm[7], parm[8]));
 238                 else
 239                         putp(thisstr);
 240                 return (0);
 241         }
 242 
 243         (void) fprintf(stderr,
 244             gettext("%s: unknown terminfo capability '%s'\n"), progname, cap);
 245 
 246         exit(4);
 247         /* NOTREACHED */
 248 }
 249 
 250 /*
 251  *  The decision as to whether an argument is a number or not is to simply
 252  *  look at whether there are any non-digits in the string.
 253  */
 254 static int
 255 allnumeric(char *string)
 256 {
 257         if (*string) {
 258                 while (*string) {
 259                         if (!isdigit(*string++)) {
 260                                 return (0);
 261                         }
 262                 }
 263                 return (1);
 264         } else {
 265                 return (0);
 266         }
 267 }
 268 
 269 /*
 270  *  SYSTEM DEPENDENT TERMINAL DELAY TABLES
 271  *
 272  *      These tables maintain the correspondence between the delays
 273  *      defined in terminfo and the delay algorithms in the tty driver
 274  *      on the particular systems. For each type of delay, the bits used
 275  *      for that delay must be specified, in XXbits, and a table
 276  *      must be defined giving correspondences between delays and
 277  *      algorithms. Algorithms which are not fixed delays, such
 278  *      as dependent on current column or line number, must be
 279  *      kludged in some way at this time.
 280  *
 281  *      Some of this was taken from tset(1).
 282  */
 283 
 284 struct delay
 285 {
 286     int d_delay;
 287     int d_bits;
 288 };
 289 
 290 /* The appropriate speeds for various termio settings. */
 291 static int speeds[] = {
 292                 0,      /*  B0,         */
 293                 50,     /*  B50,        */
 294                 75,     /*  B75,        */
 295                 110,    /*  B110,       */
 296                 134,    /*  B134,       */
 297                 150,    /*  B150,       */
 298                 200,    /*  B200,       */
 299                 300,    /*  B300,       */
 300                 600,    /*  B600,       */
 301                 1200,   /*  B1200,      */
 302                 1800,   /*  B1800,      */
 303                 2400,   /*  B2400,      */
 304                 4800,   /*  B4800,      */
 305                 9600,   /*  B9600,      */
 306                 19200,  /*  EXTA,       */
 307                 38400,  /*  EXTB,       */
 308                 57600,  /*  B57600,     */
 309                 76800,  /*  B76800,     */
 310                 115200, /*  B115200,    */
 311                 153600, /*  B153600,    */
 312                 230400, /*  B230400,    */
 313                 307200, /*  B307200,    */
 314                 460800, /*  B460800,    */
 315                 921600, /*  B921600,    */
 316                 0,
 317 };
 318 
 319 #if defined(SYSV) || defined(USG)
 320 /*      Unix 3.0 on up */
 321 
 322 /*    Carriage Return delays    */
 323 
 324 static int      CRbits = CRDLY;
 325 static struct delay     CRdelay[] =
 326 {
 327         0,      CR0,
 328         80,     CR1,
 329         100,    CR2,
 330         150,    CR3,
 331         -1
 332 };
 333 
 334 /*      New Line delays */
 335 
 336 static int      NLbits = NLDLY;
 337 static struct delay     NLdelay[] =
 338 {
 339         0,      NL0,
 340         100,    NL1,
 341         -1
 342 };
 343 
 344 /*      Back Space delays       */
 345 
 346 static int      BSbits = BSDLY;
 347 static struct delay     BSdelay[] =
 348 {
 349         0,      BS0,
 350         50,     BS1,
 351         -1
 352 };
 353 
 354 /*      TaB delays      */
 355 
 356 static int      TBbits = TABDLY;
 357 static struct delay     TBdelay[] =
 358 {
 359         0,      TAB0,
 360         11,     TAB1,           /* special M37 delay */
 361         100,    TAB2,
 362                                 /* TAB3 is XTABS and not a delay */
 363         -1
 364 };
 365 
 366 /*      Form Feed delays        */
 367 
 368 static int      FFbits = FFDLY;
 369 static struct delay     FFdelay[] =
 370 {
 371         0,      FF0,
 372         2000,   FF1,
 373         -1
 374 };
 375 
 376 #else   /* BSD */
 377 
 378 /*      Carriage Return delays  */
 379 
 380 int     CRbits = CRDELAY;
 381 struct delay    CRdelay[] =
 382 {
 383         0,      CR0,
 384         9,      CR3,
 385         80,     CR1,
 386         160,    CR2,
 387         -1
 388 };
 389 
 390 /*      New Line delays */
 391 
 392 int     NLbits = NLDELAY;
 393 struct delay    NLdelay[] =
 394 {
 395         0,      NL0,
 396         66,     NL1,            /* special M37 delay */
 397         100,    NL2,
 398         -1
 399 };
 400 
 401 /*      Tab delays      */
 402 
 403 int     TBbits = TBDELAY;
 404 struct delay    TBdelay[] =
 405 {
 406         0,      TAB0,
 407         11,     TAB1,           /* special M37 delay */
 408         -1
 409 };
 410 
 411 /*      Form Feed delays        */
 412 
 413 int     FFbits = VTDELAY;
 414 struct delay    FFdelay[] =
 415 {
 416         0,      FF0,
 417         2000,   FF1,
 418         -1
 419 };
 420 #endif  /* BSD */
 421 
 422 /*
 423  *  Initterm, a.k.a. reset_term, does terminal specific initialization. In
 424  *  particular, the init_strings from terminfo are output and tabs are
 425  *  set, if they aren't hardwired in. Much of this stuff was done by
 426  *  the tset(1) program.
 427  */
 428 
 429 /*
 430  *  Figure out how many milliseconds of padding the capability cap
 431  *  needs and return that number. Padding is stored in the string as "$<n>",
 432  *  where n is the number of milliseconds of padding. More than one
 433  *  padding string is allowed within the string, although this is unlikely.
 434  */
 435 
 436 static int
 437 getpad(char *cap)
 438 {
 439         int padding = 0;
 440 
 441         /* No padding needed at speeds below padding_baud_rate */
 442         if (padding_baud_rate > CurrentBaudRate || cap == NULL)
 443                 return (0);
 444 
 445         while (*cap) {
 446                 if ((cap[0] == '$') && (cap[1] == '<')) {
 447                         cap++;
 448                         cap++;
 449                         padding += atoi(cap);
 450                         while (isdigit (*cap))
 451                                 cap++;
 452                         while (*cap == '.' || *cap == '/' || *cap == '*' ||
 453                             isdigit(*cap))
 454                                 cap++;
 455                         while (*cap == '>')
 456                                 cap++;
 457                 } else {
 458                         cap++;
 459                 }
 460         }
 461 
 462         return (padding);
 463 }
 464 
 465 /*
 466  *  Set the appropriate delay bits in the termio structure for
 467  *  the given delay.
 468  */
 469 static void
 470 setdelay(delay, delaytable, bits, flags)
 471 register int delay;
 472 struct delay delaytable[];
 473 int bits;
 474 #ifdef SYSV
 475 tcflag_t *flags;
 476 #else   /* SYSV */
 477 unsigned short *flags;
 478 #endif  /* SYSV */
 479 {
 480         register struct delay  *p;
 481         register struct delay  *lastdelay;
 482 
 483         /* Clear out the bits, replace with new ones */
 484         *flags &= ~bits;
 485 
 486         /* Scan the delay table for first entry with adequate delay */
 487         for (lastdelay = p = delaytable;
 488             (p -> d_delay >= 0) && (p -> d_delay < delay);
 489             p++) {
 490                 lastdelay = p;
 491         }
 492 
 493         /* use last entry if none will do */
 494         *flags |= lastdelay -> d_bits;
 495 }
 496 
 497 /*
 498  * Set the hardware tabs on the terminal, using clear_all_tabs,
 499  * set_tab, and column_address capabilities. Cursor_address and cursor_right
 500  * may also be used, if necessary.
 501  * This is done before the init_file and init_3string, so they can patch in
 502  * case we blow this.
 503  */
 504 
 505 static void
 506 settabs()
 507 {
 508         register int c;
 509 
 510         /* Do not set tabs if they power up properly. */
 511         if (init_tabs == 8)
 512                 return;
 513 
 514         if (set_tab) {
 515                 /* Force the cursor to be at the left margin. */
 516                 if (carriage_return)
 517                         putp(carriage_return);
 518                 else
 519                         (void) putchar('\r');
 520 
 521                 /* Clear any current tab settings. */
 522                 if (clear_all_tabs)
 523                         putp(clear_all_tabs);
 524 
 525                 /* Set the tabs. */
 526                 for (c = 8; c < columns; c += 8) {
 527                         /* Get to that column. */
 528                         (void) fputs("        ", stdout);
 529 
 530                         /* Set the tab. */
 531                         putp(set_tab);
 532                 }
 533 
 534                 /* Get back to the left column. */
 535                 if (carriage_return)
 536                         putp(carriage_return);
 537                 else
 538                         (void) putchar('\r');
 539 
 540         }
 541 }
 542 
 543 /*
 544  *  Copy "file" onto standard output.
 545  */
 546 
 547 static void
 548 cat(file)
 549 char *file;                             /* File to copy. */
 550 {
 551         register int fd;                        /* File descriptor. */
 552         register ssize_t i;                     /* Number characters read. */
 553         char buf[BUFSIZ];                       /* Buffer to read into. */
 554 
 555         fd = open(file, O_RDONLY);
 556 
 557         if (fd < 0) {
 558                 perror("Cannot open initialization file");
 559         } else {
 560                 while ((i = read(fd, buf, BUFSIZ)) > (ssize_t)0)
 561                         (void) write(fileno(stdout), buf, (unsigned)i);
 562                 (int)close(fd);
 563         }
 564 }
 565 
 566 /*
 567  *  Initialize the terminal.
 568  *  Send the initialization strings to the terminal.
 569  */
 570 
 571 static void
 572 initterm()
 573 {
 574         register int filedes;           /* File descriptor for ioctl's. */
 575 #if defined(SYSV) || defined(USG)
 576         struct termio termmode;         /* To hold terminal settings. */
 577         struct termios termmodes;       /* To hold terminal settings. */
 578         int i;
 579         int istermios = -1;
 580 #define GTTY(fd, mode)  ioctl(fd, TCGETA, mode)
 581 #define GTTYS(fd, mode) \
 582         (istermios = ioctl(fd, TCGETS, mode))
 583 #define STTY(fd, mode)  ioctl(fd, TCSETAW, mode)
 584 #define STTYS(fd, mode) ioctl(fd, TCSETSW, mode)
 585 #define SPEED(mode)     (mode.c_cflag & CBAUD)
 586 #define SPEEDS(mode)    (cfgetospeed(&mode))
 587 #define OFLAG(mode)     mode.c_oflag
 588 #else   /* BSD */
 589         struct sgttyb termmode;         /* To hold terminal settings. */
 590 #define GTTY(fd, mode)  gtty(fd, mode)
 591 #define STTY(fd, mode)  stty(fd, mode)
 592 #define SPEED(mode)     (mode.sg_ospeed & 017)
 593 #define OFLAG(mode)     mode.sg_flags
 594 #define TAB3            XTABS
 595 #endif
 596 
 597         /* Get the terminal settings. */
 598         /* First try standard output, then standard error, */
 599         /* then standard input, then /dev/tty. */
 600 #ifdef SYSV
 601         if ((filedes = 1, GTTYS(filedes, &termmodes) < 0) ||
 602             (filedes = 2, GTTYS(filedes, &termmodes) < 0) ||
 603             (filedes = 0, GTTYS(filedes, &termmodes) < 0) ||
 604             (filedes = open("/dev/tty", O_RDWR),
 605             GTTYS(filedes, &termmodes) < 0)) {
 606 #endif  /* SYSV */
 607                 if ((filedes = 1, GTTY(filedes, &termmode) == -1) ||
 608                     (filedes = 2, GTTY(filedes, &termmode) == -1) ||
 609                     (filedes = 0, GTTY(filedes, &termmode) == -1) ||
 610                     (filedes = open("/dev/tty", O_RDWR),
 611                     GTTY(filedes, &termmode) == -1)) {
 612                         filedes = -1;
 613                         CurrentBaudRate = speeds[B1200];
 614                 } else
 615                         CurrentBaudRate = speeds[SPEED(termmode)];
 616 #ifdef SYSV
 617                 termmodes.c_lflag = termmode.c_lflag;
 618                 termmodes.c_oflag = termmode.c_oflag;
 619                 termmodes.c_iflag = termmode.c_iflag;
 620                 termmodes.c_cflag = termmode.c_cflag;
 621                 for (i = 0; i < NCC; i++)
 622                         termmodes.c_cc[i] = termmode.c_cc[i];
 623         } else
 624                 CurrentBaudRate = speeds[SPEEDS(termmodes)];
 625 #endif  /* SYSV */
 626 
 627         if (xon_xoff) {
 628 #ifdef SYSV
 629                 OFLAG(termmodes) &=
 630                     ~(NLbits | CRbits | BSbits | FFbits | TBbits);
 631 #else   /* SYSV */
 632                 OFLAG(termmode) &=
 633                     ~(NLbits | CRbits | BSbits | FFbits | TBbits);
 634 #endif  /* SYSV */
 635         } else {
 636 #ifdef SYSV
 637                 setdelay(getpad(carriage_return),
 638                     CRdelay, CRbits, &OFLAG(termmodes));
 639                 setdelay(getpad(scroll_forward),
 640                     NLdelay, NLbits, &OFLAG(termmodes));
 641                 setdelay(getpad(cursor_left),
 642                     BSdelay, BSbits, &OFLAG(termmodes));
 643                 setdelay(getpad(form_feed),
 644                     FFdelay, FFbits, &OFLAG(termmodes));
 645                 setdelay(getpad(tab),
 646                     TBdelay, TBbits, &OFLAG(termmodes));
 647 #else   /* SYSV */
 648                 setdelay(getpad(carriage_return),
 649                     CRdelay, CRbits, &OFLAG(termmode));
 650                 setdelay(getpad(scroll_forward),
 651                     NLdelay, NLbits, &OFLAG(termmode));
 652                 setdelay(getpad(cursor_left),
 653                     BSdelay, BSbits, &OFLAG(termmode));
 654                 setdelay(getpad(form_feed),
 655                     FFdelay, FFbits, &OFLAG(termmode));
 656                 setdelay(getpad(tab),
 657                     TBdelay, TBbits, &OFLAG(termmode));
 658 #endif  /* SYSV */
 659         }
 660 
 661         /* If tabs can be sent to the tty, turn off their expansion. */
 662         if (tab && set_tab || init_tabs == 8) {
 663 #ifdef SYSV
 664                 OFLAG(termmodes) &= ~(TAB3);
 665 #else   /* SYSV */
 666                 OFLAG(termmode) &= ~(TAB3);
 667 #endif  /* SYSV */
 668         } else {
 669 #ifdef SYSV
 670                 OFLAG(termmodes) |= TAB3;
 671 #else   /* SYSV */
 672                 OFLAG(termmode) |= TAB3;
 673 #endif  /* SYSV */
 674         }
 675 
 676         /* Do the changes to the terminal settings */
 677 #ifdef SYSV
 678         if (istermios < 0) {
 679                 int i;
 680 
 681                 termmode.c_lflag = termmodes.c_lflag;
 682                 termmode.c_oflag = termmodes.c_oflag;
 683                 termmode.c_iflag = termmodes.c_iflag;
 684                 termmode.c_cflag = termmodes.c_cflag;
 685                 for (i = 0; i < NCC; i++)
 686                         termmode.c_cc[i] = termmodes.c_cc[i];
 687                 (void) STTY(filedes, &termmode);
 688         } else
 689                 (void) STTYS(filedes, &termmodes);
 690 
 691 #else   /* SYSV */
 692         (void) STTY(filedes, &termmode);
 693 #endif  /* SYSV */
 694 
 695         /* Send first initialization strings. */
 696         if (init_prog)
 697         (void) system(init_prog);
 698 
 699         if (reset && reset_1string) {
 700                 putp(reset_1string);
 701         } else if (init_1string) {
 702                 putp(init_1string);
 703         }
 704 
 705         if (reset && reset_2string) {
 706                 putp(reset_2string);
 707         } else if (init_2string) {
 708                 putp(init_2string);
 709         }
 710 
 711         /* Set up the tabs stops. */
 712         settabs();
 713 
 714         /* Send out initializing file. */
 715         if (reset && reset_file) {
 716                 cat(reset_file);
 717         } else if (init_file) {
 718                 cat(init_file);
 719         }
 720 
 721         /* Send final initialization strings. */
 722         if (reset && reset_3string) {
 723                 putp(reset_3string);
 724         } else if (init_3string) {
 725                 putp(init_3string);
 726         }
 727 
 728         if (carriage_return) {
 729                 putp(carriage_return);
 730         } else {
 731                 (void) putchar('\r');
 732         }
 733 
 734         /* Send color initialization strings */
 735 
 736         if (orig_colors)
 737                 putp(orig_colors);
 738 
 739         if (orig_pair)
 740         putp(orig_pair);
 741 
 742         /* Let the terminal settle down. */
 743         (void) fflush(stdout);
 744         (void) sleep(1);
 745 }
 746 
 747 static void
 748 reset_term()
 749 {
 750         reset++;
 751         initterm();
 752 }