commit 967f0bb8f21e10c4bb64a89de29f1994b40b57ac
parent dc445b6bb783f4e31c4007b264d5a04dc66c16a1
Author: hhvn <dev@hhvn.uk>
Date: Wed, 17 Nov 2021 00:08:30 +0000
chan.c commands.c handle.c hirc.h struct.h: /topic command
Diffstat:
5 files changed, 103 insertions(+), 0 deletions(-)
diff --git a/chan.c b/chan.c
@@ -37,6 +37,7 @@ chan_create(struct Server *server, char *name) {
channel->next = channel->prev = NULL;
channel->nicks = NULL;
channel->old = 0;
+ channel->mode = channel->topic = NULL;
channel->server = server;
channel->history = emalloc(sizeof(struct HistInfo));
channel->history->activity = Activity_ignore;
diff --git a/commands.c b/commands.c
@@ -52,6 +52,10 @@ struct Command commands[] = {
{"names", command_names, {
"usage: /names <channel>",
"List nicks in channel (pretty useless with nicklist.", NULL}},
+ {"topic", command_topic, {
+ "usage: /topic [-clear] <channel> [topic]",
+ "Sets, clears, or checks topic in channel.",
+ "Provide only channel name to check.", NULL}},
{"help", command_help, {
"usage: /help [command or variable]",
"Print help information.",
@@ -349,6 +353,49 @@ command_names(struct Server *server, char *str) {
}
void
+command_topic(struct Server *server, char *str) {
+ char *channel, *topic, *save = NULL;
+ int clear = 0, ret;
+ enum { opt_clear, };
+ struct CommandOpts opts[] = {
+ {"clear", CMD_NARG, opt_clear},
+ {NULL, 0, 0},
+ };
+
+ while ((ret = command_getopt(&str, opts)) != opt_done) {
+ switch (ret) {
+ case opt_error:
+ return;
+ case opt_clear:
+ clear = 1;
+ break;
+ }
+ }
+
+ channel = strtok_r(str, " ", &save);
+ topic = strtok_r(NULL, " ", &save);
+
+ if (!channel && selected.channel) {
+ channel = selected.channel->name;
+ } else if (!channel) {
+ ui_error("no channel selected", NULL);
+ return;
+ }
+
+ if (clear) {
+ if (topic)
+ ui_error("ignoring argument as -clear passed", NULL);
+ ircprintf(server, "TOPIC %s :\r\n", channel);
+ return;
+ }
+
+ if (!topic) {
+ ircprintf(server, "TOPIC %s\r\n", channel);
+ handle_expect(server, Expect_topic, channel);
+ } else ircprintf(server, "TOPIC %s :%s\r\n", channel, topic);
+}
+
+void
command_help(struct Server *server, char *str) {
int cmdonly = 0;
int i, j;
diff --git a/handle.c b/handle.c
@@ -17,6 +17,8 @@ struct Handler handlers[] = {
{ "NOTICE", handle_PRIVMSG },
{ "001", handle_WELCOME },
{ "005", handle_ISUPPORT },
+ { "332", handle_RPLTOPIC },
+ { "333", handle_TOPICWHOTIME },
{ "353", handle_NAMREPLY },
{ "366", handle_ENDOFNAMES },
{ "376", handle_ENDOFMOTD },
@@ -337,6 +339,53 @@ handle_NICK(char *msg, char **params, struct Server *server, time_t timestamp) {
}
void
+handle_RPLTOPIC(char *msg, char **params, struct Server *server, time_t timestamp) {
+ struct Channel *chan;
+ char *target, *topic;
+
+ if (param_len(params) < 5 || **params != ':')
+ return;
+
+ target = *(params+3);
+ topic = *(params+4);
+
+ if ((chan = chan_get(&server->channels, target, -1)) == NULL)
+ return;
+
+ free(chan->topic);
+ chan->topic = topic ? strdup(topic) : NULL;
+
+ if (strcmp_n(target, handle_expect_get(server, Expect_topic)) == 0) {
+ hist_add(chan->history, NULL, msg, params, Activity_status, timestamp, HIST_DFL);
+ handle_expect(server, Expect_topic, NULL);
+ handle_expect(server, Expect_topicwhotime, target);
+ } else {
+ hist_add(chan->history, NULL, msg, params, Activity_status, timestamp, HIST_LOG);
+ }
+}
+
+void
+handle_TOPICWHOTIME(char *msg, char **params, struct Server *server, time_t timestamp) {
+ struct Channel *chan;
+ char *target;
+
+ if (param_len(params) < 6 || **params != ':')
+ return;
+
+ target = *(params+3);
+
+ if ((chan = chan_get(&server->channels, target, -1)) == NULL)
+ return;
+
+ if (strcmp_n(target, handle_expect_get(server, Expect_topicwhotime)) == 0) {
+ hist_add(chan->history, NULL, msg, params, Activity_status, timestamp, HIST_DFL);
+ handle_expect(server, Expect_topicwhotime, NULL);
+ } else {
+ hist_add(chan->history, NULL, msg, params, Activity_status, timestamp, HIST_LOG);
+ }
+}
+
+void
handle_WELCOME(char *msg, char **params, struct Server *server, time_t timestamp) {
server->status = ConnStatus_connected;
hist_add(server->history, NULL, msg, params, Activity_status, timestamp, HIST_DFL);
diff --git a/hirc.h b/hirc.h
@@ -95,6 +95,9 @@ void handle_QUIT(char *msg, char **params, struct Server *server, time_t timest
void handle_PRIVMSG(char *msg, char **params, struct Server *server, time_t timestamp);
void handle_WELCOME(char *msg, char **params, struct Server *server, time_t timestamp);
void handle_ISUPPORT(char *msg, char **params, struct Server *server, time_t timestamp);
+void handle_RPLTOPIC(char *msg, char **params, struct Server *server, time_t timestamp);
+void handle_TOPICWHOTIME(char *msg, char **params, struct Server *server, time_t timestamp);
+void handle_NAMREPLY(char *msg, char **params, struct Server *server, time_t timestamp);
void handle_NAMREPLY(char *msg, char **params, struct Server *server, time_t timestamp);
void handle_ENDOFNAMES(char *msg, char **params, struct Server *server, time_t timestamp);
void handle_ENDOFMOTD(char *msg, char **params, struct Server *server, time_t timestamp);
@@ -145,6 +148,7 @@ void command_select(struct Server *server, char *str);
void command_set(struct Server *server, char *str);
void command_server(struct Server *server, char *str);
void command_names(struct Server *server, char *str);
+void command_topic(struct Server *server, char *str);
void command_help(struct Server *server, char *str);
/* config.c */
diff --git a/struct.h b/struct.h
@@ -90,6 +90,8 @@ enum Expect {
Expect_part,
Expect_pong,
Expect_names,
+ Expect_topic,
+ Expect_topicwhotime,
Expect_last,
};