#include <time.h>
#include <unistd.h>
-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];
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;
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);
}
}
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(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, user ? user : "unknown", 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");
- }
- }
+ 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);
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);