summaryrefslogtreecommitdiffstats
path: root/rx.c
diff options
context:
space:
mode:
authorroot <root@nolonger-other.tetra.james.local>2020-10-25 01:08:03 +0000
committerroot <root@nolonger-other.tetra.james.local>2020-10-25 01:08:03 +0000
commit4b4e4972088d82cac99941398834d8e6d661682c (patch)
tree97eb9edd980ea0121b94d7de158787f132922576 /rx.c
downloadgalaxy_tools-4b4e4972088d82cac99941398834d8e6d661682c.tar.gz
galaxy_tools-4b4e4972088d82cac99941398834d8e6d661682c.tar.bz2
galaxy_tools-4b4e4972088d82cac99941398834d8e6d661682c.zip
fish
Diffstat (limited to 'rx.c')
-rw-r--r--rx.c208
1 files changed, 208 insertions, 0 deletions
diff --git a/rx.c b/rx.c
new file mode 100644
index 0000000..a02c964
--- /dev/null
+++ b/rx.c
@@ -0,0 +1,208 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+
+void poll (int fd)
+{
+}
+
+int valid_fn (unsigned char fn)
+{
+ switch (fn) {
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ case 0x33:
+ case 0x34:
+ case 0x35:
+ case 0x36:
+ case 0x37:
+ case 0x38:
+ case 0x08:
+ case 0x39:
+ case 0x09:
+ case 0x43:
+ case 0x45:
+ case 0x4E:
+ case 0x4F:
+ case 0x50:
+ case 0x40:
+ case 0x3F:
+ case 0x23:
+ case 0x26:
+ case 0x41:
+ case 0x58:
+ case 0x4C:
+ case 0x56:
+ case 0x76:
+ case 0x49:
+ return 1;
+ }
+
+ return 0;
+}
+
+
+void ack (int fd)
+{
+ char buf[3];
+
+ buf[0] = 0;
+ buf[1] = 0x38;
+ buf[2] = 0xff ^ buf[0] ^ buf[1];
+
+ write (fd, buf, sizeof (buf));
+
+}
+
+
+void msg (char *account, char *event, char *ascii)
+{
+ printf ("%s %64s %s\n", account, event, ascii);
+}
+
+
+int rx_pkt (int fd, unsigned char *pkt, unsigned len)
+{
+ unsigned char parity = 0xff;
+ unsigned i;
+
+ static char account[65];
+ static char event[65];
+ static char ascii[65];
+
+
+
+ for (i = 0; i < len; ++i)
+ parity ^= pkt[i];
+
+ if (parity) return -1;
+
+ len--;
+
+
+ switch (pkt[1]) {
+ case 0x23:
+ memcpy (account, &pkt[2], len - 2);
+ account[len - 2] = 0;
+ break;
+
+ case 0x4e:
+ case 0x4f:
+ memcpy (event, &pkt[2], len - 2);
+ event[len - 2] = 0;
+ break;
+
+ case 0x41:
+ memcpy (ascii, &pkt[2], len - 2);
+ ascii[len - 2] = 0;
+
+ msg (account, event, ascii);
+ break;
+ }
+
+
+ if (pkt[0] & 0x40) ack (fd);
+
+ return 0;
+}
+
+
+
+int rx (int fd)
+{
+ static unsigned char pkt[67];
+ static unsigned ptr;
+ unsigned char byte;
+ unsigned len;
+
+ if (read (fd, &byte, 1) != 1) {
+ ptr = 0;
+ return -1;
+ }
+
+ pkt[ptr++] = byte;
+
+ if (ptr > 2 && !valid_fn (pkt[1])) {
+ ptr = 0;
+ return 0;
+ }
+
+ len = pkt[0] & 0x3f;
+
+ if (ptr == (len + 3)) {
+ ptr = 0;
+ return rx_pkt (fd, pkt, len + 3);
+ }
+
+ return 0;
+}
+
+
+int main (int argc, char *argv)
+{
+ struct sockaddr_in sin;
+ struct timeval tv = {0};
+ int rc;
+ int fd;
+ int afd = -1;
+ fd_set rfds;
+ fd_set wfds;
+
+
+ fd = socket (PF_INET, SOCK_STREAM, 0);
+
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons (10002);
+ sin.sin_addr.s_addr = INADDR_ANY;
+
+ bind (fd, (struct sockaddr *)&sin, sizeof (sin));
+
+ listen (fd, 5);
+
+ tv.tv_sec = 5;
+
+ FD_ZERO (&wfds);
+
+ for (;;) {
+
+ FD_ZERO (&rfds);
+
+ FD_SET (fd, &rfds);
+
+ if (afd > 0)
+ FD_SET (afd, &rfds);
+
+ rc = select (afd > fd ? afd + 1 : fd + 1, &rfds, &wfds, NULL, &tv);
+
+ if ((!rc) && (afd > 0)) poll (afd);
+
+
+ if (FD_ISSET (fd, &rfds)) {
+ if (afd > 0) close (afd);
+
+ afd = accept (fd, NULL, NULL);
+ }
+
+ if ((afd > 0) && (FD_ISSET (afd, &rfds))) {
+ if (rx (afd)) {
+ close (afd);
+ afd = -1;
+ }
+ }
+
+ if (!tv.tv_sec && !tv.tv_usec)
+ tv.tv_sec = 5;
+
+
+
+
+ }
+}
+