summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorC. McEnroe2020-02-25 02:12:35 -0500
committerC. McEnroe2020-02-25 02:12:35 -0500
commit3c5e1c95a4091c26de8cc47e9cf222b74cec4fb3 (patch)
tree8c3d66e9729d990f0e031a83f9f2e2e5bfacbf89
parentc3c40d738ba7da34429eb98cca28640513d22ba3 (diff)
Add /mode, /except, /invex and handle lists replies
-rw-r--r--catgirl.132
-rw-r--r--chat.h2
-rw-r--r--command.c70
-rw-r--r--handle.c48
4 files changed, 134 insertions, 18 deletions
diff --git a/catgirl.1 b/catgirl.1
index fd8d40a..b1b72de 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -1,4 +1,4 @@
-.Dd February 19, 2020
+.Dd February 23, 2020
.Dt CATGIRL 1
.Os
.
@@ -242,16 +242,12 @@ can be typed
.Bl -tag -width Ds
.It Ic /away Op Ar message
Set or clear your away status.
-.It Ic /ban Op Ar mask ...
-List or ban masks from the channel.
.It Ic /cs Ar command
Send a command to ChanServ.
.It Ic /invite Ar nick
Invite a user to the channel.
.It Ic /join Ar channel
Join a channel.
-.It Ic /kick Ar nick Op Ar message
-Kick a user from the channel.
.It Ic /list Op Ar channel
List channels.
.It Ic /me Op Ar action
@@ -276,8 +272,6 @@ Quit IRC.
Send a raw IRC command.
.It Ic /topic Op Ar topic
Show or set the topic of the channel.
-.It Ic /unban Ar mask ...
-Unban masks from the channel.
.It Ic /whois Ar nick
Query information about a user.
.El
@@ -326,6 +320,30 @@ Switch to window by name.
Switch to window by number.
.El
.
+.Ss Operator Commands
+.Bl -tag -width Ds
+.It Ic /ban Op Ar mask ...
+List or ban masks from the channel.
+.It Ic /except Op Ar mask ...
+List or add masks to the channel ban exception list.
+.It Ic /invex Op Ar mask ...
+List or add masks to the channel invite list.
+.It Ic /kick Ar nick Op Ar message
+Kick a user from the channel.
+.It Ic /mode Oo Ar modes Oc Op Ar param ...
+Show or set channel modes.
+In the
+.Sy <network>
+window,
+show or set user modes.
+.It Ic /unban Ar mask ...
+Unban masks from the channel.
+.It Ic /unexcept Ar mask ...
+Remove masks from the channel ban exception list.
+.It Ic /uninvex Ar mask ...
+Remove masks from the channel invite list.
+.El
+.
.Sh KEY BINDINGS
The
.Nm
diff --git a/chat.h b/chat.h
index e42cf7b..5b4e14c 100644
--- a/chat.h
+++ b/chat.h
@@ -176,6 +176,8 @@ static inline void utilPush(struct Util *util, const char *arg) {
extern struct Replies {
uint away;
uint ban;
+ uint excepts;
+ uint invex;
uint join;
uint list;
uint names;
diff --git a/command.c b/command.c
index 1d19a91..c2ebab7 100644
--- a/command.c
+++ b/command.c
@@ -143,14 +143,34 @@ static void commandKick(uint id, char *params) {
}
}
+static void commandMode(uint id, char *params) {
+ if (id == Network) {
+ if (params) {
+ ircFormat("MODE %s %s\r\n", self.nick, params);
+ } else {
+ ircFormat("MODE %s\r\n", self.nick);
+ }
+ } else {
+ if (params) {
+ ircFormat("MODE %s %s\r\n", idNames[id], params);
+ } else {
+ ircFormat("MODE %s\r\n", idNames[id]);
+ }
+ }
+}
+
+static void channelListMode(uint id, char pm, char l, char *params) {
+ int count = 1;
+ for (char *ch = params; *ch; ++ch) {
+ if (*ch == ' ') count++;
+ }
+ char modes[ParamCap - 2] = { l, l, l, l, l, l, l, l, l, l, l, l, l };
+ ircFormat("MODE %s %c%.*s %s\r\n", idNames[id], pm, count, modes, params);
+}
+
static void commandBan(uint id, char *params) {
if (params) {
- int count = 1;
- for (char *ch = params; *ch; ++ch) {
- if (*ch == ' ') count++;
- }
- char b[ParamCap - 2] = "bbbbbbbbbbbbb";
- ircFormat("MODE %s +%.*s %s\r\n", idNames[id], count, b, params);
+ channelListMode(id, '+', 'b', params);
} else {
ircFormat("MODE %s b\r\n", idNames[id]);
replies.ban++;
@@ -159,12 +179,35 @@ static void commandBan(uint id, char *params) {
static void commandUnban(uint id, char *params) {
if (!params) return;
- int count = 1;
- for (char *ch = params; *ch; ++ch) {
- if (*ch == ' ') count++;
+ channelListMode(id, '-', 'b', params);
+}
+
+static void commandExcept(uint id, char *params) {
+ if (params) {
+ channelListMode(id, '+', network.excepts, params);
+ } else {
+ ircFormat("MODE %s %c\r\n", idNames[id], network.excepts);
+ replies.excepts++;
}
- char b[ParamCap - 2] = "bbbbbbbbbbbbb";
- ircFormat("MODE %s -%.*s %s\r\n", idNames[id], count, b, params);
+}
+
+static void commandUnexcept(uint id, char *params) {
+ if (!params) return;
+ channelListMode(id, '-', network.excepts, params);
+}
+
+static void commandInvex(uint id, char *params) {
+ if (params) {
+ channelListMode(id, '+', network.invex, params);
+ } else {
+ ircFormat("MODE %s %c\r\n", idNames[id], network.invex);
+ replies.invex++;
+ }
+}
+
+static void commandUninvex(uint id, char *params) {
+ if (!params) return;
+ channelListMode(id, '-', network.invex, params);
}
static void commandList(uint id, char *params) {
@@ -293,13 +336,16 @@ static const struct Handler {
{ "/copy", .fn = commandCopy, .restricted = true },
{ "/cs", .fn = commandCS },
{ "/debug", .fn = commandDebug, .restricted = true },
+ { "/except", .fn = commandExcept },
{ "/exec", .fn = commandExec, .restricted = true },
{ "/help", .fn = commandHelp },
+ { "/invex", .fn = commandInvex },
{ "/invite", .fn = commandInvite },
{ "/join", .fn = commandJoin, .restricted = true },
{ "/kick", .fn = commandKick },
{ "/list", .fn = commandList },
{ "/me", .fn = commandMe },
+ { "/mode", .fn = commandMode },
{ "/move", .fn = commandMove },
{ "/msg", .fn = commandMsg, .restricted = true },
{ "/names", .fn = commandNames },
@@ -313,6 +359,8 @@ static const struct Handler {
{ "/quote", .fn = commandQuote, .restricted = true },
{ "/topic", .fn = commandTopic },
{ "/unban", .fn = commandUnban },
+ { "/unexcept", .fn = commandUnexcept },
+ { "/uninvex", .fn = commandUninvex },
{ "/whois", .fn = commandWhois },
{ "/window", .fn = commandWindow },
};
diff --git a/handle.c b/handle.c
index 2dc4654..f1fc75d 100644
--- a/handle.c
+++ b/handle.c
@@ -606,6 +606,50 @@ static void handleReplyEndOfBanList(struct Message *msg) {
if (replies.ban) replies.ban--;
}
+static void onList(const char *list, struct Message *msg) {
+ uint id = idFor(msg->params[1]);
+ if (msg->params[3] && msg->params[4]) {
+ char since[sizeof("0000-00-00 00:00:00")];
+ time_t time = strtol(msg->params[4], NULL, 10);
+ strftime(since, sizeof(since), "%F %T", localtime(&time));
+ uiFormat(
+ id, Cold, 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, completeColor(id, msg->params[3]), msg->params[3],
+ msg->params[2]
+ );
+ } else {
+ uiFormat(
+ id, Cold, tagTime(msg),
+ "On the \3%02d%s\3 %s list: %s",
+ hash(msg->params[1]), msg->params[1], list, msg->params[2]
+ );
+ }
+}
+
+static void handleReplyExceptList(struct Message *msg) {
+ require(msg, false, 3);
+ if (!replies.excepts) return;
+ onList("except", msg);
+}
+
+static void handleReplyEndOfExceptList(struct Message *msg) {
+ (void)msg;
+ if (replies.excepts) replies.excepts--;
+}
+
+static void handleReplyInviteList(struct Message *msg) {
+ require(msg, false, 3);
+ if (!replies.invex) return;
+ onList("invite", msg);
+}
+
+static void handleReplyEndOfInviteList(struct Message *msg) {
+ (void)msg;
+ if (replies.invex) replies.invex--;
+}
+
static void handleReplyList(struct Message *msg) {
require(msg, false, 4);
if (!replies.list) return;
@@ -881,6 +925,10 @@ static const struct Handler {
{ "331", handleReplyNoTopic },
{ "332", handleReplyTopic },
{ "341", handleReplyInviting },
+ { "346", handleReplyInviteList },
+ { "347", handleReplyEndOfInviteList },
+ { "348", handleReplyExceptList },
+ { "349", handleReplyEndOfExceptList },
{ "353", handleReplyNames },
{ "366", handleReplyEndOfNames },
{ "367", handleReplyBanList },