blob: 316ff5800e212cab3827e6ce6268d2c79f58f222 [file]
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include <getopt.h>
#include <sysexits.h>
#include "libcommon.h"
static const char *action = NULL;
static const char *value = NULL;
static void KBD_ATTR_NORETURN
usage(int rc, const struct kbd_help *options)
{
fprintf(stderr,
_("Usage: %1$s [option...] getmode [text|graphics]\n"
" or: %1$s [option...] gkbmode [raw|xlate|mediumraw|unicode]\n"
" or: %1$s [option...] gkbmeta [metabit|escprefix]\n"
" or: %1$s [option...] gkbled [scrolllock|numlock|capslock]\n"),
program_invocation_short_name);
fprintf(stderr, "\n");
fprintf(stderr, _(
"The utility allows to read and check various parameters\n"
"of the keyboard and virtual console.\n"));
print_options(options);
print_report_bugs();
exit(rc);
}
static int
answer(const char *ans)
{
if (value)
return strcasecmp(value, ans) ? EXIT_FAILURE : EXIT_SUCCESS;
printf("%s\n", ans);
return EXIT_SUCCESS;
}
int main(int argc, char **argv)
{
int fd, mode, c;
int rc = EXIT_FAILURE;
char flags;
const char *console = NULL;
setuplocale();
const char *short_opts = "C:hV";
const struct option long_opts[] = {
{ "console", required_argument, NULL, 'C' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
};
const struct kbd_help opthelp[] = {
{ "-C, --console=DEV", _("the console device to be used.") },
{ "-V, --version", _("print version number.") },
{ "-h, --help", _("print this usage message.") },
{ NULL, NULL }
};
while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
switch (c) {
case 'C':
if (optarg == NULL || optarg[0] == '\0')
usage(EX_USAGE, opthelp);
console = optarg;
break;
case 'V':
print_version_and_exit();
break;
case 'h':
usage(EXIT_SUCCESS, opthelp);
break;
case '?':
usage(EX_USAGE, opthelp);
break;
}
}
if (optind == argc) {
kbd_error(EXIT_FAILURE, 0, _("Not enough arguments."));
}
action = argv[optind++];
if (optind < argc)
value = argv[optind++];
if ((fd = getfd(console)) < 0)
kbd_error(EXIT_FAILURE, 0, _("Couldn't get a file descriptor referring to the console."));
if (!strcasecmp("GETMODE", action)) {
if (ioctl(fd, KDGETMODE, &mode) == -1)
kbd_error(EXIT_FAILURE, errno, _("Unable to read console mode"));
switch (mode) {
case KD_TEXT:
rc = answer("text");
break;
case KD_GRAPHICS:
rc = answer("graphics");
break;
}
} else if (!strcasecmp("GKBMODE", action)) {
if (ioctl(fd, KDGKBMODE, &mode) == -1)
kbd_error(EXIT_FAILURE, errno, _("Unable to read keyboard mode"));
switch (mode) {
case K_RAW:
rc = answer("raw");
break;
case K_XLATE:
rc = answer("xlate");
break;
case K_MEDIUMRAW:
rc = answer("mediumraw");
break;
case K_UNICODE:
rc = answer("unicode");
break;
}
} else if (!strcasecmp("GKBMETA", action)) {
if (ioctl(fd, KDGKBMETA, &mode) == -1)
kbd_error(EXIT_FAILURE, errno, _("Unable to read meta key handling mode"));
switch (mode) {
case K_METABIT:
rc = answer("metabit");
break;
case K_ESCPREFIX:
rc = answer("escprefix");
break;
}
} else if (!strcasecmp("GKBLED", action)) {
if (ioctl(fd, KDGKBLED, &flags) == -1)
kbd_error(EXIT_FAILURE, errno, _("Unable to read keyboard flags"));
mode = (flags & 0x7);
if (value) {
if (((mode & LED_SCR) && !strcasecmp(value, "scrolllock")) ||
((mode & LED_NUM) && !strcasecmp(value, "numlock")) ||
((mode & LED_CAP) && !strcasecmp(value, "capslock")))
rc = EXIT_SUCCESS;
} else {
printf("scrolllock:%s ", (mode & LED_SCR) ? "on" : "off");
printf("numlock:%s ", (mode & LED_NUM) ? "on" : "off");
printf("capslock:%s\n", (mode & LED_CAP) ? "on" : "off");
rc = EXIT_SUCCESS;
}
} else {
kbd_warning(0, _("Unrecognized argument: %s"), action);
}
close(fd);
return rc;
}