aboutsummaryrefslogtreecommitdiff
path: root/thing.c
diff options
context:
space:
mode:
Diffstat (limited to 'thing.c')
-rw-r--r--thing.c327
1 files changed, 0 insertions, 327 deletions
diff --git a/thing.c b/thing.c
deleted file mode 100644
index 3f84948..0000000
--- a/thing.c
+++ /dev/null
@@ -1,327 +0,0 @@
-#include "conf.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <grp.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-
-
-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;
- }
-
- struct addrinfo *cur;
- for (cur = res; cur != NULL; cur = cur->ai_next) {
- if ((sockfd = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol)) == -1) {
- perror("socket");
- continue;
- }
- if (connect(sockfd, cur->ai_addr, cur->ai_addrlen) != 0) {
- perror("connect");
- continue;
- }
- goto success;
- }
- return -1;
- success:
- 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) {
- DP("irc_handle...");
-#ifdef DEBUG
- char *the = strndup(start,end-start);
- printf("HANDLE [%s]\n",the);
- free(the);
-#endif
-
- if (strncmp(start, "PING", 4) == 0) {
- start[1] = 'O';
- sendall(sockfd, start, end-start);
- start[1] = 'I';
- return;
- }
-
- char *msg = start;
- size_t msglen = end-start;
- if (msglen > 512) {
- fprintf(stderr,"message longer than 512 bytes, this is bad probably\n");
- return;
- }
-
- // this is quite bad
- // i should change it one day
-
- char msg_source[512];
- msg_source[0] = '\0';
-
- char msg_command[512];
- msg_command[0] = '\0';
-
- char msg_params[16][512];
- for (int i = 0; i < 16; i++)
- msg_params[i][0] = '\0';
-
- int i = 0;
- if (msg[0] == ':') {
- for (i = 1; i < msglen && msg[i] != ' ' && msg[i] != '\r' && msg[i] != '\n'; i++)
- msg_source[i-1] = msg[i];
- msg_source[i-1] = '\0';
- i++;
- }
- int j;
- for (j=0; i < msglen && msg[i] != ' ' && msg[i] != '\r' && msg[i] != '\n'; i++, j++)
- msg_command[j] = msg[i];
- msg_command[j] = '\0';
- i++;
-
- for (int px = 0; px < 16; px++) {
- if (i >= msglen) break;
- if (msg[i] == ':') {
- memcpy(msg_params[px],&msg[i+1],msglen-i-2);
- msg_params[px][msglen-i-1] = '\0';
- break;
- }
- for (j = 0; i < msglen && msg[i] != ' ' && msg[i] != '\r' && msg[i] != '\n'; i++, j++)
- msg_params[px][j] = msg[i];
- msg_params[px][j] = '\0';
- i++;
- }
-#ifdef DEBUG
- printf("source [%s]\n",msg_source);
- printf("command [%s]\n",msg_command);
- printf("params: ");
- for (int px = 0; px < 16; px++)
- printf("%d:[%s] ",px,msg_params[px]);
- printf("\n");
-#endif
-
-
-
-}
-
-#define IRC_RECVBUF_SIZE 1024
-char irc_recvbuf[IRC_RECVBUF_SIZE];
-const char *irc_recvbuf_end = &irc_recvbuf[IRC_RECVBUF_SIZE];
-char *irc_recvbuf_cur = &irc_recvbuf[0];
-
-void irc_recv(int sockfd) {
- DP("irc_recv...");
-
-
- ssize_t s = recv(sockfd, irc_recvbuf_cur, irc_recvbuf_end-irc_recvbuf_cur, 0);
-
- if (s == 0) {
- fputs("socket eof\n",stderr);
- exit(3); // todo: reconnecting properly
- }
-
- if (s == -1) {
- perror("recv");
- exit(1);
- }
-#ifdef DEBUG
- char *the = strndup(irc_recvbuf_cur,s);
- printf("RECV %ld [%s]\n",s,the);
- free(the);
-#endif
- char *buf_last = irc_recvbuf_cur+s;
-
- char *cur;
- char *start = irc_recvbuf;
- for (cur = irc_recvbuf; cur < buf_last; cur++) {
- if (*cur=='\r' && *(cur+1) == '\n') {
- irc_handle(sockfd, start, cur+2);
- start = cur+2;
- cur++;
- }
- }
-
- if (start == buf_last) {
- // all done
- irc_recvbuf_cur = irc_recvbuf;
- } else {
- size_t remainder_len = buf_last-start;
- // if we are to support ircv3 message tags then this should be
- // quite a lot bigger, but i don't care about that
- // (buffer would have to be bigger too, at least 16384 i think)
- if (remainder_len > 512) {
- fputs("message longer than 512 bytes! this indicates a broken server\n",stderr);
- exit(2);
- }
- memmove(irc_recvbuf,start,remainder_len);
- irc_recvbuf_cur = irc_recvbuf+remainder_len;
- }
-}
-
-
-
-int unix_setup() {
- unlink(SOCKETNAME);
-
- int sock = socket(AF_UNIX, SOCK_DGRAM, 0);
- if (sock == -1) {
- perror("(unix) socket");
- return -1;
- }
-
- struct sockaddr_un name;
- memset(&name, 0, sizeof name);
- name.sun_family = AF_UNIX;
- strncpy(name.sun_path, SOCKETNAME, (sizeof name.sun_path)-1);
- if (bind(sock, (const struct sockaddr*)&name, sizeof name) == -1) {
- perror("(unix) bind");
- return -1;
- }
-
- // set group and permissions on socket
- long buflen = sysconf(_SC_GETGR_R_SIZE_MAX);
- buflen = (buflen == -1) ? 1024 : buflen;
- char *buf = malloc(buflen);
- struct group grp;
- struct group *res;
- errno = 0;
- // get group gid from name
- getgrnam_r(SOCKETGROUP,&grp,buf,buflen,&res);
- if (res == NULL) {
- if (errno != 0)
- perror("getgrnam_r");
- else
- fprintf(stderr,"group %s does not exist",SOCKETGROUP);
- free(buf);
- return -1;
- }
- free(buf);
-
- // set socket's group
- if (chown(SOCKETNAME,-1,grp.gr_gid) == -1) {
- perror("chown");
- return -1;
- }
-
- struct stat sb;
- if (stat(SOCKETNAME,&sb) == -1) {
- perror("stat");
- return -1;
- }
- if (chmod(SOCKETNAME,sb.st_mode|S_IWGRP) == -1) {
- perror("chmod");
- return -1;
- }
-
-
- return sock;
-}
-
-
-
-int main(int argc, char *argv[]) {
-
- int ircsock = irc_connect();
- if (ircsock == -1) {
- return 1;
- }
- if (irc_handshake(ircsock) != 0) {
- perror("irc_handshake");
- return 1;
- }
-
- int unixsock = unix_setup();
- if (unixsock == -1)
- return 1;
-
- struct pollfd pollfds[2] = {
- {
- .fd = unixsock,
- .events = POLLIN,
- },
- {
- .fd = ircsock,
- .events = POLLIN,
- },
- };
-#ifdef DEBUG
- printf("POLLIN %d POLLERR %d POLLHUP %d\n",POLLIN,POLLERR,POLLHUP);
-#endif
-
- for (;;) {
- int r;
- if ((r = poll(pollfds, 2, -1)) == -1) {
- perror("poll");
- return 1;
- }
-#ifdef DEBUG
- printf("sock %d unix %d\n",pollfds[1].revents, pollfds[0].revents);
-#endif
-
-
- 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) {
- DP("socket...");
- // socket
- irc_recv(ircsock);
- }
- if (pollfds[0].revents & POLLIN) {
- unsigned char buf[128];
- ssize_t amt;
- if ((amt = recv(unixsock,buf,sizeof buf,0)) == -1) {
- perror("(unix) read");
- return 1;
- }
- for (size_t i = 0; i < amt; i++)
- if (buf[i] == '\r' || buf[i] == '\n' || buf[i] == '\0')
- buf[i] = ' ';
- char msg[] = "PRIVMSG "CHANNEL" :";
-
- if (sendall(ircsock, msg, sizeof msg-1) == -1) { perror("sendall"); return 1; }
- if (sendall(ircsock, buf, amt) == -1) { perror("sendall"); return 1; }
- if (sendall(ircsock, "\r\n", 2) == -1) { perror("sendall"); return 1; }
-
- }
- }
-
-
-
-
- return 0;
-}