]> git.armaanb.net Git - sic.git/commitdiff
merged kris' changes into mainstream sic
authorAnselm R Garbe <anselm@garbe.us>
Sat, 28 Nov 2009 12:16:35 +0000 (12:16 +0000)
committerAnselm R Garbe <anselm@garbe.us>
Sat, 28 Nov 2009 12:16:35 +0000 (12:16 +0000)
LICENSE
config.mk
kris/Makefile [deleted symlink]
kris/config.mk [deleted symlink]
kris/sic.c [deleted file]
kris/util.c [deleted file]
sic.c
util.c [new file with mode: 0644]

diff --git a/LICENSE b/LICENSE
index d1435a1f3b2323ff79b7b627827cd1b71060bf19..c6d9111ecac4d3b170b20f6ce4af38eaa081fd2b 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,8 +1,8 @@
 MIT/X Consortium License
 
-
-© 2005-2009 Anselm R Garbe <garbeam at gmail dot com>
-© 2008-2009 Jeroen Schot <schot at a-eskwadraat dot nl>
+© 2005-2009 Anselm R Garbe <anselm@garbe.us>
+© 2008-2009 Jeroen Schot <schot@a-eskwadraat.nl>
+© 2007-2009 Kris Maglione <maglione.k@gmail.com>
 © 2005 Nico Golde <nico at ngolde dot de>
 
 Permission is hereby granted, free of charge, to any person obtaining a
index fe059aa8bd7785fc7f10c0d13db0ca7e6b145d66..f8d1751b2aacbcafc09abbe6a81d10feff100b2a 100644 (file)
--- a/config.mk
+++ b/config.mk
@@ -1,5 +1,5 @@
 # sic version
-VERSION = 1.0
+VERSION = 1.1
 
 # Customize below to fit your system
 
