]> PatchyGit - patchyircd.git/commitdiff
add/move 42 numerics to ircfmt
authorEgor <egor@patchysicp.xyz>
Thu, 12 May 2022 17:26:13 +0000 (20:26 +0300)
committerEgor <egor@patchysicp.xyz>
Thu, 12 May 2022 17:26:13 +0000 (20:26 +0300)
also some WHOIS improvments

irc.c
ircfmt.c
ircfmt.h

diff --git a/irc.c b/irc.c
index 52f54d7..2b02a0e 100644 (file)
--- a/irc.c
+++ b/irc.c
@@ -280,8 +280,7 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                        err_passwdmismatch(client), sendbuf(client);
                } else {
                        client->umode |= UMODE_OPER;
-                       copy_strf(&databuf, ":%s 381 %s :You are now an IRC operator\r\n", hostname, client->nick);
-                       sendbuf(client);
+                       rpl_youreoper(client), sendbuf(client);
                        copy_strf(&databuf, ":%s MODE %s +o\r\n", hostname, client->nick);
                        sendbuf(client);
                }
@@ -412,12 +411,9 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                        if (trie_findfirst(&f, &client->invites) == 1)
                                do {
                                        struct channel *chan = f->n->value;
-                                       copy_strf(&databuf, ":%s 336 %s %s\n", hostname, client->nick, chan->name);
-                                       sendbuf(client);
+                                       rpl_invitelist(client, chan), sendbuf(client);
                                } while(trie_findnext(&f) == 1);
-                       copy_strf(&databuf, ":%s 337 %s :End of /INVITE list\n", hostname, client->nick);
-                       sendbuf(client);
-                       return 0;
+                       return rpl_endofinvitelist(client), sendbuf(client), 0;
                }
                if (!args[1])
                        return err_needmoreparams(client, command), sendbuf(client), 0;
@@ -440,7 +436,7 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                        return err_useronchannel(client, cl->nick, chan), sendbuf(client), 0;
                trie_set(&chan->invitees, cl->nick, cl, NULL);
                trie_set(&cl->invites, chan->name, chan, NULL);
-               copy_strf(&databuf, ":%s 341 %s %s %s\r\n", hostname, client->nick, cl->nick, chan->name);
+               rpl_inviting(client, cl, chan);
                sendbuf(client);
                msg_invite(client, cl, chan);
                sendbuf(cl);
@@ -488,10 +484,8 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                                return err_nosuchnick(client, args[0]), sendbuf(client), 0;
                        } else {
                                sendbuf(cl);
-                               if (cl->away) {
-                                       copy_strf(&databuf, ":%s 301 %s %s :%s\n", hostname, client->nick, cl->nick, cl->away);
-                                       sendbuf(client);
-                               }
+                               if (cl->away)
+                                       rpl_away(client, cl), sendbuf(client);
                        }
                }
        // Start GitHub Copilot - this shit actually be copy pasting my code lmao
@@ -552,28 +546,13 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                                        sendbuf(client);
                                        return 0;
                                }
