#include #include #include #include #include #include #include #include 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; } }