From 6ad38c3670d67ab8eb68d052b0edf03eb25fa92a Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 3 Feb 2023 18:38:31 +0200 Subject: [PATCH] add extended-join cap --- common.h | 1 + irc.c | 20 +++++++++++++++++--- ircfmt.c | 6 ++++++ ircfmt.h | 1 + 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/common.h b/common.h index 387f3f9..c6c6109 100644 --- a/common.h +++ b/common.h @@ -21,6 +21,7 @@ struct tls; #define REG_REGISTERED 2 #define CAP_302 1 #define CAP_MULTIPREFIX 2 +#define CAP_EXTENDEDJOIN 4 struct client_data { SOCKET FD; struct tls *cctx; diff --git a/irc.c b/irc.c index b1e0a96..71fce10 100644 --- a/irc.c +++ b/irc.c @@ -35,6 +35,15 @@ void sendbuf_chan(struct channel *chan) { sendbuf(cl); } while (trie_findnext(&f) == 1); } +void sendbuf_chan_caps(struct channel *chan, unsigned positive, unsigned negative) { + struct trie_find *f = NULL; + if (trie_findfirst(&f, &chan->members) == 1) + do { + struct client_data *cl = f->n->value; + if (!(~cl->caps & positive) && !(cl->caps & negative)) + sendbuf(cl); + } while (trie_findnext(&f) == 1); +} void sendbuf_list_sans_self(struct client_data *client, struct trie_node **ls, int cookie) { struct trie_find *f = NULL; if (trie_findfirst(&f, ls) == 1) @@ -182,8 +191,9 @@ int processPacket(struct client_data *client, char *source, char *command, int a const char *name; unsigned caps; } caps[] = { - { "multi-prefix", CAP_MULTIPREFIX }, { "cap-notify", 0 }, + { "multi-prefix", CAP_MULTIPREFIX }, + { "extended-join", CAP_EXTENDEDJOIN }, { 0, 0 } }; @@ -193,7 +203,7 @@ int processPacket(struct client_data *client, char *source, char *command, int a if (strcmp(args[0], "LS") == 0) { if (args[1] && atoi(args[1]) >= 302) client->caps |= CAP_302; - copy_strf(&databuf, ":%s CAP * LS :multi-prefix\r\n", hostname); + copy_strf(&databuf, ":%s CAP * LS :multi-prefix extended-join\r\n", hostname); sendbuf(client); if (!is_registered(client)) { client->regstate = REG_CAPLS; @@ -219,6 +229,7 @@ int processPacket(struct client_data *client, char *source, char *command, int a const struct cap *c; for (c = caps; c->name; c++) { if (strcmp(p, c->name) == 0) { + // FIXME: it's preferrable to send these in one line copy_strf(&databuf, ":%s CAP * ACK :%s%s\r\n", hostname, invert?"-":"", c->name); if (!invert) client->caps |= c->caps; @@ -239,6 +250,7 @@ int processPacket(struct client_data *client, char *source, char *command, int a newUser(client); } } else { + // FIXME: error 410 goto unknown; } } else if(strcmp(command, "NICK") == 0) { @@ -1228,7 +1240,9 @@ void channel_join(struct client_data *client, const char *channel, const char *c msg_join(client, chan); if (newchan) chanlog_time(chan->creation); - sendbuf_chan(chan); + sendbuf_chan_caps(chan, 0, CAP_EXTENDEDJOIN); + msg_join_extended(client, chan); + sendbuf_chan_caps(chan, CAP_EXTENDEDJOIN, 0); // TODO: send channel modes to the joining client // apply +w modes if (match_list(client, &chan->listwo)) { diff --git a/ircfmt.c b/ircfmt.c index ad70f48..8100876 100644 --- a/ircfmt.c +++ b/ircfmt.c @@ -46,6 +46,12 @@ void msg_join(struct client_data *src, struct channel *chan) copy_strf(&databuf, ":%s!%s@%s JOIN %s\r\n", src->nick, src->username, src->hostname, chan->name); } +void msg_join_extended(struct client_data *src, struct channel *chan) +{ + copy_strf(&databuf, ":%s!%s@%s JOIN %s %s :%s\r\n", + src->nick, src->username, src->hostname, chan->name, + src->username[0] != '~' ? src->username : "*", src->realname); +} void msg_part(struct client_data *src, struct channel *chan, const char *reason) { if (reason) diff --git a/ircfmt.h b/ircfmt.h index 975a1de..8df2ed3 100644 --- a/ircfmt.h +++ b/ircfmt.h @@ -7,6 +7,7 @@ void msg_pong(const char *token); void msg_quit(struct client_data *src, const char *prefix, const char *reason); void msg_error(const char *reason); void msg_join(struct client_data *src, struct channel *chan); +void msg_join_extended(struct client_data *src, struct channel *chan); void msg_part(struct client_data *src, struct channel *chan, const char *reason); void msg_topic(struct client_data *src, struct channel *chan); void msg_invite(struct client_data *src, struct client_data *dst, struct channel *chan); -- 2.56.0