-                               copy_strf(&databuf, ":%s 221 %s %s\r\n", hostname, client->nick, format_umodes(client));
-                               sendbuf(client);
+                               rpl_umodeis(client), sendbuf(client);
                        } else {
                                struct channel *chan = findChannel(nick);
                                if (!chan)
                                        return err_nosuchchannel(client, nick), sendbuf(client), 0;
-                               copy_strf(&databuf, ":%s 324 %s %s +", hostname, client->nick, nick);
-                               if (chan->dmode & DMODE_PERSIST) append_str(&databuf, "P");
-                               if (chan->dmode & DMODE_INVITEONLY) append_str(&databuf, "i");
-                               if (chan->dmode & DMODE_MODERATED) append_str(&databuf, "m");
-                               if (chan->dmode & DMODE_NOEXTERNAL) append_str(&databuf, "n");
-                               if (chan->dmode & DMODE_SECRET) append_str(&databuf, "s");
-                               if (chan->dmode & DMODE_TOPICPROT) append_str(&databuf, "t");
-                               if (chan->member_limit != -1) append_str(&databuf, "l");
-                               if (chan->chankey) append_str(&databuf, "k");
-                               if (chan->member_limit != -1) append_strf(&databuf, " %u", chan->member_limit);
-                               if (chan->chankey) append_strf(&databuf, " %s", chan->chankey);
-                               append_str(&databuf, "\r\n");
-                               sendbuf(client);
-                               // FIXME: 64-bit time_t support
-                               copy_strf(&databuf, ":%s 329 %s %s %u\n", hostname, client->nick, chan->name, (unsigned)chan->creation);
-                               sendbuf(client);
+                               rpl_channelmodeis(client, chan), sendbuf(client);
+                               rpl_creationtime(client, chan), sendbuf(client);
                        }
                } else { // set mode
                        if (*nick != '#' && *nick != '&') {
@@ -630,57 +609,41 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                                        if (!strcmp(args[1], "+b")) {
                                                if (trie_findfirst(&f, &chan->listb) == 1)
                                                        do {
-                                                               copy_strf(&databuf, ":%s 367 %s %s %s\n", hostname, client->nick, chan->name, f->key);
-                                                               sendbuf(client);
+                                                               rpl_banlist(client, chan, f->key), sendbuf(client);
                                                        } while(trie_findnext(&f) == 1);
-                                               copy_strf(&databuf, ":%s 368 %s %s :End of channel ban list\n", hostname, client->nick, chan->name);
-                                               sendbuf(client);
-                                               return 0;
+                                               return rpl_endofbanlist(client, chan), sendbuf(client), 0;
                                        }
                                        if (!strcmp(args[1], "+e")) {
                                                if (trie_findfirst(&f, &chan->liste) == 1)
                                                        do {
-                                                               copy_strf(&databuf, ":%s 348 %s %s %s\n", hostname, client->nick, chan->name, f->key);
-                                                               sendbuf(client);
+                                                               rpl_exceptlist(client, chan, f->key), sendbuf(client);
                                                        } while(trie_findnext(&f) == 1);
-                                               copy_strf(&databuf, ":%s 349 %s %s :End of channel exception list\n", hostname, client->nick, chan->name);
-                                               sendbuf(client);
-                                               return 0;
+                                               return rpl_endofexceptlist(client, chan), sendbuf(client), 0;
                                        }
                                        if (!strcmp(args[1], "+I")) {
                                                if (trie_findfirst(&f, &chan->listI) == 1)
                                                        do {
-                                                               copy_strf(&databuf, ":%s 346 %s %s %s\n", hostname, client->nick, chan->name, f->key);
-                                                               sendbuf(client);
+                                                               rpl_invexlist(client, chan, f->key), sendbuf(client);
                                                        } while(trie_findnext(&f) == 1);
-                                               copy_strf(&databuf, ":%s 347 %s %s :End of Channel Invite Exception List\n", hostname, client->nick, chan->name);
-                                               sendbuf(client);
-                                               return 0;
+                                               return rpl_endofinvexlist(client, chan), sendbuf(client), 0;
                                        }
                                        if (!strcmp(args[1], "+q")) {
                                                if (trie_findfirst(&f, &chan->listq) == 1)
                                                        do {
-                                                               copy_strf(&databuf, ":%s 728 %s %s q %s\n", hostname, client->nick, chan->name, f->key);
-                                                               sendbuf(client);
+                                                               rpl_quietlist(client, chan, f->key), sendbuf(client);
                                                        } while(trie_findnext(&f) == 1);
-                                               copy_strf(&databuf, ":%s 729 %s %s q :End of channel quiet list\n", hostname, client->nick, chan->name);
-                                               sendbuf(client);
-                                               return 0;
+                                               return rpl_endofquietlist(client, chan), sendbuf(client), 0;
                                        }
                                        if (!strcmp(args[1], "+w")) {
                                                if (trie_findfirst(&f, &chan->listwo) == 1)
                                                        do {
-                                                               copy_strf(&databuf, ":%s 910 %s %s o:%s\n", hostname, client->nick, chan->name, f->key);
-                                                               sendbuf(client);
+                                                               rpl_accesslist(client, chan, 'o', f->key), sendbuf(client);
                                                        } while(trie_findnext(&f) == 1);
                                                if (trie_findfirst(&f, &chan->listwv) == 1)
                                                        do {
-                                                               copy_strf(&databuf, ":%s 910 %s %s v:%s\n", hostname, client->nick, chan->name, f->key);
-                                                               sendbuf(client);
+                                                               rpl_accesslist(client, chan, 'v', f->key), sendbuf(client);
                                                        } while(trie_findnext(&f) == 1);
-                                               copy_strf(&databuf, ":%s 911 %s %s :End of channel access list\n", hostname, client->nick, chan->name);
-                                               sendbuf(client);
-                                               return 0;
+                                               return rpl_endofaccesslist(client, chan), sendbuf(client), 0;
                                        }
                                }
                                int is_plus;
@@ -856,21 +819,15 @@ int processPacket(struct client_data *client, char *source, char *command, int a
        } else if(strcmp(command, "LIST") == 0) {
                if (!is_registered(client))
                        return err_notregistered(client), sendbuf(client), 0;
-               copy_strf(&databuf, ":%s 321 %s Channel :Users  Name\n", hostname, client->nick);
-               sendbuf(client);
+               rpl_listend(client), sendbuf(client);
                struct trie_find *f = NULL;
                if (trie_findfirst(&f, &channel_map) == 1)
                        do {
                                struct channel *chan = f->n->value;
-                               if (!(chan->dmode & DMODE_SECRET) || trie_get(&chan->members, client->key)) {
-                                       channel_sendnames(client, chan);
-                                       copy_strf(&databuf, ":%s 322 %s %s %u :%s\n", hostname, client->nick,
-                                                       chan->name, chan->member_count, chan->topic ? chan->topic : "");
-                                       sendbuf(client);
-                               }
+                               if (!(chan->dmode & DMODE_SECRET) || trie_get(&chan->members, client->key))
+                                       rpl_list(client, chan), sendbuf(client);
                        } while(trie_findnext(&f) == 1);
-               copy_strf(&databuf, ":%s 323 %s :End of /LIST\n", hostname, client->nick);
-               sendbuf(client);
+               rpl_listend(client), sendbuf(client);
        } else if(strcmp(command, "NAMES") == 0) {
                if (!is_registered(client))
                        return err_notregistered(client), sendbuf(client), 0;
@@ -894,23 +851,15 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                        return err_notregistered(client), sendbuf(client), 0;
                if (argc == 0)
                        return err_needmoreparams(client, command), sendbuf(client), 0;
-               copy_strf(&databuf, ":%s 302 %s", hostname, client->nick);
-               int has_output = 0;
+               struct client_data *cls[5], **p = cls;
                for (int i = 0; i < 5; i++) {
                        if (!args[i])
                                break;
                        struct client_data *cl = findClient(args[i]);
-                       if (cl) {
-                               append_strf(&databuf, " %s%s%s=%s%s",
-                                               has_output ? "" : ":",
-                                               cl->nick,
-                                               cl->umode&UMODE_OPER ? "*" : "",
-                                               cl->away ? "-" : "+",
-                                               cl->hostname);
-                               has_output = 1;
-                       }
-                       append_str(&databuf, "\r\n");
+                       if (cl)
+                               *p++ = cl;
                }
+               rpl_userhost(client, cls, p - cls);
                sendbuf(client);
        // User-Based Queries
        } else if(strcmp(command, "WHO") == 0) {
@@ -927,28 +876,15 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                                if (trie_findfirst(&f, &chan->members) == 1)
                                        do {
                                                struct client_data *cl = f->n->value;
-                                               char prefix[2] = {0,0};
-                                               if (trie_get(&chan->o, cl->key))
-                                                       prefix[0] = '@';
-                                               else if (trie_get(&chan->v, cl->key))
-                                                       prefix[0] = '+';
-                                               copy_strf(&databuf, ":%s 352 %s %s %s %s %s %s %s%s%s :1 %s\n",
-                                                               hostname, client->nick, chan->name, cl->username, cl->hostname, hostname, cl->nick,
-                                                               cl->away ? "G" : "H", cl->umode&UMODE_OPER ? "*" : "", prefix, cl->realname);
-                                               sendbuf(client);
+                                               rpl_whoreply(client, cl, chan), sendbuf(client);
                                        } while(trie_findnext(&f) == 1);
                        }
                } else {
                        struct client_data *cl = findClient(args[0]);
-                       if (cl) {
-                               copy_strf(&databuf, ":%s 352 %s * %s %s %s %s %s%s :1 %s\n",
-                                               hostname, client->nick, cl->username, cl->hostname, hostname, cl->nick,
-                                               cl->away ? "G" : "H", cl->umode&UMODE_OPER ? "*" : "", cl->realname);
-                               sendbuf(client);
-                       }
+                       if (cl)
+                               rpl_whoreply(client, cl, NULL), sendbuf(client);
                }
