From 3475f03ec8c9ee26544c17b5f3d1cba7b1104f5e Mon Sep 17 00:00:00 2001 From: June McEnroe Date: Sun, 29 May 2022 18:09:52 -0400 Subject: Allow setting fallback nicks and highlight on any As a side-effect, even with only one nick set you'll still be highlighted by it even if your current nick is different. --- catgirl.1 | 7 ++++++- chat.c | 17 ++++++++++------- chat.h | 7 ++++--- handle.c | 25 +++++++++++++++++++------ 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/catgirl.1 b/catgirl.1 index 9e28bda..c5cb101 100644 --- a/catgirl.1 +++ b/catgirl.1 @@ -312,12 +312,17 @@ Log chat events to files in paths Set the user .Ar mode . . -.It Fl n Ar nick | Cm nick No = Ar nick +.It Fl n Ar nick Oo Ar ... Oc | Cm nick No = Ar nick Oo Ar ... Oc Set nickname to .Ar nick . The default nickname is the value of the environment variable .Ev USER . +Additional space-separated nicks +will be tried in order +if the first is not available, +and all nicks +are treated as highlight words. . .It Fl o Print the server certificate chain diff --git a/chat.c b/chat.c index b74fdc0..2d35771 100644 --- a/chat.c +++ b/chat.c @@ -237,7 +237,6 @@ int main(int argc, char *argv[]) { bool log = false; bool sasl = false; char *pass = NULL; - const char *nick = NULL; const char *user = NULL; const char *real = NULL; @@ -306,7 +305,11 @@ int main(int argc, char *argv[]) { break; case 'k': priv = optarg; break; case 'l': log = true; logOpen(); break; case 'm': self.mode = optarg; - break; case 'n': nick = optarg; + break; case 'n': { + for (uint i = 0; i < ARRAY_LEN(self.nicks); ++i) { + self.nicks[i] = strsep(&optarg, " "); + } + } break; case 'o': printCert = true; break; case 'p': port = optarg; break; case 'q': windowThreshold = Warm; @@ -333,10 +336,10 @@ int main(int argc, char *argv[]) { return EX_OK; } - if (!nick) nick = getenv("USER"); - if (!nick) errx(EX_CONFIG, "USER unset"); - if (!user) user = nick; - if (!real) real = nick; + if (!self.nicks[0]) self.nicks[0] = getenv("USER"); + if (!self.nicks[0]) errx(EX_CONFIG, "USER unset"); + if (!user) user = self.nicks[0]; + if (!real) real = self.nicks[0]; if (self.kiosk) { char *hash; @@ -404,7 +407,7 @@ int main(int argc, char *argv[]) { } if (sasl) ircFormat("CAP REQ :sasl\r\n"); ircFormat("CAP LS\r\n"); - ircFormat("NICK :%s\r\n", nick); + ircFormat("NICK %s\r\n", self.nicks[0]); ircFormat("USER %s 0 * :%s\r\n", user, real); // Avoid disabling VINTR until main loop. diff --git a/chat.h b/chat.h index 1c46f00..b252210 100644 --- a/chat.h +++ b/chat.h @@ -193,10 +193,11 @@ extern struct Self { bool restricted; size_t pos; enum Cap caps; - char *plainUser; + const char *plainUser; char *plainPass; - char *mode; - char *join; + const char *nicks[8]; + const char *mode; + const char *join; char *nick; char *user; char *host; diff --git a/handle.c b/handle.c index f51323d..e4fe0ab 100644 --- a/handle.c +++ b/handle.c @@ -148,7 +148,12 @@ static void handleReplyGeneric(struct Message *msg) { static void handleErrorNicknameInUse(struct Message *msg) { require(msg, false, 2); if (!strcmp(self.nick, "*")) { - ircFormat("NICK :%s_\r\n", msg->params[1]); + static uint i = 1; + if (i < ARRAY_LEN(self.nicks) && self.nicks[i]) { + ircFormat("NICK %s\r\n", self.nicks[i++]); + } else { + ircFormat("NICK %s_\r\n", msg->params[1]); + } } else { handleErrorGeneric(msg); } @@ -1207,11 +1212,11 @@ static bool isAction(struct Message *msg) { return true; } -static bool isMention(const struct Message *msg) { - size_t len = strlen(self.nick); - const char *match = msg->params[1]; - while (NULL != (match = strstr(match, self.nick))) { - char a = (match > msg->params[1] ? match[-1] : ' '); +static bool matchWord(const char *str, const char *word) { + size_t len = strlen(word); + const char *match = str; + while (NULL != (match = strstr(match, word))) { + char a = (match > str ? match[-1] : ' '); char b = (match[len] ?: ' '); if ((isspace(a) || ispunct(a)) && (isspace(b) || ispunct(b))) { return true; @@ -1221,6 +1226,14 @@ static bool isMention(const struct Message *msg) { return false; } +static bool isMention(const struct Message *msg) { + if (matchWord(msg->params[1], self.nick)) return true; + for (uint i = 0; i < ARRAY_LEN(self.nicks) && self.nicks[i]; ++i) { + if (matchWord(msg->params[1], self.nicks[i])) return true; + } + return false; +} + static void colorMentions(char *buf, size_t cap, uint id, struct Message *msg) { *buf = '\0'; -- cgit 1.4.1