From 6d4ffc24c11fe0cc04ed2943aff8baf9f5d1b206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=C3=A1n=20Healy?= Date: Thu, 19 Feb 2026 17:47:33 +0000 Subject: [PATCH] Backup scan2.c --- scan2.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 scan2.c diff --git a/scan2.c b/scan2.c new file mode 100644 index 0000000..fae32f5 --- /dev/null +++ b/scan2.c @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Interval in seconds between reminders (default 20 minutes), +// can be overridden with -i (supports optional s/m suffix). +static unsigned long long interval_seconds = 20ULL * 60ULL; + +// Shared timestamp of when the "standing" event last occurred. +static unsigned long long last_time_standing = 0; + +// Map a subset of key codes (digits and Enter) to characters. +static char keycode_to_char(unsigned short code) +{ + switch (code) { + case KEY_0: return '0'; + case KEY_1: return '1'; + case KEY_2: return '2'; + case KEY_3: return '3'; + case KEY_4: return '4'; + case KEY_5: return '5'; + case KEY_6: return '6'; + case KEY_7: return '7'; + case KEY_8: return '8'; + case KEY_9: return '9'; + default: return '\0'; + } +} + +// Thread that once per second prints how long it has been since +// last_time_standing was updated. +static void *time_watcher_thread(void *arg) +{ + (void)arg; + for (;;) { + sleep(1); + unsigned long long now = (unsigned long long)time(NULL); + if (last_time_standing != 0) { + unsigned long long delta = now - last_time_standing; + printf("Seconds since last_time_standing: %llu (interval=%llus)\n", + delta, interval_seconds); + fflush(stdout); + // If we've exceeded the configured interval, lock the screen + if (delta >= interval_seconds) { + // Use xinput to disable all keyboard-like devices until user stands again. + // This pipeline lists input devices, filters keyboards (excluding XTEST), + // extracts their IDs, and disables each one. + system("xinput --list --short | " + "grep -i 'keyboard' | grep -v 'XTEST' | " + "sed -E 's/.*id=([0-9]+).*/\\1/' | " + "xargs -r -n1 xinput disable"); + + system("i3lock -n -i /usr/local/share/lockscreens/standing_gopher.png"); + } + } + } + return NULL; +} + +int main(int argc, char **argv) { + // Replace with the specific event node for your keyboard + // Use 'lsusb' and 'cat /proc/bus/input/devices' to find the right one + const char *dev = "/dev/input/by-id/usb-IC_Reader_IC_Reader_08FF20171101-event-kbd"; + struct input_event ev; + int fd; + + // Optional: -i [s|m] to override interval_seconds + int opt; + while ((opt = getopt(argc, argv, "i:")) != -1) { + switch (opt) { + case 'i': { + char *end = NULL; + unsigned long long v = strtoull(optarg, &end, 10); + if (!optarg[0] || end == optarg || v == 0) { + fprintf(stderr, "Invalid interval '%s' for -i (must start with positive integer)\n", optarg); + return EXIT_FAILURE; + } + + char unit = 'm'; // default unit: minutes + if (*end != '\0') { + // Allow a single unit character 's' or 'm' + if (end[1] != '\0') { + fprintf(stderr, "Invalid interval suffix in '%s' (use optional 's' or 'm')\n", optarg); + return EXIT_FAILURE; + } + unit = (char)tolower((unsigned char)*end); + if (unit != 's' && unit != 'm') { + fprintf(stderr, "Unknown interval unit '%c' in '%s' (use 's' or 'm')\n", *end, optarg); + return EXIT_FAILURE; + } + } + + if (unit == 's') { + interval_seconds = v; + } else { // 'm' + interval_seconds = v * 60ULL; + } + break; + } + default: + fprintf(stderr, "Usage: %s [-i interval{s|m}]\n", argv[0]); + return EXIT_FAILURE; + } + } + + fd = open(dev, O_RDONLY); + if (fd == -1) { + perror("Cannot open device"); + return EXIT_FAILURE; + } + + // Grab the device: This blocks all other apps from seeing these keystrokes + if (ioctl(fd, EVIOCGRAB, 1) == -1) { + perror("Could not grab device"); + close(fd); + return EXIT_FAILURE; + } + + printf("Input blocked from %s. Press Ctrl+C in this terminal to stop.\n", dev); + + // Buffer to accumulate the characters the reader "types" + char buf_str[128]; + size_t buf_len = 0; + + // Initialize last_time_standing and start the watcher thread + last_time_standing = (unsigned long long)time(NULL); + pthread_t watcher; + if (pthread_create(&watcher, NULL, time_watcher_thread, NULL) != 0) { + perror("Failed to create watcher thread"); + ioctl(fd, EVIOCGRAB, 0); + close(fd); + return EXIT_FAILURE; + } + pthread_detach(watcher); + // Continuous loop to capture events + while (1) { + ssize_t n = read(fd, &ev, sizeof(ev)); + if (n == (ssize_t)-1) { + perror("Read error"); + break; + } else if (n != sizeof(ev)) { + continue; + } + // Process only key events (type 1) + if (ev.type == EV_KEY) { + if (ev.value == 1) { // key press + if (ev.code == KEY_ENTER || ev.code == KEY_KPENTER) { + // End of the "typed" sequence: print the accumulated string + if (buf_len > 0) { + buf_str[buf_len] = '\0'; + long long val = strtoll(buf_str, NULL, 10); + // Get the SHA-256 hash of the value + unsigned char hash[SHA256_DIGEST_LENGTH]; + SHA256((unsigned char*)buf_str, buf_len, hash); + printf("SHA-256: "); + unsigned long long hash_val = 0; + for (int i = 0; i < 8; i++) { + hash_val = (hash_val << 8) | hash[i]; + } + printf(" (as number: %llu)", hash_val); + printf("\n"); + printf("Typed: %s (as number: %lld)\n", buf_str, val); + buf_len = 0; + if (hash_val == 4798061567229363866L) { + last_time_standing = (unsigned long long)time(NULL); + printf("Desk reminder timer reset at %llu seconds since epoch.\n", last_time_standing); + system("pkill i3lock"); + system("xinput --list --short | " + "grep -i 'keyboard' | grep -v 'XTEST' | " + "sed -E 's/.*id=([0-9]+).*/\\1/' | " + "xargs -r -n1 xinput enable"); + } + } + } else { + char c = keycode_to_char(ev.code); + if (c != '\0' && buf_len + 1 < sizeof(buf_str)) + buf_str[buf_len++] = c; + } + } + } + } + + // Release the grab before exiting + ioctl(fd, EVIOCGRAB, 0); + close(fd); + return 0; +}