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);
}
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;
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);
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
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 != '&') {
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;
} 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;
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) {
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;
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);
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:
}
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) {
}
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
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,
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,
}
// 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
// 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
// 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);
+}
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
// 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
// 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