home *** CD-ROM | disk | FTP | other *** search
/ Chip 1995 March / CHIP3.mdf / slackwar / a / util / util-lin.10 / util-lin / util-linux-1.10 / setterm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-22  |  29.0 KB  |  1,076 lines

  1. /* setterm.c, set terminal attributes.
  2.  *
  3.  * Copyright (C) 1990 Gordon Irlam (gordoni@cs.ua.oz.au).  Conditions of use,
  4.  * modification, and redistribution are contained in the file COPYRIGHT that
  5.  * forms part of this distribution.
  6.  * 
  7.  * Adaption to Linux by Peter MacDonald.
  8.  *
  9.  * Enhancements by Mika Liljeberg (liljeber@cs.Helsinki.FI)
  10.  *
  11.  *
  12.  * Syntax:
  13.  *
  14.  * setterm
  15.  *   [ -term terminal_name ]
  16.  *   [ -reset ]
  17.  *   [ -initialize ]
  18.  *   [ -cursor [on|off] ]
  19.  *   [ -keyboard pc|olivetti|dutch|extended ]
  20.  *   [ -repeat [on|off] ]
  21.  *   [ -appcursorkeys [on|off] ]
  22.  *   [ -linewrap [on|off] ]
  23.  *   [ -snow [on|off] ]
  24.  *   [ -softscroll [on|off] ]
  25.  *   [ -defaults ]
  26.  *   [ -foreground black|red|green|yellow|blue|magenta|cyan|white|default ]
  27.  *   [ -background black|red|green|yellow|blue|magenta|cyan|white|default ]
  28.  *   [ -ulcolor black|grey|red|green|yellow|blue|magenta|cyan|white ]
  29.  *   [ -ulcolor bright red|green|yellow|blue|magenta|cyan|white ]
  30.  *   [ -hbcolor black|grey|red|green|yellow|blue|magenta|cyan|white ]
  31.  *   [ -hbcolor bright red|green|yellow|blue|magenta|cyan|white ]
  32.  *   [ -inversescreen [on|off] ]
  33.  *   [ -bold [on|off] ]
  34.  *   [ -half-bright [on|off] ]
  35.  *   [ -blink [on|off] ]
  36.  *   [ -reverse [on|off] ]
  37.  *   [ -underline [on|off] ]
  38.  *   [ -store ]
  39.  *   [ -clear [ all|rest ] ]
  40.  *   [ -tabs [tab1 tab2 tab3 ... ] ]     (tabn = 1-160)
  41.  *   [ -clrtabs [ tab1 tab2 tab3 ... ]   (tabn = 1-160)
  42.  *   [ -regtabs [1-160] ]
  43.  *   [ -blank [0-60] ]
  44.  *   [ -dump   [1-NR_CONS ] ]
  45.  *   [ -append [1-NR_CONS ] ]
  46.  *   [ -file dumpfilename ]
  47.  *   [ -standout [attr] ]
  48.  *   [ -msg [on|off] ]
  49.  *   [ -msglevel [0-8] ]
  50.  *
  51.  *
  52.  * Semantics:
  53.  *
  54.  * Setterm writes to standard output a character string that will invoke the
  55.  * specified terminal capabilities.  Where possibile termcap is consulted to
  56.  * find the string to use.  Some options however do not correspond to a
  57.  * termcap capability.  In this case if the terminal type is "minix-vc", or
  58.  * "minix-vcam" the string that invokes the specified capabilities on the PC
  59.  * Minix virtual console driver is output.  Options that are not implemented
  60.  * by the terminal are ignored.
  61.  *
  62.  * The following options are non-obvious.
  63.  *
  64.  *   -term can be used to override the TERM environment variable.
  65.  *
  66.  *   -reset displays the terminal reset string, which typically resets the
  67.  *      terminal to its power on state.
  68.  *
  69.  *   -initialize displays the terminal initialization string, which typically
  70.  *      sets the terminal's rendering options, and other attributes to the
  71.  *      default values.
  72.  *
  73.  *   -default sets the terminal's rendering options to the default values.
  74.  *
  75.  *   -store stores the terminal's current rendering options as the default
  76.  *      values.
  77.  */
  78.  
  79. #include <stdlib.h>
  80. #include <stdio.h>
  81. #include <ctype.h>
  82. #include <termcap.h>
  83. #include <linux/config.h>
  84. #include <sys/time.h>
  85. #include <unistd.h>
  86. #include <termios.h>
  87. #include <string.h>
  88.  
  89. /* for syslog system call */
  90. #include <linux/unistd.h>
  91. #include <errno.h>
  92. _syscall3(int, syslog, int, type, char*, buf, int, len);
  93.  
  94. /* Constants. */
  95.  
  96. /* Termcap constants. */
  97. #define TC_BUF_SIZE 1024    /* Size of termcap(3) buffer. */
  98. #define TC_ENT_SIZE 50        /* Size of termcap(3) entry buffer. */
  99.  
  100. /* General constants. */
  101. #define TRUE  1
  102. #define FALSE 0
  103.  
  104. /* Keyboard types. */
  105. #define PC     0
  106. #define OLIVETTI 1
  107. #define DUTCH    2
  108. #define EXTENDED 3
  109.  
  110. /* Colors. */
  111. #define BLACK   0
  112. #define RED     1
  113. #define GREEN   2
  114. #define YELLOW  3
  115. #define BLUE    4
  116. #define MAGENTA 5
  117. #define CYAN    6
  118. #define WHITE   7
  119. #define GREY    8
  120. #define DEFAULT 9
  121.  
  122. /* Control sequences. */
  123. #define ESC "\033"
  124. #define DCS "\033P"
  125. #define ST  "\033\\"
  126.  
  127. /* Static variables. */
  128.  
  129. char tc_buf[TC_BUF_SIZE];    /* Termcap buffer. */
  130.  
  131. /* Option flags.  Set if the option is to be invoked. */
  132. int opt_term, opt_reset, opt_initialize, opt_cursor, opt_keyboard;
  133. int opt_linewrap, opt_snow, opt_softscroll, opt_default, opt_foreground;
  134. int opt_background, opt_bold, opt_blink, opt_reverse, opt_underline;
  135. int opt_store, opt_clear, opt_blank, opt_snap, opt_snapfile, opt_standout;
  136. int opt_append, opt_ulcolor, opt_hbcolor, opt_halfbright, opt_repeat;
  137. int opt_tabs, opt_clrtabs, opt_regtabs, opt_appcursorkeys, opt_inversescreen;
  138. int opt_msg, opt_msglevel;
  139.  
  140. /* Option controls.  The variable names have been contracted to ensure
  141.  * uniqueness.
  142.  */
  143. char *opt_te_terminal_name;    /* Terminal name. */
  144. int opt_cu_on, opt_li_on, opt_sn_on, opt_so_on, opt_bo_on, opt_hb_on, opt_bl_on;
  145. int opt_re_on, opt_un_on, opt_rep_on, opt_appck_on, opt_invsc_on;
  146. int opt_msg_on;        /* Boolean switches. */
  147. int opt_ke_type;        /* Keyboard type. */
  148. int opt_fo_color, opt_ba_color;    /* Colors. */
  149. int opt_ul_color, opt_hb_color;
  150. int opt_cl_all;            /* Clear all or rest. */
  151. int opt_bl_min;            /* Blank screen. */
  152. int opt_sn_num = 0;        /* Snap screen. */
  153. int opt_st_attr;
  154. int opt_rt_len;            /* regular tab length */
  155. int opt_tb_array[161];        /* Array for tab list */
  156. int opt_msglevel_num;
  157.  
  158. char opt_sn_name[200] = "screen.dump";
  159.  
  160. /* Command line parsing routines.
  161.  *
  162.  * Note that it is an error for a given option to be invoked more than once.
  163.  */
  164.  
  165. void parse_term(argc, argv, option, opt_term, bad_arg)
  166. int argc;            /* Number of arguments for this option. */
  167. char *argv[];            /* Arguments for this option. */
  168. int *option;            /* Term flag to set. */
  169. char **opt_term;        /* Terminal name to set. */
  170. int *bad_arg;            /* Set to true if an error is detected. */
  171. {
  172. /* Parse a -term specification. */
  173.  
  174.   if (argc != 1 || *option) *bad_arg = TRUE;
  175.   *option = TRUE;
  176.   if (argc == 1) {
  177.     *opt_term = argv[0];
  178.   }
  179. }
  180.  
  181. void parse_none(argc, argv, option, bad_arg)
  182. int argc;            /* Number of arguments for this option. */
  183. char *argv[];            /* Arguments for this option. */
  184. int *option;            /* Option flag to set. */
  185. int *bad_arg;            /* Set to true if an error is detected. */
  186. {
  187. /* Parse a parameterless specification. */
  188.  
  189.   if (argc != 0 || *option) *bad_arg = TRUE;
  190.   *option = TRUE;
  191. }
  192.  
  193. void parse_switch(argc, argv, option, opt_on, bad_arg)
  194. int argc;            /* Number of arguments for this option. */
  195. char *argv[];            /* Arguments for this option. */
  196. int *option;            /* Option flag to set. */
  197. int *opt_on;            /* Boolean option switch to set or reset. */
  198. int *bad_arg;            /* Set to true if an error is detected. */
  199. {
  200. /* Parse a boolean (on/off) specification. */
  201.  
  202.   if (argc > 1 || *option) *bad_arg = TRUE;
  203.   *option = TRUE;
  204.   if (argc == 1) {
  205.     if (strcmp(argv[0], "on") == 0)
  206.         *opt_on = TRUE;
  207.     else if (strcmp(argv[0], "off") == 0)
  208.         *opt_on = FALSE;
  209.     else
  210.         *bad_arg = TRUE;
  211.   } else {
  212.     *opt_on = TRUE;
  213.   }
  214. }
  215.  
  216. #if 0
  217. void parse_keyboard(argc, argv, option, opt_keyboard, bad_arg)
  218. int argc;            /* Number of arguments for this option. */
  219. char *argv[];            /* Arguments for this option. */
  220. int *option;            /* Keyboard flag to set. */
  221. int *opt_keyboard;        /* Keyboard type to set. */
  222. int *bad_arg;            /* Set to true if an error is detected. */
  223. {
  224. /* Parse a -keyboard specification. */
  225.  
  226.   if (argc != 1 || *option) *bad_arg = TRUE;
  227.   *option = TRUE;
  228.   if (argc == 1) {
  229.     if (strcmp(argv[0], "pc") == 0)
  230.         *opt_keyboard = PC;
  231.     else if (strcmp(argv[0], "olivetti") == 0)
  232.         *opt_keyboard = OLIVETTI;
  233.     else if (strcmp(argv[0], "dutch") == 0)
  234.         *opt_keyboard = DUTCH;
  235.     else if (strcmp(argv[0], "extended") == 0)
  236.         *opt_keyboard = EXTENDED;
  237.     else
  238.         *bad_arg = TRUE;
  239.   }
  240. }
  241. #endif
  242.  
  243. void par_color(argc, argv, option, opt_color, bad_arg)
  244. int argc;            /* Number of arguments for this option. */
  245. char *argv[];            /* Arguments for this option. */
  246. int *option;            /* Color flag to set. */
  247. int *opt_color;            /* Color to set. */
  248. int *bad_arg;            /* Set to true if an error is detected. */
  249. {
  250. /* Parse a -foreground or -background specification. */
  251.  
  252.   if (argc != 1 || *option) *bad_arg = TRUE;
  253.   *option = TRUE;
  254.   if (argc == 1) {
  255.     if (strcmp(argv[0], "black") == 0)
  256.         *opt_color = BLACK;
  257.     else if (strcmp(argv[0], "red") == 0)
  258.         *opt_color = RED;
  259.     else if (strcmp(argv[0], "green") == 0)
  260.         *opt_color = GREEN;
  261.     else if (strcmp(argv[0], "yellow") == 0)
  262.         *opt_color = YELLOW;
  263.     else if (strcmp(argv[0], "blue") == 0)
  264.         *opt_color = BLUE;
  265.     else if (strcmp(argv[0], "magenta") == 0)
  266.         *opt_color = MAGENTA;
  267.     else if (strcmp(argv[0], "cyan") == 0)
  268.         *opt_color = CYAN;
  269.     else if (strcmp(argv[0], "white") == 0)
  270.         *opt_color = WHITE;
  271.     else if (strcmp(argv[0], "default") == 0)
  272.         *opt_color = DEFAULT;
  273.     else if (isdigit(argv[0][0]))
  274.         *opt_color = atoi(argv[0]);
  275.     else    
  276.         *bad_arg = TRUE;
  277.        if(*opt_color < 0 || *opt_color > 15)
  278.         *bad_arg = TRUE;
  279.   }
  280. }
  281.  
  282. void par_color2(argc, argv, option, opt_color, bad_arg)
  283. int argc;            /* Number of arguments for this option. */
  284. char *argv[];            /* Arguments for this option. */
  285. int *option;            /* Color flag to set. */
  286. int *opt_color;            /* Color to set. */
  287. int *bad_arg;            /* Set to true if an error is detected. */
  288. {
  289. /* Parse a -ulcolor or -hbcolor specification. */
  290.  
  291.   if (!argc || argc > 2 || *option) *bad_arg = TRUE;
  292.   *option = TRUE;
  293.   *opt_color = 0;
  294.   if (argc == 2) {
  295.     if (strcmp(argv[0], "bright") == 0)
  296.         *opt_color = 8;
  297.     else {
  298.         *bad_arg = TRUE;
  299.         return;
  300.     }
  301.   }
  302.   if (argc) {
  303.     if (strcmp(argv[argc-1], "black") == 0) {
  304.         if(*opt_color)
  305.             *bad_arg = TRUE;
  306.         else
  307.             *opt_color = BLACK;
  308.     } else if (strcmp(argv[argc-1], "grey") == 0) {
  309.         if(*opt_color)
  310.             *bad_arg = TRUE;
  311.         else
  312.             *opt_color = GREY;
  313.     } else if (strcmp(argv[argc-1], "red") == 0)
  314.         *opt_color |= RED;
  315.     else if (strcmp(argv[argc-1], "green") == 0)
  316.         *opt_color |= GREEN;
  317.     else if (strcmp(argv[argc-1], "yellow") == 0)
  318.         *opt_color |= YELLOW;
  319.     else if (strcmp(argv[argc-1], "blue") == 0)
  320.         *opt_color |= BLUE;
  321.     else if (strcmp(argv[argc-1], "magenta") == 0)
  322.         *opt_color |= MAGENTA;
  323.     else if (strcmp(argv[argc-1], "cyan") == 0)
  324.         *opt_color |= CYAN;
  325.     else if (strcmp(argv[argc-1], "white") == 0)
  326.         *opt_color |= WHITE;
  327.     else if (isdigit(argv[argc-1][0]))
  328.         *opt_color = atoi(argv[argc-1]);
  329.     else    
  330.         *bad_arg = TRUE;
  331.         if(*opt_color < 0 || *opt_color > 15)
  332.         *bad_arg = TRUE;
  333.   }
  334. }
  335.  
  336. void parse_clear(argc, argv, option, opt_all, bad_arg)
  337. int argc;            /* Number of arguments for this option. */
  338. char *argv[];            /* Arguments for this option. */
  339. int *option;            /* Clear flag to set. */
  340. int *opt_all;            /* Clear all switch to set or reset. */
  341. int *bad_arg;            /* Set to true if an error is detected. */
  342. {
  343. /* Parse a -clear specification. */
  344.  
  345.   if (argc > 1 || *option) *bad_arg = TRUE;
  346.   *option = TRUE;
  347.   if (argc == 1) {
  348.     if (strcmp(argv[0], "all") == 0)
  349.         *opt_all = TRUE;
  350.     else if (strcmp(argv[0], "rest") == 0)
  351.         *opt_all = FALSE;
  352.     else
  353.         *bad_arg = TRUE;
  354.   } else {
  355.     *opt_all = TRUE;
  356.   }
  357. }
  358.  
  359. void parse_blank(argc, argv, option, opt_all, bad_arg)
  360. int argc;            /* Number of arguments for this option. */
  361. char *argv[];            /* Arguments for this option. */
  362. int *option;            /* Clear flag to set. */
  363. int *opt_all;            /* Clear all switch to set or reset. */
  364. int *bad_arg;            /* Set to true if an error is detected. */
  365. {
  366. /* Parse a -clear specification. */
  367.  
  368.   if (argc > 1 || *option) *bad_arg = TRUE;
  369.   *option = TRUE;
  370.   if (argc == 1) {
  371.     *opt_all = atoi(argv[0]);
  372.     if ((*opt_all > 60) || (*opt_all < 0))
  373.         *bad_arg = TRUE;
  374.   } else {
  375.     *opt_all = 0;
  376.   }
  377. }
  378.  
  379. #if 0
  380. void parse_standout(argc, argv, option, opt_all, bad_arg)
  381. int argc;            /* Number of arguments for this option. */
  382. char *argv[];            /* Arguments for this option. */
  383. int *option;            /* Clear flag to set. */
  384. int *opt_all;            /* Clear all switch to set or reset. */
  385. int *bad_arg;            /* Set to true if an error is detected. */
  386. {
  387. /* Parse a -clear specification. */
  388.  
  389.   if (argc > 1 || *option) *bad_arg = TRUE;
  390.   *option = TRUE;
  391.   if (argc == 1) {
  392.     *opt_all = atoi(argv[0]);
  393.   } else {
  394.     *opt_all = -1;
  395.   }
  396. }
  397. #endif
  398.  
  399. void parse_msglevel(argc, argv, option, opt_all, bad_arg)
  400. int argc;            /* Number of arguments for this option. */
  401. char *argv[];            /* Arguments for this option. */
  402. int *option;            /* Clear flag to set. */
  403. int *opt_all;            /* Clear all switch to set or reset. */
  404. int *bad_arg;            /* Set to true if an error is detected. */
  405. {
  406.  
  407.   if (argc > 1 || *option) *bad_arg = TRUE;
  408.   *option = TRUE;
  409.   if (argc == 1) {
  410.     *opt_all = atoi(argv[0]);
  411.       if (*opt_all < 0 || *opt_all > 8)
  412.         *bad_arg = TRUE;
  413.   } else {
  414.     *opt_all = -1;
  415.   }
  416. }
  417.  
  418. void parse_snap(argc, argv, option, opt_all, bad_arg)
  419. int argc;            /* Number of arguments for this option. */
  420. char *argv[];            /* Arguments for this option. */
  421. int *option;            /* Clear flag to set. */
  422. int *opt_all;            /* Clear all switch to set or reset. */
  423. int *bad_arg;            /* Set to true if an error is detected. */
  424. {
  425. /* Parse a -clear specification. */
  426.  
  427.   if (argc > 1 || *option) *bad_arg = TRUE;
  428.   *option = TRUE;
  429.   if (argc == 1) {
  430.     *opt_all = atoi(argv[0]);
  431.     if ((*opt_all <= 0))
  432.         *bad_arg = TRUE;
  433.   } else {
  434.     *opt_all = 0;
  435.   }
  436. }
  437.  
  438. void parse_snapfile(argc, argv, option, opt_all, bad_arg)
  439. int argc;            /* Number of arguments for this option. */
  440. char *argv[];            /* Arguments for this option. */
  441. int *option;            /* Clear flag to set. */
  442. int *opt_all;            /* Clear all switch to set or reset. */
  443. int *bad_arg;            /* Set to true if an error is detected. */
  444. {
  445. /* Parse a -clear specification. */
  446.  
  447.   if (argc != 1 || *option) *bad_arg = TRUE;
  448.   *option = TRUE;
  449.   if (argc == 1) {
  450.       strcpy((char *)opt_all, argv[0]);
  451.   }
  452. }
  453.  
  454. void parse_tabs(argc, argv, option, tab_array, bad_arg)
  455. int argc;            /* Number of arguments for this option. */
  456. char *argv[];            /* Arguments for this option. */
  457. int *option;            /* Clear flag to set. */
  458. int *tab_array;            /* Array of tabs */
  459. int *bad_arg;            /* Set to true if an error is detected. */
  460. {
  461.   if (*option || argc > 160) *bad_arg = TRUE;
  462.   *option = TRUE;
  463.   tab_array[argc] = -1;
  464.   while(argc--) {
  465.     tab_array[argc] = atoi(argv[argc]);
  466.     if(tab_array[argc] < 1 || tab_array[argc] > 160) {
  467.       *bad_arg = TRUE;
  468.       return;
  469.     }
  470.   }
  471. }
  472.  
  473. void parse_clrtabs(argc, argv, option, tab_array, bad_arg)
  474. int argc;            /* Number of arguments for this option. */
  475. char *argv[];            /* Arguments for this option. */
  476. int *option;            /* Clear flag to set. */
  477. int *tab_array;            /* Array of tabs */
  478. int *bad_arg;            /* Set to true if an error is detected. */
  479. {
  480.   if (*option || argc > 160) *bad_arg = TRUE;
  481.   *option = TRUE;
  482.   if(argc == 0) {
  483.     tab_array[0] = -1;
  484.     return;
  485.   }
  486.   tab_array[argc] = -1;
  487.   while(argc--) {
  488.     tab_array[argc] = atoi(argv[argc]);
  489.     if(tab_array[argc] < 1 || tab_array[argc] > 160) {
  490.       *bad_arg = TRUE;
  491.       return;
  492.     }
  493.   }
  494. }
  495.  
  496. void parse_regtabs(argc, argv, option, opt_len, bad_arg)
  497. int argc;            /* Number of arguments for this option. */
  498. char *argv[];            /* Arguments for this option. */
  499. int *option;            /* Clear flag to set. */
  500. int *opt_len;            /* Regular tab length. */
  501. int *bad_arg;            /* Set to true if an error is detected. */
  502. {
  503.   if (*option || argc > 1) *bad_arg = TRUE;
  504.   *option = TRUE;
  505.   if(argc == 0) {
  506.     *opt_len = 8;
  507.     return;
  508.   }
  509.   *opt_len = atoi(argv[0]);
  510.   if(*opt_len < 1 || *opt_len > 160) {
  511.     *bad_arg = TRUE;
  512.     return;
  513.   }
  514. }
  515.  
  516. void show_tabs()
  517. {
  518.   int i, co = tgetnum("co");
  519.  
  520.   if(co > 0) {
  521.     printf("\r         ");
  522.     for(i = 10; i < co-2; i+=10)
  523.       printf("%-10d", i);
  524.     putchar('\n');
  525.     for(i = 1; i <= co; i++)
  526.       putchar(i%10+'0');
  527.     putchar('\n');
  528.     for(i = 1; i < co; i++)
  529.       printf("\tT\b");
  530.     putchar('\n');
  531.   }
  532. }
  533.  
  534.  
  535. #define STRCMP(str1,str2) strncmp(str1,str2,strlen(str1))
  536.  
  537. void parse_option(option, argc, argv, bad_arg)
  538. char *option;            /* Option with leading '-' removed. */
  539. int argc;            /* Number of arguments for this option. */
  540. char *argv[];            /* Arguments for this option. */
  541. int *bad_arg;            /* Set to true if an error is detected. */
  542. {
  543. /* Parse a single specification. */
  544.  
  545.   if (STRCMP(option, "term") == 0)
  546.     parse_term(argc, argv, &opt_term, &opt_te_terminal_name, bad_arg);
  547.   else if (STRCMP(option, "reset") == 0)
  548.     parse_none(argc, argv, &opt_reset, bad_arg);
  549.   else if (STRCMP(option, "initialize") == 0)
  550.     parse_none(argc, argv, &opt_initialize, bad_arg);
  551.   else if (STRCMP(option, "cursor") == 0)
  552.     parse_switch(argc, argv, &opt_cursor, &opt_cu_on, bad_arg);
  553. #if 0
  554.   else if (STRCMP(option, "keyboard") == 0)
  555.     parse_keyboard(argc, argv, &opt_keyboard, &opt_ke_type, bad_arg);
  556. #endif
  557.   else if (STRCMP(option, "repeat") == 0)
  558.     parse_switch(argc, argv, &opt_repeat, &opt_rep_on, bad_arg);
  559.   else if (STRCMP(option, "appcursorkeys") == 0)
  560.     parse_switch(argc, argv, &opt_appcursorkeys, &opt_appck_on, bad_arg);
  561.   else if (STRCMP(option, "linewrap") == 0)
  562.     parse_switch(argc, argv, &opt_linewrap, &opt_li_on, bad_arg);
  563. #if 0
  564.   else if (STRCMP(option, "snow") == 0)
  565.     parse_switch(argc, argv, &opt_snow, &opt_sn_on, bad_arg);
  566.   else if (STRCMP(option, "softscroll") == 0)
  567.     parse_switch(argc, argv, &opt_softscroll, &opt_so_on, bad_arg);
  568. #endif
  569.   else if (STRCMP(option, "default") == 0)
  570.     parse_none(argc, argv, &opt_default, bad_arg);
  571.   else if (STRCMP(option, "foreground") == 0)
  572.     par_color(argc, argv, &opt_foreground, &opt_fo_color, bad_arg);
  573.   else if (STRCMP(option, "background") == 0)
  574.     par_color(argc, argv, &opt_background, &opt_ba_color, bad_arg);
  575.   else if (STRCMP(option, "ulcolor") == 0)
  576.     par_color2(argc, argv, &opt_ulcolor, &opt_ul_color, bad_arg);
  577.   else if (STRCMP(option, "hbcolor") == 0)
  578.     par_color2(argc, argv, &opt_hbcolor, &opt_hb_color, bad_arg);
  579.   else if (STRCMP(option, "inversescreen") == 0)
  580.     parse_switch(argc, argv, &opt_inversescreen, &opt_invsc_on, bad_arg);
  581.   else if (STRCMP(option, "bold") == 0)
  582.     parse_switch(argc, argv, &opt_bold, &opt_bo_on, bad_arg);
  583.   else if (STRCMP(option, "half-bright") == 0)
  584.     parse_switch(argc, argv, &opt_halfbright, &opt_hb_on, bad_arg);
  585.   else if (STRCMP(option, "blink") == 0)
  586.     parse_switch(argc, argv, &opt_blink, &opt_bl_on, bad_arg);
  587.   else if (STRCMP(option, "reverse") == 0)
  588.     parse_switch(argc, argv, &opt_reverse, &opt_re_on, bad_arg);
  589.   else if (STRCMP(option, "underline") == 0)
  590.     parse_switch(argc, argv, &opt_underline, &opt_un_on, bad_arg);
  591.   else if (STRCMP(option, "store") == 0)
  592.     parse_none(argc, argv, &opt_store, bad_arg);
  593.   else if (STRCMP(option, "clear") == 0)
  594.     parse_clear(argc, argv, &opt_clear, &opt_cl_all, bad_arg);
  595.   else if (STRCMP(option, "tabs") == 0)
  596.     parse_tabs(argc, argv, &opt_tabs, opt_tb_array, bad_arg);
  597.   else if (STRCMP(option, "clrtabs") == 0)
  598.     parse_clrtabs(argc, argv, &opt_clrtabs, opt_tb_array, bad_arg);
  599.   else if (STRCMP(option, "regtabs") == 0)
  600.     parse_regtabs(argc, argv, &opt_regtabs, &opt_rt_len, bad_arg);
  601.   else if (STRCMP(option, "blank") == 0)
  602.     parse_blank(argc, argv, &opt_blank, &opt_bl_min, bad_arg);
  603.   else if (STRCMP(option, "dump") == 0)
  604.     parse_snap(argc, argv, &opt_snap, &opt_sn_num, bad_arg);
  605.   else if (STRCMP(option, "append") == 0)
  606.     parse_snap(argc, argv, &opt_append, &opt_sn_num, bad_arg);
  607.   else if (STRCMP(option, "file") == 0)
  608.     parse_snapfile(argc, argv, &opt_snapfile, (int *)opt_sn_name, bad_arg);
  609.   else if (STRCMP(option, "msg") == 0)
  610.     parse_switch(argc, argv, &opt_msg, &opt_msg_on, bad_arg);
  611.   else if (STRCMP(option, "msglevel") == 0)
  612.     parse_msglevel(argc, argv, &opt_msglevel, &opt_msglevel_num, bad_arg);
  613. #if 0
  614.   else if (STRCMP(option, "standout") == 0)
  615.     parse_standout(argc, argv, &opt_standout, &opt_st_attr, bad_arg);
  616. #endif
  617.   else
  618.     *bad_arg = TRUE;
  619. }
  620.  
  621. /* End of command line parsing routines. */
  622.  
  623. void usage(prog_name)
  624. char *prog_name;        /* Name of this program. */
  625. {
  626. /* Print error message about arguments, and the command's syntax. */
  627.  
  628.   fprintf(stderr, "%s: Argument error, usage\n", prog_name);
  629.   fprintf(stderr, "\n");
  630.   fprintf(stderr, "%s\n", prog_name);
  631.   fprintf(stderr, "  [ -term terminal_name ]\n");
  632.   fprintf(stderr, "  [ -reset ]\n");
  633.   fprintf(stderr, "  [ -initialize ]\n");
  634.   fprintf(stderr, "  [ -cursor [on|off] ]\n");
  635. #if 0
  636.   fprintf(stderr, "  [ -snow [on|off] ]\n");
  637.   fprintf(stderr, "  [ -softscroll [on|off] ]\n");
  638.   fprintf(stderr, "  [ -keyboard pc|olivetti|dutch|extended ]\n");
  639. #endif
  640.   fprintf(stderr, "  [ -repeat [on|off] ]\n");
  641.   fprintf(stderr, "  [ -appcursorkeys [on|off] ]\n");
  642.   fprintf(stderr, "  [ -linewrap [on|off] ]\n");
  643.   fprintf(stderr, "  [ -default ]\n");
  644.   fprintf(stderr, "  [ -foreground black|blue|green|cyan");
  645.   fprintf(stderr, "|red|magenta|yellow|white|default ]\n");
  646.   fprintf(stderr, "  [ -background black|blue|green|cyan");
  647.   fprintf(stderr, "|red|magenta|yellow|white|default ]\n");
  648.   fprintf(stderr, "  [ -ulcolor black|grey|blue|green|cyan");
  649.   fprintf(stderr, "|red|magenta|yellow|white ]\n");
  650.   fprintf(stderr, "  [ -ulcolor bright blue|green|cyan");
  651.   fprintf(stderr, "|red|magenta|yellow|white ]\n");
  652.   fprintf(stderr, "  [ -hbcolor black|grey|blue|green|cyan");
  653.   fprintf(stderr, "|red|magenta|yellow|white ]\n");
  654.   fprintf(stderr, "  [ -hbcolor bright blue|green|cyan");
  655.   fprintf(stderr, "|red|magenta|yellow|white ]\n");
  656. #if 0
  657.   fprintf(stderr, "  [ -standout [ attr ] ]\n");
  658. #endif
  659.   fprintf(stderr, "  [ -inversescreen [on|off] ]\n");
  660.   fprintf(stderr, "  [ -bold [on|off] ]\n");
  661.   fprintf(stderr, "  [ -half-bright [on|off] ]\n");
  662.   fprintf(stderr, "  [ -blink [on|off] ]\n");
  663.   fprintf(stderr, "  [ -reverse [on|off] ]\n");
  664.   fprintf(stderr, "  [ -underline [on|off] ]\n");
  665.   fprintf(stderr, "  [ -store ]\n");
  666.   fprintf(stderr, "  [ -clear [all|rest] ]\n");
  667.   fprintf(stderr, "  [ -tabs [ tab1 tab2 tab3 ... ] ]      (tabn = 1-160)\n");
  668.   fprintf(stderr, "  [ -clrtabs [ tab1 tab2 tab3 ... ] ]   (tabn = 1-160)\n");
  669.   fprintf(stderr, "  [ -regtabs [1-160] ]\n");
  670.   fprintf(stderr, "  [ -blank [0-60] ]\n");
  671.   fprintf(stderr, "  [ -dump   [1-NR_CONSOLES] ]\n");
  672.   fprintf(stderr, "  [ -append [1-NR_CONSOLES] ]\n");
  673.   fprintf(stderr, "  [ -file dumpfilename ]\n");
  674.   fprintf(stderr, "  [ -msg [on|off] ]\n");
  675.   fprintf(stderr, "  [ -msglevel [0-8] ]\n");
  676. }
  677.  
  678. char tc_ent_buf[TC_ENT_SIZE];    /* Buffer for storing a termcap entry. */
  679.  
  680. #define NUM_COLS 160 
  681. #define NUM_ROWS 75
  682.  
  683. char screenbuf[NUM_ROWS*NUM_COLS]; 
  684.  
  685. char *tc_entry(name)
  686. char *name;            /* Termcap capability string to lookup. */
  687. {
  688. /* Return the specified termcap string, or an empty string if no such termcap
  689.  * capability exists.
  690.  */
  691.  
  692.   char *buf_ptr;
  693.  
  694.   buf_ptr = tc_ent_buf;
  695.   if (tgetstr(name, &buf_ptr) == NULL) tc_ent_buf[0] = '\0';
  696.   return tc_ent_buf;
  697. }
  698.  
  699. void perform_sequence(vcterm)
  700. int vcterm;            /* Set if terminal is a virtual console. */
  701. {
  702.   int result;
  703. /* Perform the selected options. */
  704.  
  705.   /* -reset. */
  706.   if (opt_reset) {
  707.     printf("%s", tc_entry("rs"));
  708.   }
  709.  
  710.   /* -initialize. */
  711.   if (opt_initialize) {
  712.     printf("%s", tc_entry("is"));
  713.   }
  714.  
  715.   /* -cursor [on|off]. */
  716.   if (opt_cursor) {
  717.     if (opt_cu_on)
  718.         printf("%s", tc_entry("ve"));
  719.     else
  720.         printf("%s", tc_entry("vi"));
  721.   }
  722.  
  723. #if 0
  724.   /* -keyboard pc|olivetti|dutch|extended.  Vc only. */
  725.   if (opt_keyboard && vcterm) {
  726.     switch (opt_ke_type) {
  727.         case PC:
  728.         printf("%s%s%s", DCS, "keyboard.pc", ST);
  729.         break;
  730.         case OLIVETTI:
  731.         printf("%s%s%s", DCS, "keyboard.olivetti", ST);
  732.         break;
  733.         case DUTCH:
  734.         printf("%s%s%s", DCS, "keyboard.dutch", ST);
  735.         break;
  736.         case EXTENDED:
  737.         printf("%s%s%s", DCS, "keyboard.extended", ST);
  738.         break;
  739.     }
  740.   }
  741. #endif
  742.  
  743.   /* -linewrap [on|off]. Vc only (vt102) */
  744.   if (opt_linewrap && vcterm) {
  745.     if (opt_li_on)
  746.         printf("\033[?7h");
  747.     else
  748.         printf("\033[?7l");
  749.   }
  750.  
  751.   /* -repeat [on|off]. Vc only (vt102) */
  752.   if (opt_repeat && vcterm) {
  753.     if (opt_rep_on)
  754.         printf("\033[?8h");
  755.     else
  756.         printf("\033[?8l");
  757.   }
  758.  
  759.   /* -appcursorkeys [on|off]. Vc only (vt102) */
  760.   if (opt_appcursorkeys && vcterm) {
  761.     if (opt_appck_on)
  762.         printf("\033[?1h");
  763.     else
  764.         printf("\033[?1l");
  765.   }
  766.  
  767. #if 0
  768.   /* -snow [on|off].  Vc only. */
  769.   if (opt_snow && vcterm) {
  770.     if (opt_sn_on)
  771.         printf("%s%s%s", DCS, "snow.on", ST);
  772.     else
  773.         printf("%s%s%s", DCS, "snow.off", ST);
  774.   }
  775.  
  776.   /* -softscroll [on|off].  Vc only. */
  777.   if (opt_softscroll && vcterm) {
  778.     if (opt_so_on)
  779.         printf("%s%s%s", DCS, "softscroll.on", ST);
  780.     else
  781.         printf("%s%s%s", DCS, "softscroll.off", ST);
  782.   }
  783. #endif
  784.  
  785.   /* -default.  Vc sets default rendition, otherwise clears all
  786.    * attributes.
  787.    */
  788.   if (opt_default) {
  789.     if (vcterm)
  790.         printf("\033[0m");
  791.     else
  792.         printf("%s", tc_entry("me"));
  793.   }
  794.  
  795.   /* -foreground black|red|green|yellow|blue|magenta|cyan|white|default.
  796.    * Vc only (ANSI).
  797.    */
  798.   if (opt_foreground && vcterm) {
  799.     printf("%s%s%c%s", ESC, "[3", '0' + opt_fo_color, "m");
  800.   }
  801.  
  802.   /* -background black|red|green|yellow|blue|magenta|cyan|white|default.
  803.    * Vc only (ANSI).
  804.    */
  805.   if (opt_background && vcterm) {
  806.     printf("%s%s%c%s", ESC, "[4", '0' + opt_ba_color, "m");
  807.   }
  808.  
  809.   /* -ulcolor black|red|green|yellow|blue|magenta|cyan|white|default.
  810.    * Vc only.
  811.    */
  812.   if (opt_ulcolor && vcterm) {
  813.     printf("\033[1;%d]", opt_ul_color);
  814.   }
  815.  
  816.   /* -hbcolor black|red|green|yellow|blue|magenta|cyan|white|default.
  817.    * Vc only.
  818.    */
  819.   if (opt_hbcolor && vcterm) {
  820.     printf("\033[2;%d]", opt_hb_color);
  821.   }
  822.  
  823.   /* -inversescreen [on|off].  Vc only (vt102).
  824.    */
  825.   if (opt_inversescreen) {
  826.     if (vcterm)
  827.         if (opt_invsc_on)
  828.             printf("\033[?5h");
  829.         else
  830.             printf("\033[?5l");
  831.   }
  832.  
  833.   /* -bold [on|off].  Vc behaves as expected, otherwise off turns off
  834.    * all attributes.
  835.    */
  836.   if (opt_bold) {
  837.     if (opt_bo_on)
  838.         printf("%s", tc_entry("md"));
  839.     else {
  840.         if (vcterm)
  841.             printf("%s%s", ESC, "[22m");
  842.         else
  843.             printf("%s", tc_entry("me"));
  844.     }
  845.   }
  846.  
  847.   /* -half-bright [on|off].  Vc behaves as expected, otherwise off turns off
  848.    * all attributes.
  849.    */
  850.   if (opt_halfbright) {
  851.     if (opt_hb_on)
  852.         printf("%s", tc_entry("mh"));
  853.     else {
  854.         if (vcterm)
  855.             printf("%s%s", ESC, "[22m");
  856.         else
  857.             printf("%s", tc_entry("me"));
  858.     }
  859.   }
  860.  
  861.   /* -blink [on|off].  Vc behaves as expected, otherwise off turns off
  862.    * all attributes.
  863.    */
  864.   if (opt_blink) {
  865.     if (opt_bl_on)
  866.         printf("%s", tc_entry("mb"));
  867.     else {
  868.         if (vcterm)
  869.             printf("%s%s", ESC, "[25m");
  870.         else
  871.             printf("%s", tc_entry("me"));
  872.     }
  873.   }
  874.  
  875.   /* -reverse [on|off].  Vc behaves as expected, otherwise off turns
  876.    * off all attributes.
  877.    */
  878.   if (opt_reverse) {
  879.     if (opt_re_on)
  880.         printf("%s", tc_entry("mr"));
  881.     else {
  882.         if (vcterm)
  883.             printf("%s%s", ESC, "[27m");
  884.         else
  885.             printf("%s", tc_entry("me"));
  886.     }
  887.   }
  888.  
  889.   /* -underline [on|off]. */
  890.   if (opt_underline) {
  891.     if (opt_un_on)
  892.         printf("%s", tc_entry("us"));
  893.     else
  894.         printf("%s", tc_entry("ue"));
  895.   }
  896.  
  897.   /* -store.  Vc only. */
  898.   if (opt_store && vcterm) {
  899.     printf("\033[8]");
  900.   }
  901.  
  902.   /* -clear [all|rest]. */
  903.   if (opt_clear) {
  904.     if (opt_cl_all)
  905.         printf("%s", tc_entry("cl"));
  906.     else
  907.         printf("%s", tc_entry("cd"));
  908.   }
  909.  
  910.   /* -tabs Vc only. */
  911.   if (opt_tabs && vcterm) {
  912.     int i;
  913.  
  914.     if (opt_tb_array[0] == -1)
  915.       show_tabs();
  916.     else {
  917.       for(i=0; opt_tb_array[i] > 0; i++)
  918.         printf("\033[%dG\033H", opt_tb_array[i]);
  919.       putchar('\r');
  920.     }
  921.   }
  922.  
  923.   /* -clrtabs Vc only. */
  924.   if (opt_clrtabs && vcterm) {
  925.     int i;
  926.  
  927.     if (opt_tb_array[0] == -1)
  928.       printf("\033[3g");
  929.     else
  930.       for(i=0; opt_tb_array[i]; i++)
  931.         printf("\033[%dG\033[g", opt_tb_array[i]);
  932.     putchar('\r');
  933.   }
  934.  
  935.   /* -regtabs Vc only. */
  936.   if (opt_regtabs && vcterm) {
  937.     int i;
  938.  
  939.     printf("\033[3g\r");
  940.     for(i=opt_rt_len+1; i<=160; i+=opt_rt_len)
  941.       printf("\033[%dC\033H",opt_rt_len);
  942.     putchar('\r');
  943.   }
  944.  
  945.   /* -blank [0-60]. */
  946.   if (opt_blank) 
  947.     printf("\033[9;%d]", opt_bl_min);
  948.     
  949. #if 0
  950.   /* -standout [num]. */
  951.   if (opt_standout)
  952.     /* nothing */;
  953. #endif
  954.  
  955.   /* -snap [1-NR_CONS]. */
  956.   if (opt_snap || opt_append) 
  957.   { FILE *F;
  958.     char buf[NUM_COLS+1];
  959.     int i, j;
  960.     if (opt_snap)
  961.       F = fopen(opt_sn_name,"w");
  962.     else  
  963.       F = fopen(opt_sn_name,"a");
  964.     if (!F)
  965.     { fprintf(stderr,"can not open dump file %s for output\n",opt_sn_name); 
  966.       exit(-1);
  967.     }
  968.     screenbuf[0] = 0;
  969.     screenbuf[1] = (unsigned char)opt_sn_num;
  970.     if (ioctl(0,TIOCLINUX,screenbuf)>=0)
  971.     { int rows, cols;
  972.       rows = (int)screenbuf[0];
  973.       cols = (int)screenbuf[1];
  974.       for (i=0; i<rows; i++)
  975.       { strncpy(buf, screenbuf+2+(cols*i),cols);
  976.         buf[cols] = '\0';
  977.         j = cols;
  978.         while (--j && (buf[j] == ' '))
  979.           buf[j] = '\0';
  980.         fputs(buf,F);
  981.         fputc('\n',F); 
  982.       }  
  983.     }
  984.     else
  985.       fprintf(stderr,"can not ioctl dump\n");
  986.   }
  987.  
  988.   /* -msg [on|off]. */
  989.   if (opt_msg && vcterm) {
  990.        if (opt_msg_on)
  991.                /* 7 -- Enable printk's to console */
  992.                result = syslog(7, NULL, 0);
  993.        else
  994.                /*  6 -- Disable printk's to console */
  995.                result = syslog(6, NULL, 0);
  996.  
  997.        if (result != 0)
  998.                printf("syslog error: %s\n", strerror(result));
  999.   }
  1000.  
  1001.   /* -msglevel [0-8] */
  1002.   if (opt_msglevel && vcterm) {
  1003.        /* 8 -- Set level of messages printed to console */
  1004.        result = syslog(8, NULL, opt_msglevel_num);
  1005.        if (result != 0)
  1006.                printf("syslog error: %s\n", strerror(result));
  1007.    }
  1008. }
  1009.  
  1010. void main(int argc, char **argv)
  1011. {
  1012.   int bad_arg = FALSE;        /* Set if error in arguments. */
  1013.   int arg, modifier;
  1014.   char *term;            /* Terminal type. */
  1015.   int vcterm;            /* Set if terminal is a virtual console. */
  1016.  
  1017.   if (argc < 2) bad_arg = TRUE;
  1018.  
  1019.   /* Parse arguments. */
  1020.  
  1021.   for (arg = 1; arg < argc;) {
  1022.     if (*argv[arg] == '-') {
  1023.  
  1024.         /* Parse a single option. */
  1025.  
  1026.         for (modifier = arg + 1; modifier < argc; modifier++) {
  1027.             if (*argv[modifier] == '-') break;
  1028.         }
  1029.         parse_option(argv[arg] + 1, modifier - arg - 1,
  1030.                  &argv[arg + 1], &bad_arg);
  1031.         arg = modifier;
  1032.     } else {
  1033.  
  1034.         bad_arg = TRUE;
  1035.         arg++;
  1036.     }
  1037.   }
  1038.  
  1039.   /* Display syntax message if error in arguments. */
  1040.  
  1041.   if (bad_arg) {
  1042.     usage(argv[0]);
  1043.     exit(1);
  1044.   }
  1045.  
  1046.   /* Find out terminal name. */
  1047.  
  1048.   if (opt_term) {
  1049.     term = opt_te_terminal_name;
  1050.   } else {
  1051.     term = getenv("TERM");
  1052.     if (term == NULL) {
  1053.         fprintf(stderr, "%s: $TERM is not defined.\n", argv[0]);
  1054.         exit(1);
  1055.     }
  1056.   }
  1057.  
  1058.   /* Find termcap entry. */
  1059.  
  1060.   if (tgetent(tc_buf, term) != 1) {
  1061.     fprintf(stderr, "%s: Could not find termcap entry for %s.\n",
  1062.         argv[0], term);
  1063.     exit(1);
  1064.   }
  1065.  
  1066.   /* See if the terminal is a virtual console terminal. */
  1067.  
  1068.   vcterm = !strncmp(term, "con", 3);
  1069.  
  1070.   /* Perform the selected options. */
  1071.  
  1072.   perform_sequence(vcterm);
  1073.  
  1074.   exit(0);
  1075. }
  1076.