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.
20 * @brief Error handling support.
29 /* #include <assert.h> -- Now using assert in ircd_log.h */
32 /** Array of Numeric replies, indexed by numeric. */
33 static Numeric replyTable[] = {
37 { RPL_WELCOME, ":Welcome to the %s IRC Network%s%s, %s", "001" },
39 { RPL_YOURHOST, ":Your host is %s, running version %s", "002" },
41 { RPL_CREATED, ":This server was created %s", "003" },
43 { RPL_MYINFO, "%s %s %s %s %s", "004" },
45 { RPL_ISUPPORT, "%s :are supported by this server", "005" },
51 { RPL_SNOMASK, "%d :: Server notice mask (%#x)", "008" },
65 { RPL_MAP, ":%s%s%s %s [%i clients]", "015" },
67 { RPL_MAPMORE, ":%s%s --> *more*", "016" },
69 { RPL_MAPEND, ":End of /MAP", "017" },
95 { RPL_APASSWARN, ":%s%s%s%s%s", "030" },
435 { RPL_TRACELINK, "Link %s.%s %s %s", "200" },
437 { RPL_TRACECONNECTING, "Try. %s %s", "201" },
439 { RPL_TRACEHANDSHAKE, "H.S. %s %s", "202" },
441 { RPL_TRACEUNKNOWN, "???? %s %s", "203" },
443 { RPL_TRACEOPERATOR, "Oper %s %s %ld", "204" },
445 { RPL_TRACEUSER, "User %s %s %ld", "205" },
447 { RPL_TRACESERVER, "Serv %s %dS %dC %s %s!%s@%s %ld %ld", "206" },
451 { RPL_TRACENEWTYPE, "<newtype> 0 %s", "208" },
453 { RPL_TRACECLASS, "Class %s %d", "209" },
457 { RPL_STATSLINKINFO, 0, "211" },
459 { RPL_STATSCOMMANDS, "%s %u %u", "212" },
461 { RPL_STATSCLINE, "C %s %s %d %d %s %s", "213" },
465 { RPL_STATSILINE, "I %s %d %s %d %s", "215" },
467 { RPL_STATSKLINE, "%c %s \"%s\" %s 0 0", "216" },
469 { RPL_STATSPLINE, "P %d %d %s %s", "217" },
471 { RPL_STATSYLINE, "%c %s %d %d %d %ld %d", "218" },
473 { RPL_ENDOFSTATS, "%s :End of /STATS report", "219" },
477 { RPL_UMODEIS, "%s", "221" },
487 { RPL_STATSALINE, "%s", "226" },
491 { RPL_STATSQLINE, "Q %s :%s", "228" },
497 { RPL_SERVICEINFO, 0, "231" },
499 { RPL_ENDOFSERVICES, 0, "232" },
501 { RPL_SERVICE, 0, "233" },
503 { RPL_SERVLIST, 0, "234" },
505 { RPL_SERVLISTEND, 0, "235" },
507 { RPL_STATSVERBOSE, "V :Sent as explicit", "236" },
509 { RPL_STATSENGINE, "%s :Event loop engine", "237" },
511 { RPL_STATSFLINE, "%c %s %s", "238" },
517 { RPL_STATSLLINE, "Module Description EntryPoint", "241" },
519 { RPL_STATSUPTIME, ":Server Up %d days, %d:%02d:%02d", "242" },
521 { RPL_STATSOLINE, "O %s * %s %d %d", "243" },
527 { RPL_STATSTLINE, "%c %s %s", "246" },
529 { RPL_STATSGLINE, "%c %s%s%s %Tu :%s", "247" },
531 { RPL_STATSULINE, "U %s", "248" },
533 { RPL_STATSDEBUG, 0, "249" },
535 { RPL_STATSCONN, ":Highest connection count: %d (%d clients)", "250" },
537 { RPL_LUSERCLIENT, ":There are %d users and %d invisible on %d servers", "251" },
539 { RPL_LUSEROP, "%d :operator(s) online", "252" },
541 { RPL_LUSERUNKNOWN, "%d :unknown connection(s)", "253" },
543 { RPL_LUSERCHANNELS, "%d :channels formed", "254" },
545 { RPL_LUSERME, ":I have %d clients and %d servers", "255" },
547 { RPL_ADMINME, ":Administrative info about %s", "256" },
549 { RPL_ADMINLOC1, ":%s", "257" },
551 { RPL_ADMINLOC2, ":%s", "258" },
553 { RPL_ADMINEMAIL, ":%s", "259" },
557 { RPL_TRACELOG, "File %s %d", "261" },
559 { RPL_TRACEEND, ":End of TRACE", "262" },
575 { RPL_PRIVS, "%s :", "270" },
577 { RPL_SILELIST, "%s %s%s", "271" },
579 { RPL_ENDOFSILELIST, "%s :End of Silence List", "272" },
585 { RPL_STATSDLINE, "%c %s %s", "275" },
587 { RPL_STATSRLINE, "%-9s %-9s %-10s %s", "276" },
595 { RPL_GLIST, "%s%s%s %Tu %s %c :%s", "280" },
597 { RPL_ENDOFGLIST, ":End of G-line List", "281" },
599 { RPL_JUPELIST, "%s %Tu %s %c :%s", "282" },
601 { RPL_ENDOFJUPELIST, ":End of Jupe List", "283" },
603 { RPL_FEATURE, 0, "284" },
635 { RPL_NONE, 0, "300" },
637 { RPL_AWAY, "%s :%s", "301" },
639 { RPL_USERHOST, ":", "302" },
641 { RPL_ISON, ":", "303" },
643 { RPL_TEXT, 0, "304" },
645 { RPL_UNAWAY, ":You are no longer marked as being away", "305" },
647 { RPL_NOWAWAY, ":You have been marked as being away", "306" },
657 { RPL_WHOISUSER, "%s %s %s * :%s", "311" },
659 { RPL_WHOISSERVER, "%s %s :%s", "312" },
661 { RPL_WHOISOPERATOR, "%s :is an IRC Operator", "313" },
663 { RPL_WHOWASUSER, "%s %s %s * :%s", "314" },
665 { RPL_ENDOFWHO, "%s :End of /WHO list.", "315" },
669 { RPL_WHOISIDLE, "%s %ld %ld :seconds idle, signon time", "317" },
671 { RPL_ENDOFWHOIS, "%s :End of /WHOIS list.", "318" },
673 { RPL_WHOISCHANNELS, "%s :%s", "319" },
677 { RPL_LISTSTART, "Channel :Users Name", "321" },
679 { RPL_LIST, "%s %d :%s", "322" },
681 { RPL_LISTEND, ":End of /LIST", "323" },
683 { RPL_CHANNELMODEIS, "%s %s %s", "324" },
693 { RPL_CREATIONTIME, "%s %Tu", "329" },
695 { RPL_WHOISACCOUNT, "%s %s :is logged in as", "330" },
697 { RPL_NOTOPIC, "%s :No topic is set.", "331" },
699 { RPL_TOPIC, "%s :%s", "332" },
701 { RPL_TOPICWHOTIME, "%s %s %Tu", "333" },
703 { RPL_LISTUSAGE, ":%s", "334" },
711 { RPL_WHOISACTUALLY, "%s %s@%s %s :Actual user@host, Actual IP", "338" },
715 { RPL_USERIP, ":", "340" },
717 { RPL_INVITING, "%s %s", "341" },
725 { RPL_ISSUEDINVITE, "%s %s %s :%s has been invited by %s", "345" },
727 { RPL_INVITELIST, ":%s", "346" },
729 { RPL_ENDOFINVITELIST, ":End of Invite List", "347" },
737 { RPL_VERSION, "%s.%s %s :%s", "351" },
739 { RPL_WHOREPLY, "%s", "352" },
741 { RPL_NAMREPLY, "%s", "353" },
743 { RPL_WHOSPCRPL, "%s", "354" },
745 { RPL_DELNAMREPLY, "%s", "355" },
757 { RPL_KILLDONE, 0, "361" }, /* Not used */
759 { RPL_CLOSING, "%s :Operator enforced Close", "362" },
761 { RPL_CLOSEEND, "%d :Connections Closed", "363" },
763 { RPL_LINKS, "%s %s :%d P%u %s", "364" },
765 { RPL_ENDOFLINKS, "%s :End of /LINKS list.", "365" },
767 { RPL_ENDOFNAMES, "%s :End of /NAMES list.", "366" },
769 { RPL_BANLIST, "%s %s %s %Tu", "367" },
771 { RPL_ENDOFBANLIST, "%s :End of Channel Ban List", "368" },
773 { RPL_ENDOFWHOWAS, "%s :End of WHOWAS", "369" },
777 { RPL_INFO, ":%s", "371" },
779 { RPL_MOTD, ":- %s", "372" },
781 { RPL_INFOSTART, ":Server INFO", "373" },
783 { RPL_ENDOFINFO, ":End of /INFO list.", "374" },
785 { RPL_MOTDSTART, ":- %s Message of the Day - ", "375" },
787 { RPL_ENDOFMOTD, ":End of /MOTD command.", "376" },
797 { RPL_YOUREOPER, ":You are now an IRC Operator", "381" },
799 { RPL_REHASHING, "%s :Rehashing", "382" },
803 { RPL_MYPORTIS, "%d :Port to local server is", "384" }, /* not used */
805 { RPL_NOTOPERANYMORE, 0, "385" }, /* not used */
817 { RPL_TIME, "%s %Tu %ld :%s", "391" },
827 { RPL_HOSTHIDDEN, "%s :is now your hidden host", "396" },
835 { ERR_FIRSTERROR, "", "400" },
837 { ERR_NOSUCHNICK, "%s :No such nick", "401" },
839 { ERR_NOSUCHSERVER, "%s :No such server", "402" },
841 { ERR_NOSUCHCHANNEL, "%s :No such channel", "403" },
843 { ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel", "404" },
845 { ERR_TOOMANYCHANNELS, "%s :You have joined too many channels", "405" },
847 { ERR_WASNOSUCHNICK, "%s :There was no such nickname", "406" },
849 { ERR_TOOMANYTARGETS, "%s :Duplicate recipients. No message delivered", "407" },
853 { ERR_NOORIGIN, ":No origin specified", "409" },
857 { ERR_NORECIPIENT, ":No recipient given (%s)", "411" },
859 { ERR_NOTEXTTOSEND, ":No text to send", "412" },
861 { ERR_NOTOPLEVEL, "%s :No toplevel domain specified", "413" },
863 { ERR_WILDTOPLEVEL, "%s :Wildcard in toplevel Domain", "414" },
867 { ERR_QUERYTOOLONG, "%s :Too many lines in the output, restrict your query", "416" },
877 { ERR_UNKNOWNCOMMAND, "%s :Unknown command", "421" },
879 { ERR_NOMOTD, ":MOTD File is missing", "422" },
881 { ERR_NOADMININFO, "%s :No administrative info available", "423" },
897 { ERR_NONICKNAMEGIVEN, ":No nickname given", "431" },
899 { ERR_ERRONEUSNICKNAME, "%s :Erroneous Nickname", "432" },
901 { ERR_NICKNAMEINUSE, "%s :Nickname is already in use.", "433" },
907 { ERR_NICKCOLLISION, "%s :Nickname collision KILL", "436" },
909 { ERR_BANNICKCHANGE, "%s :Cannot change nickname while banned on channel or channel is moderated", "437" },
911 { ERR_NICKTOOFAST, "%s :Nick change too fast. Please wait %d seconds.", "438" },
913 { ERR_TARGETTOOFAST, "%s :Target change too fast. Please wait %d seconds.", "439" },
915 { ERR_SERVICESDOWN, "%s :Services are currently unavailable.", "440" },
917 { ERR_USERNOTINCHANNEL, "%s %s :They aren't on that channel", "441" },
919 { ERR_NOTONCHANNEL, "%s :You're not on that channel", "442" },
921 { ERR_USERONCHANNEL, "%s %s :is already on channel", "443" },
937 { ERR_NOTREGISTERED, ":You have not registered", "451" },
957 { ERR_NEEDMOREPARAMS, "%s :Not enough parameters", "461" },
959 { ERR_ALREADYREGISTRED, ":You may not reregister", "462" },
961 { ERR_NOPERMFORHOST, ":Your host isn't among the privileged", "463" },
963 { ERR_PASSWDMISMATCH, ":Password Incorrect", "464" },
965 { ERR_YOUREBANNEDCREEP, ":You are banned from this server", "465" },
967 { ERR_YOUWILLBEBANNED, "", "466" },
969 { ERR_KEYSET, "%s :Channel key already set", "467" },
971 { ERR_INVALIDUSERNAME, 0, "468" },
977 { ERR_CHANNELISFULL, "%s :Cannot join channel (+l)", "471" },
979 { ERR_UNKNOWNMODE, "%c :is unknown mode char to me", "472" },
981 { ERR_INVITEONLYCHAN, "%s :Cannot join channel (+i)", "473" },
983 { ERR_BANNEDFROMCHAN, "%s :Cannot join channel (+b)", "474" },
985 { ERR_BADCHANNELKEY, "%s :Cannot join channel (+k)", "475" },
987 { ERR_BADCHANMASK, "%s :Bad Channel Mask", "476" },
989 { ERR_NEEDREGGEDNICK, "%s :Cannot join channel (+r)", "477" },
991 { ERR_BANLISTFULL, "%s %s :Channel ban/ignore list is full", "478" },
993 { ERR_BADCHANNAME, "%s :Cannot join channel (access denied on this server)", "479" },
997 { ERR_NOPRIVILEGES, ":Permission Denied: Insufficient privileges", "481" },
999 { ERR_CHANOPRIVSNEEDED, "%s :You're not channel operator", "482" },
1001 { ERR_CANTKILLSERVER, ":You cant kill a server!", "483" },
1003 { ERR_ISCHANSERVICE, "%s %s :Cannot kill, kick or deop a network service", "484" },
1013 { ERR_VOICENEEDED, "%s :You're neither voiced nor channel operator", "489" },
1017 { ERR_NOOPERHOST, ":No O-lines for your host", "491" },
1021 { ERR_NOFEATURE, "%s :No such feature", "493" },
1023 { ERR_BADFEATVALUE, "%s :Bad value for feature %s", "494" },
1025 { ERR_BADLOGTYPE, "%s :No such log type", "495" },
1027 { ERR_BADLOGSYS, "%s :No such log subsystem", "496" },
1029 { ERR_BADLOGVALUE, "%s :Bad value for log type", "497" },
1031 { ERR_ISOPERLCHAN, "%s %s :Cannot kick or deop an IRC Operator on a local channel", "498" },
1037 { ERR_UMODEUNKNOWNFLAG, "%c :Unknown user MODE flag", "501" },
1039 { ERR_USERSDONTMATCH, ":Cant change mode for other users", "502" },
1057 { ERR_SILELISTFULL, "%s :Your silence list is full", "511" },
1059 { ERR_NOSUCHGLINE, "%s :No such gline", "512" },
1061 { ERR_BADPING, 0, "513" },
1063 { ERR_NOSUCHJUPE, "%s :No such jupe", "514" },
1065 { ERR_BADEXPIRE, "%Tu :Bad expire time", "515" },
1067 { ERR_DONTCHEAT, " :Don't Cheat.", "516" },
1069 { ERR_DISABLED, "%s :Command disabled.", "517" },
1071 { ERR_LONGMASK, " :Mask is too long", "518" },
1073 { ERR_TOOMANYUSERS, "%d :Too many users affected by mask", "519" },
1075 { ERR_MASKTOOWIDE, "%s :Mask is too wide", "520" },
1083 { ERR_QUARANTINED, "%s :Channel is quarantined : %s", "524" },
1135 { ERR_NOTLOWEROPLEVEL, "%s %s %hu %hu :Cannot %s someone with %s op-level", "550" },
1137 { ERR_NOTMANAGER, "%s :You must be channel Admin to add or remove a password. %s %s %s", "551" },
1139 { ERR_CHANSECURED, "%s :Channel is older than 48 hours and secured. Cannot change Admin pass anymore", "552" },
1141 { ERR_UPASSSET, "%s :Cannot remove Admin pass (+A) while User pass (+U) is still set. First use /MODE %s -U <userpass>", "553" },
1143 { ERR_UPASSNOTSET, "%s :Cannot set user pass (+U) until Admin pass (+A) is set. First use /MODE %s +A <adminpass>", "554" },
1236 /** Return a pointer to the Numeric for a particular code.
1237 * @param n %Numeric to look up.
1238 * @return Numeric structure.
1240 const struct Numeric* get_error_numeric(int n)
1243 assert(n < ERR_LASTERROR);
1244 assert(0 != replyTable[n].value);
1246 return &replyTable[n];
1249 /** Return a format string for a numeric response.
1250 * @param n %Numeric to look up.
1251 * @return Pointer to a static buffer containing the format string.
1253 char* rpl_str(int n)
1255 static char numbuff[512];
1259 assert(n < ERR_LASTERROR);
1260 assert(0 != replyTable[n].value);
1263 strcpy(numbuff, ":%s 000 %s ");
1265 numbuff[4] = p->str[0];
1266 numbuff[5] = p->str[1];
1267 numbuff[6] = p->str[2];
1268 strcpy(numbuff + 11, p->format);