aboutsummaryrefslogtreecommitdiff
path: root/irc.c
diff options
context:
space:
mode:
Diffstat (limited to 'irc.c')
-rw-r--r--irc.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/irc.c b/irc.c
new file mode 100644
index 0000000..5c206bd
--- /dev/null
+++ b/irc.c
@@ -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;
+}