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