|
#include "sormc.h"
|
|
#include <fcntl.h>
|
|
#include <linux/input.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/ioctl.h>
|
|
#include <unistd.h>
|
|
|
|
#define MAX_DEVICES 32
|
|
#define DEVICE_PATH "/dev/input/event"
|
|
|
|
const char *keycode_to_char[] = {
|
|
[2] = "1", [3] = "2", [4] = "3", [5] = "4", [6] = "5",
|
|
[7] = "6", [8] = "7", [9] = "8", [10] = "9", [11] = "0",
|
|
[12] = "-", [13] = "=", [14] = "[BACKSPACE]", [15] = "[TAB]",
|
|
|
|
[16] = "Q", [17] = "W", [18] = "E", [19] = "R", [20] = "T",
|
|
[21] = "Y", [22] = "U", [23] = "I", [24] = "O", [25] = "P",
|
|
[26] = "[", [27] = "]", [28] = "[ENTER]\n", [29] = "[LEFT_CTRL]",
|
|
[30] = "A", [31] = "S", [32] = "D", [33] = "F", [34] = "G",
|
|
[35] = "H", [36] = "J", [37] = "K", [38] = "L", [39] = ";",
|
|
[40] = "'", [41] = "`", [42] = "[LEFT_SHIFT]", [43] = "\\",
|
|
[44] = "Z", [45] = "X", [46] = "C", [47] = "V", [48] = "B",
|
|
[49] = "N", [50] = "M", [51] = ",", [52] = ".", [53] = "/",
|
|
[54] = "[RIGHT_SHIFT]", [55] = "[KEYPAD_*]", [56] = "[LEFT_ALT]",
|
|
[57] = " ", [58] = "[CAPSLOCK]",
|
|
|
|
[59] = "[F1]", [60] = "[F2]", [61] = "[F3]", [62] = "[F4]",
|
|
[63] = "[F5]", [64] = "[F6]", [65] = "[F7]", [66] = "[F8]",
|
|
[67] = "[F9]", [68] = "[F10]", [87] = "[F11]", [88] = "[F12]",
|
|
|
|
[69] = "[NUMLOCK]", [70] = "[SCROLLLOCK]", [71] = "[KEYPAD_7]",
|
|
[72] = "[KEYPAD_8]", [73] = "[KEYPAD_9", [74] = "[KEYPAD_-]",
|
|
[75] = "[KEYPAD_4]", [76] = "[KEYPAD_5", [77] = "[KEYPAD_6]",
|
|
[78] = "[KEYPAD_+]", [79] = "[KEYPAD_1", [80] = "[KEYPAD_2]",
|
|
[81] = "[KEYPAD_3]", [82] = "[KEYPAD_0", [83] = "[KEYPAD_.]",
|
|
|
|
[86] = "<", [100] = "[RIGHT_ALT]", [97] = "[RIGHT_CTRL]",
|
|
[119] = "[PAUSE]", [120] = "[SYSRQ]", [121] = "[BREAK]",
|
|
|
|
[102] = "[HOME]", [103] = "[UP]", [104] = "[PAGEUP]",
|
|
[105] = "[LEFT]", [106] = "[RIGHT]", [107] = "[END]",
|
|
[108] = "[DOWN]", [109] = "[PAGEDOWN]", [110] = "[INSERT]",
|
|
[111] = "[DELETE]",
|
|
|
|
[113] = "[MUTE]", [114] = "[VOLUME_DOWN]", [115] = "[VOLUME_UP]",
|
|
[163] = "[MEDIA_NEXT]", [165] = "[MEDIA_PREV]", [164] = "[MEDIA_PLAY_PAUSE]"
|
|
};
|
|
|
|
|
|
|
|
int is_keyboard(int fd) {
|
|
char device_name[256] = {0};
|
|
|
|
if (ioctl(fd, EVIOCGNAME(sizeof(device_name)), device_name) < 0) {
|
|
return 0;
|
|
}
|
|
|
|
return strstr(device_name, "keyboard") != NULL;
|
|
}
|
|
|
|
int main() {
|
|
|
|
int db = sormc("tikker.db");
|
|
|
|
ulonglong times_repeated = 0;
|
|
ulonglong times_pressed = 0;
|
|
ulonglong times_released = 0;
|
|
|
|
sormq(db, "CREATE TABLE IF NOT EXISTS kevent (id INTEGER PRIMARY KEY AUTOINCREMENT, code,event,name,timestamp,char)");
|
|
|
|
int keyboard_fds[MAX_DEVICES];
|
|
int num_keyboards = 0;
|
|
|
|
for (int i = 0; i < MAX_DEVICES; i++) {
|
|
char device_path[32];
|
|
snprintf(device_path, sizeof(device_path), "%s%d", DEVICE_PATH, i);
|
|
|
|
int fd = open(device_path, O_RDONLY);
|
|
if (fd < 0) {
|
|
continue;
|
|
}
|
|
|
|
if (is_keyboard(fd)) {
|
|
keyboard_fds[num_keyboards++] = fd;
|
|
printf("Found keyboard: %s\n", device_path);
|
|
} else {
|
|
close(fd);
|
|
}
|
|
}
|
|
|
|
if (num_keyboards == 0) {
|
|
fprintf(stderr, "No keyboard found.\n");
|
|
return 1;
|
|
}
|
|
|
|
printf("Monitoring %d keyboards.\n", num_keyboards);
|
|
|
|
struct input_event ev;
|
|
fd_set read_fds;
|
|
|
|
while (1) {
|
|
FD_ZERO(&read_fds);
|
|
int max_fd = -1;
|
|
|
|
for (int i = 0; i < num_keyboards; i++) {
|
|
FD_SET(keyboard_fds[i], &read_fds);
|
|
if (keyboard_fds[i] > max_fd) {
|
|
max_fd = keyboard_fds[i];
|
|
}
|
|
}
|
|
|
|
if (select(max_fd + 1, &read_fds, NULL, NULL, NULL) < 0) {
|
|
perror("select error");
|
|
break;
|
|
}
|
|
|
|
for (int i = 0; i < num_keyboards; i++) {
|
|
if (FD_ISSET(keyboard_fds[i], &read_fds)) {
|
|
ssize_t bytes = read(keyboard_fds[i], &ev, sizeof(struct input_event));
|
|
|
|
if (bytes == sizeof(struct input_event)) {
|
|
if (ev.type == EV_KEY) {
|
|
char * char_name = NULL;
|
|
if (ev.code < sizeof(keycode_to_char) / sizeof(keycode_to_char[0])) {
|
|
char_name = (char *)keycode_to_char[ev.code];
|
|
}
|
|
|
|
char keyboard_name[256];
|
|
ioctl(keyboard_fds[i], EVIOCGNAME(sizeof(keyboard_name)), keyboard_name);
|
|
|
|
printf("Keyboard: %s, ", keyboard_name);
|
|
char *event_name = NULL;
|
|
if (ev.value == 1) {
|
|
event_name = "PRESSED";
|
|
times_pressed++;
|
|
} else if (ev.value == 0) {
|
|
event_name = "RELEASED";
|
|
times_released++;
|
|
} else {
|
|
event_name = "REPEATED";
|
|
times_repeated++;
|
|
}
|
|
|
|
sormq(db, "INSERT INTO kevent (code, event, name,timestamp,char) VALUES (%d, %s, %s, DATETIME('now'),%s)", ev.code,
|
|
event_name, keyboard_name,char_name);
|
|
printf("Event: %s, ", ev.value == 1 ? "PRESSED" : ev.value == 0 ? "RELEASED" : "REPEATED");
|
|
printf("Key Code: %d, ", ev.code);
|
|
printf("Name: %s, ", char_name);
|
|
printf("Pr: %lld Rel: %lld Rep: %lld\n", times_pressed, times_released, times_repeated);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < num_keyboards; i++) {
|
|
close(keyboard_fds[i]);
|
|
}
|
|
|
|
return 0;
|
|
}
|