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