irC

an attempt at writing an irc "client"
git clone git://bvnf.space/irC.git
Log | Files | Refs | README

commit adaf953fdaa5da05d0c4fc100ac13bcd5eb1b763
parent 1c58927f7c75430f54b660733fc7d10a01b592cc
Author: aabacchus <ben@bvnf.space>
Date:   Tue,  5 Oct 2021 14:03:01 +0100

main.c -> irC.c

Diffstat:
MMakefile | 4++--
AirC.c | 145+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dmain.c | 124-------------------------------------------------------------------------------
3 files changed, 147 insertions(+), 126 deletions(-)

diff --git a/Makefile b/Makefile @@ -2,8 +2,8 @@ XCFLAGS = $(CFLAGS) -Wall -Wextra -Wpedantic -g -Og -D_XOPEN_SOURCE=700 -irC: main.c - $(CC) $(XCFLAGS) $(LDFLAGS) main.c -o $@ +irC: irC.c + $(CC) $(XCFLAGS) $(LDFLAGS) irC.c -o $@ nc: nc.c $(CC) $(XCFLAGS) $(LDFLAGS) nc.c -o $@ diff --git a/irC.c b/irC.c @@ -0,0 +1,145 @@ +/* + * This file is in the public domain. + * Author: Ben Fuller + * + */ +#include <stdio.h> +#include <errno.h> +#include <poll.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <netdb.h> + +#define BUF_LEN 1024 + +void usage(const char *); +int sock_write(int, char *); +int sock_read(int); + +int main(int argc, char *argv[]) { + char *nick; + + int s, sfd; + struct addrinfo hints, *result, *rp; + if (argc < 4) { + usage(argv[0]); + } + nick = argv[3]; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + hints.ai_protocol = 0; + + + s = getaddrinfo(argv[1], argv[2], &hints, &result); + if (s != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); + return 1; + } + + printf("connecting to %s...\n", result->ai_canonname); + + sfd = socket(result->ai_family, result->ai_socktype, result->ai_protocol); + for (rp = result; rp != NULL; rp = rp->ai_next) { + sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (sfd == -1) + continue; + + if (connect(sfd, rp->ai_addr, rp->ai_addrlen) == 0) + break; + + if (close(sfd) == -1) { + perror("close"); + return 1; + } + } + + freeaddrinfo(result); + + if (rp == NULL) + return 1; + + size_t linelen = 0; + + int pollret; + struct pollfd fds[2]; + fds[0].fd = 0; + fds[0].events = POLLIN; + fds[1].fd = sfd; + fds[1].events = POLLIN | POLLWRBAND; + + /* connect as nick */ + size_t nicklen = strlen(nick); + char buf[3 * nicklen + 21]; + snprintf(buf, 4 * nicklen + 21, "NICK %s\r\nUSER %s 8 x :%s\r\n", nick, nick, nick); + sock_write(sfd, buf); + + while (1) { + pollret = poll(fds, 2, -1); + if (pollret <= 0) { + if (pollret == 0 || errno == EAGAIN) + continue; + perror("poll"); + return 1; + } + if (fds[1].revents & POLLIN) + if (sock_read(sfd) != 0) + return 1; + if (fds[0].revents & POLLIN) { + char *line = NULL; + if (getline(&line, &linelen, stdin) == -1) { + free(line); + break; + } + if (sock_write(sfd, line) != 0) { + free(line); + return 1; + } + free(line); + } + fds[0].revents = 0; + fds[1].revents = 0; + } + + if (close(sfd) == -1) { + perror("close"); + return 1; + } + return 0; +} + +void usage(const char *argv0){ + fprintf(stderr, "usage: %s host port nick\n", argv0); + exit(1); +} + +int sock_write(int sfd, char *msg){ + ssize_t ret; + int len = strlen(msg); + ret = send(sfd, msg, len, 0); + if (ret != (ssize_t) len) { + perror("sock_write"); + return 1; + } + return 0; +} + +int sock_read(int sfd){ + unsigned char buff[BUF_LEN]; + memset(&buff, 0, sizeof buff); + ssize_t ret; + + ret = recv(sfd, buff, BUF_LEN, 0); + + if (ret < 0) { + perror("sock_read"); + return 1; + } + printf("%s", buff); + return 0; +} diff --git a/main.c b/main.c @@ -1,124 +0,0 @@ -#include <stdio.h> -#include <errno.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <netdb.h> - -#define BUF_LEN 512 - -int sfd; -void usage(const char *argv0); -int ircWrite(char *format, ...); -int ircRead(); -int ircQuit(); - -int main(int argc, char *argv[]) { - int s, c; - struct addrinfo hints, *result; - if (argc < 3) { - usage(argv[0]); - } - - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - - if ((s = getaddrinfo(argv[1], argv[2], &hints, &result)) != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); - exit(EXIT_FAILURE); - } - - sfd = socket(result->ai_family, result->ai_socktype, result->ai_protocol); - - if (sfd < 0) { - fprintf(stderr, "error creating socket\n"); - perror("socket"); - return errno; - } - - c = connect(sfd, result->ai_addr, result->ai_addrlen); - - fprintf(stderr, "connecting to %s\n", result->ai_canonname); - if (c == -1) { - fprintf(stderr, "error connecting to %s\n", result->ai_canonname); - close(sfd); - perror("connect"); - return errno; - } - freeaddrinfo(result); - - // connect as USER - char *startmsg; - startmsg = "NICK hirC\r\nUSER hirC- 8 x :hirC-\r\n"; - ircWrite(startmsg); - printf("%s", startmsg); - ircRead(); - ircWrite("JOIN #abcdefghhh\r\n"); - printf("JOIN #abcdefghhh\r\n"); - ircRead(); - printf("we've read\n"); - ircWrite("PRIVMSG #abcdefghhh :hi there!\r\n"); - printf("PRIVMSG #abcdefghhh :hi there!\r\n"); - ircRead(); - printf("we've read after PRIVMSG\n"); - - char *quit = 0; - size_t linelen = 0; - printf("gonna go into loop\n"); - while (quit == 0) { - char *line = NULL; - //printf("going into loop\n"); - // read from stdin - //printf("gonna getline\n"); - if (getline(&line, &linelen, stdin) == -1) quit = (char *) 2; - //printf("gotline: %s\n", line); - if (strncmp(line, "/quit", 5) == 0) return ircQuit(); //quit = (char *) 1; - //printf("strncmp\n"); - ircWrite(line); - free(line); - ircRead(); - } - - close(sfd); - return 0; -} - -void usage(const char *argv0){ - fprintf(stderr, "usage: %s host port\n", argv0); - exit(1); -} - -int ircWrite(char *msg, ...){ - ssize_t ret; - int len = strlen(msg); - ret = send(sfd, msg, len, 0); - if (ret != (ssize_t) len) { - perror("ircWrite"); - return errno; - } - return 0; -} - -int ircRead(){ - char buff[BUF_LEN]; - memset(&buff, 0, sizeof buff); - ssize_t ret; - - ret = recv(sfd, buff, BUF_LEN, 0); - - printf("Received %zd bytes:\n%s\n", ret, buff); - if (ret < 0) { - perror("ircRead"); - return errno; - } - return 0; -} - -int ircQuit(){ - ircWrite("QUIT"); - return ircRead(); -}