diff options
Diffstat (limited to 'handle.c')
-rw-r--r-- | handle.c | 158 |
1 files changed, 57 insertions, 101 deletions
diff --git a/handle.c b/handle.c index b8434c6..0cc7c04 100644 --- a/handle.c +++ b/handle.c @@ -32,7 +32,6 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sysexits.h> #include <wchar.h> #include "chat.h" @@ -83,7 +82,7 @@ static void require(struct Message *msg, bool origin, uint len) { } for (uint i = 0; i < len; ++i) { if (msg->params[i]) continue; - errx(EX_PROTOCOL, "%s missing parameter %u", msg->cmd, 1 + i); + errx(1, "%s missing parameter %u", msg->cmd, 1 + i); } } @@ -162,7 +161,7 @@ static void handleErrorNicknameInUse(struct Message *msg) { static void handleErrorErroneousNickname(struct Message *msg) { require(msg, false, 3); if (!strcmp(self.nick, "*")) { - errx(EX_CONFIG, "%s: %s", msg->params[1], msg->params[2]); + errx(1, "%s: %s", msg->params[1], msg->params[2]); } else { handleErrorGeneric(msg); } @@ -193,7 +192,7 @@ static void handleCap(struct Message *msg) { } if (!(self.caps & CapSASL)) ircFormat("CAP END\r\n"); } else if (!strcmp(msg->params[1], "NAK")) { - errx(EX_CONFIG, "server does not support %s", msg->params[2]); + errx(1, "server does not support %s", msg->params[2]); } } @@ -237,7 +236,7 @@ static void handleAuthenticate(struct Message *msg) { size_t userLen = strlen(self.plainUser); size_t passLen = strlen(self.plainPass); size_t len = 1 + userLen + 1 + passLen; - if (sizeof(buf) < len) errx(EX_USAGE, "SASL PLAIN is too long"); + if (sizeof(buf) < len) errx(1, "SASL PLAIN is too long"); memcpy(&buf[1], self.plainUser, userLen); memcpy(&buf[1 + userLen + 1], self.plainPass, passLen); @@ -260,13 +259,13 @@ static void handleReplyLoggedIn(struct Message *msg) { static void handleErrorSASLFail(struct Message *msg) { require(msg, false, 2); - errx(EX_CONFIG, "%s", msg->params[1]); + errx(1, "%s", msg->params[1]); } static void handleReplyWelcome(struct Message *msg) { require(msg, false, 1); set(&self.nick, msg->params[0]); - cacheInsert(true, Network, self.nick); + completePull(Network, self.nick, Default); if (self.mode) ircFormat("MODE %s %s\r\n", self.nick, self.mode); if (self.join) { uint count = 1; @@ -278,7 +277,7 @@ static void handleReplyWelcome(struct Message *msg) { replies[ReplyTopicAuto] += count; replies[ReplyNamesAuto] += count; } - commandCache(); + commandCompletion(); handleReplyGeneric(msg); } @@ -315,7 +314,7 @@ static void handleReplyISupport(struct Message *msg) { char *modes = strsep(&msg->params[i], ")"); char *prefixes = msg->params[i]; if (!modes || !prefixes || strlen(modes) != strlen(prefixes)) { - errx(EX_PROTOCOL, "invalid PREFIX value"); + errx(1, "invalid PREFIX value"); } set(&network.prefixModes, modes); set(&network.prefixes, prefixes); @@ -325,7 +324,7 @@ static void handleReplyISupport(struct Message *msg) { char *setParam = strsep(&msg->params[i], ","); char *channel = strsep(&msg->params[i], ","); if (!list || !param || !setParam || !channel) { - errx(EX_PROTOCOL, "invalid CHANMODES value"); + errx(1, "invalid CHANMODES value"); } set(&network.listModes, list); set(&network.paramModes, param); @@ -372,13 +371,13 @@ static void handleJoin(struct Message *msg) { set(&self.host, msg->host); } idColors[id] = hash(msg->params[0]); - cacheInsert(true, None, msg->params[0])->color = idColors[id]; + completePull(None, msg->params[0], idColors[id]); if (replies[ReplyJoin]) { windowShow(windowFor(id)); replies[ReplyJoin]--; } } - cacheInsert(true, id, msg->nick)->color = hash(msg->user); + completePull(id, msg->nick, hash(msg->user)); if (msg->params[2] && !strcasecmp(msg->params[2], msg->nick)) { msg->params[2] = NULL; } @@ -410,9 +409,9 @@ static void handlePart(struct Message *msg) { require(msg, true, 1); uint id = idFor(msg->params[0]); if (!strcmp(msg->nick, self.nick)) { - cacheClear(id); + completeRemove(id, NULL); } - cacheRemove(id, msg->nick); + completeRemove(id, msg->nick); enum Heat heat = filterCheck(Cold, id, msg); if (heat > Ice) urlScan(id, msg->nick, msg->params[1]); uiFormat( @@ -432,14 +431,14 @@ static void handleKick(struct Message *msg) { require(msg, true, 2); uint id = idFor(msg->params[0]); bool kicked = !strcmp(msg->params[1], self.nick); - cacheInsert(true, id, msg->nick)->color = hash(msg->user); + completePull(id, msg->nick, hash(msg->user)); urlScan(id, msg->nick, msg->params[2]); uiFormat( id, (kicked ? Hot : Cold), tagTime(msg), "%s\3%02d%s\17\tkicks \3%02d%s\3 out of \3%02d%s\3%s%s", (kicked ? "\26" : ""), hash(msg->user), msg->nick, - cacheGet(id, msg->params[1])->color, msg->params[1], + completeColor(id, msg->params[1]), msg->params[1], hash(msg->params[0]), msg->params[0], (msg->params[2] ? ": " : ""), (msg->params[2] ?: "") ); @@ -448,8 +447,8 @@ static void handleKick(struct Message *msg) { msg->nick, msg->params[1], msg->params[0], (msg->params[2] ? ": " : ""), (msg->params[2] ?: "") ); - cacheRemove(id, msg->params[1]); - if (kicked) cacheClear(id); + completeRemove(id, msg->params[1]); + if (kicked) completeRemove(id, NULL); } static void handleNick(struct Message *msg) { @@ -459,7 +458,7 @@ static void handleNick(struct Message *msg) { inputUpdate(); } struct Cursor curs = {0}; - for (uint id; (id = cacheID(&curs, msg->nick));) { + for (uint id; (id = completeEachID(&curs, msg->nick));) { if (!strcmp(idNames[id], msg->nick)) { set(&idNames[id], msg->params[0]); } @@ -474,13 +473,13 @@ static void handleNick(struct Message *msg) { msg->nick, msg->params[0] ); } - cacheReplace(true, msg->nick, msg->params[0]); + completeReplace(msg->nick, msg->params[0]); } static void handleSetname(struct Message *msg) { require(msg, true, 1); struct Cursor curs = {0}; - for (uint id; (id = cacheID(&curs, msg->nick));) { + for (uint id; (id = completeEachID(&curs, msg->nick));) { uiFormat( id, filterCheck(Cold, id, msg), tagTime(msg), "\3%02d%s\3\tis now known as \3%02d%s\3 (%s\17)", @@ -493,7 +492,7 @@ static void handleSetname(struct Message *msg) { static void handleQuit(struct Message *msg) { require(msg, true, 0); struct Cursor curs = {0}; - for (uint id; (id = cacheID(&curs, msg->nick));) { + for (uint id; (id = completeEachID(&curs, msg->nick));) { enum Heat heat = filterCheck(Cold, id, msg); if (heat > Ice) urlScan(id, msg->nick, msg->params[0]); uiFormat( @@ -509,7 +508,7 @@ static void handleQuit(struct Message *msg) { (msg->params[0] ? ": " : ""), (msg->params[0] ?: "") ); } - cacheRemove(None, msg->nick); + completeRemove(None, msg->nick); } static void handleInvite(struct Message *msg) { @@ -555,17 +554,11 @@ static void handleErrorUserOnChannel(struct Message *msg) { uiFormat( id, Warm, tagTime(msg), "\3%02d%s\3 is already in \3%02d%s\3", - cacheGet(id, msg->params[1])->color, msg->params[1], + completeColor(id, msg->params[1]), msg->params[1], hash(msg->params[2]), msg->params[2] ); } -static uint prefixBit(char p) { - char *s = strchr(network.prefixes, p); - if (!s) return 0; - return 1 << (s - network.prefixes); -} - static void handleReplyNames(struct Message *msg) { require(msg, false, 4); uint id = idFor(msg->params[2]); @@ -581,9 +574,8 @@ static void handleReplyNames(struct Message *msg) { for (char *p = prefixes; p < nick; ++p) { bits |= prefixBit(*p); } - struct Entry *entry = cacheInsert(false, id, nick); - if (user) entry->color = color; - entry->prefixBits = bits; + completePush(id, nick, color); + *completeBits(id, nick) = bits; if (!replies[ReplyNames] && !replies[ReplyNamesAuto]) continue; ptr = seprintf( ptr, end, "%s\3%02d%s\3", (ptr > buf ? ", " : ""), color, prefixes @@ -606,41 +598,6 @@ static void handleReplyEndOfNames(struct Message *msg) { } } -static struct { - char buf[1024]; - char *ptr; - char *end; -} who = { - .ptr = who.buf, - .end = &who.buf[sizeof(who.buf)], -}; - -static void handleReplyWho(struct Message *msg) { - require(msg, false, 7); - if (who.ptr == who.buf) { - who.ptr = seprintf( - who.ptr, who.end, "The council of \3%02d%s\3 are ", - hash(msg->params[1]), msg->params[1] - ); - } - char *prefixes = &msg->params[6][1]; - if (prefixes[0] == '*') prefixes++; - prefixes[strspn(prefixes, network.prefixes)] = '\0'; - if (!prefixes[0] || prefixes[0] == '+') return; - who.ptr = seprintf( - who.ptr, who.end, "%s\3%02d%s%s\3%s", - (who.ptr[-1] == ' ' ? "" : ", "), - hash(msg->params[2]), prefixes, msg->params[5], - (msg->params[6][0] == 'H' ? "" : " (away)") - ); -} - -static void handleReplyEndOfWho(struct Message *msg) { - require(msg, false, 2); - uiWrite(idFor(msg->params[1]), Warm, tagTime(msg), who.buf); - who.ptr = who.buf; -} - static void handleReplyNoTopic(struct Message *msg) { require(msg, false, 2); uiFormat( @@ -650,24 +607,24 @@ static void handleReplyNoTopic(struct Message *msg) { ); } -static void topicCache(uint id, const char *topic) { +static void topicComplete(uint id, const char *topic) { char buf[512]; struct Cursor curs = {0}; - const char *prev = cacheComplete(&curs, id, "/topic "); + const char *prev = completePrefix(&curs, id, "/topic "); if (prev) { snprintf(buf, sizeof(buf), "%s", prev); - cacheRemove(id, buf); + completeRemove(id, buf); } if (topic) { snprintf(buf, sizeof(buf), "/topic %s", topic); - cacheInsert(false, id, buf); + completePush(id, buf, Default); } } static void handleReplyTopic(struct Message *msg) { require(msg, false, 3); uint id = idFor(msg->params[1]); - topicCache(id, msg->params[2]); + topicComplete(id, msg->params[2]); if (!replies[ReplyTopic] && !replies[ReplyTopicAuto]) return; urlScan(id, NULL, msg->params[2]); uiFormat( @@ -718,7 +675,7 @@ static void handleTopic(struct Message *msg) { require(msg, true, 2); uint id = idFor(msg->params[0]); if (!msg->params[1][0]) { - topicCache(id, NULL); + topicComplete(id, NULL); uiFormat( id, Warm, tagTime(msg), "\3%02d%s\3\tremoves the sign in \3%02d%s\3", @@ -732,7 +689,7 @@ static void handleTopic(struct Message *msg) { } struct Cursor curs = {0}; - const char *prev = cacheComplete(&curs, id, "/topic "); + const char *prev = completePrefix(&curs, id, "/topic "); if (prev) { prev += 7; } else { @@ -782,7 +739,7 @@ log: id, tagTime(msg), "%s places a new sign in %s: %s", msg->nick, msg->params[0], msg->params[1] ); - topicCache(id, msg->params[1]); + topicComplete(id, msg->params[1]); urlScan(id, msg->nick, msg->params[1]); } @@ -899,22 +856,23 @@ static void handleMode(struct Message *msg) { if (strchr(network.prefixModes, *ch)) { if (i >= ParamCap || !msg->params[i]) { - errx(EX_PROTOCOL, "MODE missing %s parameter", mode); + errx(1, "MODE missing %s parameter", mode); } char *nick = msg->params[i++]; char prefix = network.prefixes[ strchr(network.prefixModes, *ch) - network.prefixModes ]; + completePush(id, nick, Default); if (set) { - cacheInsert(false, id, nick)->prefixBits |= prefixBit(prefix); + *completeBits(id, nick) |= prefixBit(prefix); } else { - cacheInsert(false, id, nick)->prefixBits &= ~prefixBit(prefix); + *completeBits(id, nick) &= ~prefixBit(prefix); } uiFormat( id, Cold, tagTime(msg), "\3%02d%s\3\t%s \3%02d%c%s\3 %s%s in \3%02d%s\3", hash(msg->user), msg->nick, verb, - cacheGet(id, nick)->color, prefix, nick, + completeColor(id, nick), prefix, nick, mode, name, hash(msg->params[0]), msg->params[0] ); logFormat( @@ -925,7 +883,7 @@ static void handleMode(struct Message *msg) { if (strchr(network.listModes, *ch)) { if (i >= ParamCap || !msg->params[i]) { - errx(EX_PROTOCOL, "MODE missing %s parameter", mode); + errx(1, "MODE missing %s parameter", mode); } char *mask = msg->params[i++]; if (*ch == 'b') { @@ -958,7 +916,7 @@ static void handleMode(struct Message *msg) { if (strchr(network.paramModes, *ch)) { if (i >= ParamCap || !msg->params[i]) { - errx(EX_PROTOCOL, "MODE missing %s parameter", mode); + errx(1, "MODE missing %s parameter", mode); } char *param = msg->params[i++]; uiFormat( @@ -975,7 +933,7 @@ static void handleMode(struct Message *msg) { if (strchr(network.setParamModes, *ch) && set) { if (i >= ParamCap || !msg->params[i]) { - errx(EX_PROTOCOL, "MODE missing %s parameter", mode); + errx(1, "MODE missing %s parameter", mode); } char *param = msg->params[i++]; uiFormat( @@ -1052,7 +1010,7 @@ static void handleReplyBanList(struct Message *msg) { id, Warm, tagTime(msg), "Banned from \3%02d%s\3 since %s by \3%02d%s\3: %s", hash(msg->params[1]), msg->params[1], - since, cacheGet(id, msg->params[3])->color, msg->params[3], + since, completeColor(id, msg->params[3]), msg->params[3], msg->params[2] ); } else { @@ -1075,7 +1033,7 @@ static void onList(const char *list, struct Message *msg) { id, Warm, tagTime(msg), "On the \3%02d%s\3 %s list since %s by \3%02d%s\3: %s", hash(msg->params[1]), msg->params[1], list, - since, cacheGet(id, msg->params[3])->color, msg->params[3], + since, completeColor(id, msg->params[3]), msg->params[3], msg->params[2] ); } else { @@ -1096,19 +1054,19 @@ static void handleReplyInviteList(struct Message *msg) { } static void handleReplyList(struct Message *msg) { - require(msg, false, 4); + require(msg, false, 3); uiFormat( Network, Warm, tagTime(msg), "In \3%02d%s\3 are %ld under the banner: %s", hash(msg->params[1]), msg->params[1], strtol(msg->params[2], NULL, 10), - msg->params[3] + (msg->params[3] ?: "") ); } static void handleReplyWhoisUser(struct Message *msg) { require(msg, false, 6); - cacheInsert(true, Network, msg->params[1])->color = hash(msg->params[2]); + completePull(Network, msg->params[1], hash(msg->params[2])); uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\tis %s!%s@%s (%s\17)", @@ -1123,7 +1081,7 @@ static void handleReplyWhoisServer(struct Message *msg) { uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\t%s connected to %s (%s)", - cacheGet(Network, msg->params[1])->color, msg->params[1], + completeColor(Network, msg->params[1]), msg->params[1], (replies[ReplyWhowas] ? "was" : "is"), msg->params[2], msg->params[3] ); } @@ -1147,7 +1105,7 @@ static void handleReplyWhoisIdle(struct Message *msg) { uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\tis idle for %lu %s%s%s%s", - cacheGet(Network, msg->params[1])->color, msg->params[1], + completeColor(Network, msg->params[1]), msg->params[1], idle, unit, (idle != 1 ? "s" : ""), (msg->params[3] ? ", signed on " : ""), (msg->params[3] ? signon : "") ); @@ -1169,7 +1127,7 @@ static void handleReplyWhoisChannels(struct Message *msg) { uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\tis in %s", - cacheGet(Network, msg->params[1])->color, msg->params[1], buf + completeColor(Network, msg->params[1]), msg->params[1], buf ); } @@ -1183,7 +1141,7 @@ static void handleReplyWhoisGeneric(struct Message *msg) { uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\t%s%s%s", - cacheGet(Network, msg->params[1])->color, msg->params[1], + completeColor(Network, msg->params[1]), msg->params[1], msg->params[2], (msg->params[3] ? " " : ""), (msg->params[3] ?: "") ); } @@ -1191,13 +1149,13 @@ static void handleReplyWhoisGeneric(struct Message *msg) { static void handleReplyEndOfWhois(struct Message *msg) { require(msg, false, 2); if (strcmp(msg->params[1], self.nick)) { - cacheRemove(Network, msg->params[1]); + completeRemove(Network, msg->params[1]); } } static void handleReplyWhowasUser(struct Message *msg) { require(msg, false, 6); - cacheInsert(true, Network, msg->params[1])->color = hash(msg->params[2]); + completePull(Network, msg->params[1], hash(msg->params[2])); uiFormat( Network, Warm, tagTime(msg), "\3%02d%s\3\twas %s!%s@%s (%s)", @@ -1209,7 +1167,7 @@ static void handleReplyWhowasUser(struct Message *msg) { static void handleReplyEndOfWhowas(struct Message *msg) { require(msg, false, 2); if (strcmp(msg->params[1], self.nick)) { - cacheRemove(Network, msg->params[1]); + completeRemove(Network, msg->params[1]); } } @@ -1220,7 +1178,7 @@ static void handleReplyAway(struct Message *msg) { uiFormat( id, (id == Network ? Warm : Cold), tagTime(msg), "\3%02d%s\3\tis away: %s", - cacheGet(id, msg->params[1])->color, msg->params[1], msg->params[2] + completeColor(id, msg->params[1]), msg->params[1], msg->params[2] ); logFormat( id, tagTime(msg), "%s is away: %s", @@ -1291,7 +1249,7 @@ static char *colorMentions(char *ptr, char *end, uint id, const char *msg) { size_t len = strcspn(msg, ",:<> "); char *p = seprintf(ptr, end, "%.*s", (int)len, msg); - enum Color color = cacheGet(id, ptr)->color; + enum Color color = completeColor(id, ptr); if (color != Default) { ptr = seprintf(ptr, end, "\3%02d%.*s\3", color, (int)len, msg); } else { @@ -1331,7 +1289,7 @@ static void handlePrivmsg(struct Message *msg) { heat = filterCheck(heat, id, msg); if (heat > Warm && !mine && !query) highlight = true; if (!notice && !mine && heat > Ice) { - cacheInsert(true, id, msg->nick)->color = hash(msg->user); + completePull(id, msg->nick, hash(msg->user)); } if (heat > Ice) urlScan(id, msg->nick, msg->params[1]); @@ -1378,7 +1336,7 @@ static void handlePing(struct Message *msg) { static void handleError(struct Message *msg) { require(msg, false, 1); - errx(EX_UNAVAILABLE, "%s", msg->params[0]); + errx(69, "%s", msg->params[0]); } static const struct Handler { @@ -1398,7 +1356,6 @@ static const struct Handler { { "312", 0, handleReplyWhoisServer }, { "313", +ReplyWhois, handleReplyWhoisGeneric }, { "314", +ReplyWhowas, handleReplyWhowasUser }, - { "315", -ReplyWho, handleReplyEndOfWho }, { "317", +ReplyWhois, handleReplyWhoisIdle }, { "318", -ReplyWhois, handleReplyEndOfWhois }, { "319", +ReplyWhois, handleReplyWhoisChannels }, @@ -1416,7 +1373,6 @@ static const struct Handler { { "347", -ReplyInvex, NULL }, { "348", +ReplyExcepts, handleReplyExceptList }, { "349", -ReplyExcepts, NULL }, - { "352", +ReplyWho, handleReplyWho }, { "353", 0, handleReplyNames }, { "366", 0, handleReplyEndOfNames }, { "367", +ReplyBan, handleReplyBanList }, |