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