From e763e7f06b3d37a0d9c0a0321dff957b55532e0f Mon Sep 17 00:00:00 2001 From: Egor Date: Fri, 27 Oct 2023 19:31:10 +0300 Subject: [PATCH] add WHOX support --- src/irc.c | 4 ++-- src/ircfmt.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/ircfmt.h | 1 + 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/irc.c b/src/irc.c index c02c367..4184026 100644 --- a/src/irc.c +++ b/src/irc.c @@ -981,12 +981,12 @@ int processPacket(struct client_data *client, char *source, char *command, int a if (chan) { struct client_data *cl; map_foreach(&chan->members, 0, &cl) - rpl_whoreply(client, cl, chan), sendbuf(client); + (args[1] ? rpl_whospcrpl(client, cl, chan, args[1]) : rpl_whoreply(client, cl, chan)), sendbuf(client); } } else { struct client_data *cl = findClient(args[0]); if (cl) - rpl_whoreply(client, cl, NULL), sendbuf(client); + (args[1] ? rpl_whospcrpl(client, cl, 0, args[1]) : rpl_whoreply(client, cl, 0)), sendbuf(client); } rpl_endofwho(client, args[0]), sendbuf(client); } else if(strcmp(command, "WHOIS") == 0) { diff --git a/src/ircfmt.c b/src/ircfmt.c index fc3affe..202267e 100644 --- a/src/ircfmt.c +++ b/src/ircfmt.c @@ -133,7 +133,7 @@ void rpl_myinfo(struct client_data *client) // 004 } void rpl_isupport(struct client_data *client) // 005 { - copy_strf(&databuf, ":%s 005 %s NETWORK=PatchyIRC CASEMAPPING=ascii NICKLEN=%u EXCEPTS=e INVEX=I MAXTARGETS=1 CHANMODES=beIqw,k,l,Pimnst CHANTYPES=#& PREFIX=(ov)@+ STATUSMSG=@+ BOT=B :are supported by this server\r\n", hostname, client->nick, MAX_NICKLEN-1); + copy_strf(&databuf, ":%s 005 %s NETWORK=PatchyIRC CASEMAPPING=ascii NICKLEN=%u EXCEPTS=e INVEX=I MAXTARGETS=1 CHANMODES=beIqw,k,l,Pimnst CHANTYPES=#& PREFIX=(ov)@+ STATUSMSG=@+ BOT=B WHOX :are supported by this server\r\n", hostname, client->nick, MAX_NICKLEN-1); } #if 0 @@ -253,6 +253,64 @@ void rpl_whoreply(struct client_data *client, struct client_data *cl, struct cha cl->umode&UMODE_BOT ? "B" : "", cl->realname); } +void rpl_whospcrpl(struct client_data *client, struct client_data *cl, struct channel *chan, const char *fmt) // 354 +{ + int flags = 0; + while (*fmt != '%') + fmt++; + while (*fmt) { + if (*fmt == ',') { + fmt++; + break; + } + switch (*fmt) { + case 't': flags |= 1<<0; break; + case 'c': flags |= 1<<1; break; + case 'u': flags |= 1<<2; break; + case 'i': flags |= 1<<3; break; + case 'h': flags |= 1<<4; break; + case 's': flags |= 1<<5; break; + case 'n': flags |= 1<<6; break; + case 'f': flags |= 1<<7; break; + case 'd': flags |= 1<<8; break; + case 'l': flags |= 1<<9; break; + case 'a': flags |= 1<<10; break; + case 'o': flags |= 1<<11; break; + case 'r': flags |= 1<<11; break; + } + fmt++; + } + copy_strf(&databuf, ":%s 354 %s", hostname, client->nick); + if (flags & 1<<0) /* t */ + append_strf(&databuf, " %s", fmt); + if (flags & 1<<1) /* c */ + append_strf(&databuf, " %s", chan ? chan->name : "*"); + if (flags & 1<<2) /* u */ + append_strf(&databuf, " %s", cl->username); + if (flags & 1<<3) /* i */ + append_strf(&databuf, " %s", (client == cl || client->umode & UMODE_OPER) && cl->peername ? cl->peername : "255.255.255.255"); + if (flags & 1<<4) /* h */ + append_strf(&databuf, " %s", cl->hostname); + if (flags & 1<<5) /* s */ + append_strf(&databuf, " %s", hostname); + if (flags & 1<<6) /* n */ + append_strf(&databuf, " %s", cl->nick); + if (flags & 1<<7) /* f */ + append_strf(&databuf, " %s%s%s%s", + cl->away ? "G" : "H", cl->umode&UMODE_OPER ? "*" : "", format_prefixes(client, cl, chan), + cl->umode&UMODE_BOT ? "B" : ""); + if (flags & 1<<8) /* d */ + append_strf(&databuf, " 1"); + if (flags & 1<<9) /* l */ + append_strf(&databuf, " %u", (unsigned)(get_time()-cl->lastactivity)); + if (flags & 1<<10) /* a */ + append_strf(&databuf, " %s", cl->username[0] != '~' ? cl->username : "0"); + if (flags & 1<<11) /* o */ + append_strf(&databuf, " n/a"); + if (flags & 1<<11) /* r */ + append_strf(&databuf, " :%s", cl->realname); + append_strf(&databuf, "\r\n"); +} void rpl_endofwho(struct client_data *client, const char *query) // 315 { copy_strf(&databuf, ":%s 315 %s %s :End of WHO list\r\n", hostname, client->nick, query); diff --git a/src/ircfmt.h b/src/ircfmt.h index ad22826..f4ab13f 100644 --- a/src/ircfmt.h +++ b/src/ircfmt.h @@ -44,6 +44,7 @@ void rpl_userhost(struct client_data *client, struct client_data **cls, int coun void rpl_unaway(struct client_data *client); // 305 void rpl_nowaway(struct client_data *client); // 306 void rpl_whoreply(struct client_data *client, struct client_data *cl, struct channel *chan); // 352 +void rpl_whospcrpl(struct client_data *client, struct client_data *cl, struct channel *chan, const char *fmt); // 354 void rpl_endofwho(struct client_data *client, const char *query); // 315 void rpl_whoisregnick(struct client_data *client, struct client_data *cl); // 307 void rpl_whoisuser(struct client_data *client, struct client_data *cl); // 311 -- 2.56.0