summaryrefslogtreecommitdiffstats
path: root/pingid.c
diff options
context:
space:
mode:
authorfishsoupisgood <github@madingley.org>2020-06-16 20:52:36 +0100
committerfishsoupisgood <github@madingley.org>2020-06-16 20:52:36 +0100
commit43e7d8d003f31bf9648e6bb82988fd33e93cda0f (patch)
tree0776dfb13c79dd40377e72c4a8b79a5bff41808a /pingid.c
downloadpingid-43e7d8d003f31bf9648e6bb82988fd33e93cda0f.zip
pingid-43e7d8d003f31bf9648e6bb82988fd33e93cda0f.tar.gz
pingid-43e7d8d003f31bf9648e6bb82988fd33e93cda0f.tar.bz2
fish
Diffstat (limited to 'pingid.c')
-rw-r--r--pingid.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/pingid.c b/pingid.c
new file mode 100644
index 0000000..76309ba
--- /dev/null
+++ b/pingid.c
@@ -0,0 +1,157 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <strings.h>
+#include <sys/types.h>
+#include <linux/input.h>
+
+
+char *names[KEY_MAX + 1] =
+ { "", "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "",
+ "\t", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "", "",
+ "a", "s", "d", "f", "g",
+ "h", "j", "k", "l", ";", "'", "`", "", "\\", "z", "x", "c", "v", "b", "n",
+ "m", ",", ".",
+ "/"
+};
+
+static char *
+strcasestr (const char *haystack, const char *needle)
+{
+ size_t len = strlen (needle);
+
+ for (; *haystack; haystack++)
+ {
+
+ if (!strncasecmp (haystack, needle, len))
+ return (char *) haystack;
+
+ }
+
+ return NULL;
+
+}
+
+static int
+squirt (const char *fn, const char *content)
+{
+ size_t len = strlen (content);
+ int fd = open (fn, O_WRONLY);
+ int ret = -1;
+
+ if (fd < 0)
+ return ret;
+
+ if (write (fd, content, len) == len)
+ ret = 0;
+
+ close (fd);
+ return ret;
+}
+
+int
+open_ykhid (void)
+{
+#define MAX_DEV 64
+ char name[128];
+ unsigned i;
+ int fd;
+
+ for (i = 0; i < MAX_DEV; ++i)
+ {
+ sprintf (name, "/dev/input/event%d", i);
+ fd = open (name, O_RDWR);
+ if (fd < 0)
+ continue;
+
+ ioctl (fd, EVIOCGNAME (sizeof (name)), name);
+ name[sizeof (name) - 1] = 0;
+
+ if (strcasestr (name, "yubikey"))
+ return fd;
+
+ close (fd);
+ }
+
+ return -1;
+}
+
+
+
+static int
+get_string_with_timeout (int fd, struct timeval *tv, char *buf,
+ size_t buf_len)
+{
+ fd_set rfds;
+ struct input_event ev;
+
+ if (buf_len)
+ buf_len--;
+
+
+ FD_ZERO (&rfds);
+ for (;;)
+ {
+ FD_SET (fd, &rfds);
+
+ if (select (fd + 1, &rfds, NULL, NULL, tv) < 1)
+ break;
+
+ if (read (fd, &ev, sizeof (struct input_event)) !=
+ sizeof (struct input_event))
+ continue;
+
+ if (ev.type != EV_KEY)
+ continue;
+
+ if (buf_len && ev.code == KEY_ENTER && !ev.value)
+ return 0;
+
+ if (!ev.value)
+ continue;
+
+// printf("code %d (%s)\n",ev.code,names[ev.code]);
+
+ if (buf_len && names[ev.code][0])
+ {
+ *(buf++) = names[ev.code][0];
+ *buf = 0;
+ buf_len--;
+ }
+ }
+
+
+ return -1;
+}
+
+int
+main (int argc, char *argv[])
+{
+ int fd = open_ykhid ();
+ struct timeval tv;
+ char ret[128];
+
+ squirt ("/sys/class/gpio/export", "4");
+ squirt ("/sys/class/gpio/gpio4/direction", "out");
+ squirt ("/sys/class/gpio/gpio4/value", "0");
+
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 100;
+ get_string_with_timeout (fd, &tv, NULL, 0);
+
+ squirt ("/sys/class/gpio/gpio4/value", "1");
+
+
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+
+ get_string_with_timeout (fd, &tv, ret, sizeof (ret));
+
+ squirt ("/sys/class/gpio/gpio4/value", "0");
+
+ printf ("Content-Type: text/plain\n\n%s\n", ret);
+
+ return 0;
+}