diff options
-rw-r--r-- | thing.c | 210 |
1 files changed, 210 insertions, 0 deletions
@@ -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; +} |