From 7a17c3a4ea869a04041ff2568fd02ec676ab8dff Mon Sep 17 00:00:00 2001 From: ubq323 Date: Fri, 28 Oct 2022 00:48:14 +0100 Subject: large refactor continues --- Makefile | 22 +++++++---- bee.c | 19 ++++++++++ common.c | 31 +++++++++++++++ conf.h | 40 ++++++++++++++++++++ irc.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ irc.h | 29 ++++++++++++++ thing.c | 39 +------------------ util.c | 17 +++++++++ util.h | 16 ++++++++ 9 files changed, 297 insertions(+), 46 deletions(-) create mode 100644 bee.c create mode 100644 common.c create mode 100644 conf.h create mode 100644 irc.c create mode 100644 irc.h create mode 100644 util.c create mode 100644 util.h diff --git a/Makefile b/Makefile index df7073c..cb02b50 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/bee.c b/bee.c new file mode 100644 index 0000000..f7d1270 --- /dev/null +++ b/bee.c @@ -0,0 +1,19 @@ +#include "irc.h" + +#include + + +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 +#include + + +#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; +} + diff --git a/conf.h b/conf.h new file mode 100644 index 0000000..80d7181 --- /dev/null +++ b/conf.h @@ -0,0 +1,40 @@ +#ifndef conf_h_INCLUDED +#define conf_h_INCLUDED + +#include +#include +#include + +#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 + 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"); + break; + case '\n': + printf(""); + 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 512) { + fprintf(stderr,"my receive buffer is filled with NONSENSE!!!\n"); + return -1; + } + memmove(recv_buf, msg_start, remlen); + } + + return 0; +} diff --git a/irc.h b/irc.h new file mode 100644 index 0000000..a56379d --- /dev/null +++ b/irc.h @@ -0,0 +1,29 @@ +#ifndef irc_h_INCLUDED +#define irc_h_INCLUDED + +#include +#include +#include +#include +#include +#include + +#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 + diff --git a/thing.c b/thing.c index 6ea805a..3f84948 100644 --- a/thing.c +++ b/thing.c @@ -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 #include @@ -37,22 +16,6 @@ #include #include -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; diff --git a/util.c b/util.c new file mode 100644 index 0000000..c545724 --- /dev/null +++ b/util.c @@ -0,0 +1,17 @@ +#include "util.h" + +#include +#include + +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; +} diff --git a/util.h b/util.h new file mode 100644 index 0000000..f273e2f --- /dev/null +++ b/util.h @@ -0,0 +1,16 @@ +#ifndef util_h_INCLUDED +#define util_h_INCLUDED + +#include +#include +#include +#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 + -- cgit v1.2.3