diff --git a/kris/Makefile b/kris/Makefile
deleted file mode 120000 (symlink)
index d0b0e8e..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../Makefile
\ No newline at end of file
diff --git a/kris/config.mk b/kris/config.mk
deleted file mode 120000 (symlink)
index f2cf390..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../config.mk
\ No newline at end of file
diff --git a/kris/sic.c b/kris/sic.c
deleted file mode 100644 (file)
index 7835fec..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/* ? 2005-2007 Anselm R. Garbe <garbeam at gmail dot com>
- * ? 2007 Kris Maglione <fbsdaemon@gmail.com>
- * ? 2005 Nico Golde <nico at ngolde dot de>
- * See LICENSE file for license details.
- */
-#include <ctype.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#define nil ((void*)0)
-typedef unsigned short ushort;
-
-#define PINGTIMEOUT 300
-
-static char*   host = "irc.oftc.net";
-static char*   port = "ircd";
-static char*   password;
-static char    nick[32];
-
-static char bufin[4096];
-static char bufout[4096];
-static char channel[256];
-static time_t trespond;
-static FILE *srv;
-
-#include "util.c"
-
-static void
-pout(char *channel, char *fmt, ...) {
-       static char timestr[18];
-       time_t t;
-
-       va_buf(bufout, fmt);
-
-       t = time(nil);
-       strftime(timestr, sizeof timestr, "%D %R", localtime(&t));
-       fprintf(stdout, "%-12s: %s %s\n", channel, timestr, bufout);
-}
-
-static void
-sout(char *fmt, ...) {
-       va_buf(bufout, fmt);
-       fprintf(srv, "%s\r\n", bufout);
-}
-
-static void
-privmsg(char *channel, char *msg) {
-       if(channel[0] == '\0') {
-               pout("", "No channel to send to");
-               return;
-       }
-       pout(channel, "<%s> %s", nick, msg);
-       sout("PRIVMSG %s :%s", channel, msg);
-}
-
-static void
-parsein(char *msg) {
-       char *p;
-       char c;
-
-       if(msg[0] == '\0')
-               return;
-       msg = ctok(&msg, '\n');
-       if(msg[0] != ':') {
-               privmsg(channel, msg);
-               return;
-       }
-       c = *++msg;
-       if(!c || !isspace(msg[1]))
-               sout("%s", msg);
-       else {
-               if(msg[1])
-                       msg += 2;
-               switch(c) {
-               case 'j':
-                       sout("JOIN %s", msg);
-                       if(channel[0] == '\0')
-                               strlcpy(channel, msg, sizeof channel);
-                       break;
-               case 'l':
-                       p = tok(&msg);
-                       if(!*p)
-                               p = channel;
-                       if(!*msg)
-                               msg = "sic - 250 LOC are too much!";
-                       sout("PART %s :%s", p, msg);
-                       break;
-               case 'm':
-                       p = tok(&msg);
-                       privmsg(p, msg);
-                       break;
-               case 's':
-                       strlcpy(channel, msg, sizeof channel);
-                       break;
-               default:
-                       sout("%c %s", c, msg);
-                       break;
-               }
-       }
-}
-
-static void
-parsesrv(char *msg) {
-       char *cmd, *p, *usr, *txt;
-
-       usr = host;
-       if(!msg || !*msg)
-               return;
-       if(msg[0] == ':') {
-               msg++;
-               p = tok(&msg);
-               if(!*msg)
-                       return;
-               usr = ctok(&p, '!');
-       }
-       txt = ctok(&msg, '\r');
-       msg = ctok(&txt, ':');
-       cmd = tok(&msg);
-       if(!strcmp("PONG", cmd))
-               return;
-       if(!strcmp("PRIVMSG", cmd))
-               pout(msg, "<%s> %s", usr, txt);
-       else if(!strcmp("PING", cmd))
-               sout("PONG %s", txt);
-       else {
-               pout(usr, ">< %s: %s", cmd, txt);
-               if(!strcmp("NICK", cmd) && !strcmp(usr, nick))
-                       strlcpy(nick, txt, sizeof nick);
-       }
-}
-
-int
-main(int argc, char *argv[]) {
-       int i, c;
-       struct timeval tv;
-       fd_set rd;
-
-       strlcpy(nick, getenv("USER"), sizeof nick);
-       for(i = 1; i < argc; i++) {
-               c = argv[i][1];
-               if(argv[i][0] != '-' || argv[i][2])
-                       c = -1;
-               switch(c) {
-               case 'h':
-                       if(++i < argc) host = argv[i];
-                       break;
-               case 'p':
-                       if(++i < argc) port = argv[i];
-                       break;
-               case 'n':
-                       if(++i < argc) strlcpy(nick, argv[i], sizeof nick);
-                       break;
-               case 'k':
-                       if(++i < argc) password = argv[i];
-                       break;
-               case 'v':
-                       eprint("sic-"VERSION", ©2005-2009 Kris Maglione, Anselm R. Garbe, Nico Golde\n");
-               default:
-                       eprint("usage: sic [-h host] [-p port] [-n nick] [-k keyword] [-v]\n");
-               }
-       }
-
-       /* init */
-       i = dial(host, port);
-       srv = fdopen(i, "r+");
-
-       /* login */
-       if(password)
-               sout("PASS %s", password);
-       sout("NICK %s", nick);
-       sout("USER %s localhost %s :%s", nick, host, nick);
-       fflush(srv);
-
-       setbuf(stdout, nil);
-       setbuf(srv, nil);
-
-       for(;;) { /* main loop */
-               FD_ZERO(&rd);
-               FD_SET(0, &rd);
-               FD_SET(fileno(srv), &rd);
-               tv.tv_sec = 120;
-               tv.tv_usec = 0;
-               i = select(fileno(srv) + 1, &rd, 0, 0, &tv);
-               if(i < 0) {
-                       if(errno == EINTR)
-                               continue;
-                       eprint("sic: error on select():");
-               }
-               else if(i == 0) {
-                       if(time(nil) - trespond >= PINGTIMEOUT)
-                               eprint("sic shutting down: parse timeout\n");
-                       sout("PING %s", host);
-                       continue;
-               }
-               if(FD_ISSET(fileno(srv), &rd)) {
-                       if(fgets(bufin, sizeof bufin, srv) == nil)
-                               eprint("sic: remote host closed connection\n");
-                       parsesrv(bufin);
-                       trespond = time(nil);
-               }
-               if(FD_ISSET(0, &rd)) {
-                       if(fgets(bufin, sizeof bufin, stdin) == nil)
-                               eprint("sic: broken pipe\n");
-                       parsein(bufin);
-               }
-       }
-       return 0;
-}
-
-
diff --git a/kris/util.c b/kris/util.c
deleted file mode 100644 (file)
index 33d5693..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-#define va_buf(buf, fmt) {\
-       va_list ap; \
-       va_start(ap, fmt); \
-       vsnprintf(buf, sizeof buf, fmt, ap); \
-       va_end(ap); \
-}
-
-static void
-eprint(const char *fmt, ...) {
-
-       va_buf(bufout, fmt);
-       fprintf(stderr, "%s", bufout);
-
-       if(fmt[0] && fmt[strlen(fmt)-1] == ':')
-               fprintf(stderr, " %s\n", strerror(errno));
-       exit(1);
-}
-
-static int
-dial(char *host, char *port) {
-       static struct addrinfo hints;
-       struct addrinfo *res, *r;
-       int srv;
-
-       memset(&hints, 0, sizeof hints);
-       hints.ai_family = AF_UNSPEC;
-       hints.ai_socktype = SOCK_STREAM;
-       if(getaddrinfo(host, port, &hints, &res) != 0)
-               eprint("error: cannot resolve hostname '%s':", host);
-       for(r = res; r; r = r->ai_next) {
-               if((srv = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1)
-                       continue;
-               if(connect(srv, r->ai_addr, r->ai_addrlen) == 0)
-                       break;
-               close(srv);
-       }
-       freeaddrinfo(res);
-       if(!r)
-               eprint("error: cannot connect to host '%s'\n", host);
-       return srv;
-}
-
-#define strlcpy _strlcpy
-static void
-strlcpy(char *to, const char *from, int l) {
-       memccpy(to, from, '\0', l);
-       to[l-1] = '\0';
-}
-
-static void
-eat(char **s, int (*p)(int), int r) {
-       char *q;
-
-       for(q=*s; *q && p(*q) == r; q++)
-               ;
-       *s = q;
-}
-
-static char*
-tok(char **s) {
-       char *p;
-
-       eat(s, isspace, 1);
-       p = *s;
-       eat(s, isspace, 0);
-       if(**s) *(*s)++ = '\0';
-       return p;
-}
-
-static char*
-ctok(char **s, int c) {
-       char *p, *q;
-
-       q = *s;
-       for(p=q; *p && *p != c; p++)
-               ;
-       if(*p) *p++ = '\0';
-       *s = p;
-       return q;
-}
-
-
diff --git a/sic.c b/sic.c
index 424ce4f16b01829afde94d423730355af09034e6..53f5aba9cb91bd7f408470cf6507417aabf5548e 100644 (file)
--- a/sic.c
+++ b/sic.c
-/* See LICENSE file for license details. */
+ /* See LICENSE file for license details. */
+#include <ctype.h>
 #include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
-#include <sys/socket.h>
-#include <sys/time.h>
 
-#define PINGTIMEOUT 300
-#define MAXMSG      4096
-#ifndef VERSION
-#define VERSION "dev"
-#endif
-
-static void die(const char *errstr, ...);
-static void printl(char *channel, char *msg);
-static void privmsg(char *channel, char *msg);
-static void parsein(char *msg);
-static void parsesrv(char *msg);
-static int readl(int fd, unsigned int len, char *buf);
-
-static char *host = "irc6.oftc.net";
-static char *port = "6667";
+static char *host = "irc.oftc.net";
+static char *port = "ircd";
+static char *password;
 static char nick[32];
-
-static char bufin[MAXMSG], bufout[MAXMSG];
+static char bufin[4096];
+static char bufout[4096];
 static char channel[256];
-static int srv;
 static time_t trespond;
+static FILE *srv;
+
+#include "util.c"
 
-void
-die(const char *errstr, ...) {
+static void
+pout(char *channel, char *fmt, ...) {
+       static char timestr[18];
+       time_t t;
        va_list ap;
-       va_start(ap, errstr);
-       vfprintf(stderr, errstr, ap);
+
+       va_start(ap, fmt);
+       vsnprintf(bufout, sizeof bufout, fmt, ap);
        va_end(ap);
-       exit(EXIT_FAILURE);
+       t = time(NULL);
+       strftime(timestr, sizeof timestr, "%D %R", localtime(&t));
+       fprintf(stdout, "%-12s: %s %s\n", channel, timestr, bufout);
 }
 
-void
-printl(char *channel, char *msg) {
-       static char timestr[18];
-       time_t t = time(0);
-       strftime(timestr, sizeof timestr, "%D %R", localtime(&t));
-       fprintf(stdout, "%-12.12s: %s %s\n", channel, timestr, msg);
+static void
+sout(char *fmt, ...) {
+       va_list ap;
+
+       va_start(ap, fmt);
+       vsnprintf(bufout, sizeof bufout, fmt, ap);
+       va_end(ap);
+       fprintf(srv, "%s\r\n", bufout);
+       fprintf(stderr, "debug: %s\n", bufout);
 }
 
-void
+static void
 privmsg(char *channel, char *msg) {
-       if(channel[0] == '\0')
+       if(channel[0] == '\0') {
+               pout("", "No channel to send to");
                return;
-       snprintf(bufout, sizeof bufout, "<%s> %s", nick, msg);
-       printl(channel, bufout);
-       snprintf(bufout, sizeof bufout, "PRIVMSG %s :%s\r\n", channel, msg);
-       write(srv, bufout, strlen(bufout));
+       }
+       pout(channel, "<%s> %s", nick, msg);
+       sout("PRIVMSG %s :%s", channel, msg);
 }
 
-void
+static void
 parsein(char *msg) {
-       char *p = NULL;
+       char *p;
+       char c;
+
        if(msg[0] == '\0')
                return;
+       msg = ctok(&msg, '\n');
        if(msg[0] != ':') {
                privmsg(channel, msg);
                return;
        }
-       if(strncmp(msg + 1, "j ", 2) == 0 && (msg[3] == '#'))
-               snprintf(bufout, sizeof bufout, "JOIN %s\r\n", msg + 3);
-       else if(strncmp(msg + 1, "l ", 2) == 0)
-               snprintf(bufout, sizeof bufout, "PART %s :sic - 250 LOC are too much!\r\n", msg + 3);
-       else if(strncmp(msg + 1, "m ", 2) == 0 && (p = strchr(msg + 3, ' '))) {
-               *(p++) = '\0';
-               privmsg(msg + 3, p);
-               return;
-       }
-       else if(strncmp(msg + 1, "s ", 2) == 0) {
-               strncpy(channel, msg + 3, sizeof channel - 1);
-               return;
+       c = *++msg;
+       if(!c || !isspace(msg[1]))
+               sout("%s", msg);
+       else {
+               if(msg[1])
+                       msg += 2;
+               switch(c) {
+               case 'j':
+                       sout("JOIN %s", msg);
+                       if(channel[0] == '\0')
+                               strlcpy(channel, msg, sizeof channel);
+                       break;
+               case 'l':
+                       p = tok(&msg);
+                       if(!*p)
+                               p = channel;
+                       if(!*msg)
+                               msg = "sic - 250 LOC are too much!";
+                       sout("PART %s :%s", p, msg);
+                       break;
+               case 'm':
+                       p = tok(&msg);
+                       privmsg(p, msg);
+                       break;
+               case 's':
+                       strlcpy(channel, msg, sizeof channel);
+                       break;
+               default:
+                       sout("%c %s", c, msg);
+                       break;
+               }
        }
-       else
-               snprintf(bufout, sizeof bufout, "%s\r\n", msg + 1);
-       write(srv, bufout, strlen(bufout));
 }
 
-void
+static void
 parsesrv(char *msg) {
-       char *chan, *cmd, *p, *txt, *usr; 
+       char *cmd, *p, *usr, *txt;
 
-       txt = NULL;
        usr = host;
-       if(msg == NULL || *msg == '\0' )
+       if(!msg || !*msg)
                return;
-       if(msg[0] != ':')
-               cmd = msg;
-       else {
-               if(!(p = strchr(msg, ' ')))
+       if(msg[0] == ':') {
+               msg++;
+               p = tok(&msg);
+               if(!*msg)
                        return;
-               *p = '\0';
-               usr = msg + 1;
-               cmd = ++p;
-               if((p = strchr(usr, '!')))
-                       *p = '\0';
+               usr = ctok(&p, '!');
        }
-       for(p = cmd; *p != '\0'; p++) /* remove CRLFs */
-               if(*p == '\r' || *p == '\n')
-                       *p = '\0';
-       if((p = strchr(cmd, ':'))) {
-               *p = '\0';
-               txt = ++p;
-       }
-       if(strncmp("PONG", cmd, 4) == 0)
+       txt = ctok(&msg, '\r');
+       msg = ctok(&txt, ':');
+       cmd = tok(&msg);
+       if(!strcmp("PONG", cmd))
                return;
-       if(strncmp("PRIVMSG", cmd, 7) == 0 && txt != NULL) {
-               if(!(p = strchr(cmd, ' ')))
-                       return;
-               *p = '\0';
-               chan = ++p;
-               for(; *p != '\0' && *p != ' '; p++);
-               *p = '\0';
-               snprintf(bufout, sizeof bufout, "<%s> %s", usr, txt);
-               printl(chan, bufout);
-       }
-       else if(strncmp("PING", cmd, 4) == 0 && txt != NULL) {
-               snprintf(bufout, sizeof bufout, "PONG %s\r\n", txt);
-               write(srv, bufout, strlen(bufout));
-       }
+       if(!strcmp("PRIVMSG", cmd))
+               pout(msg, "<%s> %s", usr, txt);
+       else if(!strcmp("PING", cmd))
+               sout("PONG %s", txt);
        else {
-               if (txt != NULL)
-                       (void) snprintf(bufout, sizeof bufout, ">< %s: %s", cmd, txt);
-               else
-                       (void) snprintf(bufout, sizeof bufout, ">< %s: ", cmd);
-               printl(usr, bufout);
-               if(strncmp("NICK", cmd, 4) == 0 && strncmp(usr, nick, sizeof nick) == 0 && txt != NULL)
-                       strncpy(nick, txt, sizeof nick - 1);
+               pout(usr, ">< %s: %s", cmd, txt);
+               if(!strcmp("NICK", cmd) && !strcmp(usr, nick))
+                       strlcpy(nick, txt, sizeof nick);
        }
 }
 
 int
-readl(int fd, unsigned int len, char *buf) {
-       unsigned int i = 0;
-       char c = '\0';
-
-       do {
-               if(read(fd, &c, sizeof(char)) != (ssize_t) sizeof(char))
-                       return -1;
-               buf[i++] = c;
-       }
-       while(c != '\n' && i < len);
-       buf[i - 1] = '\0';
-       return 0;
-}
-
-
-int
-main(const int argc, char *const argv[]) {
-       int i;
+main(int argc, char *argv[]) {
+       int i, c;
        struct timeval tv;
-       static struct addrinfo hints, *res, *r;
-       char ping[256];
        fd_set rd;
-       char *password = NULL;
 
-       strncpy(nick, getenv("USER"), sizeof nick - 1);
-       for(i = 1; i < argc; i++)
-               if(strcmp(argv[i], "-h") == 0) {
+       strlcpy(nick, getenv("USER"), sizeof nick);
+       for(i = 1; i < argc; i++) {
+               c = argv[i][1];
+               if(argv[i][0] != '-' || argv[i][2])
+                       c = -1;
+               switch(c) {
+               case 'h':
                        if(++i < argc) host = argv[i];
-               }
-               else if(strcmp(argv[i], "-p") == 0) {
+                       break;
+               case 'p':
                        if(++i < argc) port = argv[i];
-               }
-               else if(strcmp(argv[i], "-n") == 0) {
-                       if(++i < argc) strncpy(nick, argv[i], sizeof nick - 1);
-               }
-               else if(strcmp(argv[i], "-k") == 0) {
+                       break;
+               case 'n':
+                       if(++i < argc) strlcpy(nick, argv[i], sizeof nick);
+                       break;
+               case 'k':
                        if(++i < argc) password = argv[i];
-               }
-               else if(strcmp(argv[i], "-v") == 0)
-                       die("sic-%s, © 2005-2009 sic engineers\n", VERSION);
-               else
-                       die("usage: sic [-h host] [-p port] [-n nick] [-k keyword] [-v]\n");
-
-       /* init */
-       memset(&hints, 0, sizeof hints);
-       hints.ai_family = AF_UNSPEC;
-       hints.ai_socktype = SOCK_STREAM;
-       if(getaddrinfo(host, port, &hints, &res) != 0)
-               die("error: cannot resolve hostname '%s'\n", host);
-       for(r = res; r; r = r->ai_next) {
-               if((srv = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1)
-                       continue;
-               if(connect(srv, r->ai_addr, r->ai_addrlen) == 0)
                        break;
-               close(srv);
+               case 'v':
+                       eprint("sic-"VERSION", © 2005-2009 Kris Maglione, Anselm R. Garbe, Nico Golde\n");
+               default:
+                       eprint("usage: sic [-h host] [-p port] [-n nick] [-k keyword] [-v]\n");
+               }
        }
-       freeaddrinfo(res);
-       if(!r)
-               die("error: cannot connect to host '%s'\n", host);
-
+       /* init */
+       i = dial(host, port);
+       srv = fdopen(i, "r+");
        /* login */
-       if (password)
-               snprintf(bufout, sizeof bufout,
-                       "PASS %s\r\nNICK %s\r\nUSER %s localhost %s :%s\r\n",
-                       password, nick, nick, host, nick);
-       else
-               snprintf(bufout, sizeof bufout, "NICK %s\r\nUSER %s localhost %s :%s\r\n",
-                        nick, nick, host, nick);
-       write(srv, bufout, strlen(bufout));
-       snprintf(ping, sizeof ping, "PING %s\r\n", host);
-       channel[0] = '\0';
-       setbuf(stdout, NULL); /* unbuffered stdout */
-
+       if(password)
+               sout("PASS %s", password);
+       sout("NICK %s", nick);
+       sout("USER %s localhost %s :%s", nick, host, nick);
+       fflush(srv);
+       setbuf(stdout, NULL);
+       setbuf(srv, NULL);
        for(;;) { /* main loop */
                FD_ZERO(&rd);
                FD_SET(0, &rd);
-               FD_SET(srv, &rd);
+               FD_SET(fileno(srv), &rd);
                tv.tv_sec = 120;
                tv.tv_usec = 0;
-               i = select(srv + 1, &rd, 0, 0, &tv);
+               i = select(fileno(srv) + 1, &rd, 0, 0, &tv);
                if(i < 0) {
                        if(errno == EINTR)
                                continue;
-                       die("error: error on select()\n");
+                       eprint("sic: error on select():");
                }
                else if(i == 0) {
-                       if(time(NULL) - trespond >= PINGTIMEOUT)
-                               die("error: sic shutting down: parse timeout\n");
-                       write(srv, ping, strlen(ping));
+                       if(time(NULL) - trespond >= 300)
+                               eprint("sic shutting down: parse timeout\n");
+                       sout("PING %s", host);
                        continue;
                }
-               if(FD_ISSET(srv, &rd) != 0) {
-                       if(readl(srv, sizeof bufin, bufin) == -1)
-                               die("error: remote host closed connection\n");
+               if(FD_ISSET(fileno(srv), &rd)) {
+                       if(fgets(bufin, sizeof bufin, srv) == NULL)
+                               eprint("sic: remote host closed connection\n");
                        parsesrv(bufin);
                        trespond = time(NULL);
                }
-               if(FD_ISSET(0, &rd) != 0) {
-                       if(readl(0, sizeof bufin, bufin) == -1)
-                               die("error: broken pipe\n");
+               if(FD_ISSET(0, &rd)) {
+                       if(fgets(bufin, sizeof bufin, stdin) == NULL)
+                               eprint("sic: broken pipe\n");
                        parsein(bufin);
                }
        }
diff --git a/util.c b/util.c
new file mode 100644 (file)
index 0000000..5412efc
--- /dev/null
+++ b/util.c
@@ -0,0 +1,81 @@
+/* See LICENSE file for license details. */
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+static void
+eprint(const char *fmt, ...) {
+       va_list ap;
+
+       va_start(ap, fmt);
+       vsnprintf(bufout, sizeof bufout, fmt, ap);
+       va_end(ap);
+       fprintf(stderr, "%s", bufout);
+       if(fmt[0] && fmt[strlen(fmt) - 1] == ':')
+               fprintf(stderr, " %s\n", strerror(errno));
+       exit(1);
+}
+
+static int
+dial(char *host, char *port) {
+       static struct addrinfo hints;
+       int srv;
+       struct addrinfo *res, *r;
+
+       memset(&hints, 0, sizeof hints);
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_STREAM;
+       if(getaddrinfo(host, port, &hints, &res) != 0)
+               eprint("error: cannot resolve hostname '%s':", host);
+       for(r = res; r; r = r->ai_next) {
+               if((srv = socket(r->ai_family, r->ai_socktype, r->ai_protocol)) == -1)
+                       continue;
+               if(connect(srv, r->ai_addr, r->ai_addrlen) == 0)
+                       break;
+               close(srv);
+       }
+       freeaddrinfo(res);
+       if(!r)
+               eprint("error: cannot connect to host '%s'\n", host);
+       return srv;
+}
+
+#define strlcpy _strlcpy
+static void
+strlcpy(char *to, const char *from, int l) {
+       memccpy(to, from, '\0', l);
+       to[l-1] = '\0';
+}
+
+static void
+eat(char **s, int (*p)(int), int r) {
+       char *q;
+
+       for(q = *s; *q && p(*q) == r; q++)
+               ;
+       *s = q;
+}
+
+static char*
+tok(char **s) {
+       char *p;
+
+       eat(s, isspace, 1);
+       p = *s;
+       eat(s, isspace, 0);
+       if(**s)
+               *(*s)++ = '\0';
+       return p;
+}
+
+static char*
+ctok(char **s, int c) {
+       char *p, *q;
+
+       q = *s;
+       for(p = q; *p && *p != c; p++)
+               ;
+       if(*p) *p++ = '\0';
+       *s = p;
+       return q;
+}