diff options
Diffstat (limited to 'irc.c')
-rw-r--r-- | irc.c | 130 |
1 files changed, 130 insertions, 0 deletions
@@ -0,0 +1,130 @@ + +#include "irc.h" +#include "conf.h" +#include "util.h" + +int g_ircsock = -1; + +int +irc_connect() +{ + struct addrinfo hints; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + int status; + struct addrinfo *res; + if ((status = getaddrinfo(HOST, PORT, &hints, &res)) != 0) { + fprintf(stderr, "gettaddrinfo fail: %s\n", gai_strerror(status)); + return -1; + } + + int sockfd; + for (; res != NULL; res = res->ai_next) { + if ((sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) { + perror("socket"); + continue; + } + if (connect(sockfd, res->ai_addr, res->ai_addrlen) != 0) { + perror("connect"); + continue; + } + goto success; + } + return -1; +success: + g_ircsock = sockfd; + return 0; +} + +int +irc_sendall(char msg[], size_t len) +{ + return sendall(g_ircsock, msg, len); +} + +int +irc_handshake() +{ + char msg[] = "NICK "NICK"\r\nUSER "USERNAME" 0 * :"REALNAME"\r\nJOIN "CHANNEL"\r\n"; + return irc_sendall(msg, sizeof msg-1); +} + + + +/* **** */ + +static void +handle(char msg[], size_t len) +{ + printf("HANDLE {"); + int i; + for (i=0; i<len; i++) { + switch (msg[i]) { + case '\r': + printf("<CR>"); + break; + case '\n': + printf("<LF>"); + break; + default: + putchar(msg[i]); + break; + } + } + printf("}\n"); +} + + +#define RECVBUF_SIZE 1024 +char recv_buf[RECVBUF_SIZE]; +char *recv_cur = &recv_buf[0]; +// one past the end +char *recv_end = &recv_buf[RECVBUF_SIZE]; + +// i can't be bothered to implement a proper circular buffer +// (it'd be more effort than this anyway, for very little gain) +// the start of the buffer (index 0) is always the start of the buffer +// then cur points to one past the most recently recieved byte. +// after processing a message, if there's more stuff in the buffer, memmove it back. + +int +irc_recv() +{ + ssize_t amt; + if ((amt = recv(g_ircsock, recv_cur, recv_end-recv_cur, 0)) == -1) { + // socket error + perror("recv"); + return -1; + } else if (amt == 0) { + // eof + fprintf(stderr,"irc eof\n"); + return -1; + } + + // find the end of a message + char *c; + char *end = recv_cur+amt; + char *msg_start = recv_buf; + for (c=recv_buf; c<end; c++) { + if (*c == '\r' && *(c+1) == '\n') { + handle(msg_start, (c+2)-msg_start); + msg_start = c+2; + c++; + } + } + + if (msg_start == end) + recv_cur = recv_buf; + else { + size_t remlen = end - msg_start; + if (remlen > 512) { + fprintf(stderr,"my receive buffer is filled with NONSENSE!!!\n"); + return -1; + } + memmove(recv_buf, msg_start, remlen); + } + + return 0; +} |