2 * IRC - Internet Relay Chat, ircd/s_err.c
3 * Copyright (C) 1992 Darren Reed
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 1, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "sprintf_irc.h"
27 static Numeric local_replies[] = {
31 { RPL_WELCOME, ":Welcome to the Internet Relay Network %s", "001" },
33 { RPL_YOURHOST, ":Your host is %s, running version %s", "002" },
35 { RPL_CREATED, ":This server was created %s", "003" },
37 { RPL_MYINFO, "%s %s dioswkg biklmnopstv", "004" },
39 { RPL_ISUPPORT, "%s :are supported by this server", "005" },
45 { RPL_SNOMASK, "%d :: Server notice mask (%#x)", "008" },
47 { RPL_STATMEMTOT, "%u %u :Bytes Blocks", "009" },
50 { RPL_STATMEM, "%u %u %s %u", "010" },
52 { RPL_STATMEM, "%u %u %s", "010" },
63 { RPL_MAP, ":%s%s%s %s [%i clients]", "015" },
65 { RPL_MAPMORE, ":%s%s --> *more*", "016" },
67 { RPL_MAPEND, ":End of /MAP", "017" },
71 static Numeric numeric_errors[] = {
73 { ERR_FIRSTERROR, "", "400" },
75 { ERR_NOSUCHNICK, "%s :No such nick", "401" },
77 { ERR_NOSUCHSERVER, "%s :No such server", "402" },
79 { ERR_NOSUCHCHANNEL, "%s :No such channel", "403" },
81 { ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel", "404" },
83 { ERR_TOOMANYCHANNELS, "%s :You have joined too many channels", "405" },
85 { ERR_WASNOSUCHNICK, "%s :There was no such nickname", "406" },
87 { ERR_TOOMANYTARGETS, "%s :Duplicate recipients. No message delivered", "407" },
91 { ERR_NOORIGIN, ":No origin specified", "409" },
95 { ERR_NORECIPIENT, ":No recipient given (%s)", "411" },
97 { ERR_NOTEXTTOSEND, ":No text to send", "412" },
99 { ERR_NOTOPLEVEL, "%s :No toplevel domain specified", "413" },
101 { ERR_WILDTOPLEVEL, "%s :Wildcard in toplevel Domain", "414" },
105 { ERR_QUERYTOOLONG, "%s :Too many lines in the output, restrict your query", "416" },
115 { ERR_UNKNOWNCOMMAND, "%s :Unknown command", "421" },
117 { ERR_NOMOTD, ":MOTD File is missing", "422" },
119 { ERR_NOADMININFO, "%s :No administrative info available", "423" },
135 { ERR_NONICKNAMEGIVEN, ":No nickname given", "431" },
137 { ERR_ERRONEUSNICKNAME, "%s :Erroneous Nickname", "432" },
139 { ERR_NICKNAMEINUSE, "%s :Nickname is already in use.", "433" },
145 { ERR_NICKCOLLISION, "%s :Nickname collision KILL", "436" },
147 { ERR_BANNICKCHANGE, "%s :Cannot change nickname while banned on channel", "437" },
149 { ERR_NICKTOOFAST, "%s :Nick change too fast. Please wait %d seconds.", "438" },
151 { ERR_TARGETTOOFAST, "%s :Target change too fast. Please wait %d seconds.", "439" },
155 { ERR_USERNOTINCHANNEL, "%s %s :They aren't on that channel", "441" },
157 { ERR_NOTONCHANNEL, "%s :You're not on that channel", "442" },
159 { ERR_USERONCHANNEL, "%s %s :is already on channel", "443" },
175 { ERR_NOTREGISTERED, ":You have not registered", "451" },
195 { ERR_NEEDMOREPARAMS, "%s :Not enough parameters", "461" },
197 { ERR_ALREADYREGISTRED, ":You may not reregister", "462" },
199 { ERR_NOPERMFORHOST, ":Your host isn't among the privileged", "463" },
201 { ERR_PASSWDMISMATCH, ":Password Incorrect", "464" },
203 { ERR_YOUREBANNEDCREEP, ":You are banned from this server", "465" },
205 { ERR_YOUWILLBEBANNED, "", "466" },
207 { ERR_KEYSET, "%s :Channel key already set", "467" },
209 { ERR_INVALIDUSERNAME, "", "468" },
215 { ERR_CHANNELISFULL, "%s :Cannot join channel (+l)", "471" },
217 { ERR_UNKNOWNMODE, "%c :is unknown mode char to me", "472" },
219 { ERR_INVITEONLYCHAN, "%s :Cannot join channel (+i)", "473" },
221 { ERR_BANNEDFROMCHAN, "%s :Cannot join channel (+b)", "474" },
223 { ERR_BADCHANNELKEY, "%s :Cannot join channel (+k)", "475" },
225 { ERR_BADCHANMASK, "%s :Bad Channel Mask", "476" },
229 { ERR_BANLISTFULL, "%s %s :Channel ban/ignore list is full", "478" },
231 { ERR_BADCHANNAME, "%s :Cannot join channel (access denied on this server)", "479" },
235 { ERR_NOPRIVILEGES, ":Permission Denied: You're not an IRC operator", "481" },
237 { ERR_CHANOPRIVSNEEDED, "%s :You're not channel operator", "482" },
239 { ERR_CANTKILLSERVER, ":You cant kill a server!", "483" },
241 { ERR_ISCHANSERVICE, "%s %s :Cannot kill, kick or deop channel service", "484" },
251 { ERR_VOICENEEDED, "%s :You're neither voiced nor channel operator", "489" },
255 { ERR_NOOPERHOST, ":No O-lines for your host", "491" },
269 { ERR_ISOPERLCHAN, "%s %s :Cannot kick or deop an IRC Operator on a local channel", "498" },
275 { ERR_UMODEUNKNOWNFLAG, ":Unknown MODE flag", "501" },
277 { ERR_USERSDONTMATCH, ":Cant change mode for other users", "502" },
295 { ERR_SILELISTFULL, "%s :Your silence list is full", "511" },
297 { ERR_NOSUCHGLINE, "%s@%s :No such gline", "512" },
299 { ERR_BADPING, "", "513" },
301 { ERR_NOSUCHJUPE, "%s :No such jupe", "514" },
303 { ERR_BADEXPIRE, TIME_T_FMT " :Bad expire time", "515" },
305 { ERR_DONTCHEAT, " :Don't Cheat.", "516" }
308 static Numeric numeric_replies[] = {
310 { RPL_NONE, 0, "300" },
312 { RPL_AWAY, "%s :%s", "301" },
314 { RPL_USERHOST, ":", "302" },
316 { RPL_ISON, ":", "303" },
318 { RPL_TEXT, 0, "304" },
320 { RPL_UNAWAY, ":You are no longer marked as being away", "305" },
322 { RPL_NOWAWAY, ":You have been marked as being away", "306" },
324 { RPL_USERIP, ":", "307" },
332 { RPL_WHOISUSER, "%s %s %s * :%s", "311" },
334 { RPL_WHOISSERVER, "%s %s :%s", "312" },
336 { RPL_WHOISOPERATOR, "%s :is an IRC Operator", "313" },
338 { RPL_WHOWASUSER, "%s %s %s * :%s", "314" },
340 { RPL_ENDOFWHO, "%s :End of /WHO list.", "315" },
344 { RPL_WHOISIDLE, "%s %ld %ld :seconds idle, signon time", "317" },
346 { RPL_ENDOFWHOIS, "%s :End of /WHOIS list.", "318" },
348 { RPL_WHOISCHANNELS, "%s :%s", "319" },
352 { RPL_LISTSTART, "Channel :Users Name", "321" },
354 { RPL_LIST, "%s %d :%s", "322" },
356 { RPL_LISTEND, ":End of /LIST", "323" },
358 { RPL_CHANNELMODEIS, "%s %s %s", "324" },
368 { RPL_CREATIONTIME, "%s " TIME_T_FMT, "329" },
372 { RPL_NOTOPIC, "%s :No topic is set.", "331" },
374 { RPL_TOPIC, "%s :%s", "332" },
376 { RPL_TOPICWHOTIME, "%s %s " TIME_T_FMT, "333" },
378 { RPL_LISTUSAGE, ":%s", "334" },
392 { RPL_INVITING, "%s %s", "341" },
402 { RPL_INVITELIST, ":%s", "346" },
404 { RPL_ENDOFINVITELIST, ":End of Invite List", "347" },
412 { RPL_VERSION, "%s.%s %s :%s", "351" },
414 { RPL_WHOREPLY, "%s", "352" },
416 { RPL_NAMREPLY, "%s", "353" },
418 { RPL_WHOSPCRPL, "%s", "354" },
432 { RPL_KILLDONE, 0, "361" }, /* Not used */
434 { RPL_CLOSING, "%s :Operator enforced Close", "362" },
436 { RPL_CLOSEEND, "%d :Connections Closed", "363" },
439 { RPL_LINKS, "%s %s :%d P%u %s", "364" },
441 { RPL_LINKS, "%s %s :%d P%u " TIME_T_FMT " (%s) %s", "364" },
444 { RPL_ENDOFLINKS, "%s :End of /LINKS list.", "365" },
446 { RPL_ENDOFNAMES, "%s :End of /NAMES list.", "366" },
448 { RPL_BANLIST, "%s %s %s " TIME_T_FMT, "367" },
450 { RPL_ENDOFBANLIST, "%s :End of Channel Ban List", "368" },
452 { RPL_ENDOFWHOWAS, "%s :End of WHOWAS", "369" },
456 { RPL_INFO, ":%s", "371" },
458 { RPL_MOTD, ":- %s", "372" },
460 { RPL_INFOSTART, ":Server INFO", "373" },
462 { RPL_ENDOFINFO, ":End of /INFO list.", "374" },
464 { RPL_MOTDSTART, ":- %s Message of the Day - ", "375" },
466 { RPL_ENDOFMOTD, ":End of /MOTD command.", "376" },
476 { RPL_YOUREOPER, ":You are now an IRC Operator", "381" },
478 { RPL_REHASHING, "%s :Rehashing", "382" },
482 { RPL_MYPORTIS, "%d :Port to local server is", "384" }, /* not used */
484 { RPL_NOTOPERANYMORE, 0, "385" }, /* not used */
496 { RPL_TIME, "%s " TIME_T_FMT " %ld :%s", "391" },
515 { RPL_TRACELINK, "Link %s%s %s %s", "200" },
517 { RPL_TRACELINK, "Link %s%s %s %s " TIME_T_FMT, "200" },
520 { RPL_TRACECONNECTING, "Try. %d %s", "201" },
522 { RPL_TRACEHANDSHAKE, "H.S. %d %s", "202" },
524 { RPL_TRACEUNKNOWN, "???? %d %s", "203" },
526 { RPL_TRACEOPERATOR, "Oper %d %s %ld", "204" },
528 { RPL_TRACEUSER, "User %d %s %ld", "205" },
530 { RPL_TRACESERVER, "Serv %d %dS %dC %s %s!%s@%s %ld %ld", "206" },
534 { RPL_TRACENEWTYPE, "<newtype> 0 %s", "208" },
536 { RPL_TRACECLASS, "Class %d %d", "209" },
540 { RPL_STATSLINKINFO, 0, "211" },
542 { RPL_STATSCOMMANDS, "%s %u %u", "212" },
544 { RPL_STATSCLINE, "%c %s * %s %d %d", "213" },
546 { RPL_STATSNLINE, "%c %s * %s %d %d", "214" },
548 { RPL_STATSILINE, "%c %s * %s %d %d", "215" },
550 { RPL_STATSKLINE, "%c %s %s %s %d %d", "216" },
552 { RPL_STATSPLINE, "P %d %d %s %s", "217" },
554 { RPL_STATSYLINE, "%c %d %d %d %d %ld", "218" },
556 { RPL_ENDOFSTATS, "%c :End of /STATS report", "219" },
560 { RPL_UMODEIS, "%s", "221" },
580 { RPL_SERVICEINFO, 0, "231" },
582 { RPL_ENDOFSERVICES, 0, "232" },
584 { RPL_SERVICE, 0, "233" },
586 { RPL_SERVLIST, 0, "234" },
588 { RPL_SERVLISTEND, 0, "235" },
600 { RPL_STATSLLINE, "%c %s * %s %d %d", "241" },
602 { RPL_STATSUPTIME, ":Server Up %d days, %d:%02d:%02d", "242" },
604 { RPL_STATSOLINE, "%c %s * %s %d %d", "243" },
606 { RPL_STATSHLINE, "%c %s * %s %d %d", "244" },
610 { RPL_STATSTLINE, "%c %s %s", "246" },
612 { RPL_STATSGLINE, "%c %s@%s " TIME_T_FMT " :%s", "247" },
614 { RPL_STATSULINE, "%c %s %s %s %d %d", "248" },
618 { RPL_STATSCONN, ":Highest connection count: %d (%d clients)", "250" },
620 { RPL_LUSERCLIENT, ":There are %d users and %d invisible on %d servers", "251" },
622 { RPL_LUSEROP, "%d :operator(s) online", "252" },
624 { RPL_LUSERUNKNOWN, "%d :unknown connection(s)", "253" },
626 { RPL_LUSERCHANNELS, "%d :channels formed", "254" },
628 { RPL_LUSERME, ":I have %d clients and %d servers", "255" },
630 { RPL_ADMINME, ":Administrative info about %s", "256" },
632 { RPL_ADMINLOC1, ":%s", "257" },
634 { RPL_ADMINLOC2, ":%s", "258" },
636 { RPL_ADMINEMAIL, ":%s", "259" },
640 { RPL_TRACELOG, "File %s %d", "261" },
642 { RPL_TRACEPING, "Ping %s %s", "262" },
660 { RPL_SILELIST, "%s %s", "271" },
662 { RPL_ENDOFSILELIST, "%s :End of Silence List", "272" },
668 { RPL_STATSDLINE, "%c %s %s", "275" },
678 { RPL_GLIST, "%s@%s " TIME_T_FMT " %s%s", "280" },
680 { RPL_ENDOFGLIST, ":End of G-line List", "281" },
682 { RPL_JUPELIST, "%s " TIME_T_FMT " %s %c :%s", "282" },
684 { RPL_ENDOFJUPELIST, ":End of Jupe List", "283" },
689 const struct Numeric* get_error_numeric(int numeric)
692 assert(ERR_FIRSTERROR < num);
693 assert(num < ERR_LASTERROR);
695 num -= ERR_FIRSTERROR;
696 assert(0 != numeric_errors[num].value);
698 return &numeric_errors[num];
701 static char numbuff[512];
704 #define prepbuf(buffer, num, tail) \
706 char *s = buffer + 4; \
707 const char *ap = atoi_tab + (num << 2); \
709 strcpy(buffer, ":%s 000 %s "); \
713 strcpy(s + 5, tail); \
716 char *err_str(int numeric)
721 num -= numeric_errors[0].value;
724 if (num < 0 || num > ERR_USERSDONTMATCH)
726 ":%%s %d %%s :INTERNAL ERROR: BAD NUMERIC! %d", numeric, num);
729 nptr = &numeric_errors[num];
730 if (!nptr->format || !nptr->value)
731 sprintf_irc(numbuff, ":%%s %d %%s :NO ERROR FOR NUMERIC ERROR %d",
734 prepbuf(numbuff, nptr->value, nptr->format);
737 nptr = &numeric_errors[num];
738 prepbuf(numbuff, nptr->value, nptr->format);
744 char *rpl_str(int numeric)
749 if (num > (int)(sizeof(local_replies) / sizeof(Numeric) - 2))
750 num -= (num > 300) ? 300 : 100;
753 if (num < 0 || num > 200)
754 sprintf_irc(numbuff, ":%%s %d %%s :INTERNAL REPLY ERROR: BAD NUMERIC! %d",
759 nptr = &numeric_replies[num];
761 nptr = &local_replies[num];
762 Debug((DEBUG_NUM, "rpl_str: numeric %d num %d %d %s",
763 numeric, num, nptr->value, nptr->format ? nptr->format : ""));
764 if (!nptr->format || !nptr->value)
765 sprintf_irc(numbuff, ":%%s %d %%s :NO REPLY FOR NUMERIC ERROR %d",
768 prepbuf(numbuff, nptr->value, nptr->format);
772 nptr = &numeric_replies[num];
774 nptr = &local_replies[num];
775 prepbuf(numbuff, nptr->value, nptr->format);