hirc

IRC client
Log | Files | Refs

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:
Mchan.c | 1+
Mcommands.c | 47+++++++++++++++++++++++++++++++++++++++++++++++
Mhandle.c | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Mhirc.h | 4++++
Mstruct.h | 2++
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, };