Patch attached. What I have changed:
* Replaced `tok` and `ctok` functions with `skip` and (already
existing, but a little different) `eat`
* Changed parsing of separators (<SPACE> from RFC) in server
responses. Now tabs are not skipped. Also no more than one space is
skipped. RFC says there can be more than one space but I have seen
no server that will add extra separator characters. It is not hard
to parse but simplicity > correctness.
* Removed always true `if(msg[1])` check
* Added output of command parameters:
- pout(usr, ">< %s: %s", cmd, txt);
+ pout(usr, ">< %s (%s): %s", cmd, msg, txt);
Now it is possible to use such commands as "LIST"
* Added function `trim` for removing trailing whitespace.
It is now used on `msg` variable before outputting it so instead of
reticulum.oftc.net: 04/15/10 17:45 >< NOTICE (AUTH ): *** Looking up your
hostname...
you get
reticulum.oftc.net: 04/15/10 17:45 >< NOTICE (AUTH): *** Looking up your
hostname...
It is not a problem when you output it with "%-12s" format like
first argument of pout, but it is easy to see the problem when you
output it in parenthesis.
Code is one line less now.
diff -r 10f41d80803e sic.c
--- a/sic.c Tue Mar 23 18:00:37 2010 +0000
+++ b/sic.c Thu Apr 15 17:53:34 2010 +0400
@@ -55,68 +55,74 @@
}
static void
-parsein(char *msg) {
+parsein(char *s) {
char *p;
char c;
- 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] != ':') {
+ privmsg(channel, s);
return;
}
- c = *++msg;
- if(!c || !isspace(msg[1]))
- sout("%s", msg);
+ c = *++s;
+ if(c == '\0' || !isspace(s[1]))
+ sout("%s", s);
else {
- if(msg[1])
- msg += 2;
+ p = s + 2;
switch(c) {
case 'j':
- sout("JOIN %s", msg);
+ sout("JOIN %s", p);
if(channel[0] == '\0')
- strlcpy(channel, msg, sizeof channel);
+ strlcpy(channel, p, sizeof channel);
break;
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);
+ p = "sic - 250 LOC are too much!";
+ sout("PART %s :%s", s, p);
break;
case 'm':
- p = tok(&msg);
- privmsg(p, msg);
+ s = eat(p, isspace, 1);
+ p = eat(s, isspace, 0);
+ if(*p)
+ *p++ = '\0';
+ privmsg(s, p);
break;
case 's':
- strlcpy(channel, msg, sizeof channel);
+ strlcpy(channel, p, sizeof channel);
break;
default:
- sout("%c %s", c, msg);
+ sout("%s", s);
break;
}
}
}
static void
-parsesrv(char *msg) {
- char *cmd, *p, *usr, *txt;
+parsesrv(char *cmd) {
+ char *msg, *usr, *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');
+ msg = skip(cmd, ' ');
+ txt = skip(msg, ':');
+ trim(msg);
if(!strcmp("PONG", cmd))
return;
if(!strcmp("PRIVMSG", cmd))
@@ -124,7 +130,7 @@
else if(!strcmp("PING", cmd))
sout("PONG %s", txt);
else {
- pout(usr, ">< %s: %s", cmd, txt);
+ pout(usr, ">< %s (%s): %s", cmd, msg, txt);
if(!strcmp("NICK", cmd) && !strcmp(usr, nick))
strlcpy(nick, txt, sizeof nick);
}
diff -r 10f41d80803e util.c
--- a/util.c Tue Mar 23 18:00:37 2010 +0000
+++ b/util.c Thu Apr 15 17:53:34 2010 +0400
@@ -47,35 +47,28 @@
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 *
+eat(char *s, int (*p)(int), int r) {
+ while(s != '\0' && p(*s) == r)
+ s++;
+ return s;
}
static char*
-tok(char **s) {
- char *p;
-
- eat(s, isspace, 1);
- p = *s;
- eat(s, isspace, 0);
- if(**s)
- *(*s)++ = '\0';
- return p;
+skip(char *s, char c) {
+ while(*s != c && *s != '\0')
+ s++;
+ if (*s != '\0')
+ *s++ = '\0';
+ return s;
}
-static char*
-ctok(char **s, int c) {
- char *p, *q;
+static void
+trim(char *s) {
+ char *e;
- q = *s;
- for(p = q; *p && *p != c; p++)
- ;
- if(*p) *p++ = '\0';
- *s = p;
- return q;
+ e = s + strlen(s) - 1;
+ while (isspace(*e) && e > s)
+ e--;
+ *(e + 1) = '\0';
}