irC

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

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

do some command parsing, sock_write uses va_args

Diffstat:
MirC.c | 129++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
1 file changed, 85 insertions(+), 44 deletions(-)

diff --git a/irC.c b/irC.c @@ -5,9 +5,11 @@ */ #include <stdio.h> #include <errno.h> +#include <ctype.h> #include <poll.h> #include <sys/socket.h> #include <sys/types.h> +#include <stdarg.h> #include <stdlib.h> #include <string.h> #include <unistd.h> @@ -16,54 +18,26 @@ #define BUF_LEN 1024 void usage(const char *); -int sock_write(int, char *); +int sock_write(int sfd, char *msg, ...); int sock_read(int); +int server_connect(char *nodename, char *servname); +char *get_next_word(char *); int main(int argc, char *argv[]) { char *nick; + int sfd; - 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)); + printf("connecting to %s...\n", argv[1]); + sfd = server_connect(argv[1], argv[2]); + if (sfd == -1) { 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; @@ -74,10 +48,7 @@ int main(int argc, char *argv[]) { 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); + sock_write(sfd, "NICK %s\r\nUSER %s 8 x :%s\r\n", nick, nick, nick); while (1) { pollret = poll(fds, 2, -1); @@ -96,6 +67,31 @@ int main(int argc, char *argv[]) { free(line); break; } + if (linelen && line[0] == '/') { + char *command = line; + command++; + char *channel; + switch (*command) { + case 'q': + /* QUIT */ + if (sock_write(sfd, "QUIT\r\n") != 0) { + free(line); + return 1; + } + free(line); + goto end; + case 'j': + /* JOIN */ + channel = get_next_word(line); + if (sock_write(sfd, "JOIN :%s", channel) != 0) { + free(line); + return 1; + } + break; + } + free(line); + continue; + } if (sock_write(sfd, line) != 0) { free(line); return 1; @@ -106,6 +102,7 @@ int main(int argc, char *argv[]) { fds[1].revents = 0; } +end: if (close(sfd) == -1) { perror("close"); return 1; @@ -113,19 +110,63 @@ int main(int argc, char *argv[]) { return 0; } +int server_connect(char *nodename, char *servname) { + int s, sfd; + struct addrinfo hints = {0}, *result, *rp; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + hints.ai_protocol = 0; + + s = getaddrinfo(nodename, servname, &hints, &result); + if (s != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); + return -1; + } + + 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; + + return sfd; +} + 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) { +char *get_next_word(char *line) { + while (!isspace(*line)) + line++; + while(isspace(*line)) + line++; + return line; +} + +int sock_write(int sfd, char *msg, ...){ + va_list ap; + va_start(ap, msg); + if (vdprintf(sfd, msg, ap) < 0) { perror("sock_write"); return 1; } + va_end(ap); return 0; }