diff options
author | June McEnroe <june@causal.agency> | 2019-10-23 17:14:08 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2019-10-23 17:14:08 -0400 |
commit | 617f3f8b05fa4538c5ef0628196a6e473185fdc5 (patch) | |
tree | 4d03fc97bf939336c835aadad00b0ad9a7aeaa80 | |
parent | Respond to pings (diff) | |
download | pounce-617f3f8b05fa4538c5ef0628196a6e473185fdc5.tar.gz pounce-617f3f8b05fa4538c5ef0628196a6e473185fdc5.zip |
Clean up state.c and factor out parsing
-rw-r--r-- | bounce.h | 24 | ||||
-rw-r--r-- | state.c | 62 |
2 files changed, 45 insertions, 41 deletions
diff --git a/bounce.h b/bounce.h index e81ed8f..491616b 100644 --- a/bounce.h +++ b/bounce.h @@ -16,6 +16,7 @@ #include <stdbool.h> #include <stdlib.h> +#include <string.h> #include <tls.h> #ifndef DEFAULT_CERT_PATH @@ -30,6 +31,29 @@ struct Client { struct tls *tls; }; +#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0])) + +enum { ParamCap = 15 }; +struct Command { + const char *origin; + const char *name; + const char *params[ParamCap]; +}; + +static inline struct Command parse(char *line) { + struct Command cmd = {0}; + if (line[0] == ':') cmd.origin = 1 + strsep(&line, " "); + cmd.name = strsep(&line, " "); + for (size_t i = 0; line && i < ParamCap; ++i) { + if (line[0] == ':') { + cmd.params[i] = &line[1]; + break; + } + cmd.params[i] = strsep(&line, " "); + } + return cmd; +} + bool verbose; void listenConfig(const char *cert, const char *priv); diff --git a/state.c b/state.c index ecbf368..c7d517e 100644 --- a/state.c +++ b/state.c @@ -34,11 +34,21 @@ static struct { char *myInfo[4]; } intro; -enum { ISupportCap = 32 }; +enum { SupportCap = 32 }; static struct { - char *values[ISupportCap]; + char *tokens[SupportCap]; size_t len; -} iSupport; +} support; + +bool stateReady(void) { + return nick + && intro.origin + && intro.welcome + && intro.yourHost + && intro.created + && intro.myInfo[0] + && support.len; +} static void set(char **field, const char *value) { if (*field) free(*field); @@ -46,30 +56,14 @@ static void set(char **field, const char *value) { if (!*field) err(EX_OSERR, "strdup"); } -static void iSupportSet(const char *value) { - if (iSupport.len == ISupportCap) { - warnx("truncating ISUPPORT value %s", value); +static void supportSet(const char *token) { + if (support.len == SupportCap) { + warnx("dropping ISUPPORT token %s", token); return; } - set(&iSupport.values[iSupport.len++], value); + set(&support.tokens[support.len++], token); } -bool stateReady(void) { - return nick - && intro.origin - && intro.welcome - && intro.yourHost - && intro.created - && intro.myInfo[0] - && iSupport.len; -} - -enum { ParamCap = 15 }; -struct Command { - const char *origin; - const char *name; - const char *params[ParamCap]; -}; typedef void Handler(struct Command); static void handleCap(struct Command cmd) { @@ -104,7 +98,7 @@ static void handleReplyMyInfo(struct Command cmd) { static void handleReplyISupport(struct Command cmd) { for (size_t i = 1; i < ParamCap; ++i) { if (!cmd.params[i] || strchr(cmd.params[i], ' ')) break; - iSupportSet(cmd.params[i]); + supportSet(cmd.params[i]); } } @@ -124,25 +118,11 @@ static const struct { { "CAP", handleCap }, { "ERROR", handleError }, }; -static const size_t HandlersLen = sizeof(Handlers) / sizeof(Handlers[0]); void stateParse(char *line) { - struct Command cmd = {0}; - if (line[0] == ':') { - cmd.origin = 1 + strsep(&line, " "); - if (!line) errx(EX_PROTOCOL, "eof after origin"); - } - - cmd.name = strsep(&line, " "); - for (size_t i = 0; line && i < ParamCap; ++i) { - if (line[0] == ':') { - cmd.params[i] = &line[1]; - break; - } - cmd.params[i] = strsep(&line, " "); - } - - for (size_t i = 0; i < HandlersLen; ++i) { + struct Command cmd = parse(line); + if (!cmd.name) errx(EX_PROTOCOL, "no command"); + for (size_t i = 0; i < ARRAY_LEN(Handlers); ++i) { if (strcmp(cmd.name, Handlers[i].cmd)) continue; Handlers[i].fn(cmd); break; |