Initial public busybox upstream commit
[busybox4maemo] / console-tools / kbd_mode.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Mini loadkmap implementation for busybox
4  *
5  * Copyright (C) 2007 Loïc Grenié <loic.grenie@gmail.com>
6  *   written using Andries Brouwer <aeb@cwi.nl>'s kbd_mode from
7  *   console-utils v0.2.3, licensed under GNU GPLv2
8  *
9  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
10  *
11  */
12
13 #include <getopt.h>
14 #include "libbb.h"
15 #include <linux/kd.h>
16
17 int kbd_mode_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
18 int kbd_mode_main(int argc, char **argv)
19 {
20         static const char opts[] = "saku";
21
22         const char *opt = argv[1];
23         const char *p;
24         int fd;
25
26         fd = get_console_fd();
27         if (fd < 0) /* get_console_fd() already complained */
28                 return EXIT_FAILURE;
29
30         if (opt == NULL) {
31                 /* No arg */
32                 const char *msg = "unknown";
33                 int mode;
34
35                 ioctl(fd, KDGKBMODE, &mode);
36                 switch(mode) {
37                 case K_RAW:
38                         msg = "raw (scancode)";
39                         break;
40                 case K_XLATE:
41                         msg = "default (ASCII)";
42                         break;
43                 case K_MEDIUMRAW:
44                         msg = "mediumraw (keycode)";
45                         break;
46                 case K_UNICODE:
47                         msg = "Unicode (UTF-8)";
48                         break;
49                 }
50                 printf("The keyboard is in %s mode\n", msg);
51         }
52         else if (argc > 2 /* more than 1 arg */
53          || *opt != '-' /* not an option */
54          || (p = strchr(opts, opt[1])) == NULL /* not an option we expect */
55          || opt[2] != '\0' /* more than one option char */
56         ) {
57                 bb_show_usage();
58                 /* return EXIT_FAILURE; - not reached */
59         }
60         else {
61 #if K_RAW != 0 || K_XLATE != 1 || K_MEDIUMRAW != 2 || K_UNICODE != 3
62 #error kbd_mode must be changed
63 #endif
64                 /* The options are in the order of the various K_xxx */
65                 ioctl(fd, KDSKBMODE, p - opts);
66         }
67
68         if (ENABLE_FEATURE_CLEAN_UP)
69                 close(fd);
70         return EXIT_SUCCESS;
71 }