fflush(fchanlog);
}
}
-void sendbuf_chan(struct channel *chan) {
- struct trie_find *f = NULL;
- if (trie_findfirst(&f, &chan->members) == 1)
- do {
- struct client_data *cl = f->n->value;
- 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)
sendbuf(cl);
} while (trie_findnext(&f) == 1);
}
-void sendbuf_list_sans_self(struct client_data *client, struct trie_node **ls, int cookie) {
+void sendbuf_chan(struct channel *chan) {
+ sendbuf_chan_caps(chan, 0, 0);
+}
+void sendbuf_list_sans_self_caps(struct client_data *client, struct trie_node **ls, int cookie, int positive, int negative) {
struct trie_find *f = NULL;
if (trie_findfirst(&f, ls) == 1)
do {
else
continue;
}
- sendbuf(cl);
+ 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) {
+ sendbuf_list_sans_self_caps(client, ls, cookie, 0, 0);
+}
int get_cookie() {
static int cookie = 0;
if (++cookie == 0) {
}
return cookie;
}
-void sendbuf_visible(struct client_data *client) {
+void sendbuf_visible_caps(struct client_data *client, int positive, int negative) {
int cookie = get_cookie();
struct trie_find *f = NULL;
if (trie_findfirst(&f, &client->channels) == 1)
do {
struct channel *chan = f->n->value;
- sendbuf_list_sans_self(client, &chan->members, cookie);
+ sendbuf_list_sans_self_caps(client, &chan->members, cookie, positive, negative);
} while (trie_findnext(&f) == 1);
}
+void sendbuf_visible(struct client_data *client) {
+ sendbuf_visible_caps(client, 0, 0);
+}
const char *format_umodes(struct client_data *cl) {
static char umodes[6] = "";
char *p = umodes;
{ "cap-notify", 0 },
{ "multi-prefix", CAP_MULTIPREFIX },
{ "extended-join", CAP_EXTENDEDJOIN },
+ { "away-notify", CAP_AWAYNOTIFY },
{ 0, 0 }
};
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 extended-join\r\n", hostname);
+ copy_strf(&databuf, ":%s CAP * LS :multi-prefix extended-join away-notify\r\n", hostname);
sendbuf(client);
if (!is_registered(client)) {
client->regstate = REG_CAPLS;
client->away = NULL;
rpl_unaway(client), sendbuf(client);
}
+ msg_away(client);
+ sendbuf_visible_caps(client, CAP_AWAYNOTIFY, 0);
} else {
unknown:
err_unknowncommand(client, command), sendbuf(client);
sendbuf_chan_caps(chan, 0, CAP_EXTENDEDJOIN);
msg_join_extended(client, chan);
sendbuf_chan_caps(chan, CAP_EXTENDEDJOIN, 0);
+ // send AWAY
+ if (client->away) {
+ msg_away(client);
+ sendbuf_list_sans_self_caps(client, &chan->members, 0, CAP_AWAYNOTIFY, 0);
+ }
// TODO: send channel modes to the joining client
// apply +w modes
if (match_list(client, &chan->listwo)) {
return "";
}
+void msg_away(struct client_data *src)
+{
+ if (src->away)
+ copy_strf(&databuf, ":%s!%s@%s AWAY :%s\r\n",
+ src->nick, src->username, src->hostname, src->away);
+ else
+ copy_strf(&databuf, ":%s!%s@%s AWAY\r\n",
+ src->nick, src->username, src->hostname);
+}
void msg_nick(struct client_data *src, const char *newnick)
{
copy_strf(&databuf, ":%s!%s@%s NICK %s\r\n",
}
void rpl_unaway(struct client_data *client) // 305
{
- copy_strf(&databuf, ":%s 305 %s :You have been marked as being away\r\n", hostname, client->nick);
+ copy_strf(&databuf, ":%s 305 %s :You are no longer marked as being away\r\n", hostname, client->nick);
}
void rpl_nowaway(struct client_data *client) // 306
{
- copy_strf(&databuf, ":%s 306 %s :You are no longer marked as being away\r\n", hostname, client->nick);
+ copy_strf(&databuf, ":%s 306 %s :You have been marked as being away\r\n", hostname, client->nick);
}
void rpl_whoreply(struct client_data *client, struct client_data *cl, struct channel *chan) // 352
{