X-Git-Url: https://git.armaanb.net/?p=sic.git;a=blobdiff_plain;f=sic.c;h=c1e428effa57a8675c123f100d122a1971a210a2;hp=53f5aba9cb91bd7f408470cf6507417aabf5548e;hb=HEAD;hpb=1a4256ef71ddba6c3cbb28861e0321184860653f diff --git a/sic.c b/sic.c index 53f5aba..c1e428e 100644 --- a/sic.c +++ b/sic.c @@ -1,4 +1,6 @@ /* See LICENSE file for license details. */ +#include + #include #include #include @@ -8,8 +10,12 @@ #include #include -static char *host = "irc.oftc.net"; -static char *port = "ircd"; +#include "arg.h" +#include "config.h" + +char *argv0; +static char *host = DEFAULT_HOST; +static char *port = DEFAULT_PORT; static char *password; static char nick[32]; static char bufin[4096]; @@ -18,11 +24,13 @@ static char channel[256]; static time_t trespond; static FILE *srv; +#undef strlcpy +#include "strlcpy.c" #include "util.c" static void pout(char *channel, char *fmt, ...) { - static char timestr[18]; + static char timestr[80]; time_t t; va_list ap; @@ -30,7 +38,7 @@ pout(char *channel, char *fmt, ...) { vsnprintf(bufout, sizeof bufout, fmt, ap); va_end(ap); t = time(NULL); - strftime(timestr, sizeof timestr, "%D %R", localtime(&t)); + strftime(timestr, sizeof timestr, TIMESTAMP_FORMAT, localtime(&t)); fprintf(stdout, "%-12s: %s %s\n", channel, timestr, bufout); } @@ -42,7 +50,6 @@ sout(char *fmt, ...) { vsnprintf(bufout, sizeof bufout, fmt, ap); va_end(ap); fprintf(srv, "%s\r\n", bufout); - fprintf(stderr, "debug: %s\n", bufout); } static void @@ -56,114 +63,120 @@ privmsg(char *channel, char *msg) { } static void -parsein(char *msg) { - char *p; - char c; +parsein(char *s) { + char c, *p; - if(msg[0] == '\0') + if(s[0] == '\0') return; - msg = ctok(&msg, '\n'); - if(msg[0] != ':') { - privmsg(channel, msg); + skip(s, '\n'); + if(s[0] != COMMAND_PREFIX_CHARACTER) { + privmsg(channel, s); return; } - c = *++msg; - if(!c || !isspace(msg[1])) - sout("%s", msg); - else { - if(msg[1]) - msg += 2; + c = *++s; + if(c != '\0' && isspace((unsigned char)s[1])) { + p = s + 2; switch(c) { case 'j': - sout("JOIN %s", msg); + sout("JOIN %s", p); if(channel[0] == '\0') - strlcpy(channel, msg, sizeof channel); - break; + strlcpy(channel, p, sizeof channel); + return; case 'l': - p = tok(&msg); + s = eat(p, isspace, 1); + p = eat(s, isspace, 0); + if(!*s) + s = channel; + if(*p) + *p++ = '\0'; if(!*p) - p = channel; - if(!*msg) - msg = "sic - 250 LOC are too much!"; - sout("PART %s :%s", p, msg); - break; + p = DEFAULT_PARTING_MESSAGE; + sout("PART %s :%s", s, p); + return; case 'm': - p = tok(&msg); - privmsg(p, msg); - break; + s = eat(p, isspace, 1); + p = eat(s, isspace, 0); + if(*p) + *p++ = '\0'; + privmsg(s, p); + return; case 's': - strlcpy(channel, msg, sizeof channel); - break; - default: - sout("%c %s", c, msg); - break; + strlcpy(channel, p, sizeof channel); + return; } } + sout("%s", s); } static void -parsesrv(char *msg) { - char *cmd, *p, *usr, *txt; +parsesrv(char *cmd) { + char *usr, *par, *txt; usr = host; - if(!msg || !*msg) + if(!cmd || !*cmd) return; - if(msg[0] == ':') { - msg++; - p = tok(&msg); - if(!*msg) + if(cmd[0] == ':') { + usr = cmd + 1; + cmd = skip(usr, ' '); + if(cmd[0] == '\0') return; - usr = ctok(&p, '!'); + skip(usr, '!'); } - txt = ctok(&msg, '\r'); - msg = ctok(&txt, ':'); - cmd = tok(&msg); + skip(cmd, '\r'); + par = skip(cmd, ' '); + txt = skip(par, ':'); + trim(par); if(!strcmp("PONG", cmd)) return; if(!strcmp("PRIVMSG", cmd)) - pout(msg, "<%s> %s", usr, txt); + pout(par, "<%s> %s", usr, txt); else if(!strcmp("PING", cmd)) sout("PONG %s", txt); else { - pout(usr, ">< %s: %s", cmd, txt); + pout(usr, ">< %s (%s): %s", cmd, par, txt); if(!strcmp("NICK", cmd) && !strcmp(usr, nick)) strlcpy(nick, txt, sizeof nick); } } + +static void +usage(void) { + eprint("usage: sic [-h host] [-p port] [-n nick] [-k keyword] [-v]\n", argv0); +} + int main(int argc, char *argv[]) { - int i, c; struct timeval tv; + const char *user = getenv("USER"); + int n; 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"); - } - } + strlcpy(nick, user ? user : "unknown", sizeof nick); + ARGBEGIN { + case 'h': + host = EARGF(usage()); + break; + case 'p': + port = EARGF(usage()); + break; + case 'n': + strlcpy(nick, EARGF(usage()), sizeof nick); + break; + case 'k': + password = EARGF(usage()); + break; + case 'v': + eprint("sic-"VERSION", © 2005-2014 Kris Maglione, Anselm R. Garbe, Nico Golde\n"); + break; + default: + usage(); + } ARGEND; + /* init */ - i = dial(host, port); - srv = fdopen(i, "r+"); + srv = fdopen(dial(host, port), "r+"); + if (!srv) + eprint("fdopen:"); /* login */ if(password) sout("PASS %s", password); @@ -172,19 +185,24 @@ main(int argc, char *argv[]) { fflush(srv); setbuf(stdout, NULL); setbuf(srv, NULL); + setbuf(stdin, NULL); +#ifdef __OpenBSD__ + if (pledge("stdio", NULL) == -1) + eprint("error: pledge:"); +#endif 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) { + n = select(fileno(srv) + 1, &rd, 0, 0, &tv); + if(n < 0) { if(errno == EINTR) continue; eprint("sic: error on select():"); } - else if(i == 0) { + else if(n == 0) { if(time(NULL) - trespond >= 300) eprint("sic shutting down: parse timeout\n"); sout("PING %s", host);