aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorubq323 <ubq323@ubq323.website>2021-12-14 15:50:29 +0000
committerubq323 <ubq323@ubq323.website>2021-12-14 15:50:29 +0000
commita0069d69d064ba98176c7c19dc6c503909661ed0 (patch)
tree1d7f5db0363f8548dc6cba740a80543d4f8f0dec
initial commit
-rw-r--r--thing.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/thing.c b/thing.c
new file mode 100644
index 0000000..2ffd843
--- /dev/null
+++ b/thing.c
@@ -0,0 +1,210 @@
+#ifdef LOCAL
+#define HOST "0.0.0.0"
+#define PORT "6970"
+#else
+#define HOST "ubq323.website"
+#define PORT "6667"
+#endif
+
+#define NICK "ffbm"
+#define USERNAME "ffbm"
+#define REALNAME ",flappy fly bird man?"
+#define CHANNEL "#a"
+
+#define PIPE "/run/apionet.pipe"
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+int hasjoined = 0;
+
+ssize_t sendall(int sockfd, void *buf, size_t len) {
+ ssize_t total_sent = 0;
+ ssize_t sent;
+ do {
+ if ((sent = send(sockfd, buf+total_sent, len-total_sent, 0)) == -1) {
+ return -1;
+ }
+ total_sent += sent;
+ } while (total_sent < len);
+ total_sent = 0;
+ do {
+ if ((sent = write(0, buf+total_sent, len-total_sent)) == -1) {
+ return -1;
+ }
+ total_sent += sent;
+ } while (total_sent < len);
+ return total_sent;
+}
+
+int irc_connect() {
+ struct addrinfo hints;
+ int status, sockfd;
+ struct addrinfo *res;
+
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ // assuming the first one is valid because it normally is
+
+ if ((status = getaddrinfo(HOST, PORT, &hints, &res)) != 0) {
+ fprintf(stderr, "getaddrinfo fail: %s\n", gai_strerror(status));
+ return -1;
+ }
+
+ if ((sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {
+ perror("socket");
+ return -1;
+ }
+ if (connect(sockfd, res->ai_addr, res->ai_addrlen) != 0) {
+ perror("connect");
+ return -1;
+ }
+ return sockfd;
+}
+
+int irc_handshake(int sockfd) {
+ char msg[] = "NICK "NICK"\r\nUSER "USERNAME" 0 * :"REALNAME"\r\nJOIN "CHANNEL"\r\n";
+ if (sendall(sockfd, msg, sizeof msg-1) == -1) {
+ return -1;
+ }
+ return 0;
+}
+
+void irc_handle(int sockfd, char *start, char *end) {
+ if (strncmp(start, "PING", 4) == 0) {
+ start[1] = 'O';
+ sendall(sockfd, start, end-start);
+ start[1] = 'I';
+ }
+ char *str = strndup(start, end-start);
+ printf("[%s]\n",str);
+ free(str);
+}
+
+void irc_recv(int sockfd) {
+ char recvbuf[1024];
+ ssize_t amt;
+ if ((amt = recv(sockfd, recvbuf, 1024, 0)) == -1) {
+ perror("recv");
+ exit(1);
+ }
+
+ char *start = &recvbuf[0];
+ char *cur;
+ char *end = start+amt ;
+ for (cur = start; cur < end; cur++) {
+ if (*cur == '\r' && *(cur+1) == '\n') {
+ irc_handle(sockfd, start, cur+2);
+ start = cur + 2;
+ cur = start;
+ }
+ }
+}
+
+int main(int argc, char *argv[]) {
+ // this only works on linux, i think.
+ // sorry
+ int pipefd = open(PIPE, O_RDWR|O_NONBLOCK);
+ if (pipefd == -1) {
+ perror("(pipe) open");
+ return 1;
+ }
+
+ printf("bees\n");
+ int sockfd = irc_connect();
+ if (sockfd == -1) {
+ return 1;
+ }
+ if (irc_handshake(sockfd) != 0) {
+ perror("irc_handshake");
+ return 1;
+ }
+
+ // setup pollfds
+ struct pollfd pollfds[2] = {
+ {
+ .fd = pipefd,
+ .events = POLLIN,
+ },
+ {
+ .fd = sockfd,
+ .events = POLLIN,
+ },
+ };
+ printf("POLLIN %d POLLERR %d POLLHUP %d\n",POLLIN,POLLERR,POLLHUP);
+ for (;;) {
+ int r;
+ if ((r = poll(pollfds, 2, -1)) == -1) {
+ perror("poll");
+ return 1;
+ }
+ printf("poll %d\n",r);
+ printf("sock %d pipe %d\n",pollfds[1].revents, pollfds[0].revents);
+
+ if (pollfds[1].revents & POLLHUP) {
+ // socket closed, probably
+ puts("socket hup");
+ break;
+ }
+ if (pollfds[1].revents & POLLERR) {
+ // socket error
+ puts("socket err");
+ break;
+ }
+ if (pollfds[1].revents & POLLIN) {
+ // socket
+ char buf[1];
+ // there is probably a better way of doing this
+ // but if there is, i don't know what it is
+ ssize_t h = recv(sockfd, buf, 1, MSG_PEEK);
+ if (h<0) {
+ perror("recv");
+ return -1;
+ } else if (h == 0) {
+ // eof ish
+ puts("socket end");
+ break;
+ } else {
+ irc_recv(sockfd);
+ }
+ }
+ if (pollfds[0].revents & POLLIN) {
+ puts("pipe");
+ ssize_t amt;
+ unsigned char buf[128];
+ if ((amt = read(pipefd, buf, 128)) == -1) {
+ perror("(pipe) read");
+ return 1;
+ }
+ for (size_t i = 0; i < amt; i++) {
+ if (buf[i] == '\r' || buf[i] == '\n' || buf[i] < ' ') {
+ buf[i] = ' ';
+ }
+ }
+ char msg[] = "PRIVMSG "CHANNEL" :";
+
+ if (sendall(sockfd, msg, sizeof msg-1) == -1) { perror("sendall"); exit(1); }
+ if (sendall(sockfd, buf, amt) == -1) { perror("sendall"); exit(1); }
+ if (sendall(sockfd, "\r\n", 2) == -1) { perror("sendall"); exit(1); }
+ }
+ }
+
+
+
+
+ return 0;
+}