diff options
-rw-r--r-- | Makefile | 22 | ||||
-rw-r--r-- | bee.c | 19 | ||||
-rw-r--r-- | common.c | 31 | ||||
-rw-r--r-- | conf.h | 40 | ||||
-rw-r--r-- | irc.c | 130 | ||||
-rw-r--r-- | irc.h | 29 | ||||
-rw-r--r-- | thing.c | 39 | ||||
-rw-r--r-- | util.c | 17 | ||||
-rw-r--r-- | util.h | 16 |
9 files changed, 297 insertions, 46 deletions
@@ -1,21 +1,27 @@ .POSIX: -.SUFFIXES: +.SUFFIXES: .c .o CFLAGS=-Wall CC=cc debug=-g -DDEBUG -DLOCAL -fs=thing.c -all: thing +OBJS=bee.o irc.o util.o -thing: $(fs) - $(CC) $(CFLAGS) -o thing $(fs) +all: apiobot +apiobot: $(OBJS) + $(CC) $(CFLAGS) -o apiobot $(OBJS) debug: - $(CC) $(CFLAGS) $(debug) -o thing $(fs) + $(CC) $(CFLAGS) $(debug) -o apiobot $(OBJS) + +.c.o: + $(CC) -c $< $(CFLAGS) -o $@ run: all - ./thing + ./apiobot dr: debug - ./thing + ./apiobot + +clean: + rm *.o apiobot @@ -0,0 +1,19 @@ +#include "irc.h" + +#include <stdio.h> + + +int +main() +{ + if (!irc_connect()) { fputs("irc_connect\n",stderr); return 1; } + if (!irc_handshake()) { fputs("irc_handshake\n",stderr); return 1; } + + int x; + do { + x = irc_recv(); + } while (!x); + + return 0; +} + diff --git a/common.c b/common.c new file mode 100644 index 0000000..f217001 --- /dev/null +++ b/common.c @@ -0,0 +1,31 @@ +#include <stdio.h> +#include <string.h> + + +#define SOCKDIR "/run/apionet" + +int +channel_socket_path(char chname[], char out[], size_t lim) +{ + if (strlen(chname) > 16) return -1; + if (snprintf(out, lim, SOCKDIR "/apionet.%s.sock", chname) >= lim) + return -1; + return 0; +} + +char *channels[] = { + "a","b","robots","jonathan","secret-channel",NULL, +}; + +int +main() +{ + char b[200]; + for (int i = 0; channels[i]; i++) { + memset(b,0,200); + channel_socket_path(channels[i], b, 200); + printf("%s\n",b); + } + return 0; +} + @@ -0,0 +1,40 @@ +#ifndef conf_h_INCLUDED +#define conf_h_INCLUDED + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifdef LOCAL + #define HOST "0.0.0.0" + #define PORT "6971" + #define SOCKETNAME "bees.sock" + #define SOCKETGROUP "cdrom" +#else + #define HOST "ubq323.website" + #define PORT "6667" + #define SOCKETNAME "/srv/apiobot/bees.sock" + #define SOCKETGROUP "apionet" +#endif + +#ifdef DEBUG + #define DP(x) puts(x) + #define DPn(name,x,len) \ + do { \ + char *__xxx = strndup(x,len); \ + printf(name " [%s]\n",__xxx); \ + free(__xxx); \ + } while (0) +#else + #define DP(x) + #define DPn(n,x,l) +#endif + +#define NICK "Bee" +#define USERNAME "apiobot" +#define REALNAME "apiobot" +#define CHANNEL "#a" + + +#endif // conf_h_INCLUDED + @@ -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; +} @@ -0,0 +1,29 @@ +#ifndef irc_h_INCLUDED +#define irc_h_INCLUDED + +#include <stddef.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <netdb.h> + +#define IRC_RECVBUF_SIZE 1024 + +extern int g_ircsock; + +// connects to the irc server, as defined in config.h +// returns -1 on failure. +int irc_connect(); + +int irc_handshake(); + +// reads from irc socket into its buffer. +// if a full message / many full messages are available, handles them all. +int irc_recv(); + +// sends a string to the irc socket. returns -1 on failure. +int irc_sendall(char msg[], size_t len); + +#endif // irc_h_INCLUDED + @@ -1,25 +1,4 @@ -#ifdef LOCAL -#define HOST "0.0.0.0" -#define PORT "6971" -#define SOCKETNAME "bees.sock" -#else -#define HOST "ubq323.website" -#define PORT "6667" -#define SOCKETNAME "/srv/apiobot/bees.sock" -#endif - -#ifdef DEBUG -#define DP(x) puts(x) -#else -#define DP(x) -#endif - -#define NICK "Bee" -#define USERNAME "apiobot" -#define REALNAME "apiobot" -#define CHANNEL "#a" - -#define SOCKETGROUP "apionet" +#include "conf.h" #include <stdio.h> #include <stdlib.h> @@ -37,22 +16,6 @@ #include <arpa/inet.h> #include <netinet/in.h> -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); -#ifdef DEBUG - char *the = strndup(buf, len); - printf("SEND [%s]\n",the); - free(the); -#endif - return total_sent; -} int irc_connect() { struct addrinfo hints; @@ -0,0 +1,17 @@ +#include "util.h" + +#include <sys/types.h> +#include <sys/socket.h> + +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); + DPn("SEND",buf,len); + return total_sent; +} @@ -0,0 +1,16 @@ +#ifndef util_h_INCLUDED +#define util_h_INCLUDED + +#include <sys/types.h> +#include <sys/socket.h> +#include <stddef.h> +#include "conf.h" + +// repeatedly call send until all the data has been sent down +// the socket. +ssize_t sendall(int sockfd, void *buf, size_t len); + + + +#endif // util_h_INCLUDED + |