summaryrefslogtreecommitdiffstats
path: root/term-utils/setterm.c
diff options
context:
space:
mode:
authorKarel Zak2014-05-20 11:44:26 +0200
committerKarel Zak2014-05-20 11:44:26 +0200
commit10bd07cad86923b89fc2d2a61fe34c35cb258772 (patch)
treed372dae12be68c725acf6d5fca5bcb041094d536 /term-utils/setterm.c
parentfsck.cramfs: cleanup usage() and warning messages (diff)
parentsetterm: remove ulcolor and hbcolor duplicates (diff)
downloadkernel-qcow2-util-linux-10bd07cad86923b89fc2d2a61fe34c35cb258772.tar.gz
kernel-qcow2-util-linux-10bd07cad86923b89fc2d2a61fe34c35cb258772.tar.xz
kernel-qcow2-util-linux-10bd07cad86923b89fc2d2a61fe34c35cb258772.zip
Merge branch '2014wk19' of git://github.com/kerolasa/lelux-utiliteetit
* '2014wk19' of git://github.com/kerolasa/lelux-utiliteetit: setterm: remove ulcolor and hbcolor duplicates setterm: add set_blanking() action setterm: mark some options to be exclusive with each other setterm: various visual terminal effects are not console specific setterm: improve error messages setterm: tell user when options does not effect setterm: improve perform_sequence() coding style setterm: correct usage() bright color argument setterm: make -msglevel 0 to work as is did earlier setterm: remove devfs and /dev/vcsa0 support setterm: clean up screendump() setterm: add init_terminal() to make main() shorter setterm: add option control structure setterm: remove usage comment segment setterm: move show_tabs() and screendump() functions setterm: use string utils to numeric parsing setterm: recommend long options with double hyphen setterm: use getopt_long_only() for option parsing setterm: clean up includes
Diffstat (limited to 'term-utils/setterm.c')
-rw-r--r--term-utils/setterm.c1665
1 files changed, 759 insertions, 906 deletions
diff --git a/term-utils/setterm.c b/term-utils/setterm.c
index 7a3131f5f..edaf6b85d 100644
--- a/term-utils/setterm.c
+++ b/term-utils/setterm.c
@@ -19,52 +19,6 @@
* 1999-02-22 Arkadiusz Miƛkiewicz <misiek@pld.ORG.PL>
* - added Native Language Support
*
- *
- * Syntax:
- *
- * setterm
- * [ -term terminal_name ]
- * [ -reset ]
- * [ -initialize ]
- * [ -cursor [on|off] ]
- * [ -repeat [on|off] ]
- * [ -appcursorkeys [on|off] ]
- * [ -linewrap [on|off] ]
- * [ -snow [on|off] ]
- * [ -softscroll [on|off] ]
- * [ -defaults ]
- * [ -foreground black|red|green|yellow|blue|magenta|cyan|white|default ]
- * [ -background black|red|green|yellow|blue|magenta|cyan|white|default ]
- * [ -ulcolor black|grey|red|green|yellow|blue|magenta|cyan|white ]
- * [ -ulcolor bright red|green|yellow|blue|magenta|cyan|white ]
- * [ -hbcolor black|grey|red|green|yellow|blue|magenta|cyan|white ]
- * [ -hbcolor bright red|green|yellow|blue|magenta|cyan|white ]
- * [ -inversescreen [on|off] ]
- * [ -bold [on|off] ]
- * [ -half-bright [on|off] ]
- * [ -blink [on|off] ]
- * [ -reverse [on|off] ]
- * [ -underline [on|off] ]
- * [ -store ]
- * [ -clear [ all|rest ] ]
- * [ -tabs [tab1 tab2 tab3 ... ] ] (tabn = 1-160)
- * [ -clrtabs [ tab1 tab2 tab3 ... ] (tabn = 1-160)
- * [ -regtabs [1-160] ]
- * [ -blank [0-60|force|poke|] ]
- * [ -dump [1-NR_CONS ] ]
- * [ -append [1-NR_CONS ] ]
- * [ -file dumpfilename ]
- * [ -standout [attr] ]
- * [ -msg [on|off] ]
- * [ -msglevel [0-8] ]
- * [ -powersave [on|vsync|hsync|powerdown|off] ]
- * [ -powerdown [0-60] ]
- * [ -blength [0-2000] ]
- * [ -bfreq freq ]
- * [ -version ]
- * [ -help ]
- *
- *
* Semantics:
*
* Setterm writes to standard output a character string that will
@@ -92,48 +46,41 @@
* -store stores the terminal's current rendering options as the default
* values. */
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
-#include <errno.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <termios.h>
#include <string.h>
-#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/klog.h>
+#include <sys/param.h> /* for MAXPATHLEN */
+#include <sys/time.h>
+#include <termios.h>
+#include <unistd.h>
#ifndef NCURSES_CONST
-#define NCURSES_CONST const /* define before including term.h */
+# define NCURSES_CONST const /* define before including term.h */
#endif
#ifdef HAVE_NCURSES_H
-#include <ncurses.h>
+# include <ncurses.h>
#elif defined(HAVE_NCURSES_NCURSES_H)
-#include <ncurses/ncurses.h>
+# include <ncurses/ncurses.h>
#endif
/* must include after ncurses.h */
#include <term.h>
-#include <sys/param.h> /* for MAXPATHLEN */
-#include <sys/ioctl.h>
-#include <sys/time.h>
#ifdef HAVE_LINUX_TIOCL_H
-#include <linux/tiocl.h>
+# include <linux/tiocl.h>
#endif
#include "c.h"
-#include "xalloc.h"
-#include "nls.h"
#include "closestream.h"
-
-#if defined(__GNU_LIBRARY__) && __GNU_LIBRARY__ < 5
-#ifndef __alpha__
-# include <linux/unistd.h>
-#define __NR_klogctl __NR_syslog
-_syscall3(int, klogctl, int, type, char*, buf, int, len);
-#else /* __alpha__ */
-#define klogctl syslog
-#endif
-#endif
-extern int klogctl(int type, char *buf, int len);
+#include "nls.h"
+#include "optutils.h"
+#include "strutils.h"
+#include "xalloc.h"
/* Constants. */
@@ -188,7 +135,7 @@ enum {
/* Console log levels */
enum {
- CONSOLE_LEVEL_MIN = 1,
+ CONSOLE_LEVEL_MIN = 0,
CONSOLE_LEVEL_MAX = 8
};
@@ -198,730 +145,771 @@ enum {
#define TABS_MAX 160
#define BLENGTH_MAX 2000
-/* Option flags. Set if the option is to be invoked. */
-int opt_term, opt_reset, opt_initialize, opt_cursor;
-int opt_linewrap, opt_default, opt_foreground;
-int opt_background, opt_bold, opt_blink, opt_reverse, opt_underline;
-int opt_store, opt_clear, opt_blank, opt_snap, opt_snapfile;
-int opt_append, opt_ulcolor, opt_hbcolor, opt_halfbright, opt_repeat;
-int opt_tabs, opt_clrtabs, opt_regtabs, opt_appcursorkeys, opt_inversescreen;
-int opt_msg, opt_msglevel, opt_powersave, opt_powerdown;
-int opt_blength, opt_bfreq;
-
-/* Option controls. The variable names have been contracted to ensure
- * uniqueness.
- */
-char *opt_te_terminal_name; /* Terminal name. */
-int opt_cu_on, opt_li_on, opt_bo_on, opt_hb_on, opt_bl_on;
-int opt_re_on, opt_un_on, opt_rep_on, opt_appck_on, opt_invsc_on;
-int opt_msg_on; /* Boolean switches. */
-int opt_fo_color, opt_ba_color; /* Colors. */
-int opt_ul_color, opt_hb_color;
-int opt_cl_all; /* Clear all or rest. */
-int opt_bl_min; /* Blank screen. */
-int opt_blength_l;
-int opt_bfreq_f;
-int opt_sn_num; /* Snap screen. */
-int opt_rt_len; /* regular tab length */
-int opt_tb_array[TABS_MAX + 1]; /* Array for tab list */
-int opt_msglevel_num;
-int opt_ps_mode, opt_pd_min; /* powersave mode/powerdown time */
-
-char opt_sn_name[PATH_MAX + 1] = "screen.dump";
-
-static void screendump(int vcnum, FILE *F);
+/* Command controls. */
+struct setterm_control {
+ char *opt_te_terminal_name; /* terminal name */
+ int opt_bl_min; /* blank screen */
+ int opt_blength_l; /* bell duration in milliseconds */
+ int opt_bfreq_f; /* bell frequency in Hz */
+ int opt_sn_num; /* console number to be snapshoted */
+ char *opt_sn_name; /* path to write snap */
+ char *in_device; /* device to snapshot */
+ int opt_msglevel_num; /* printk() loging level */
+ int opt_ps_mode; /* powersave mode */
+ int opt_pd_min; /* powerdown time */
+ int opt_rt_len; /* regular tab length */
+ int opt_tb_array[TABS_MAX + 1]; /* array for tab list */
+ /* colors */
+ int opt_fo_color:4, opt_ba_color:4, opt_ul_color:4, opt_hb_color:4;
+ /* boolean options */
+ int opt_cu_on:1, opt_li_on:1, opt_bo_on:1, opt_hb_on:1, opt_bl_on:1,
+ opt_re_on:1, opt_un_on:1, opt_rep_on:1, opt_appck_on:1,
+ opt_invsc_on:1, opt_msg_on:1, opt_cl_all:1, vcterm:1;
+ /* Option flags. Set when an option is invoked. */
+ uint64_t opt_term:1, opt_reset:1, opt_initialize:1, opt_cursor:1,
+ opt_linewrap:1, opt_default:1, opt_foreground:1,
+ opt_background:1, opt_bold:1, opt_blink:1, opt_reverse:1,
+ opt_underline:1, opt_store:1, opt_clear:1, opt_blank:1,
+ opt_snap:1, opt_snapfile:1, opt_append:1, opt_ulcolor:1,
+ opt_hbcolor:1, opt_halfbright:1, opt_repeat:1, opt_tabs:1,
+ opt_clrtabs:1, opt_regtabs:1, opt_appcursorkeys:1,
+ opt_inversescreen:1, opt_msg:1, opt_msglevel:1, opt_powersave:1,
+ opt_powerdown:1, opt_blength:1, opt_bfreq:1;
+};
/* Command line parsing routines.
*
* Note that it is an error for a given option to be invoked more than once.
*/
-static void
-parse_term(int argc, char **argv, int *option, char **ttyname, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Term flag to set. */
- /* ttyname: Terminal name to set. */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse a -term specification. */
-
- if (argc != 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- if (argc == 1)
- *ttyname = argv[0];
+static int parse_switch(const char *arg, const char *t, const char *f)
+{
+ if (strcmp(arg, t) == 0)
+ return 1;
+ else if (strcmp(arg, f) == 0)
+ return 0;
+ errx(EXIT_FAILURE, _("argument error: %s"), arg);
}
-static void
-parse_none(int argc, char **argv __attribute__ ((__unused__)), int *option, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Term flag to set. */
- /* bad_arg: Set to true if an error is detected. */
+static int parse_febg_color(const char *arg)
+{
+ int color;
+
+ if (strcmp(arg, "black") == 0)
+ return BLACK;
+ else if (strcmp(arg, "red") == 0)
+ return RED;
+ else if (strcmp(arg, "green") == 0)
+ return GREEN;
+ else if (strcmp(arg, "yellow") == 0)
+ return YELLOW;
+ else if (strcmp(arg, "blue") == 0)
+ return BLUE;
+ else if (strcmp(arg, "magenta") == 0)
+ return MAGENTA;
+ else if (strcmp(arg, "cyan") == 0)
+ return CYAN;
+ else if (strcmp(arg, "white") == 0)
+ return WHITE;
+ else if (strcmp(arg, "default") == 0)
+ return DEFAULT;
+ else
+ color = strtos32_or_err(arg, _("argument error"));
+ if (color < BLACK || DEFAULT < color || color == GREY)
+ errx(EXIT_FAILURE, _("argument error: %s"), arg);
+ return color;
+}
-/* Parse a parameterless specification. */
+static int parse_ulhb_color(char **argv, int *optind)
+{
+ char *color_name;
+ int bright = 0;
+ int color = -1;
+
+ if (argv[*optind] && strcmp(argv[*optind - 1], "bright") == 0) {
+ bright = 1;
+ color_name = argv[*optind];
+ (*optind)++;
+ } else
+ color_name = argv[*optind - 1];
+
+ if (strcmp(color_name, "black") == 0)
+ color = BLACK;
+ else if (strcmp(color_name, "grey") == 0)
+ color = GREY;
+ else if (strcmp(color_name, "red") == 0)
+ color = RED;
+ else if (strcmp(color_name, "green") == 0)
+ color = GREEN;
+ else if (strcmp(color_name, "yellow") == 0)
+ color = YELLOW;
+ else if (strcmp(color_name, "blue") == 0)
+ color = BLUE;
+ else if (strcmp(color_name, "magenta") == 0)
+ color = MAGENTA;
+ else if (strcmp(color_name, "cyan") == 0)
+ color = CYAN;
+ else if (strcmp(color_name, "white") == 0)
+ color = WHITE;
+ else {
+ color = strtos32_or_err(color_name, _("argument error"));
+ if (color < BLACK || DEFAULT < color)
+ errx(EXIT_FAILURE, _("argument error: %s"), color_name);
+ }
+ if (bright && (color == BLACK || color == GREY))
+ errx(EXIT_FAILURE, _("argument error: bright %s is not supported"), color_name);
- if (argc != 0 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
+ return color;
}
-static void
-parse_switch(int argc, char **argv, int *option, int *opt_on, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Option flag to set. */
- /* opt_on: Boolean option switch to set or reset. */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse a boolean (on/off) specification. */
-
- if (argc > 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- if (argc == 1) {
- if (strcmp(argv[0], "on") == 0)
- *opt_on = TRUE;
- else if (strcmp(argv[0], "off") == 0)
- *opt_on = FALSE;
- else
- *bad_arg = TRUE;
- } else {
- *opt_on = TRUE;
+static char *find_optional_arg(char **argv, char *optarg, int *optind)
+{
+ char *arg;
+ if (optarg)
+ return optarg;
+ else {
+ arg = argv[*optind];
+ if (!arg || arg[0] == '-')
+ return NULL;
}
+ (*optind)++;
+ return arg;
}
-static void
-par_color(int argc, char **argv, int *option, int *opt_color, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Color flag to set. */
- /* opt_color: Color to set. */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse a -foreground or -background specification. */
-
- if (argc != 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- if (argc == 1) {
- if (strcmp(argv[0], "black") == 0)
- *opt_color = BLACK;
- else if (strcmp(argv[0], "red") == 0)
- *opt_color = RED;
- else if (strcmp(argv[0], "green") == 0)
- *opt_color = GREEN;
- else if (strcmp(argv[0], "yellow") == 0)
- *opt_color = YELLOW;
- else if (strcmp(argv[0], "blue") == 0)
- *opt_color = BLUE;
- else if (strcmp(argv[0], "magenta") == 0)
- *opt_color = MAGENTA;
- else if (strcmp(argv[0], "cyan") == 0)
- *opt_color = CYAN;
- else if (strcmp(argv[0], "white") == 0)
- *opt_color = WHITE;
- else if (strcmp(argv[0], "default") == 0)
- *opt_color = DEFAULT;
- else if (isdigit(argv[0][0]))
- *opt_color = atoi(argv[0]);
- else
- *bad_arg = TRUE;
-
- if(*opt_color < BLACK || DEFAULT < *opt_color || *opt_color == GREY)
- *bad_arg = TRUE;
+static int parse_blank(char **argv, char *optarg, int *optind)
+{
+ char *arg;
+
+ arg = find_optional_arg(argv, optarg, optind);
+ if (!arg)
+ return BLANKEDSCREEN;
+ if (!strcmp(arg, "force"))
+ return BLANKSCREEN;
+ else if (!strcmp(arg, "poke"))
+ return UNBLANKSCREEN;
+ else {
+ int ret;
+
+ ret = strtos32_or_err(arg, _("argument error"));
+ if (ret < 0 || BLANK_MAX < ret)
+ errx(EXIT_FAILURE, _("argument error: %s"), arg);
+ return ret;
}
+ /* should be impossible to reach */
+ abort();
}
-static void
-par_color2(int argc, char **argv, int *option, int *opt_color, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Color flag to set. */
- /* opt_color: Color to set. */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse a -ulcolor or -hbcolor specification. */
-
- if (!argc || argc > 2 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- *opt_color = 0;
- if (argc == 2) {
- if (strcmp(argv[0], "bright") == 0)
- *opt_color = GREY;
- else {
- *bad_arg = TRUE;
- return;
- }
- }
- if (argc) {
- if (strcmp(argv[argc-1], "black") == 0) {
- if(*opt_color)
- *bad_arg = TRUE;
- else
- *opt_color = BLACK;
- } else if (strcmp(argv[argc-1], "grey") == 0) {
- if(*opt_color)
- *bad_arg = TRUE;
- else
- *opt_color = GREY;
- } else if (strcmp(argv[argc-1], "red") == 0)
- *opt_color |= RED;
- else if (strcmp(argv[argc-1], "green") == 0)
- *opt_color |= GREEN;
- else if (strcmp(argv[argc-1], "yellow") == 0)
- *opt_color |= YELLOW;
- else if (strcmp(argv[argc-1], "blue") == 0)
- *opt_color |= BLUE;
- else if (strcmp(argv[argc-1], "magenta") == 0)
- *opt_color |= MAGENTA;
- else if (strcmp(argv[argc-1], "cyan") == 0)
- *opt_color |= CYAN;
- else if (strcmp(argv[argc-1], "white") == 0)
- *opt_color |= WHITE;
- else if (isdigit(argv[argc-1][0]))
- *opt_color = atoi(argv[argc-1]);
- else
- *bad_arg = TRUE;
- if(*opt_color < BLACK || DEFAULT < *opt_color )
- *bad_arg = TRUE;
- }
+static int parse_powersave(const char *arg)
+{
+ if (strcmp(arg, "on") == 0)
+ return VESA_BLANK_MODE_SUSPENDV;
+ else if (strcmp(arg, "vsync") == 0)
+ return VESA_BLANK_MODE_SUSPENDV;
+ else if (strcmp(arg, "hsync") == 0)
+ return VESA_BLANK_MODE_SUSPENDH;
+ else if (strcmp(arg, "powerdown") == 0)
+ return VESA_BLANK_MODE_POWERDOWN;
+ else if (strcmp(arg, "off") == 0)
+ return VESA_BLANK_MODE_OFF;
+ errx(EXIT_FAILURE, _("argument error: %s"), arg);
}
-static void
-parse_clear(int argc, char **argv, int *option, int *opt_all, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Clear flag to set. */
- /* opt_all: Clear all switch to set or reset. */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse a -clear specification. */
-
- if (argc > 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- if (argc == 1) {
- if (strcmp(argv[0], "all") == 0)
- *opt_all = TRUE;
- else if (strcmp(argv[0], "rest") == 0)
- *opt_all = FALSE;
- else
- *bad_arg = TRUE;
- } else {
- *opt_all = TRUE;
- }
+static int parse_msglevel(const char *arg)
+{
+ int ret;
+
+ ret = strtos32_or_err(arg, _("argument error"));
+ if (ret < CONSOLE_LEVEL_MIN || CONSOLE_LEVEL_MAX < ret)
+ errx(EXIT_FAILURE, _("argument error: %s"), arg);
+ return ret;
}
-static void
-parse_blank(int argc, char **argv, int *option, int *opt_all, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Clear flag to set. */
- /* opt_all: Clear all switch to set or reset. */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse a -blank specification. */
-
- if (argc > 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- if (argc == 1) {
- if (!strcmp(argv[0], "force"))
- *opt_all = BLANKSCREEN;
- else if (!strcmp(argv[0], "poke"))
- *opt_all = UNBLANKSCREEN;
- else {
- *opt_all = atoi(argv[0]);
- if (*opt_all < 0 || BLANK_MAX < *opt_all)
- *bad_arg = TRUE;
- }
- } else {
- *opt_all = BLANKEDSCREEN;
- }
+static int parse_snap(char **argv, char *optarg, int *optind)
+{
+ int ret;
+ char *arg;
+
+ arg = find_optional_arg(argv, optarg, optind);
+ if (!arg)
+ return 0;
+ ret = strtos32_or_err(arg, _("argument error"));
+ if (ret < 1)
+ errx(EXIT_FAILURE, _("argument error: %s"), arg);
+ return ret;
}
-static void
-parse_powersave(int argc, char **argv, int *option, int *opt_mode, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: powersave flag to set. */
- /* opt_mode: Powersaving mode, defined in vesa_blank.c */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse a -powersave mode specification. */
-
- if (argc > 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- if (argc == 1) {
- if (strcmp(argv[0], "on") == 0)
- *opt_mode = VESA_BLANK_MODE_SUSPENDV;
- else if (strcmp(argv[0], "vsync") == 0)
- *opt_mode = VESA_BLANK_MODE_SUSPENDV;
- else if (strcmp(argv[0], "hsync") == 0)
- *opt_mode = VESA_BLANK_MODE_SUSPENDH;
- else if (strcmp(argv[0], "powerdown") == 0)
- *opt_mode = VESA_BLANK_MODE_POWERDOWN;
- else if (strcmp(argv[0], "off") == 0)
- *opt_mode = VESA_BLANK_MODE_OFF;
- else
- *bad_arg = TRUE;
- } else {
- *opt_mode = VESA_BLANK_MODE_OFF;
+static void parse_tabs(char **argv, char *optarg, int *optind, int *tab_array)
+{
+ int i = 0;
+
+ if (optarg) {
+ tab_array[i] = strtos32_or_err(optarg, _("argument error"));
+ i++;
+ }
+ while (argv[*optind]) {
+ if (TABS_MAX < i)
+ errx(EXIT_FAILURE, _("too many tabs"));
+ if (argv[*optind][0] == '-')
+ break;
+ tab_array[i] = strtos32_or_err(argv[*optind], _("argument error"));
+ (*optind)++;
+ i++;
}
+ tab_array[i] = -1;
}
-static void
-parse_msglevel(int argc, char **argv, int *option, int *opt_all, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Clear flag to set. */
- /* opt_all: Clear all switch to set or reset. */
- /* bad_arg: Set to true if an error is detected. */
-
- if (argc > 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- if (argc == 1) {
- *opt_all = atoi(argv[0]);
- if (*opt_all < CONSOLE_LEVEL_MIN || CONSOLE_LEVEL_MAX < *opt_all)
- *bad_arg = TRUE;
- } else {
- *opt_all = -1;
- }
+static int parse_regtabs(char **argv, char *optarg, int *optind)
+{
+ int ret;
+ char *arg;
+
+ arg = find_optional_arg(argv, optarg, optind);
+ if (!arg)
+ return DEFAULT_TAB_LEN;
+ ret = strtos32_or_err(arg, _("argument error"));
+ if (ret < 1 || TABS_MAX < ret)
+ errx(EXIT_FAILURE, _("argument error: %s"), arg);
+ return ret;
}
-static void
-parse_snap(int argc, char **argv, int *option, int *opt_all, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Clear flag to set. */
- /* opt_all: Clear all switch to set or reset. */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse a -dump or -append specification. */
-
- if (argc > 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- if (argc == 1) {
- *opt_all = atoi(argv[0]);
- if ((*opt_all <= 0))
- *bad_arg = TRUE;
- } else {
- *opt_all = 0;
- }
+static int parse_blength(char **argv, char *optarg, int *optind)
+{
+ int ret = -1;
+ char *arg;
+
+ arg = find_optional_arg(argv, optarg, optind);
+ if (!arg)
+ return 0;
+ ret = strtos32_or_err(arg, _("argument error"));
+ if (ret < 0 || BLENGTH_MAX < ret)
+ errx(EXIT_FAILURE, _("argument error: %s"), arg);
+ return ret;
}
-static void
-parse_snapfile(int argc, char **argv, int *option, int *opt_all, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Clear flag to set. */
- /* opt_all: Clear all switch to set or reset. */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse a -file specification. */
-
- if (argc != 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- memset(opt_all, 0, PATH_MAX + 1);
- if (argc == 1)
- strncpy((char *)opt_all, argv[0], PATH_MAX);
+static int parse_bfreq(char **argv, char *optarg, int *optind)
+{
+ char *arg;
+
+ arg = find_optional_arg(argv, optarg, optind);
+ if (!arg)
+ return 0;
+ return strtos32_or_err(arg, _("argument error"));
}
-static void
-parse_tabs(int argc, char **argv, int *option, int *tab_array, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Clear flag to set. */
- /* tab_array: Array of tabs */
- /* bad_arg: Set to true if an error is detected. */
-
- if (*option || TABS_MAX < argc)
- *bad_arg = TRUE;
- *option = TRUE;
- tab_array[argc] = -1;
- while(argc--) {
- tab_array[argc] = atoi(argv[argc]);
- if (tab_array[argc] < 1 || TABS_MAX < tab_array[argc]) {
- *bad_arg = TRUE;
- return;
- }
- }
+static void __attribute__((__noreturn__)) usage(FILE *out)
+{
+ if (out == stderr)
+ warnx(_("argument error"));
+
+ fputs(USAGE_HEADER, out);
+ fprintf(out,
+ _(" %s [options]\n"), program_invocation_short_name);
+ fputs(USAGE_OPTIONS, out);
+ fputs(_(" --term <terminal_name>\n"), out);
+ fputs(_(" --reset\n"), out);
+ fputs(_(" --initialize\n"), out);
+ fputs(_(" --cursor <on|off>\n"), out);
+ fputs(_(" --repeat <on|off>\n"), out);
+ fputs(_(" --appcursorkeys <on|off>\n"), out);
+ fputs(_(" --linewrap <on|off>\n"), out);
+ fputs(_(" --default\n"), out);
+ fputs(_(" --foreground <default|color>\n"), out);
+ fputs(_(" --background <default|color>\n"), out);
+ fputs(_(" --ulcolor <bright> <color>\n"), out);
+ fputs(_(" --hbcolor <bright> <color>\n"), out);
+ fputs(_(" <color>: black blue cyan green grey magenta red white yellow\n"), out);
+ fputs(_(" --inversescreen <on|off>\n"), out);
+ fputs(_(" --bold <on|off>\n"), out);
+ fputs(_(" --half-bright <on|off>\n"), out);
+ fputs(_(" --blink <on|off>\n"), out);
+ fputs(_(" --reverse <on|off>\n"), out);
+ fputs(_(" --underline <on|off>\n"), out);
+ fputs(_(" --store\n"), out);
+ fputs(_(" --clear <all|rest>\n"), out);
+ fputs(_(" --tabs <tab1 tab2 tab3 ...> (tabn = 1-160)\n"), out);
+ fputs(_(" --clrtabs <tab1 tab2 tab3 ...> (tabn = 1-160)\n"), out);
+ fputs(_(" --regtabs <1-160>\n"), out);
+ fputs(_(" --blank <0-60|force|poke>\n"), out);
+ fputs(_(" --dump <1-NR_CONSOLES>\n"), out);
+ fputs(_(" --append <1-NR_CONSOLES>\n"), out);
+ fputs(_(" --file dumpfilename\n"), out);
+ fputs(_(" --msg <on|off>\n"), out);
+ fputs(_(" --msglevel <0-8>\n"), out);
+ fputs(_(" --powersave <on|vsync|hsync|powerdown|off>\n"), out);
+ fputs(_(" --powerdown <0-60>\n"), out);
+ fputs(_(" --blength <0-2000>\n"), out);
+ fputs(_(" --bfreq freqnumber\n"), out);
+ fputs(_(" --version\n"), out);
+ fputs(_(" --help\n"), out);
+ fprintf(out, USAGE_MAN_TAIL("setterm(1)"));
+ exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}
-static void
-parse_clrtabs(int argc, char **argv, int *option, int *tab_array, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Clear flag to set. */
- /* tab_array: Array of tabs */
- /* bad_arg: Set to true if an error is detected. */
-
- if (*option || TABS_MAX < argc)
- *bad_arg = TRUE;
- *option = TRUE;
- if(argc == 0) {
- tab_array[0] = -1;
- return;
- }
- tab_array[argc] = -1;
- while(argc--) {
- tab_array[argc] = atoi(argv[argc]);
- if(tab_array[argc] < 1 || TABS_MAX < tab_array[argc]) {
- *bad_arg = TRUE;
- return;
- }
- }
+static int __attribute__((__pure__)) set_opt_flag(int opt)
+{
+ if (opt)
+ errx(EXIT_FAILURE, _("duplicate use of an option"));
+ return 1;
}
-static void
-parse_regtabs(int argc, char **argv, int *option, int *opt_len, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Clear flag to set. */
- /* opt_len: Regular tab length. */
- /* bad_arg: Set to true if an error is detected. */
-
- if (*option || argc > 1)
- *bad_arg = TRUE;
- *option = TRUE;
- if(argc == 0) {
- *opt_len = DEFAULT_TAB_LEN;
- return;
- }
- *opt_len = atoi(argv[0]);
- if(*opt_len < 1 || TABS_MAX < *opt_len) {
- *bad_arg = TRUE;
- return;
+static void parse_option(struct setterm_control *ctl, int argc, char **argv)
+{
+ int c;
+ enum {
+ OPT_TERM = CHAR_MAX + 1,
+ OPT_RESET,
+ OPT_INITIALIZE,
+ OPT_CURSOR,
+ OPT_REPEAT,
+ OPT_APPCURSORKEYS,
+ OPT_LINEWRAP,
+ OPT_DEFAULT,
+ OPT_FOREGROUND,
+ OPT_BACKGROUND,
+ OPT_ULCOLOR,
+ OPT_HBCOLOR,
+ OPT_INVERSESCREEN,
+ OPT_BOLD,
+ OPT_HALF_BRIGHT,
+ OPT_BLINK,
+ OPT_REVERSE,
+ OPT_UNDERLINE,
+ OPT_STORE,
+ OPT_CLEAR,
+ OPT_TABS,
+ OPT_CLRTABS,
+ OPT_REGTABS,
+ OPT_BLANK,
+ OPT_DUMP,
+ OPT_APPEND,
+ OPT_FILE,
+ OPT_MSG,
+ OPT_MSGLEVEL,
+ OPT_POWERSAVE,
+ OPT_POWERDOWN,
+ OPT_BLENGTH,
+ OPT_BFREQ,
+ OPT_VERSION,
+ OPT_HELP
+ };
+ static const struct option longopts[] = {
+ {"term", required_argument, NULL, OPT_TERM},
+ {"reset", no_argument, NULL, OPT_RESET},
+ {"initialize", no_argument, NULL, OPT_INITIALIZE},
+ {"cursor", required_argument, NULL, OPT_CURSOR},
+ {"repeat", required_argument, NULL, OPT_REPEAT},
+ {"appcursorkeys", required_argument, NULL, OPT_APPCURSORKEYS},
+ {"linewrap", required_argument, NULL, OPT_LINEWRAP},
+ {"default", no_argument, NULL, OPT_DEFAULT},
+ {"foreground", required_argument, NULL, OPT_FOREGROUND},
+ {"background", required_argument, NULL, OPT_BACKGROUND},
+ {"ulcolor", required_argument, NULL, OPT_ULCOLOR},
+ {"hbcolor", required_argument, NULL, OPT_HBCOLOR},
+ {"inversescreen", required_argument, NULL, OPT_INVERSESCREEN},
+ {"bold", required_argument, NULL, OPT_BOLD},
+ {"half-bright", required_argument, NULL, OPT_HALF_BRIGHT},
+ {"blink", required_argument, NULL, OPT_BLINK},
+ {"reverse", required_argument, NULL, OPT_REVERSE},
+ {"underline", required_argument, NULL, OPT_UNDERLINE},
+ {"store", no_argument, NULL, OPT_STORE},
+ {"clear", required_argument, NULL, OPT_CLEAR},
+ {"tabs", optional_argument, NULL, OPT_TABS},
+ {"clrtabs", optional_argument, NULL, OPT_CLRTABS},
+ {"regtabs", optional_argument, NULL, OPT_REGTABS},
+ {"blank", optional_argument, NULL, OPT_BLANK},
+ {"dump", optional_argument, NULL, OPT_DUMP},
+ {"append", required_argument, NULL, OPT_APPEND},
+ {"file", required_argument, NULL, OPT_FILE},
+ {"msg", required_argument, NULL, OPT_MSG},
+ {"msglevel", required_argument, NULL, OPT_MSGLEVEL},
+ {"powersave", required_argument, NULL, OPT_POWERSAVE},
+ {"powerdown", optional_argument, NULL, OPT_POWERDOWN},
+ {"blength", optional_argument, NULL, OPT_BLENGTH},
+ {"bfreq", optional_argument, NULL, OPT_BFREQ},
+ {"version", no_argument, NULL, OPT_VERSION},
+ {"help", no_argument, NULL, OPT_HELP},
+ {NULL, 0, NULL, 0}
+ };
+ static const ul_excl_t excl[] = {
+ { OPT_DEFAULT, OPT_STORE },
+ { OPT_TABS, OPT_CLRTABS, OPT_REGTABS },
+ { OPT_MSG, OPT_MSGLEVEL },
+ { 0 }
+ };
+ int excl_st[ARRAY_SIZE(excl)] = UL_EXCL_STATUS_INIT;
+
+ while ((c = getopt_long_only(argc, argv, "", longopts, NULL)) != -1) {
+ err_exclusive_options(c, longopts, excl, excl_st);
+ switch (c) {
+ case OPT_TERM:
+ ctl->opt_term = set_opt_flag(ctl->opt_term);
+ ctl->opt_te_terminal_name = optarg;
+ break;
+ case OPT_RESET:
+ ctl->opt_reset = set_opt_flag(ctl->opt_reset);
+ break;
+ case OPT_INITIALIZE:
+ ctl->opt_initialize = set_opt_flag(ctl->opt_initialize);
+ break;
+ case OPT_CURSOR:
+ ctl->opt_cursor = set_opt_flag(ctl->opt_cursor);
+ ctl->opt_cu_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_REPEAT:
+ ctl->opt_repeat = set_opt_flag(ctl->opt_repeat);
+ ctl->opt_rep_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_APPCURSORKEYS:
+ ctl->opt_appcursorkeys = set_opt_flag(ctl->opt_appcursorkeys);
+ ctl->opt_appck_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_LINEWRAP:
+ ctl->opt_linewrap = set_opt_flag(ctl->opt_linewrap);
+ ctl->opt_li_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_DEFAULT:
+ ctl->opt_default = set_opt_flag(ctl->opt_default);
+ break;
+ case OPT_FOREGROUND:
+ ctl->opt_foreground = set_opt_flag(ctl->opt_foreground);
+ ctl->opt_fo_color = parse_febg_color(optarg);
+ break;
+ case OPT_BACKGROUND:
+ ctl->opt_background = set_opt_flag(ctl->opt_background);
+ ctl->opt_ba_color = parse_febg_color(optarg);
+ break;
+ case OPT_ULCOLOR:
+ ctl->opt_ulcolor = set_opt_flag(ctl->opt_ulcolor);
+ ctl->opt_ul_color = parse_ulhb_color(argv, &optind);
+ break;
+ case OPT_HBCOLOR:
+ ctl->opt_hbcolor = set_opt_flag(ctl->opt_hbcolor);
+ ctl->opt_hb_color = parse_ulhb_color(argv, &optind);
+ break;
+ case OPT_INVERSESCREEN:
+ ctl->opt_inversescreen = set_opt_flag(ctl->opt_inversescreen);
+ ctl->opt_invsc_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_BOLD:
+ ctl->opt_bold = set_opt_flag(ctl->opt_bold);
+ ctl->opt_bo_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_HALF_BRIGHT:
+ ctl->opt_halfbright = set_opt_flag(ctl->opt_halfbright);
+ ctl->opt_hb_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_BLINK:
+ ctl->opt_blink = set_opt_flag(ctl->opt_blink);
+ ctl->opt_bl_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_REVERSE:
+ ctl->opt_reverse = set_opt_flag(ctl->opt_reverse);
+ ctl->opt_re_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_UNDERLINE:
+ ctl->opt_underline = set_opt_flag(ctl->opt_underline);
+ ctl->opt_un_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_STORE:
+ ctl->opt_store = set_opt_flag(ctl->opt_store);
+ break;
+ case OPT_CLEAR:
+ ctl->opt_clear = set_opt_flag(ctl->opt_clear);
+ ctl->opt_cl_all = parse_switch(optarg, "all", "reset");
+ break;
+ case OPT_TABS:
+ ctl->opt_tabs = set_opt_flag(ctl->opt_tabs);
+ parse_tabs(argv, optarg, &optind, ctl->opt_tb_array);
+ break;
+ case OPT_CLRTABS:
+ ctl->opt_clrtabs = set_opt_flag(ctl->opt_clrtabs);
+ parse_tabs(argv, optarg, &optind, ctl->opt_tb_array);
+ break;
+ case OPT_REGTABS:
+ ctl->opt_regtabs = set_opt_flag(ctl->opt_regtabs);
+ ctl->opt_rt_len = parse_regtabs(argv, optarg, &optind);
+ break;
+ case OPT_BLANK:
+ ctl->opt_blank = set_opt_flag(ctl->opt_blank);
+ ctl->opt_bl_min = parse_blank(argv, optarg, &optind);
+ break;
+ case OPT_DUMP:
+ ctl->opt_snap = set_opt_flag(ctl->opt_snap);
+ ctl->opt_sn_num = parse_snap(argv, optarg, &optind);
+ break;
+ case OPT_APPEND:
+ ctl->opt_append = set_opt_flag(ctl->opt_append);
+ ctl->opt_sn_num = parse_snap(argv, optarg, &optind);
+ break;
+ case OPT_FILE:
+ ctl->opt_snapfile = set_opt_flag(ctl->opt_snapfile);
+ ctl->opt_sn_name = optarg;
+ break;
+ case OPT_MSG:
+ ctl->opt_msg = set_opt_flag(ctl->opt_msg);
+ ctl->opt_msg_on = parse_switch(optarg, "on", "off");
+ break;
+ case OPT_MSGLEVEL:
+ ctl->opt_msglevel = set_opt_flag(ctl->opt_msglevel);
+ ctl->opt_msglevel_num = parse_msglevel(optarg);
+ if (ctl->opt_msglevel_num == 0) {
+ ctl->opt_msg = set_opt_flag(ctl->opt_msg);
+ ctl->opt_msg_on |= 1;
+ }
+ break;
+ case OPT_POWERSAVE:
+ ctl->opt_powersave = set_opt_flag(ctl->opt_powersave);
+ ctl->opt_ps_mode = parse_powersave(optarg);
+ break;
+ case OPT_POWERDOWN:
+ ctl->opt_powerdown = set_opt_flag(ctl->opt_powerdown);
+ ctl->opt_pd_min = parse_blank(argv, optarg, &optind);
+ break;
+ case OPT_BLENGTH:
+ ctl->opt_blength = set_opt_flag(ctl->opt_blength);
+ ctl->opt_blength_l = parse_blength(argv, optarg, &optind);
+ break;
+ case OPT_BFREQ:
+ ctl->opt_bfreq = set_opt_flag(ctl->opt_bfreq);
+ ctl->opt_bfreq_f = parse_bfreq(argv, optarg, &optind);
+ break;
+ case OPT_VERSION:
+ printf(UTIL_LINUX_VERSION);
+ exit(EXIT_SUCCESS);
+ case OPT_HELP:
+ usage(stdout);
+ default:
+ usage(stderr);
+ }
}
}
+/* End of command line parsing routines. */
-static void
-parse_blength(int argc, char **argv, int *option, int *opt_all, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Clear flag to set. */
- /* opt_all */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse -blength specification. */
-
- if (argc > 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- if (argc == 1) {
- *opt_all = atoi(argv[0]);
- if (BLENGTH_MAX < *opt_all)
- *bad_arg = TRUE;
- } else {
- *opt_all = 0;
- }
-}
+/* Return the specified terminfo string, or an empty string if no such
+ * terminfo capability exists. */
+static char *ti_entry(const char *name)
+{
+ char *buf_ptr;
-static void
-parse_bfreq(int argc, char **argv, int *option, int *opt_all, int *bad_arg) {
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* option: Clear flag to set. */
- /* opt_all */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse -bfreq specification. */
-
- if (argc > 1 || *option)
- *bad_arg = TRUE;
- *option = TRUE;
- if (argc == 1) {
- *opt_all = atoi(argv[0]);
- } else {
- *opt_all = 0;
- }
+ if ((buf_ptr = tigetstr((char *)name)) == (char *)-1)
+ buf_ptr = NULL;
+ return buf_ptr;
}
-
-static void
-show_tabs(void) {
+static void show_tabs(void)
+{
int i, co = tigetnum("cols");
- if(co > 0) {
+ if (co > 0) {
printf("\r ");
- for(i = 10; i < co-2; i+=10)
+ for (i = 10; i < co - 2; i += 10)
printf("%-10d", i);
putchar('\n');
- for(i = 1; i <= co; i++)
- putchar(i%10+'0');
+ for (i = 1; i <= co; i++)
+ putchar(i % 10 + '0');
putchar('\n');
- for(i = 1; i < co; i++)
+ for (i = 1; i < co; i++)
printf("\tT\b");
putchar('\n');
}
}
-static void __attribute__ ((__noreturn__))
-usage(FILE *out) {
-/* Print error message about arguments, and the command's syntax. */
-
- if (out == stderr)
- warnx(_("Argument error."));
-
- fputs(_("\nUsage:\n"), out);
- fprintf(out,
- _(" %s [options]\n"), program_invocation_short_name);
-
- fputs(_("\nOptions:\n"), out);
- fputs(_(" -term <terminal_name>\n"), out);
- fputs(_(" -reset\n"), out);
- fputs(_(" -initialize\n"), out);
- fputs(_(" -cursor <on|off>\n"), out);
- fputs(_(" -repeat <on|off>\n"), out);
- fputs(_(" -appcursorkeys <on|off>\n"), out);
- fputs(_(" -linewrap <on|off>\n"), out);
- fputs(_(" -default\n"), out);
- fputs(_(" -foreground <default|black|blue|cyan|green|magenta|red|white|yellow>\n"), out);
- fputs(_(" -background <default|black|blue|cyan|green|magenta|red|white|yellow>\n"), out);
- fputs(_(" -ulcolor <black|blue|bright|cyan|green|grey|magenta|red|white|yellow>\n"), out);
- fputs(_(" -ulcolor <black|blue|bright|cyan|green|grey|magenta|red|white|yellow>\n"), out);
- fputs(_(" -hbcolor <black|blue|bright|cyan|green|grey|magenta|red|white|yellow>\n"), out);
- fputs(_(" -hbcolor <black|blue|bright|cyan|green|grey|magenta|red|white|yellow>\n"), out);
- fputs(_(" -inversescreen <on|off>\n"), out);
- fputs(_(" -bold <on|off>\n"), out);
- fputs(_(" -half-bright <on|off>\n"), out);
- fputs(_(" -blink <on|off>\n"), out);
- fputs(_(" -reverse <on|off>\n"), out);
- fputs(_(" -underline <on|off>\n"), out);
- fputs(_(" -store\n"), out);
- fputs(_(" -clear <all|rest>\n"), out);
- fputs(_(" -tabs <tab1 tab2 tab3 ...> (tabn = 1-160)\n"), out);
- fputs(_(" -clrtabs <tab1 tab2 tab3 ...> (tabn = 1-160)\n"), out);
- fputs(_(" -regtabs <1-160>\n"), out);
- fputs(_(" -blank <0-60|force|poke>\n"), out);
- fputs(_(" -dump <1-NR_CONSOLES>\n"), out);
- fputs(_(" -append <1-NR_CONSOLES>\n"), out);
- fputs(_(" -file dumpfilename\n"), out);
- fputs(_(" -msg <on|off>\n"), out);
- fputs(_(" -msglevel <0-8>\n"), out);
- fputs(_(" -powersave <on|vsync|hsync|powerdown|off>\n"), out);
- fputs(_(" -powerdown <0-60>\n"), out);
- fputs(_(" -blength <0-2000>\n"), out);
- fputs(_(" -bfreq freqnumber\n"), out);
- fputs(_(" -version\n"), out);
- fputs(_(" -help\n"), out);
-
- fprintf(out, USAGE_MAN_TAIL("setterm(1)"));
-
- exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
-}
+static int open_snapshot_device(struct setterm_control *ctl)
+{
+ int fd;
-#define STRCMP(str1,str2) strncmp(str1,str2,strlen(str1))
-
-static void
-parse_option(char *option, int argc, char **argv, int *bad_arg) {
- /* option: Option with leading '-' removed. */
- /* argc: Number of arguments for this option. */
- /* argv: Arguments for this option. */
- /* bad_arg: Set to true if an error is detected. */
-
-/* Parse a single specification. */
-
- if (STRCMP(option, "term") == 0)
- parse_term(argc, argv, &opt_term, &opt_te_terminal_name, bad_arg);
- else if (STRCMP(option, "reset") == 0)
- parse_none(argc, argv, &opt_reset, bad_arg);
- else if (STRCMP(option, "initialize") == 0)
- parse_none(argc, argv, &opt_initialize, bad_arg);
- else if (STRCMP(option, "cursor") == 0)
- parse_switch(argc, argv, &opt_cursor, &opt_cu_on, bad_arg);
- else if (STRCMP(option, "repeat") == 0)
- parse_switch(argc, argv, &opt_repeat, &opt_rep_on, bad_arg);
- else if (STRCMP(option, "appcursorkeys") == 0)
- parse_switch(argc, argv, &opt_appcursorkeys, &opt_appck_on, bad_arg);
- else if (STRCMP(option, "linewrap") == 0)
- parse_switch(argc, argv, &opt_linewrap, &opt_li_on, bad_arg);
- else if (STRCMP(option, "default") == 0)
- parse_none(argc, argv, &opt_default, bad_arg);
- else if (STRCMP(option, "foreground") == 0)
- par_color(argc, argv, &opt_foreground, &opt_fo_color, bad_arg);
- else if (STRCMP(option, "background") == 0)
- par_color(argc, argv, &opt_background, &opt_ba_color, bad_arg);
- else if (STRCMP(option, "ulcolor") == 0)
- par_color2(argc, argv, &opt_ulcolor, &opt_ul_color, bad_arg);
- else if (STRCMP(option, "hbcolor") == 0)
- par_color2(argc, argv, &opt_hbcolor, &opt_hb_color, bad_arg);
- else if (STRCMP(option, "inversescreen") == 0)
- parse_switch(argc, argv, &opt_inversescreen, &opt_invsc_on, bad_arg);
- else if (STRCMP(option, "bold") == 0)
- parse_switch(argc, argv, &opt_bold, &opt_bo_on, bad_arg);
- else if (STRCMP(option, "half-bright") == 0)
- parse_switch(argc, argv, &opt_halfbright, &opt_hb_on, bad_arg);
- else if (STRCMP(option, "blink") == 0)
- parse_switch(argc, argv, &opt_blink, &opt_bl_on, bad_arg);
- else if (STRCMP(option, "reverse") == 0)
- parse_switch(argc, argv, &opt_reverse, &opt_re_on, bad_arg);
- else if (STRCMP(option, "underline") == 0)
- parse_switch(argc, argv, &opt_underline, &opt_un_on, bad_arg);
- else if (STRCMP(option, "store") == 0)
- parse_none(argc, argv, &opt_store, bad_arg);
- else if (STRCMP(option, "clear") == 0)
- parse_clear(argc, argv, &opt_clear, &opt_cl_all, bad_arg);
- else if (STRCMP(option, "tabs") == 0)
- parse_tabs(argc, argv, &opt_tabs, opt_tb_array, bad_arg);
- else if (STRCMP(option, "clrtabs") == 0)
- parse_clrtabs(argc, argv, &opt_clrtabs, opt_tb_array, bad_arg);
- else if (STRCMP(option, "regtabs") == 0)
- parse_regtabs(argc, argv, &opt_regtabs, &opt_rt_len, bad_arg);
- else if (STRCMP(option, "blank") == 0)
- parse_blank(argc, argv, &opt_blank, &opt_bl_min, bad_arg);
- else if (STRCMP(option, "dump") == 0)
- parse_snap(argc, argv, &opt_snap, &opt_sn_num, bad_arg);
- else if (STRCMP(option, "append") == 0)
- parse_snap(argc, argv, &opt_append, &opt_sn_num, bad_arg);
- else if (STRCMP(option, "file") == 0)
- parse_snapfile(argc, argv, &opt_snapfile, (int *)opt_sn_name, bad_arg);
- else if (STRCMP(option, "msg") == 0)
- parse_switch(argc, argv, &opt_msg, &opt_msg_on, bad_arg);
- else if (STRCMP(option, "msglevel") == 0)
- parse_msglevel(argc, argv, &opt_msglevel, &opt_msglevel_num, bad_arg);
- else if (STRCMP(option, "powersave") == 0)
- parse_powersave(argc, argv, &opt_powersave, &opt_ps_mode, bad_arg);
- else if (STRCMP(option, "powerdown") == 0)
- parse_blank(argc, argv, &opt_powerdown, &opt_pd_min, bad_arg);
- else if (STRCMP(option, "blength") == 0)
- parse_blength(argc, argv, &opt_blength, &opt_blength_l, bad_arg);
- else if (STRCMP(option, "bfreq") == 0)
- parse_bfreq(argc, argv, &opt_bfreq, &opt_bfreq_f, bad_arg);
- else if (STRCMP(option, "version") == 0) {
- printf(_("%s from %s\n"), program_invocation_short_name,
- PACKAGE_STRING);
- exit(EXIT_SUCCESS);
- } else if (STRCMP(option, "help") == 0)
- usage(stdout);
+ if (ctl->opt_sn_num)
+ xasprintf(&ctl->in_device, "/dev/vcsa%d", ctl->opt_sn_num);
else
- *bad_arg = TRUE;
+ xasprintf(&ctl->in_device, "/dev/vcsa");
+ fd = open(ctl->in_device, O_RDONLY);
+ if (fd < 0)
+ err(EXIT_DUMPFILE, _("cannot read %s"), ctl->in_device);
+ return fd;
}
-/* End of command line parsing routines. */
-
-static char *ti_entry(const char *name) {
- /* name: Terminfo capability string to lookup. */
-
-/* Return the specified terminfo string, or an empty string if no such terminfo
- * capability exists.
- */
+static void set_blanking(struct setterm_control *ctl)
+{
+ char ioctlarg;
+ int ret;
- char *buf_ptr;
+ if (0 <= ctl->opt_bl_min) {
+ printf("\033[9;%d]", ctl->opt_bl_min);
+ return;
+ }
+ switch (ctl->opt_bl_min) {
+ case BLANKSCREEN:
+ ioctlarg = TIOCL_BLANKSCREEN;
+ if (ioctl(STDIN_FILENO, TIOCLINUX, &ioctlarg))
+ warn(_("cannot force blank"));
+ break;
+ case UNBLANKSCREEN:
+ ioctlarg = TIOCL_UNBLANKSCREEN;
+ if (ioctl(STDIN_FILENO, TIOCLINUX, &ioctlarg))
+ warn(_("cannot force unblank"));
+ break;
+ case BLANKEDSCREEN:
+ ioctlarg = TIOCL_BLANKEDSCREEN;
+ ret = ioctl(STDIN_FILENO, TIOCLINUX, &ioctlarg);
+ if (ret < 0)
+ warn(_("cannot get blank status"));
+ else
+ printf("%d\n", ret);
+ break;
+ default: /* should be impossible to reach */
+ abort();
+ }
+ return;
+}
- if ((buf_ptr = tigetstr((char *)name)) == (char *)-1)
- buf_ptr = NULL;
- return buf_ptr;
+static void screendump(struct setterm_control *ctl)
+{
+ unsigned char header[4];
+ unsigned int rows, cols;
+ int fd;
+ FILE *out;
+ size_t i, j;
+ ssize_t rc;
+ char *inbuf, *outbuf, *p, *q;
+ char dump_default[] = "screen.dump";
+
+ /* open source and destination files */
+ fd = open_snapshot_device(ctl);
+ if (!ctl->opt_sn_name)
+ ctl->opt_sn_name = dump_default;
+ out = fopen(ctl->opt_sn_name, ctl->opt_snap ? "w" : "a");
+ if (!out)
+ err(EXIT_DUMPFILE, _("can not open dump file %s for output"), ctl->opt_sn_name);
+ /* determine snapshot size */
+ if (read(fd, header, 4) != 4)
+ err(EXIT_DUMPFILE, _("cannot read %s"), ctl->in_device);
+ rows = header[0];
+ cols = header[1];
+ if (rows * cols == 0)
+ err(EXIT_DUMPFILE, _("cannot read %s"), ctl->in_device);
+ /* allocate buffers */
+ inbuf = xmalloc(rows * cols * 2);
+ outbuf = xmalloc(rows * (cols + 1));
+ /* read input */
+ rc = read(fd, inbuf, rows * cols * 2);
+ if (rc < 0 || (size_t)rc != rows * cols * 2)
+ err(EXIT_DUMPFILE, _("cannot read %s"), ctl->in_device);
+ p = inbuf;
+ q = outbuf;
+ /* copy inbuf to outbuf */
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols; j++) {
+ *q++ = *p;
+ p += 2;
+ }
+ while (j-- > 0 && q[-1] == ' ')
+ q--;
+ *q++ = '\n';
+ }
+ fwrite(outbuf, 1, q - outbuf, out);
+ /* clean up allocations */
+ close(fd);
+ free(inbuf);
+ free(outbuf);
+ free(ctl->in_device);
+ if (close_stream(out) != 0)
+ errx(EXIT_FAILURE, _("write error"));
+ return;
}
-static void
-perform_sequence(int vcterm) {
- /* vcterm: Set if terminal is a virtual console. */
+/* Some options are applicable when terminal is virtual console. */
+static int vc_only(struct setterm_control *ctl, const char *err)
+{
+ if (!ctl->vcterm) {
+ if (err)
+ warnx(_("terminal %s does not support %s"),
+ ctl->opt_te_terminal_name, err);
+ }
+ return ctl->vcterm;
+}
+static void perform_sequence(struct setterm_control *ctl)
+{
int result;
-/* Perform the selected options. */
/* -reset. */
- if (opt_reset) {
+ if (ctl->opt_reset)
putp(ti_entry("rs1"));
- }
/* -initialize. */
- if (opt_initialize) {
+ if (ctl->opt_initialize)
putp(ti_entry("is2"));
- }
/* -cursor [on|off]. */
- if (opt_cursor) {
- if (opt_cu_on)
+ if (ctl->opt_cursor) {
+ if (ctl->opt_cu_on)
putp(ti_entry("cnorm"));
else
putp(ti_entry("civis"));
}
- /* -linewrap [on|off]. Vc only (vt102) */
- if (opt_linewrap && vcterm)
- fputs(opt_li_on ? "\033[?7h" : "\033[?7l", stdout);
+ /* -linewrap [on|off]. */
+ if (ctl->opt_linewrap)
+ fputs(ctl->opt_li_on ? "\033[?7h" : "\033[?7l", stdout);
- /* -repeat [on|off]. Vc only (vt102) */
- if (opt_repeat && vcterm)
- fputs(opt_rep_on ? "\033[?8h" : "\033[?8l", stdout);
+ /* -repeat [on|off]. */
+ if (ctl->opt_repeat && vc_only(ctl, "--repeat"))
+ fputs(ctl->opt_rep_on ? "\033[?8h" : "\033[?8l", stdout);
- /* -appcursorkeys [on|off]. Vc only (vt102) */
- if (opt_appcursorkeys && vcterm)
- fputs(opt_appck_on ? "\033[?1h" : "\033[?1l", stdout);
+ /* -appcursorkeys [on|off]. */
+ if (ctl->opt_appcursorkeys && vc_only(ctl, "--appcursorkeys"))
+ fputs(ctl->opt_appck_on ? "\033[?1h" : "\033[?1l", stdout);
/* -default. Vc sets default rendition, otherwise clears all
- * attributes.
- */
- if (opt_default) {
- if (vcterm)
+ * attributes. */
+ if (ctl->opt_default) {
+ if (vc_only(ctl, NULL))
printf("\033[0m");
else
putp(ti_entry("sgr0"));
}
- /* -foreground black|red|green|yellow|blue|magenta|cyan|white|default.
- * Vc only (ANSI).
- */
- if (opt_foreground && vcterm)
- printf("\033[3%c%s", '0' + opt_fo_color, "m");
-
- /* -background black|red|green|yellow|blue|magenta|cyan|white|default.
- * Vc only (ANSI).
- */
- if (opt_background && vcterm)
- printf("\033[4%c%s", '0' + opt_ba_color, "m");
-
- /* -ulcolor black|red|green|yellow|blue|magenta|cyan|white|default.
- * Vc only.
- */
- if (opt_ulcolor && vcterm) {
- printf("\033[1;%d]", opt_ul_color);
- }
+ /* -foreground black|red|green|yellow|blue|magenta|cyan|white|default. */
+ if (ctl->opt_foreground)
+ printf("\033[3%c%s", '0' + ctl->opt_fo_color, "m");
- /* -hbcolor black|red|green|yellow|blue|magenta|cyan|white|default.
- * Vc only.
- */
- if (opt_hbcolor && vcterm) {
- printf("\033[2;%d]", opt_hb_color);
- }
+ /* -background black|red|green|yellow|blue|magenta|cyan|white|default. */
+ if (ctl->opt_background)
+ printf("\033[4%c%s", '0' + ctl->opt_ba_color, "m");
+
+ /* -ulcolor black|red|green|yellow|blue|magenta|cyan|white|default. */
+ if (ctl->opt_ulcolor && vc_only(ctl, "--ulcolor"))
+ printf("\033[1;%d]", ctl->opt_ul_color);
+
+ /* -hbcolor black|red|green|yellow|blue|magenta|cyan|white|default. */
+ if (ctl->opt_hbcolor)
+ printf("\033[2;%d]", ctl->opt_hb_color);
- /* -inversescreen [on|off]. Vc only (vt102).
- */
- if (opt_inversescreen && vcterm)
- fputs(opt_invsc_on ? "\033[?5h" : "\033[?5l", stdout);
+ /* -inversescreen [on|off]. */
+ if (ctl->opt_inversescreen)
+ fputs(ctl->opt_invsc_on ? "\033[?5h" : "\033[?5l", stdout);
/* -bold [on|off]. Vc behaves as expected, otherwise off turns off
- * all attributes.
- */
- if (opt_bold) {
- if (opt_bo_on)
+ * all attributes. */
+ if (ctl->opt_bold) {
+ if (ctl->opt_bo_on)
putp(ti_entry("bold"));
else {
- if (vcterm)
+ if (vc_only(ctl, NULL))
fputs("\033[22m", stdout);
else
putp(ti_entry("sgr0"));
}
}
- /* -half-bright [on|off]. Vc behaves as expected, otherwise off turns off
- * all attributes.
- */
- if (opt_halfbright) {
- if (opt_hb_on)
+ /* -half-bright [on|off]. Vc behaves as expected, otherwise off
+ * turns off all attributes. */
+ if (ctl->opt_halfbright) {
+ if (ctl->opt_hb_on)
putp(ti_entry("dim"));
else {
- if (vcterm)
+ if (vc_only(ctl, NULL))
fputs("\033[22m", stdout);
else
putp(ti_entry("sgr0"));
@@ -929,13 +917,12 @@ perform_sequence(int vcterm) {
}
/* -blink [on|off]. Vc behaves as expected, otherwise off turns off
- * all attributes.
- */
- if (opt_blink) {
- if (opt_bl_on)
+ * all attributes. */
+ if (ctl->opt_blink) {
+ if (ctl->opt_bl_on)
putp(ti_entry("blink"));
else {
- if (vcterm)
+ if (vc_only(ctl, NULL))
fputs("\033[25m", stdout);
else
putp(ti_entry("sgr0"));
@@ -943,13 +930,12 @@ perform_sequence(int vcterm) {
}
/* -reverse [on|off]. Vc behaves as expected, otherwise off turns
- * off all attributes.
- */
- if (opt_reverse) {
- if (opt_re_on)
+ * off all attributes. */
+ if (ctl->opt_reverse) {
+ if (ctl->opt_re_on)
putp(ti_entry("rev"));
else {
- if (vcterm)
+ if (vc_only(ctl, NULL))
fputs("\033[27m", stdout);
else
putp(ti_entry("sgr0"));
@@ -957,279 +943,146 @@ perform_sequence(int vcterm) {
}
/* -underline [on|off]. */
- if (opt_underline)
- putp(ti_entry(opt_un_on ? "smul" : "rmul"));
+ if (ctl->opt_underline)
+ putp(ti_entry(ctl->opt_un_on ? "smul" : "rmul"));
- /* -store. Vc only. */
- if (opt_store && vcterm)
+ /* -store. */
+ if (ctl->opt_store && vc_only(ctl, "--store"))
fputs("\033[8]", stdout);
/* -clear [all|rest]. */
- if (opt_clear)
- putp(ti_entry(opt_cl_all ? "clear" : "ed"));
+ if (ctl->opt_clear)
+ putp(ti_entry(ctl->opt_cl_all ? "clear" : "ed"));
- /* -tabs Vc only. */
- if (opt_tabs && vcterm) {
- int i;
-
- if (opt_tb_array[0] == -1)
+ /* -tabs. */
+ if (ctl->opt_tabs) {
+ if (ctl->opt_tb_array[0] == -1)
show_tabs();
else {
- for(i=0; opt_tb_array[i] > 0; i++)
- printf("\033[%dG\033H", opt_tb_array[i]);
+ int i;
+
+ for (i = 0; ctl->opt_tb_array[i] > 0; i++)
+ printf("\033[%dG\033H", ctl->opt_tb_array[i]);
putchar('\r');
}
}
- /* -clrtabs Vc only. */
- if (opt_clrtabs && vcterm) {
+ /* -clrtabs. */
+ if (ctl->opt_clrtabs && vc_only(ctl, "--clrtabs")) {
int i;
- if (opt_tb_array[0] == -1)
+ if (ctl->opt_tb_array[0] == -1)
fputs("\033[3g", stdout);
else
- for(i=0; opt_tb_array[i] > 0; i++)
- printf("\033[%dG\033[g", opt_tb_array[i]);
+ for (i = 0; ctl->opt_tb_array[i] > 0; i++)
+ printf("\033[%dG\033[g", ctl->opt_tb_array[i]);
putchar('\r');
}
- /* -regtabs Vc only. */
- if (opt_regtabs && vcterm) {
+ /* -regtabs. */
+ if (ctl->opt_regtabs && vc_only(ctl, "--regtabs")) {
int i;
fputs("\033[3g\r", stdout);
- for(i=opt_rt_len+1; i<=TABS_MAX; i+=opt_rt_len)
- printf("\033[%dC\033H",opt_rt_len);
+ for (i = ctl->opt_rt_len + 1; i <= TABS_MAX; i += ctl->opt_rt_len)
+ printf("\033[%dC\033H", ctl->opt_rt_len);
putchar('\r');
}
/* -blank [0-60]. */
- if (opt_blank && vcterm) {
- if (opt_bl_min >= 0)
- printf("\033[9;%d]", opt_bl_min);
- else if (opt_bl_min == BLANKSCREEN) {
- char ioctlarg = TIOCL_BLANKSCREEN;
- if (ioctl(0,TIOCLINUX,&ioctlarg))
- warn(_("cannot force blank"));
- } else if (opt_bl_min == UNBLANKSCREEN) {
- char ioctlarg = TIOCL_UNBLANKSCREEN;
- if (ioctl(0,TIOCLINUX,&ioctlarg))
- warn(_("cannot force unblank"));
- } else if (opt_bl_min == BLANKEDSCREEN) {
- char ioctlarg = TIOCL_BLANKEDSCREEN;
- int ret;
- ret = ioctl(0,TIOCLINUX,&ioctlarg);
- if (ret < 0)
- warn(_("cannot get blank status"));
- else
- printf("%d\n",ret);
- }
- }
+ if (ctl->opt_blank && vc_only(ctl, "--blank"))
+ set_blanking(ctl);
/* -powersave [on|vsync|hsync|powerdown|off] (console) */
- if (opt_powersave) {
+ if (ctl->opt_powersave) {
char ioctlarg[2];
ioctlarg[0] = TIOCL_SETVESABLANK;
- ioctlarg[1] = opt_ps_mode;
- if (ioctl(0,TIOCLINUX,ioctlarg))
+ ioctlarg[1] = ctl->opt_ps_mode;
+ if (ioctl(STDIN_FILENO, TIOCLINUX, ioctlarg))
warn(_("cannot (un)set powersave mode"));
}
/* -powerdown [0-60]. */
- if (opt_powerdown) {
- printf("\033[14;%d]", opt_pd_min);
- }
+ if (ctl->opt_powerdown)
+ printf("\033[14;%d]", ctl->opt_pd_min);
/* -snap [1-NR_CONS]. */
- if (opt_snap || opt_append) {
- FILE *F;
-
- F = fopen(opt_sn_name, opt_snap ? "w" : "a");
- if (!F)
- err(EXIT_DUMPFILE, _("can not open dump file %s for output"),
- opt_sn_name);
- screendump(opt_sn_num, F);
- if (close_stream(F) != 0)
- errx(EXIT_FAILURE, _("write error"));
- }
+ if (ctl->opt_snap || ctl->opt_append)
+ screendump(ctl);
- /* -msg [on|off]. */
- if (opt_msg && vcterm) {
- if (opt_msg_on)
- /* 7 -- Enable printk's to console */
+ /* -msg [on|off]. Controls printk's to console. */
+ if (ctl->opt_msg && vc_only(ctl, "--msg")) {
+ if (ctl->opt_msg_on)
result = klogctl(SYSLOG_ACTION_CONSOLE_ON, NULL, 0);
else
- /* 6 -- Disable printk's to console */
result = klogctl(SYSLOG_ACTION_CONSOLE_OFF, NULL, 0);
if (result != 0)
warn(_("klogctl error"));
}
- /* -msglevel [0-8] */
- if (opt_msglevel && vcterm) {
- /* 8 -- Set level of messages printed to console */
- result = klogctl(SYSLOG_ACTION_CONSOLE_LEVEL, NULL, opt_msglevel_num);
+ /* -msglevel [0-8]. Console printk message level. */
+ if (ctl->opt_msglevel_num && vc_only(ctl, "--msglevel")) {
+ result =
+ klogctl(SYSLOG_ACTION_CONSOLE_LEVEL, NULL,
+ ctl->opt_msglevel_num);
if (result != 0)
warn(_("klogctl error"));
}
/* -blength [0-2000] */
- if (opt_blength && vcterm) {
- printf("\033[11;%d]", opt_blength_l);
+ if (ctl->opt_blength && vc_only(ctl, "--blength")) {
+ printf("\033[11;%d]", ctl->opt_blength_l);
}
/* -bfreq freqnumber */
- if (opt_bfreq && vcterm) {
- printf("\033[10;%d]", opt_bfreq_f);
+ if (ctl->opt_bfreq && vc_only(ctl, "--bfreq")) {
+ printf("\033[10;%d]", ctl->opt_bfreq_f);
}
-
}
-static void
-screendump(int vcnum, FILE * F)
+static void init_terminal(struct setterm_control *ctl)
{
- char infile[MAXPATHLEN];
- unsigned char header[4];
- unsigned int rows, cols;
- int fd;
- size_t i, j;
- ssize_t rc;
- char *inbuf = NULL, *outbuf = NULL, *p, *q;
-
- sprintf(infile, "/dev/vcsa%d", vcnum);
- fd = open(infile, O_RDONLY);
- if (fd < 0 && vcnum == 0) {
- /* vcsa0 is often called vcsa */
- sprintf(infile, "/dev/vcsa");
- fd = open(infile, O_RDONLY);
- }
- if (fd < 0) {
- /* try devfs name - for zero vcnum just /dev/vcc/a */
- /* some gcc's warn for %.u - add 0 */
- sprintf(infile, "/dev/vcc/a%.0u", vcnum);
- fd = open(infile, O_RDONLY);
- }
- if (fd < 0) {
- sprintf(infile, "/dev/vcsa%d", vcnum);
- goto read_error;
- }
- if (read(fd, header, 4) != 4)
- goto read_error;
- rows = header[0];
- cols = header[1];
- if (rows * cols == 0)
- goto read_error;
-
- inbuf = xmalloc(rows * cols * 2);
- outbuf = xmalloc(rows * (cols + 1));
-
- rc = read(fd, inbuf, rows * cols * 2);
- if (rc < 0 || (size_t) rc != rows * cols * 2)
- goto read_error;
- p = inbuf;
- q = outbuf;
- for (i = 0; i < rows; i++) {
- for (j = 0; j < cols; j++) {
- *q++ = *p;
- p += 2;
- }
- while (j-- > 0 && q[-1] == ' ')
- q--;
- *q++ = '\n';
- }
- if (fwrite(outbuf, 1, q - outbuf, F) != (size_t) (q - outbuf)) {
- warnx(_("Error writing screendump"));
- goto error;
- }
- close(fd);
- free(inbuf);
- free(outbuf);
- return;
-
-read_error:
- if (vcnum != 0)
- warnx(_("Couldn't read %s"), infile);
- else
- warnx(_("Couldn't read neither /dev/vcsa0 nor /dev/vcsa"));
-
-error:
- if (fd >= 0)
- close(fd);
- free(inbuf);
- free(outbuf);
- exit(EXIT_FAILURE);
-}
+ int term_errno;
-int
-main(int argc, char **argv) {
- int bad_arg = FALSE; /* Set if error in arguments. */
- int arg, modifier;
- char *term; /* Terminal type. */
- int vcterm; /* Set if terminal is a virtual console. */
- int errret;
-
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
- atexit(close_stdout);
-
- if (argc < 2)
- bad_arg = TRUE;
-
- /* Parse arguments. */
-
- for (arg = 1; arg < argc;) {
- if (*argv[arg] == '-') {
-
- /* Parse a single option. */
-
- for (modifier = arg + 1; modifier < argc; modifier++) {
- if (*argv[modifier] == '-') break;
- }
- parse_option(argv[arg] + 1, modifier - arg - 1,
- &argv[arg + 1], &bad_arg);
- arg = modifier;
- } else {
- bad_arg = TRUE;
- arg++;
- }
- }
-
- /* Display syntax message if error in arguments. */
-
- if (bad_arg)
- usage(stderr);
-
- /* Find out terminal name. */
-
- if (opt_term) {
- term = opt_te_terminal_name;
- } else {
- term = getenv("TERM");
- if (term == NULL)
+ if (!ctl->opt_te_terminal_name) {
+ ctl->opt_te_terminal_name = getenv("TERM");
+ if (ctl->opt_te_terminal_name == NULL)
errx(EXIT_FAILURE, _("$TERM is not defined."));
}
/* Find terminfo entry. */
-
- if (setupterm(term, 1, &errret))
- switch(errret) {
+ if (setupterm(ctl->opt_te_terminal_name, STDOUT_FILENO, &term_errno))
+ switch (term_errno) {
case -1:
errx(EXIT_FAILURE, _("terminfo database cannot be found"));
case 0:
- errx(EXIT_FAILURE, _("%s: unknown terminal type"), term);
+ errx(EXIT_FAILURE, _("%s: unknown terminal type"), ctl->opt_te_terminal_name);
case 1:
errx(EXIT_FAILURE, _("terminal is hardcopy"));
}
/* See if the terminal is a virtual console terminal. */
+ ctl->vcterm = (!strncmp(ctl->opt_te_terminal_name, "con", 3) ||
+ !strncmp(ctl->opt_te_terminal_name, "linux", 5));
+}
- vcterm = (!strncmp(term, "con", 3) || !strncmp(term, "linux", 5));
- /* Perform the selected options. */
+int main(int argc, char **argv)
+{
+ struct setterm_control ctl = { 0 };
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+ atexit(close_stdout);
+
+ if (argc < 2)
+ usage(stderr);
- perform_sequence(vcterm);
+ parse_option(&ctl, argc, argv);
+ init_terminal(&ctl);
+ perform_sequence(&ctl);
return EXIT_SUCCESS;
}