add netbsd nl(1)
[rofl0r-hardcore-utils.git] / dumpkmap.c
blob62396507e538d72c3738baa9e5ecb667b2fd63f2
1 #include <unistd.h>
2 #include <fcntl.h>
3 #include <sys/ioctl.h>
4 #include <netinet/in.h>
6 #define KDGKBTYPE 0x4B33
7 #define ARRAYSIZE(a) sizeof(a)/sizeof(a[0])
8 static int console_fd(int mode) {
9 const char devs[][16] = { "/dev/tty", "/dev/vc/0", "/dev/console" };
10 size_t i = 0;
11 int fd = -1;
12 while(i < ARRAYSIZE(devs) && fd == -1) {
13 fd = open(devs[i++], mode);
14 char arg = 0;
15 if(fd != -1 && ioctl(fd, KDGKBTYPE, &arg)) {
16 close(fd);
17 fd = -1;
20 return fd;
23 struct kbentry {
24 unsigned char kb_table;
25 unsigned char kb_index;
26 unsigned short kb_value;
29 #define KDGKBENT 0x4B46
30 #define NR_KEYS 128
31 #define MAX_NR_KEYMAPS 256
33 #include <stdio.h>
34 #include <stdlib.h>
35 #ifdef USE_LIBULZ
36 #include <ulz/stdio-repl.h>
37 #endif
39 #define noret __attribute__((noreturn))
41 noret static void die_perror(const char* msg) {
42 perror(msg);
43 exit(1);
46 noret static void usage(const char *arg0) {
47 dprintf(2, "usage: %s > backup.kmap\n"
48 "dumps current keymap to stdout.\n"
49 "redirect to file as output contains binary data\n", arg0);
50 exit(1);
53 int main(int argc, char** argv) {
54 (void) argc;
55 if(argv[1] || isatty(1)) usage(argv[0]);
56 const char flags[MAX_NR_KEYMAPS] = {
57 [0] = 1, [1] = 1, [2] = 1,
58 [4] = 1, [5] = 1, [6] = 1,
59 [8] = 1, [9] = 1, [10] = 1,
60 [12] = 1,
62 int cfd = console_fd(O_RDONLY);
63 if(cfd == -1) die_perror("could not get console fd");
64 write(1, "hcukmap", 7);
65 write(1, flags, MAX_NR_KEYMAPS);
66 size_t i = 0, j;
67 for(;i < 13; i++) if(flags[i]) for(j=0; j < NR_KEYS; j++) {
68 struct kbentry ke = { .kb_index = j, .kb_table = i };
69 if(ioctl(cfd, KDGKBENT, &ke)) die_perror("failed to get key setting");
70 unsigned short s;
71 s = htons(ke.kb_value);
72 write(1, &s, 2);
74 return 0;