-               copy_strf(&databuf, ":%s 315 %s %s :End of WHO list\n", hostname, client->nick, args[0]);
-               sendbuf(client);
+               rpl_endofwho(client, args[0]), sendbuf(client);
        } else if(strcmp(command, "WHOIS") == 0) {
                if (!is_registered(client))
                        return err_notregistered(client), sendbuf(client), 0;
@@ -957,38 +893,34 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                char *nick = args[1] ? args[1] : args[0];
                struct client_data *cl = findClient(nick);
                if (cl) {
-                       copy_strf(&databuf, ":%s 311 %s %s %s %s * :%s\r\n", hostname, client->nick, cl->nick, cl->username, cl->hostname, cl->realname);
-                       sendbuf(client);
-                       copy_strf(&databuf, ":%s 312 %s %s %s :Patchy server\r\n", hostname, client->nick, cl->nick, hostname);
-                       sendbuf(client);
-                       if (cl->umode & UMODE_OPER) {
-                               copy_strf(&databuf, ":%s 313 %s %s :is an IRC operator\r\n", hostname, client->nick, cl->nick);
-                               sendbuf(client);
-                       }
-                       // FIXME: 64-bit time_t
-                       copy_strf(&databuf, ":%s 317 %s %s %u %u :seconds idle, signon time\r\n",
-                                       hostname, client->nick, cl->nick, (unsigned)(get_time()-cl->lastactivity), (unsigned)cl->signon);
-                       sendbuf(client);
-                       if (cl->away) {
-                               copy_strf(&databuf, ":%s 301 %s %s :%s\r\n", hostname, client->nick, cl->nick, cl->away);
-                               sendbuf(client);
-                       }
+#ifdef HAS_TLS
+                       if (client == cl || client->umode & UMODE_OPER)
+                               if (client->cctx && tls_peer_cert_provided(client->cctx))
+                                       rpl_whoiscertfp(client, cl, tls_peer_cert_hash(cl->cctx)), sendbuf(client);
+#endif
+                       if (cl->umode & UMODE_REGISTERED && !strcmp(cl->key, cl->username))
+                               rpl_whoisregnick(client, cl), sendbuf(client);
+                       rpl_whoisuser(client, cl), sendbuf(client);
+                       rpl_whoisserver(client, cl), sendbuf(client);
+                       if (cl->umode & UMODE_OPER)
+                               rpl_whoisoperator(client, cl), sendbuf(client);
+                       rpl_whoisidle(client, cl), sendbuf(client);
+                       if (cl->away)
+                               rpl_away(client, cl), sendbuf(client);
                        struct trie_find *f = NULL;
                        if (trie_findfirst(&f, &cl->channels) == 1)
                                do {
                                        struct channel *chan = f->n->value;
                                        if ((cl->umode & UMODE_INVISIBLE || chan->dmode & DMODE_SECRET) && !trie_get(&chan->members, client->key))
                                                continue;
-                                       char prefix[2] = {0,0};
-                                       if (trie_get(&chan->o, cl->key))
-                                               prefix[0] = '@';
-                                       else if (trie_get(&chan->v, cl->key))
-                                               prefix[0] = '+';
-                                       copy_strf(&databuf, ":%s 319 %s %s :%s%s\r\n", hostname, client->nick, cl->nick, prefix, chan->name);
-                                       sendbuf(client);
+                                       rpl_whoischannels(client, cl, chan), sendbuf(client);
                                } while (trie_findnext(&f) == 1);
-                       copy_strf(&databuf, ":%s 318 %s %s :End of /WHOIS list\r\n", hostname, client->nick, cl->nick);
-                       sendbuf(client);
+                       if (cl->umode & UMODE_REGISTERED)
+                               rpl_whoisaccount(client, cl), sendbuf(client);
+                       if (client == cl || client->umode & UMODE_OPER)
+                               rpl_whoisactually(client, cl), sendbuf(client);
+                       rpl_whoismodes(client, cl), sendbuf(client);
+                       rpl_endofwhois(client, cl), sendbuf(client);
                } else {
                        err_nosuchnick(client, nick);
                        sendbuf(client);
@@ -1000,13 +932,11 @@ int processPacket(struct client_data *client, char *source, char *command, int a
                        free(client->away);
                        client->away = mystrdup(args[0]);
                        if (!client->away) abort();
-                       copy_strf(&databuf, ":%s 306 %s :You have been marked as being away\n", hostname, client->nick);
-                       sendbuf(client);
+                       rpl_nowaway(client), sendbuf(client);
                } else {
                        free(client->away);
                        client->away = NULL;
-                       copy_strf(&databuf, ":%s 305 %s :You are no longer marked as being away\n", hostname, client->nick);
-                       sendbuf(client);
+                       rpl_unaway(client), sendbuf(client);
                }
        } else {
 unknown:
@@ -1087,14 +1017,10 @@ void sendLUSERS(struct client_data *client)
 }
 
 void sendMOTD(struct client_data *client) {
-       copy_strf(&databuf, ":%s 375 %s :PatchySICP /MOTD\n", hostname, client->nick);
-       sendbuf(client);
-       copy_strf(&databuf, ":%s 372 %s :Welcome to Montreal!\n", hostname, client->nick);
-       sendbuf(client);
-       copy_strf(&databuf, ":%s 372 %s :You are retarded and I will have cybersex with your mom.\n", hostname, client->nick);
-       sendbuf(client);
-       copy_strf(&databuf, ":%s 376 %s :/MOTD over\n", hostname, client->nick);
-       sendbuf(client);
+       rpl_motdstart(client), sendbuf(client);
+       rpl_motd(client, "Welcome to Montreal!"), sendbuf(client);
+       rpl_motd(client, "You are retarded and I will have cybersex with your mom."), sendbuf(client);
+       rpl_endofmotd(client), sendbuf(client);
 }
 
 void setNick(struct client_data *client, char* nickname) {
index 895d8af..9918ec0 100644 (file)
--- a/ircfmt.c
+++ b/ircfmt.c
@@ -101,15 +101,15 @@ void rpl_yourhost(struct client_data *client) // 002
 }
 void rpl_created(struct client_data *client) // 003
 {
-       copy_strf(&databuf, ":%s 003 %s :This server was created when I had cybersex with your mother.\n", hostname, client->nick);
+       copy_strf(&databuf, ":%s 003 %s :This server was created when I had cybersex with your mother.\r\n", hostname, client->nick);
 }
 void rpl_myinfo(struct client_data *client) // 004
 {
-       copy_strf(&databuf, ":%s 004 %s PatchyIRCD 0.0.1 iworZ beIqwklPimnstov\n", hostname, client->nick);
+       copy_strf(&databuf, ":%s 004 %s PatchyIRCD 0.0.1 iworZ beIqwklPimnstov\r\n", hostname, client->nick);
 }
 void rpl_isupport(struct client_data *client) // 005
 {
-       copy_strf(&databuf, ":%s 005 %s CASEMAPPING=ascii NICKLEN=%u EXCEPTS=e INVEX=I MAXTARGETS=1 CHANMODES=beIqw,k,l,Pimnst CHANTYPES=#& PREFIX=(ov)@+ STATUSMSG=@+ :are supported by this server\n", hostname, client->nick, MAX_NICKLEN-1);
+       copy_strf(&databuf, ":%s 005 %s CASEMAPPING=ascii NICKLEN=%u EXCEPTS=e INVEX=I MAXTARGETS=1 CHANMODES=beIqw,k,l,Pimnst CHANTYPES=#& PREFIX=(ov)@+ STATUSMSG=@+ :are supported by this server\r\n", hostname, client->nick, MAX_NICKLEN-1);
 
 }
 #if 0
@@ -185,29 +185,140 @@ void rpl_globalusers(struct client_data *client, int current, int max) // 267
        copy_strf(&databuf, ":%s 266 %s %u %u :Current global users %u, max %u\r\n",
                        hostname, client->nick, current, max, current, max);
 }
