Factor out reply count checking and decrementing

master
C. McEnroe 2020-12-30 16:49:55 -05:00
parent 8b6a476c35
commit 519fcc436f
3 changed files with 121 additions and 173 deletions

33
chat.h
View File

@ -247,21 +247,24 @@ static inline void utilPush(struct Util *util, const char *arg) {
} }
} }
extern struct Replies { enum Reply {
uint away; ReplyAway = 1,
uint ban; ReplyBan,
uint excepts; ReplyExcepts,
uint help; ReplyHelp,
uint invex; ReplyInvex,
uint join; ReplyJoin,
uint list; ReplyList,
uint mode; ReplyMode,
uint names; ReplyNames,
uint topic; ReplyTopic,
uint who; ReplyWho,
uint whois; ReplyWhois,
uint whowas; ReplyWhowas,
} replies; ReplyCap,
};
extern uint replies[ReplyCap];
void handle(struct Message *msg); void handle(struct Message *msg);
void command(uint id, char *input); void command(uint id, char *input);

View File

@ -125,9 +125,9 @@ static void commandJoin(uint id, char *params) {
if (*ch == ',') count++; if (*ch == ',') count++;
} }
ircFormat("JOIN %s\r\n", params); ircFormat("JOIN %s\r\n", params);
replies.join += count; replies[ReplyJoin] += count;
replies.topic += count; replies[ReplyTopic] += count;
replies.names += count; replies[ReplyNames] += count;
} }
static void commandPart(uint id, char *params) { static void commandPart(uint id, char *params) {
@ -156,7 +156,7 @@ static void commandAway(uint id, char *params) {
} else { } else {
ircFormat("AWAY\r\n"); ircFormat("AWAY\r\n");
} }
replies.away++; replies[ReplyAway]++;
} }
static void commandSetname(uint id, char *params) { static void commandSetname(uint id, char *params) {
@ -170,20 +170,20 @@ static void commandTopic(uint id, char *params) {
ircFormat("TOPIC %s :%s\r\n", idNames[id], params); ircFormat("TOPIC %s :%s\r\n", idNames[id], params);
} else { } else {
ircFormat("TOPIC %s\r\n", idNames[id]); ircFormat("TOPIC %s\r\n", idNames[id]);
replies.topic++; replies[ReplyTopic]++;
} }
} }
static void commandNames(uint id, char *params) { static void commandNames(uint id, char *params) {
(void)params; (void)params;
ircFormat("NAMES %s\r\n", idNames[id]); ircFormat("NAMES %s\r\n", idNames[id]);
replies.names++; replies[ReplyNames]++;
} }
static void commandOps(uint id, char *params) { static void commandOps(uint id, char *params) {
(void)params; (void)params;
ircFormat("WHO %s\r\n", idNames[id]); ircFormat("WHO %s\r\n", idNames[id]);
replies.who++; replies[ReplyWho]++;
} }
static void commandInvite(uint id, char *params) { static void commandInvite(uint id, char *params) {
@ -208,14 +208,14 @@ static void commandMode(uint id, char *params) {
ircFormat("MODE %s %s\r\n", self.nick, params); ircFormat("MODE %s %s\r\n", self.nick, params);
} else { } else {
ircFormat("MODE %s\r\n", self.nick); ircFormat("MODE %s\r\n", self.nick);
replies.mode++; replies[ReplyMode]++;
} }
} else { } else {
if (params) { if (params) {
ircFormat("MODE %s %s\r\n", idNames[id], params); ircFormat("MODE %s %s\r\n", idNames[id], params);
} else { } else {
ircFormat("MODE %s\r\n", idNames[id]); ircFormat("MODE %s\r\n", idNames[id]);
replies.mode++; replies[ReplyMode]++;
} }
} }
} }
@ -258,7 +258,7 @@ static void commandBan(uint id, char *params) {
channelListMode(id, '+', 'b', params); channelListMode(id, '+', 'b', params);
} else { } else {
ircFormat("MODE %s b\r\n", idNames[id]); ircFormat("MODE %s b\r\n", idNames[id]);
replies.ban++; replies[ReplyBan]++;
} }
} }
@ -272,7 +272,7 @@ static void commandExcept(uint id, char *params) {
channelListMode(id, '+', network.excepts, params); channelListMode(id, '+', network.excepts, params);
} else { } else {
ircFormat("MODE %s %c\r\n", idNames[id], network.excepts); ircFormat("MODE %s %c\r\n", idNames[id], network.excepts);
replies.excepts++; replies[ReplyExcepts]++;
} }
} }
@ -286,7 +286,7 @@ static void commandInvex(uint id, char *params) {
channelListMode(id, '+', network.invex, params); channelListMode(id, '+', network.invex, params);
} else { } else {
ircFormat("MODE %s %c\r\n", idNames[id], network.invex); ircFormat("MODE %s %c\r\n", idNames[id], network.invex);
replies.invex++; replies[ReplyInvex]++;
} }
} }
@ -302,7 +302,7 @@ static void commandList(uint id, char *params) {
} else { } else {
ircFormat("LIST\r\n"); ircFormat("LIST\r\n");
} }
replies.list++; replies[ReplyList]++;
} }
static void commandWhois(uint id, char *params) { static void commandWhois(uint id, char *params) {
@ -313,14 +313,14 @@ static void commandWhois(uint id, char *params) {
if (*ch == ',') count++; if (*ch == ',') count++;
} }
ircFormat("WHOIS %s\r\n", params); ircFormat("WHOIS %s\r\n", params);
replies.whois += count; replies[ReplyWhois] += count;
} }
static void commandWhowas(uint id, char *params) { static void commandWhowas(uint id, char *params) {
(void)id; (void)id;
if (!params) return; if (!params) return;
ircFormat("WHOWAS %s\r\n", params); ircFormat("WHOWAS %s\r\n", params);
replies.whowas++; replies[ReplyWhowas]++;
} }
static void commandNS(uint id, char *params) { static void commandNS(uint id, char *params) {
@ -437,7 +437,7 @@ static void commandHelp(uint id, char *params) {
if (params) { if (params) {
ircFormat("HELP :%s\r\n", params); ircFormat("HELP :%s\r\n", params);
replies.help++; replies[ReplyHelp]++;
return; return;
} }

229
handle.c
View File

@ -37,7 +37,7 @@
#include "chat.h" #include "chat.h"
struct Replies replies; uint replies[ReplyCap];
static const char *CapNames[] = { static const char *CapNames[] = {
#define X(name, id) [id##Bit] = name, #define X(name, id) [id##Bit] = name,
@ -244,9 +244,9 @@ static void handleReplyWelcome(struct Message *msg) {
if (*ch == ',') count++; if (*ch == ',') count++;
} }
ircFormat("JOIN %s\r\n", self.join); ircFormat("JOIN %s\r\n", self.join);
replies.join += count; replies[ReplyJoin] += count;
replies.topic += count; replies[ReplyTopic] += count;
replies.names += count; replies[ReplyNames] += count;
} }
} }
@ -316,16 +316,10 @@ static void handleErrorNoMOTD(struct Message *msg) {
static void handleReplyHelp(struct Message *msg) { static void handleReplyHelp(struct Message *msg) {
require(msg, false, 3); require(msg, false, 3);
if (!replies.help) return;
urlScan(Network, msg->nick, msg->params[2]); urlScan(Network, msg->nick, msg->params[2]);
uiWrite(Network, Warm, tagTime(msg), msg->params[2]); uiWrite(Network, Warm, tagTime(msg), msg->params[2]);
} }
static void handleReplyEndOfHelp(struct Message *msg) {
(void)msg;
if (replies.help) replies.help--;
}
static void handleJoin(struct Message *msg) { static void handleJoin(struct Message *msg) {
require(msg, true, 1); require(msg, true, 1);
uint id = idFor(msg->params[0]); uint id = idFor(msg->params[0]);
@ -339,9 +333,9 @@ static void handleJoin(struct Message *msg) {
} }
idColors[id] = hash(msg->params[0]); idColors[id] = hash(msg->params[0]);
completeTouch(None, msg->params[0], idColors[id]); completeTouch(None, msg->params[0], idColors[id]);
if (replies.join) { if (replies[ReplyJoin]) {
uiShowID(id); uiShowID(id);
replies.join--; replies[ReplyJoin]--;
} }
} }
completeTouch(id, msg->nick, hash(msg->user)); completeTouch(id, msg->nick, hash(msg->user));
@ -535,7 +529,7 @@ static void handleReplyNames(struct Message *msg) {
char *user = strsep(&name, "@"); char *user = strsep(&name, "@");
enum Color color = (user ? hash(user) : Default); enum Color color = (user ? hash(user) : Default);
completeAdd(id, nick, color); completeAdd(id, nick, color);
if (!replies.names) continue; if (!replies[ReplyNames]) continue;
catf(&cat, "%s\3%02d%s\3", (buf[0] ? ", " : ""), color, prefixes); catf(&cat, "%s\3%02d%s\3", (buf[0] ? ", " : ""), color, prefixes);
} }
if (!cat.len) return; if (!cat.len) return;
@ -546,17 +540,11 @@ static void handleReplyNames(struct Message *msg) {
); );
} }
static void handleReplyEndOfNames(struct Message *msg) {
(void)msg;
if (replies.names) replies.names--;
}
static char whoBuf[1024]; static char whoBuf[1024];
static struct Cat whoCat = { whoBuf, sizeof(whoBuf), 0 }; static struct Cat whoCat = { whoBuf, sizeof(whoBuf), 0 };
static void handleReplyWho(struct Message *msg) { static void handleReplyWho(struct Message *msg) {
require(msg, false, 7); require(msg, false, 7);
if (!replies.who) return;
if (!whoCat.len) { if (!whoCat.len) {
catf( catf(
&whoCat, "The operators of \3%02d%s\3 are ", &whoCat, "The operators of \3%02d%s\3 are ",
@ -577,16 +565,12 @@ static void handleReplyWho(struct Message *msg) {
static void handleReplyEndOfWho(struct Message *msg) { static void handleReplyEndOfWho(struct Message *msg) {
require(msg, false, 2); require(msg, false, 2);
if (!replies.who) return;
replies.who--;
uiWrite(idFor(msg->params[1]), Cold, tagTime(msg), whoBuf); uiWrite(idFor(msg->params[1]), Cold, tagTime(msg), whoBuf);
whoCat.len = 0; whoCat.len = 0;
} }
static void handleReplyNoTopic(struct Message *msg) { static void handleReplyNoTopic(struct Message *msg) {
require(msg, false, 2); require(msg, false, 2);
if (!replies.topic) return;
replies.topic--;
uiFormat( uiFormat(
idFor(msg->params[1]), Cold, tagTime(msg), idFor(msg->params[1]), Cold, tagTime(msg),
"There is no sign in \3%02d%s\3", "There is no sign in \3%02d%s\3",
@ -611,8 +595,8 @@ static void handleReplyTopic(struct Message *msg) {
require(msg, false, 3); require(msg, false, 3);
uint id = idFor(msg->params[1]); uint id = idFor(msg->params[1]);
topicComplete(id, msg->params[2]); topicComplete(id, msg->params[2]);
if (!replies.topic) return; if (!replies[ReplyTopic]) return;
replies.topic--; replies[ReplyTopic]--;
urlScan(id, NULL, msg->params[2]); urlScan(id, NULL, msg->params[2]);
uiFormat( uiFormat(
id, Cold, tagTime(msg), id, Cold, tagTime(msg),
@ -709,9 +693,6 @@ static const char *UserModes[256] = {
static void handleReplyUserModeIs(struct Message *msg) { static void handleReplyUserModeIs(struct Message *msg) {
require(msg, false, 2); require(msg, false, 2);
if (!replies.mode) return;
replies.mode--;
char buf[1024] = ""; char buf[1024] = "";
struct Cat cat = { buf, sizeof(buf), 0 }; struct Cat cat = { buf, sizeof(buf), 0 };
for (char *ch = msg->params[1]; *ch; ++ch) { for (char *ch = msg->params[1]; *ch; ++ch) {
@ -743,9 +724,6 @@ static const char *ChanModes[256] = {
static void handleReplyChannelModeIs(struct Message *msg) { static void handleReplyChannelModeIs(struct Message *msg) {
require(msg, false, 3); require(msg, false, 3);
if (!replies.mode) return;
replies.mode--;
uint param = 3; uint param = 3;
char buf[1024] = ""; char buf[1024] = "";
struct Cat cat = { buf, sizeof(buf), 0 }; struct Cat cat = { buf, sizeof(buf), 0 };
@ -955,7 +933,6 @@ static void handleErrorBanListFull(struct Message *msg) {
static void handleReplyBanList(struct Message *msg) { static void handleReplyBanList(struct Message *msg) {
require(msg, false, 3); require(msg, false, 3);
if (!replies.ban) return;
uint id = idFor(msg->params[1]); uint id = idFor(msg->params[1]);
if (msg->params[3] && msg->params[4]) { if (msg->params[3] && msg->params[4]) {
char since[sizeof("0000-00-00 00:00:00")]; char since[sizeof("0000-00-00 00:00:00")];
@ -977,12 +954,8 @@ static void handleReplyBanList(struct Message *msg) {
} }
} }
static void handleReplyEndOfBanList(struct Message *msg) {
(void)msg;
if (replies.ban) replies.ban--;
}
static void onList(const char *list, struct Message *msg) { static void onList(const char *list, struct Message *msg) {
require(msg, false, 3);
uint id = idFor(msg->params[1]); uint id = idFor(msg->params[1]);
if (msg->params[3] && msg->params[4]) { if (msg->params[3] && msg->params[4]) {
char since[sizeof("0000-00-00 00:00:00")]; char since[sizeof("0000-00-00 00:00:00")];
@ -1005,30 +978,15 @@ static void onList(const char *list, struct Message *msg) {
} }
static void handleReplyExceptList(struct Message *msg) { static void handleReplyExceptList(struct Message *msg) {
require(msg, false, 3);
if (!replies.excepts) return;
onList("except", msg); onList("except", msg);
} }
static void handleReplyEndOfExceptList(struct Message *msg) {
(void)msg;
if (replies.excepts) replies.excepts--;
}
static void handleReplyInviteList(struct Message *msg) { static void handleReplyInviteList(struct Message *msg) {
require(msg, false, 3);
if (!replies.invex) return;
onList("invite", msg); onList("invite", msg);
} }
static void handleReplyEndOfInviteList(struct Message *msg) {
(void)msg;
if (replies.invex) replies.invex--;
}
static void handleReplyList(struct Message *msg) { static void handleReplyList(struct Message *msg) {
require(msg, false, 4); require(msg, false, 4);
if (!replies.list) return;
uiFormat( uiFormat(
Network, Warm, tagTime(msg), Network, Warm, tagTime(msg),
"In \3%02d%s\3 are %ld under the banner: %s", "In \3%02d%s\3 are %ld under the banner: %s",
@ -1038,15 +996,8 @@ static void handleReplyList(struct Message *msg) {
); );
} }
static void handleReplyListEnd(struct Message *msg) {
(void)msg;
if (!replies.list) return;
replies.list--;
}
static void handleReplyWhoisUser(struct Message *msg) { static void handleReplyWhoisUser(struct Message *msg) {
require(msg, false, 6); require(msg, false, 6);
if (!replies.whois) return;
completeTouch(Network, msg->params[1], hash(msg->params[2])); completeTouch(Network, msg->params[1], hash(msg->params[2]));
uiFormat( uiFormat(
Network, Warm, tagTime(msg), Network, Warm, tagTime(msg),
@ -1057,19 +1008,18 @@ static void handleReplyWhoisUser(struct Message *msg) {
} }
static void handleReplyWhoisServer(struct Message *msg) { static void handleReplyWhoisServer(struct Message *msg) {
if (!replies[ReplyWhois] && !replies[ReplyWhowas]) return;
require(msg, false, 4); require(msg, false, 4);
if (!replies.whois && !replies.whowas) return;
uiFormat( uiFormat(
Network, Warm, tagTime(msg), Network, Warm, tagTime(msg),
"\3%02d%s\3\t%s connected to %s (%s)", "\3%02d%s\3\t%s connected to %s (%s)",
completeColor(Network, msg->params[1]), msg->params[1], completeColor(Network, msg->params[1]), msg->params[1],
(replies.whowas ? "was" : "is"), msg->params[2], msg->params[3] (replies[ReplyWhowas] ? "was" : "is"), msg->params[2], msg->params[3]
); );
} }
static void handleReplyWhoisIdle(struct Message *msg) { static void handleReplyWhoisIdle(struct Message *msg) {
require(msg, false, 3); require(msg, false, 3);
if (!replies.whois) return;
unsigned long idle = strtoul(msg->params[2], NULL, 10); unsigned long idle = strtoul(msg->params[2], NULL, 10);
const char *unit = "second"; const char *unit = "second";
if (idle / 60) { if (idle / 60) {
@ -1095,7 +1045,6 @@ static void handleReplyWhoisIdle(struct Message *msg) {
static void handleReplyWhoisChannels(struct Message *msg) { static void handleReplyWhoisChannels(struct Message *msg) {
require(msg, false, 3); require(msg, false, 3);
if (!replies.whois) return;
char buf[1024] = ""; char buf[1024] = "";
struct Cat cat = { buf, sizeof(buf), 0 }; struct Cat cat = { buf, sizeof(buf), 0 };
while (msg->params[2]) { while (msg->params[2]) {
@ -1112,7 +1061,6 @@ static void handleReplyWhoisChannels(struct Message *msg) {
static void handleReplyWhoisGeneric(struct Message *msg) { static void handleReplyWhoisGeneric(struct Message *msg) {
require(msg, false, 3); require(msg, false, 3);
if (!replies.whois) return;
if (msg->params[3]) { if (msg->params[3]) {
msg->params[0] = msg->params[2]; msg->params[0] = msg->params[2];
msg->params[2] = msg->params[3]; msg->params[2] = msg->params[3];
@ -1128,16 +1076,13 @@ static void handleReplyWhoisGeneric(struct Message *msg) {
static void handleReplyEndOfWhois(struct Message *msg) { static void handleReplyEndOfWhois(struct Message *msg) {
require(msg, false, 2); require(msg, false, 2);
if (!replies.whois) return;
if (strcmp(msg->params[1], self.nick)) { if (strcmp(msg->params[1], self.nick)) {
completeRemove(Network, msg->params[1]); completeRemove(Network, msg->params[1]);
} }
replies.whois--;
} }
static void handleReplyWhowasUser(struct Message *msg) { static void handleReplyWhowasUser(struct Message *msg) {
require(msg, false, 6); require(msg, false, 6);
if (!replies.whowas) return;
completeTouch(Network, msg->params[1], hash(msg->params[2])); completeTouch(Network, msg->params[1], hash(msg->params[2]));
uiFormat( uiFormat(
Network, Warm, tagTime(msg), Network, Warm, tagTime(msg),
@ -1152,7 +1097,6 @@ static void handleReplyEndOfWhowas(struct Message *msg) {
if (strcmp(msg->params[1], self.nick)) { if (strcmp(msg->params[1], self.nick)) {
completeRemove(Network, msg->params[1]); completeRemove(Network, msg->params[1]);
} }
if (replies.whowas) replies.whowas--;
} }
static void handleReplyAway(struct Message *msg) { static void handleReplyAway(struct Message *msg) {
@ -1177,9 +1121,7 @@ static void handleReplyAway(struct Message *msg) {
static void handleReplyNowAway(struct Message *msg) { static void handleReplyNowAway(struct Message *msg) {
require(msg, false, 2); require(msg, false, 2);
if (!replies.away) return;
uiFormat(Network, Warm, tagTime(msg), "%s", msg->params[1]); uiFormat(Network, Warm, tagTime(msg), "%s", msg->params[1]);
replies.away--;
} }
static bool isAction(struct Message *msg) { static bool isAction(struct Message *msg) {
@ -1307,79 +1249,80 @@ static void handleError(struct Message *msg) {
static const struct Handler { static const struct Handler {
const char *cmd; const char *cmd;
int reply;
Handler *fn; Handler *fn;
} Handlers[] = { } Handlers[] = {
{ "001", handleReplyWelcome }, { "001", 0, handleReplyWelcome },
{ "005", handleReplyISupport }, { "005", 0, handleReplyISupport },
{ "221", handleReplyUserModeIs }, { "221", -ReplyMode, handleReplyUserModeIs },
{ "276", handleReplyWhoisGeneric }, { "276", +ReplyWhois, handleReplyWhoisGeneric },
{ "301", handleReplyAway }, { "301", 0, handleReplyAway },
{ "305", handleReplyNowAway }, { "305", -ReplyAway, handleReplyNowAway },
{ "306", handleReplyNowAway }, { "306", -ReplyAway, handleReplyNowAway },
{ "307", handleReplyWhoisGeneric }, { "307", +ReplyWhois, handleReplyWhoisGeneric },
{ "311", handleReplyWhoisUser }, { "311", +ReplyWhois, handleReplyWhoisUser },
{ "312", handleReplyWhoisServer }, { "312", 0, handleReplyWhoisServer },
{ "313", handleReplyWhoisGeneric }, { "313", +ReplyWhois, handleReplyWhoisGeneric },
{ "314", handleReplyWhowasUser }, { "314", +ReplyWhowas, handleReplyWhowasUser },
{ "315", handleReplyEndOfWho }, { "315", -ReplyWho, handleReplyEndOfWho },
{ "317", handleReplyWhoisIdle }, { "317", +ReplyWhois, handleReplyWhoisIdle },
{ "318", handleReplyEndOfWhois }, { "318", -ReplyWhois, handleReplyEndOfWhois },
{ "319", handleReplyWhoisChannels }, { "319", +ReplyWhois, handleReplyWhoisChannels },
{ "322", handleReplyList }, { "322", +ReplyList, handleReplyList },
{ "323", handleReplyListEnd }, { "323", -ReplyList, NULL },
{ "324", handleReplyChannelModeIs }, { "324", -ReplyMode, handleReplyChannelModeIs },
{ "330", handleReplyWhoisGeneric }, { "330", +ReplyWhois, handleReplyWhoisGeneric },
{ "331", handleReplyNoTopic }, { "331", -ReplyTopic, handleReplyNoTopic },
{ "332", handleReplyTopic }, { "332", 0, handleReplyTopic },
{ "341", handleReplyInviting }, { "341", 0, handleReplyInviting },
{ "346", handleReplyInviteList }, { "346", +ReplyInvex, handleReplyInviteList },
{ "347", handleReplyEndOfInviteList }, { "347", -ReplyInvex, NULL },
{ "348", handleReplyExceptList }, { "348", +ReplyExcepts, handleReplyExceptList },
{ "349", handleReplyEndOfExceptList }, { "349", -ReplyExcepts, NULL },
{ "352", handleReplyWho }, { "352", +ReplyWho, handleReplyWho },
{ "353", handleReplyNames }, { "353", 0, handleReplyNames },
{ "366", handleReplyEndOfNames }, { "366", -ReplyNames, NULL },
{ "367", handleReplyBanList }, { "367", +ReplyBan, handleReplyBanList },
{ "368", handleReplyEndOfBanList }, { "368", -ReplyBan, NULL },
{ "369", handleReplyEndOfWhowas }, { "369", -ReplyWhowas, handleReplyEndOfWhowas },
{ "372", handleReplyMOTD }, { "372", 0, handleReplyMOTD },
{ "378", handleReplyWhoisGeneric }, { "378", +ReplyWhois, handleReplyWhoisGeneric },
{ "379", handleReplyWhoisGeneric }, { "379", +ReplyWhois, handleReplyWhoisGeneric },
{ "422", handleErrorNoMOTD }, { "422", 0, handleErrorNoMOTD },
{ "432", handleErrorErroneousNickname }, { "432", 0, handleErrorErroneousNickname },
{ "433", handleErrorNicknameInUse }, { "433", 0, handleErrorNicknameInUse },
{ "437", handleErrorNicknameInUse }, { "437", 0, handleErrorNicknameInUse },
{ "441", handleErrorUserNotInChannel }, { "441", 0, handleErrorUserNotInChannel },
{ "443", handleErrorUserOnChannel }, { "443", 0, handleErrorUserOnChannel },
{ "478", handleErrorBanListFull }, { "478", 0, handleErrorBanListFull },
{ "482", handleErrorChanopPrivsNeeded }, { "482", 0, handleErrorChanopPrivsNeeded },
{ "671", handleReplyWhoisGeneric }, { "671", +ReplyWhois, handleReplyWhoisGeneric },
{ "704", handleReplyHelp }, { "704", +ReplyHelp, handleReplyHelp },
{ "705", handleReplyHelp }, { "705", +ReplyHelp, handleReplyHelp },
{ "706", handleReplyEndOfHelp }, { "706", -ReplyHelp, NULL },
{ "900", handleReplyLoggedIn }, { "900", 0, handleReplyLoggedIn },
{ "904", handleErrorSASLFail }, { "904", 0, handleErrorSASLFail },
{ "905", handleErrorSASLFail }, { "905", 0, handleErrorSASLFail },
{ "906", handleErrorSASLFail }, { "906", 0, handleErrorSASLFail },
{ "AUTHENTICATE", handleAuthenticate }, { "AUTHENTICATE", 0, handleAuthenticate },
{ "CAP", handleCap }, { "CAP", 0, handleCap },
{ "CHGHOST", handleChghost }, { "CHGHOST", 0, handleChghost },
{ "ERROR", handleError }, { "ERROR", 0, handleError },
{ "FAIL", handleStandardReply }, { "FAIL", 0, handleStandardReply },
{ "INVITE", handleInvite }, { "INVITE", 0, handleInvite },
{ "JOIN", handleJoin }, { "JOIN", 0, handleJoin },
{ "KICK", handleKick }, { "KICK", 0, handleKick },
{ "MODE", handleMode }, { "MODE", 0, handleMode },
{ "NICK", handleNick }, { "NICK", 0, handleNick },
{ "NOTE", handleStandardReply }, { "NOTE", 0, handleStandardReply },
{ "NOTICE", handlePrivmsg }, { "NOTICE", 0, handlePrivmsg },
{ "PART", handlePart }, { "PART", 0, handlePart },
{ "PING", handlePing }, { "PING", 0, handlePing },
{ "PRIVMSG", handlePrivmsg }, { "PRIVMSG", 0, handlePrivmsg },
{ "QUIT", handleQuit }, { "QUIT", 0, handleQuit },
{ "SETNAME", handleSetname }, { "SETNAME", 0, handleSetname },
{ "TOPIC", handleTopic }, { "TOPIC", 0, handleTopic },
{ "WARN", handleStandardReply }, { "WARN", 0, handleStandardReply },
}; };
static int compar(const void *cmd, const void *_handler) { static int compar(const void *cmd, const void *_handler) {
@ -1396,7 +1339,9 @@ void handle(struct Message *msg) {
msg->cmd, Handlers, ARRAY_LEN(Handlers), sizeof(*handler), compar msg->cmd, Handlers, ARRAY_LEN(Handlers), sizeof(*handler), compar
); );
if (handler) { if (handler) {
handler->fn(msg); if (handler->reply && !replies[abs(handler->reply)]) return;
if (handler->fn) handler->fn(msg);
if (handler->reply < 0) replies[abs(handler->reply)]--;
} else if (strcmp(msg->cmd, "400") >= 0 && strcmp(msg->cmd, "599") <= 0) { } else if (strcmp(msg->cmd, "400") >= 0 && strcmp(msg->cmd, "599") <= 0) {
handleErrorGeneric(msg); handleErrorGeneric(msg);
} }