-// 276 RPL_WHOISCERTFP
-// 300 RPL_NONE
-// 301 RPL_AWAY
-// 302 RPL_USERHOST
-// 305 RPL_UNAWAY
-// 306 RPL_NOWAWAY
-// 352 RPL_WHOREPLY
-// 315 RPL_ENDOFWHO
-// 307 RPL_WHOISREGNICK
-// 311 RPL_WHOISUSER
-// 312 RPL_WHOISSERVER
-// 313 RPL_WHOISOPERATOR
+void rpl_whoiscertfp(struct client_data *client, struct client_data *cl, const char *certfp) // 276
+{
+       copy_strf(&databuf, ":%s 276 %s %s :has client certificate fingerprint %s\r\n",
+                       hostname, client->nick, cl->nick, certfp);
+}
+#if 0
+void rpl_none(struct client_data *client, const char *line) // 300
+{
+       copy_strf(&databuf, ":%s 300 %s %s\r\n", hostname, client->nick, line);
+}
+#endif
+void rpl_away(struct client_data *client, struct client_data *cl) // 301
+{
+       copy_strf(&databuf, ":%s 301 %s %s :%s\r\n", hostname, client->nick, cl->nick, cl->away);
+}
+void rpl_userhost(struct client_data *client, struct client_data **cls, int count) // 302
+{
+       copy_strf(&databuf, ":%s 302 %s", hostname, client->nick);
+       for (int i = 0; i < count; i++) {
+               append_strf(&databuf, " %s%s%s=%s%s",
+                               i ? "" : ":",
+                               cls[i]->nick,
+                               cls[i]->umode&UMODE_OPER ? "*" : "",
+                               cls[i]->away ? "-" : "+",
+                               cls[i]->hostname);
+       }
+       append_str(&databuf, "\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);
+}
+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);
+}
+void rpl_whoreply(struct client_data *client, struct client_data *cl, struct channel *chan) // 352
+{
+       char prefix[2] = {0,0};
+       if (chan) {
+               if (trie_get(&chan->o, cl->key))
+                       prefix[0] = '@';
+               else if (trie_get(&chan->v, cl->key))
+                       prefix[0] = '+';
+       }
+       copy_strf(&databuf, ":%s 352 %s %s %s %s %s %s %s%s%s :1 %s\r\n",
+                       hostname, client->nick, chan ? chan->name : "*", cl->username, cl->hostname, hostname, cl->nick,
+                       cl->away ? "G" : "H", cl->umode&UMODE_OPER ? "*" : "", prefix, cl->realname);
+}
+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);
+}
+void rpl_whoisregnick(struct client_data *client, struct client_data *cl) // 307
+{
+       copy_strf(&databuf, ":%s 307 %s %s :has identified for this nick\r\n", hostname, client->nick, cl->nick);
+}
+void rpl_whoisuser(struct client_data *client, struct client_data *cl) // 311
+{
+       copy_strf(&databuf, ":%s 311 %s %s %s %s * :%s\r\n", hostname, client->nick, cl->nick, cl->username, cl->hostname, cl->realname);
+}
+void rpl_whoisserver(struct client_data *client, struct client_data *cl) // 312
+{
+       copy_strf(&databuf, ":%s 312 %s %s %s :Patchy server\r\n", hostname, client->nick, cl->nick, hostname);
+}
+void rpl_whoisoperator(struct client_data *client, struct client_data *cl) // 313
+{
+       copy_strf(&databuf, ":%s 313 %s %s :is an IRC operator\r\n", hostname, client->nick, cl->nick);
+}
 // 314 RPL_WHOWASUSER
-// 317 RPL_WHOISIDLE
-// 318 RPL_ENDOFWHOIS
-// 319 RPL_WHOISCHANNELS
-// 320 RPL_WHOISSPECIAL
-// 321 RPL_LISTSTART
-// 322 RPL_LIST
-// 323 RPL_LISTEND
-// 324 RPL_CHANNELMODEIS
-// 329 RPL_CREATIONTIME
-// 330 RPL_WHOISACCOUNT
+void rpl_whoisidle(struct client_data *client, struct client_data *cl) // 317
+{
+       // FIXME: 64-bit time_t support
+       copy_strf(&databuf, ":%s 317 %s %s %u %u :seconds idle, signon time\r\n",
+                       hostname, client->nick, cl->nick, (unsigned)(get_time()-cl->lastactivity), (unsigned)cl->signon);
+}
+void rpl_endofwhois(struct client_data *client, struct client_data *cl) // 318
+{
+       copy_strf(&databuf, ":%s 318 %s %s :End of /WHOIS list\r\n", hostname, client->nick, cl->nick);
+}
+void rpl_whoischannels(struct client_data *client, struct client_data *cl, struct channel *chan) // 319
+{
+       char prefix[2] = {0,0};
+       if (chan) {
+               if (trie_get(&chan->o, cl->key))
+                       prefix[0] = '@';
+               else if (trie_get(&chan->v, cl->key))
+                       prefix[0] = '+';
+       }
+       copy_strf(&databuf, ":%s 319 %s %s :%s%s\r\n", hostname, client->nick, cl->nick, prefix, chan->name);
+}
+#if 0
+void rpl_whoisspecial(struct client_data *client, struct client_data *cl, const char *info) // 320
+{
+       copy_strf(&databuf, ":%s 320 %s %s :%s\r\n", hostname, client->nick, cl->nick, info);
+}
+#endif
+void rpl_liststart(struct client_data *client) // 321
+{
+       copy_strf(&databuf, ":%s 321 %s Channel :Users  Name\r\n", hostname, client->nick);
+}
+void rpl_list(struct client_data *client, struct channel *chan) // 322
+{
+       copy_strf(&databuf, ":%s 322 %s %s %u :%s\r\n", hostname, client->nick,
+                       chan->name, chan->member_count, chan->topic ? chan->topic : "");
+}
+void rpl_listend(struct client_data *client) // 323
+{
+       copy_strf(&databuf, ":%s 323 %s :End of /LIST\r\n", hostname, client->nick);
+}
+void rpl_channelmodeis(struct client_data *client, struct channel *chan) // 324
+{
+       copy_strf(&databuf, ":%s 324 %s %s +", hostname, client->nick, chan->name);
+       if (chan->dmode & DMODE_PERSIST) append_str(&databuf, "P");
+       if (chan->dmode & DMODE_INVITEONLY) append_str(&databuf, "i");
+       if (chan->dmode & DMODE_MODERATED) append_str(&databuf, "m");
+       if (chan->dmode & DMODE_NOEXTERNAL) append_str(&databuf, "n");
+       if (chan->dmode & DMODE_SECRET) append_str(&databuf, "s");
+       if (chan->dmode & DMODE_TOPICPROT) append_str(&databuf, "t");
+       if (chan->member_limit != -1) append_str(&databuf, "l");
+       if (chan->chankey) append_str(&databuf, "k");
+       if (chan->member_limit != -1) append_strf(&databuf, " %u", chan->member_limit);
+       if (chan->chankey) append_strf(&databuf, " %s", chan->chankey);
+       append_str(&databuf, "\r\n");
+}
+void rpl_creationtime(struct client_data *client, struct channel *chan) // 329
+{
+       // FIXME: 64-bit time_t support
+       copy_strf(&databuf, ":%s 329 %s %s %u\r\n", hostname, client->nick, chan->name, (unsigned)chan->creation);
+}
+void rpl_whoisaccount(struct client_data *client, struct client_data *cl) // 330
+{
+       copy_strf(&databuf, ":%s 330 %s %s %s :is logged in as\r\n", hostname, client->nick, cl->nick, cl->username);
+}
 void rpl_notopic(struct client_data *client, struct channel *chan) // 331
 {
        copy_strf(&databuf, ":%s 331 %s %s :No topic is set\r\n", hostname, client->nick,
@@ -224,14 +335,38 @@ void rpl_topicwhotime(struct client_data *client, struct channel *chan) // 333
        copy_strf(&databuf, ":%s 333 %s %s %s %u\r\n", hostname, client->nick,
                        chan->name, chan->topic_who, (unsigned)chan->topic_when);
 }
-// 336 RPL_INVITELIST
-// 337 RPL_ENDOFINVITELIST
-// 338 RPL_WHOISACTUALLY
-// 341 RPL_INVITING
-// 346 RPL_INVEXLIST
-// 347 RPL_ENDOFINVEXLIST
-// 348 RPL_EXCEPTLIST
-// 349 RPL_ENDOFEXCEPTLIST
+void rpl_invitelist(struct client_data *client, struct channel *chan) // 336
+{
+       copy_strf(&databuf, ":%s 336 %s %s\r\n", hostname, client->nick, chan->name);
+}
+void rpl_endofinvitelist(struct client_data *client) // 337
+{
+       copy_strf(&databuf, ":%s 337 %s :End of /INVITE list\r\n", hostname, client->nick);
+}
+void rpl_whoisactually(struct client_data *client, struct client_data *cl) // 338
+{
+       copy_strf(&databuf, ":%s 338 %s %s %s :Is actually using host\r\n", hostname, client->nick, cl->nick, cl->peername);
+}
+void rpl_inviting(struct client_data *client, struct client_data *cl, struct channel *chan) // 341
+{
+       copy_strf(&databuf, ":%s 341 %s %s %s\r\n", hostname, client->nick, cl->nick, chan->name);
+}
+void rpl_invexlist(struct client_data *client, struct channel *chan, const char *mask) // 346
+{
+       copy_strf(&databuf, ":%s 346 %s %s %s\r\n", hostname, client->nick, chan->name, mask);
+}
+void rpl_endofinvexlist(struct client_data *client, struct channel *chan) // 347
+{
+       copy_strf(&databuf, ":%s 347 %s %s :End of Channel Invite Exception List\r\n", hostname, client->nick, chan->name);
+}
+void rpl_exceptlist(struct client_data *client, struct channel *chan, const char *mask) // 348
+{
+       copy_strf(&databuf, ":%s 348 %s %s %s\r\n", hostname, client->nick, chan->name, mask);
+}
+void rpl_endofexceptlist(struct client_data *client, struct channel *chan) // 349
+{
+       copy_strf(&databuf, ":%s 349 %s %s :End of channel exception list\r\n", hostname, client->nick, chan->name);
+}
 void rpl_version(struct client_data *client, const char *ver, const char *comments) // 351
 {
        copy_strf(&databuf, ":%s 351 %s %s %s :%s\r\n", hostname, client->nick,
@@ -273,19 +408,39 @@ void rpl_endofnames(struct client_data *client, const char *channel) // 366
 }
 // 364 RPL_LINKS
 // 365 RPL_ENDOFLINKS
-// 367 RPL_BANLIST
-// 368 RPL_ENDOFBANLIST
+void rpl_banlist(struct client_data *client, struct channel *chan, const char *mask) // 367
+{
+       copy_strf(&databuf, ":%s 367 %s %s %s\r\n", hostname, client->nick, chan->name, mask);
+}
+void rpl_endofbanlist(struct client_data *client, struct channel *chan) // 368
+{
+       copy_strf(&databuf, ":%s 368 %s %s :End of channel ban list\r\n", hostname, client->nick, chan->name);
+}
 // 369 RPL_ENDOFWHOWAS
 // 371 RPL_INFO
 // 374 RPL_ENDOFINFO
-// 375 RPL_MOTDSTART
-// 372 RPL_MOTD
-// 376 RPL_ENDOFMOTD
+void rpl_motdstart(struct client_data *client) // 375
+{
+       copy_strf(&databuf, ":%s 375 %s :- %s Message of the day - \r\n", hostname, client->nick, hostname);
+}
+void rpl_motd(struct client_data *client, const char *line) // 372
+{
+       copy_strf(&databuf, ":%s 372 %s :%s\r\n", hostname, client->nick, line);
+}
+void rpl_endofmotd(struct client_data *client) // 376
+{
+       copy_strf(&databuf, ":%s 376 %s :End of /MOTD command.\r\n", hostname, client->nick);
+}
 // 378 RPL_WHOISHOST
-// 379 RPL_WHOISMODES
-// 381 RPL_YOUREOPER
+void rpl_whoismodes(struct client_data *client, struct client_data *cl) // 379
+{
+       copy_strf(&databuf, ":%s 379 %s %s :is using modes %s\r\n", hostname, client->nick, cl->nick, format_umodes(cl));
+}
+void rpl_youreoper(struct client_data *client) // 381
+{
+       copy_strf(&databuf, ":%s 381 %s :You are now an IRC operator\r\n", hostname, client->nick);
+}
 // 382 RPL_REHASHING
-// 391 RPL_TIME
 void rpl_time(struct client_data *client, time_t ts) // 391
 {
        // FIXME: 64-bit time_t support
@@ -425,8 +580,14 @@ void err_badchannelkey(struct client_data *client, struct channel *chan) // 475
 // 705 RPL_HELPTXT
 // 706 RPL_ENDOFHELP
 // 723 ERR_NOPRIVS
-// 728 RPL_QUIETLIST
-// 729 RPL_ENDOFQUIETLIST
+void rpl_quietlist(struct client_data *client, struct channel *chan, const char *mask) // 728
+{
+       copy_strf(&databuf, ":%s 728 %s %s q %s\r\n", hostname, client->nick, chan->name, mask);
+}
+void rpl_endofquietlist(struct client_data *client, struct channel *chan) // 729
+{
+       copy_strf(&databuf, ":%s 729 %s %s q :End of channel quiet list\r\n", hostname, client->nick, chan->name);
+}
 // 900 RPL_LOGGEDIN
 // 901 RPL_LOGGEDOUT
 // 902 ERR_NICKLOCKED
@@ -436,3 +597,12 @@ void err_badchannelkey(struct client_data *client, struct channel *chan) // 475
 // 906 ERR_SASLABORTED
 // 907 ERR_SASLALREADY
 // 908 RPL_SASLMECHS
+void rpl_accesslist(struct client_data *client, struct channel *chan, char mode, const char *mask) // 910
+{
+       char modes[2] = {mode,0};
+       copy_strf(&databuf, ":%s 910 %s %s %s:%s\r\n", hostname, client->nick, chan->name, modes, mask);
+}
+void rpl_endofaccesslist(struct client_data *client, struct channel *chan) // 911
+{
+       copy_strf(&databuf, ":%s 911 %s %s :End of channel access list\r\n", hostname, client->nick, chan->name);
+}
index 9ea934f..975a1de 100644 (file)
--- a/ircfmt.h
+++ b/ircfmt.h
@@ -35,56 +35,57 @@ void rpl_adminemail(struct client_data *client, const char *email); // 259
 void rpl_tryagain(struct client_data *client, const char *command); // 263
 void rpl_localusers(struct client_data *client, int current, int max); // 266
 void rpl_globalusers(struct client_data *client, int current, int max); // 267
-// 276 RPL_WHOISCERTFP
-// 300 RPL_NONE
-// 301 RPL_AWAY
-// 302 RPL_USERHOST
-// 305 RPL_UNAWAY
-// 306 RPL_NOWAWAY
-// 352 RPL_WHOREPLY
-// 315 RPL_ENDOFWHO
-// 307 RPL_WHOISREGNICK
-// 311 RPL_WHOISUSER
-// 312 RPL_WHOISSERVER
-// 313 RPL_WHOISOPERATOR
+void rpl_whoiscertfp(struct client_data *client, struct client_data *cl, const char *certfp); // 276
+void rpl_none(struct client_data *client, const char *line); // 300
+void rpl_away(struct client_data *client, struct client_data *cl); // 301
+void rpl_userhost(struct client_data *client, struct client_data **cls, int count); // 302
+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_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
+void rpl_whoisserver(struct client_data *client, struct client_data *cl); // 312
+void rpl_whoisoperator(struct client_data *client, struct client_data *cl); // 313
 // 314 RPL_WHOWASUSER
-// 317 RPL_WHOISIDLE
-// 318 RPL_ENDOFWHOIS
-// 319 RPL_WHOISCHANNELS
-// 320 RPL_WHOISSPECIAL
-// 321 RPL_LISTSTART
-// 322 RPL_LIST
-// 323 RPL_LISTEND
-// 324 RPL_CHANNELMODEIS
-// 329 RPL_CREATIONTIME
-// 330 RPL_WHOISACCOUNT
+void rpl_whoisidle(struct client_data *client, struct client_data *cl); // 317
+void rpl_endofwhois(struct client_data *client, struct client_data *cl); // 318
+void rpl_whoischannels(struct client_data *client, struct client_data *cl, struct channel *chan); // 319
+void rpl_whoisspecial(struct client_data *client, struct client_data *cl, const char *info); // 320
+void rpl_whoisspecial(struct client_data *client, struct client_data *cl, const char *info); // 320
+void rpl_liststart(struct client_data *client); // 321
+void rpl_list(struct client_data *client, struct channel *chan); // 322
+void rpl_listend(struct client_data *client); // 323
+void rpl_channelmodeis(struct client_data *client, struct channel *chan); // 324
+void rpl_creationtime(struct client_data *client, struct channel *chan); // 329
+void rpl_whoisaccount(struct client_data *client, struct client_data *cl); // 330
 void rpl_notopic(struct client_data *client, struct channel *chan); // 331
 void rpl_topic(struct client_data *client, struct channel *chan); // 332
 void rpl_topicwhotime(struct client_data *client, struct channel *chan); // 333
-// 336 RPL_INVITELIST
-// 337 RPL_ENDOFINVITELIST
-// 338 RPL_WHOISACTUALLY
-// 341 RPL_INVITING
-// 346 RPL_INVEXLIST
-// 347 RPL_ENDOFINVEXLIST
-// 348 RPL_EXCEPTLIST
-// 349 RPL_ENDOFEXCEPTLIST
+void rpl_invitelist(struct client_data *client, struct channel *chan); // 336
+void rpl_endofinvitelist(struct client_data *client); // 337
+void rpl_whoisactually(struct client_data *client, struct client_data *cl); // 338
+void rpl_inviting(struct client_data *client, struct client_data *cl, struct channel *chan); // 341
+void rpl_invexlist(struct client_data *client, struct channel *chan, const char *mask); // 346
+void rpl_endofinvexlist(struct client_data *client, struct channel *chan); // 347
+void rpl_exceptlist(struct client_data *client, struct channel *chan, const char *mask); // 348
+void rpl_endofexceptlist(struct client_data *client, struct channel *chan); // 349
 void rpl_version(struct client_data *client, const char *ver, const char *comments); // 351
 int rpl_namreply(struct client_data *client, struct channel *chan, struct client_data *cl); // 353
 void rpl_endofnames(struct client_data *client, const char *channel); // 366
 // 364 RPL_LINKS
 // 365 RPL_ENDOFLINKS
-// 367 RPL_BANLIST
-// 368 RPL_ENDOFBANLIST
+void rpl_banlist(struct client_data *client, struct channel *chan, const char *mask); // 367
+void rpl_endofbanlist(struct client_data *client, struct channel *chan); // 368
 // 369 RPL_ENDOFWHOWAS
 // 371 RPL_INFO
 // 374 RPL_ENDOFINFO
-// 375 RPL_MOTDSTART
-// 372 RPL_MOTD
-// 376 RPL_ENDOFMOTD
+void rpl_motdstart(struct client_data *client); // 375
+void rpl_motd(struct client_data *client, const char *line); // 372
+void rpl_endofmotd(struct client_data *client); // 376
 // 378 RPL_WHOISHOST
-// 379 RPL_WHOISMODES
-// 381 RPL_YOUREOPER
+void rpl_whoismodes(struct client_data *client, struct client_data *cl); // 379
+void rpl_youreoper(struct client_data *client); // 381
 // 382 RPL_REHASHING
 void rpl_time(struct client_data *client, time_t ts); // 391
 void err_unknownerror(struct client_data *client, const char *command, const char *msg); // 400
@@ -130,8 +131,8 @@ void err_badchannelkey(struct client_data *client, struct channel *chan); // 475
 // 705 RPL_HELPTXT
 // 706 RPL_ENDOFHELP
 // 723 ERR_NOPRIVS
-// 728 RPL_QUIETLIST
-// 729 RPL_ENDOFQUIETLIST
+void rpl_quietlist(struct client_data *client, struct channel *chan, const char *mask); // 728
+void rpl_endofquietlist(struct client_data *client, struct channel *chan); // 729
 // 900 RPL_LOGGEDIN
 // 901 RPL_LOGGEDOUT
 // 902 ERR_NICKLOCKED
@@ -141,4 +142,6 @@ void err_badchannelkey(struct client_data *client, struct channel *chan); // 475
 // 906 ERR_SASLABORTED
 // 907 ERR_SASLALREADY
 // 908 RPL_SASLMECHS
+void rpl_accesslist(struct client_data *client, struct channel *chan, char mode, const char *mask); // 910
+void rpl_endofaccesslist(struct client_data *client, struct channel *chan); // 911
 #endif