Make realname Kill blocks more predictable, and add username="x" field.
[ircu2.10.12-pk.git] / ircd / s_err.c
index 807047b921817716cb889b37da5feb9ce2de7cae..4b03b3ddffd5b75262f40900aeee929dc0da8ae1 100644 (file)
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id$
+ */
+/** @file
+ * @brief Error handling support.
+ * @version $Id$
  */
 #include "config.h"
 
 #include "numeric.h"
+#include "ircd_log.h"
 #include "s_debug.h"
 
-#include <assert.h>
+/* #include <assert.h> -- Now using assert in ircd_log.h */
 #include <string.h>
 
+/** Array of Numeric replies, indexed by numeric. */
 static Numeric replyTable[] = {
 /* 000 */
   { 0 },
 /* 001 */
-  { RPL_WELCOME, ":Welcome to the Internet Relay Network %s", "001" },
+  { RPL_WELCOME, ":Welcome to the %s IRC Network%s%s, %s", "001" },
 /* 002 */
   { RPL_YOURHOST, ":Your host is %s, running version %s", "002" },
 /* 003 */
   { RPL_CREATED, ":This server was created %s", "003" },
 /* 004 */
-  { RPL_MYINFO, "%s %s dioswkgx Abiklmnopstuvr Abklouv", "004" },
+  { RPL_MYINFO, "%s %s %s %s %s", "004" },
 /* 005 */
   { RPL_ISUPPORT, "%s :are supported by this server", "005" },
 /* 006 */
@@ -46,13 +50,9 @@ static Numeric replyTable[] = {
 /* 008 */
   { RPL_SNOMASK, "%d :: Server notice mask (%#x)", "008" },
 /* 009 */
-  { RPL_STATMEMTOT, "%u %u :Bytes Blocks", "009" },
+  { 0 },
 /* 010 */
-#ifdef MEMSIZESTATS
-  { RPL_STATMEM, "%u %u %s %u", "010" },
-#else
-  { RPL_STATMEM, "%u %u %s", "010" },
-#endif
+  { 0 },
 /* 011 */
   { 0 },
 /* 012 */
@@ -92,11 +92,11 @@ static Numeric replyTable[] = {
 /* 029 */
   { 0 },
 /* 030 */
-  { RPL_APASSWARN, ":%s%s%s%s%s", "030" },
+  { RPL_APASSWARN_SET, ":Channel Admin password (+A) set to '%s'.  Are you SURE you want to use this as Admin password? You will NOT be able to change this password anymore once the channel is more than 48 hours old!", "030" },
 /* 031 */
-  { 0 },
+  { RPL_APASSWARN_SECRET, ":Use \"/MODE %s -A %s\" to remove the password and then immediately set a new one.  IMPORTANT: YOU CANNOT RECOVER THIS PASSWORD, EVER; WRITE THE PASSWORD DOWN (don't store this rescue password on disk)! Now set the channel user password (+U).", "031" },
 /* 032 */
-  { 0 },
+  { RPL_APASSWARN_CLEAR, ":WARNING: You removed the channel Admin password (+A). If you disconnect or leave the channel without setting a new password then you will not be able to set it again!  SET A NEW PASSWORD NOW!", "032" },
 /* 033 */
   { 0 },
 /* 034 */
@@ -458,25 +458,25 @@ static Numeric replyTable[] = {
 /* 212 */
   { RPL_STATSCOMMANDS, "%s %u %u", "212" },
 /* 213 */
-  { RPL_STATSCLINE, "%c %s * %s %d %s", "213" },
+  { RPL_STATSCLINE, "C %s %s%s %d %d %s %s", "213" },
 /* 214 */
-  { RPL_STATSNLINE, "%c %s * %s %d %d", "214" },
+  { 0 },
 /* 215 */
-  { RPL_STATSILINE, "%c %s %s %s %d %s", "215" },
+  { RPL_STATSILINE, "I %s %d %s%s %d %s", "215" },
 /* 216 */
-  { RPL_STATSKLINE, "%c %s \"%s\" %s 0 0", "216" },
+  { RPL_STATSKLINE, "%c %s@%s \"%s\" \"%s\" 0 0", "216" },
 /* 217 */
   { RPL_STATSPLINE, "P %d %d %s %s", "217" },
 /* 218 */
   { RPL_STATSYLINE, "%c %s %d %d %d %ld %d", "218" },
 /* 219 */
-  { RPL_ENDOFSTATS, "%c :End of /STATS report", "219" },
+  { RPL_ENDOFSTATS, "%s :End of /STATS report", "219" },
 /* 220 */
   { 0 },
 /* 221 */
   { RPL_UMODEIS, "%s", "221" },
 /* 222 */
-  { 0 },
+  { RPL_STATSJLINE, "J %s", "222" },
 /* 223 */
   { 0 },
 /* 224 */
@@ -484,11 +484,11 @@ static Numeric replyTable[] = {
 /* 225 */
   { 0 },
 /* 226 */
-  { 0 },
+  { RPL_STATSALINE, "%s", "226" },
 /* 227 */
   { 0 },
 /* 228 */
-  { 0 },
+  { RPL_STATSQLINE, "Q %s :%s", "228" },
 /* 229 */
   { 0 },
 /* 230 */
@@ -514,21 +514,21 @@ static Numeric replyTable[] = {
 /* 240 */
   { 0 },
 /* 241 */
-  { RPL_STATSLLINE, "%c %s * %s %d %d", "241" },
+  { RPL_STATSLLINE, "Module Description EntryPoint", "241" },
 /* 242 */
   { RPL_STATSUPTIME, ":Server Up %d days, %d:%02d:%02d", "242" },
 /* 243 */
-  { RPL_STATSOLINE, "%c %s * %s %d %d", "243" },
+  { RPL_STATSOLINE, "O %s@%s * %s %s", "243" },
 /* 244 */
-  { RPL_STATSHLINE, "%c %s * %s %d %d", "244" },
+  { 0 },
 /* 245 */
   { 0 },
 /* 246 */
   { RPL_STATSTLINE, "%c %s %s", "246" },
 /* 247 */
-  { RPL_STATSGLINE, "%c %s@%s %Tu :%s", "247" },
+  { RPL_STATSGLINE, "%c %s%s%s %Tu :%s", "247" },
 /* 248 */
-  { RPL_STATSULINE, "%c %s %s %s %d %d", "248" },
+  { RPL_STATSULINE, "U %s", "248" },
 /* 249 */
   { RPL_STATSDEBUG, 0, "249" },
 /* 250 */
@@ -556,7 +556,7 @@ static Numeric replyTable[] = {
 /* 261 */
   { RPL_TRACELOG, "File %s %d", "261" },
 /* 262 */
-  { RPL_TRACEPING, "Ping %s %s", "262" },
+  { RPL_TRACEEND, ":End of TRACE", "262" },
 /* 263 */
   { 0 },
 /* 264 */
@@ -574,7 +574,7 @@ static Numeric replyTable[] = {
 /* 270 */
   { RPL_PRIVS, "%s :", "270" },
 /* 271 */
-  { RPL_SILELIST, "%s %s", "271" },
+  { RPL_SILELIST, "%s %s%s", "271" },
 /* 272 */
   { RPL_ENDOFSILELIST, "%s :End of Silence List", "272" },
 /* 273 */
@@ -584,7 +584,7 @@ static Numeric replyTable[] = {
 /* 275 */
   { RPL_STATSDLINE, "%c %s %s", "275" },
 /* 276 */
-  { 0 },
+  { RPL_STATSRLINE, "%-9s %-9s %-10s %s", "276" },
 /* 277 */
   { 0 },
 /* 278 */
@@ -708,7 +708,7 @@ static Numeric replyTable[] = {
 /* 337 */
   { 0 },
 /* 338 */
-  { RPL_WHOISACTUALLY, ":%s is actually %s@%s [%s]", "338" },
+  { RPL_WHOISACTUALLY, "%s %s@%s %s :Actual user@host, Actual IP", "338" },
 /* 339 */
   { 0 },
 /* 340 */
@@ -722,7 +722,7 @@ static Numeric replyTable[] = {
 /* 344 */
   { 0 },
 /* 345 */
-  { 0 },
+  { RPL_ISSUEDINVITE, "%s %s %s :%s has been invited by %s", "345" },
 /* 346 */
   { RPL_INVITELIST, ":%s", "346" },
 /* 347 */
@@ -742,7 +742,7 @@ static Numeric replyTable[] = {
 /* 354 */
   { RPL_WHOSPCRPL, "%s", "354" },
 /* 355 */
-  { 0 },
+  { RPL_DELNAMREPLY, "%s", "355" },
 /* 356 */
   { 0 },
 /* 357 */
@@ -824,7 +824,7 @@ static Numeric replyTable[] = {
 /* 395 */
   { 0 },
 /* 396 */
-  { 0 },
+  { RPL_HOSTHIDDEN, "%s :is now your hidden host", "396" },
 /* 397 */
   { 0 },
 /* 398 */
@@ -852,7 +852,7 @@ static Numeric replyTable[] = {
 /* 409 */
   { ERR_NOORIGIN, ":No origin specified", "409" },
 /* 410 */
-  { 0 },
+  { ERR_UNKNOWNCAPCMD, "%s :Unknown CAP subcommand", "410" },
 /* 411 */
   { ERR_NORECIPIENT, ":No recipient given (%s)", "411" },
 /* 412 */
@@ -906,13 +906,13 @@ static Numeric replyTable[] = {
 /* 436 */
   { ERR_NICKCOLLISION, "%s :Nickname collision KILL", "436" },
 /* 437 */
-  { ERR_BANNICKCHANGE, "%s :Cannot change nickname while banned on channel", "437" },
+  { ERR_BANNICKCHANGE, "%s :Cannot change nickname while banned on channel or channel is moderated", "437" },
 /* 438 */
   { ERR_NICKTOOFAST, "%s :Nick change too fast. Please wait %d seconds.", "438" },
 /* 439 */
   { ERR_TARGETTOOFAST, "%s :Target change too fast. Please wait %d seconds.", "439" },
 /* 440 */
-  { 0 },
+  { ERR_SERVICESDOWN, "%s :Services are currently unavailable.", "440" },
 /* 441 */
   { ERR_USERNOTINCHANNEL, "%s %s :They aren't on that channel", "441" },
 /* 442 */
@@ -994,7 +994,7 @@ static Numeric replyTable[] = {
 /* 480 */
   { 0 },
 /* 481 */
-  { ERR_NOPRIVILEGES, ":Permission Denied: You're not an IRC operator", "481" },
+  { ERR_NOPRIVILEGES, ":Permission Denied: Insufficient privileges", "481" },
 /* 482 */
   { ERR_CHANOPRIVSNEEDED, "%s :You're not channel operator", "482" },
 /* 483 */
@@ -1034,7 +1034,7 @@ static Numeric replyTable[] = {
 /* 500 */
   { 0 },
 /* 501 */
-  { ERR_UMODEUNKNOWNFLAG, ":Unknown MODE flag", "501" },
+  { ERR_UMODEUNKNOWNFLAG, "%c :Unknown user MODE flag", "501" },
 /* 502 */
   { ERR_USERSDONTMATCH, ":Cant change mode for other users", "502" },
 /* 503 */
@@ -1080,7 +1080,7 @@ static Numeric replyTable[] = {
 /* 523 */
   { 0 },
 /* 524 */
-  { 0 },
+  { ERR_QUARANTINED, "%s :Channel is quarantined : %s", "524" },
 /* 525 */
   { 0 },
 /* 526 */
@@ -1134,17 +1134,17 @@ static Numeric replyTable[] = {
 /* 550 */
   { ERR_NOTLOWEROPLEVEL, "%s %s %hu %hu :Cannot %s someone with %s op-level", "550" },
 /* 551 */
-  { ERR_NOTMANAGER, "%s :You must be channel Admin to add or remove a password. %s %s %s", "551" },
+  { ERR_NOTMANAGER, "%s :You must be channel Admin to add or remove a password. Use /JOIN %s <AdminPass>.", "551" },
 /* 552 */
   { ERR_CHANSECURED, "%s :Channel is older than 48 hours and secured. Cannot change Admin pass anymore", "552" },
 /* 553 */
-  { ERR_UPASSSET, "%s :Cannot remove Admin pass (+A) while User pass (+u) is still set.  First use /MODE %s -u <userpass>", "553" },
+  { ERR_UPASSSET, "%s :Cannot remove Admin pass (+A) while User pass (+U) is still set.  First use /MODE %s -U <userpass>", "553" },
 /* 554 */
-  { ERR_UPASSNOTSET, "%s :Cannot set user pass (+u) while Admin pass (+A) is not set.  First use /MODE %s +A <adminpass>", "554" },
+  { ERR_UPASSNOTSET, "%s :Cannot set user pass (+U) until Admin pass (+A) is set.  First use /MODE %s +A <adminpass>", "554" },
 /* 555 */
-  { 0 },
+  { ERR_NOMANAGER_LONG, "%s :Re-create the channel.  The channel must be *empty* for 48 continuous hours before it can be recreated.", "555" },
 /* 556 */
-  { 0 },
+  { ERR_NOMANAGER_SHORT, "%s :Re-create the channel.  The channel must be *empty* for a minute or two before it can be recreated.", "556" },
 /* 557 */
   { 0 },
 /* 558 */
@@ -1233,6 +1233,10 @@ static Numeric replyTable[] = {
   { 0 }
 };
 
+/** Return a pointer to the Numeric for a particular code.
+ * @param n %Numeric to look up.
+ * @return Numeric structure.
+ */
 const struct Numeric* get_error_numeric(int n)
 {
   assert(0 < n);
@@ -1242,243 +1246,13 @@ const struct Numeric* get_error_numeric(int n)
   return &replyTable[n];
 }
 
-static char numbuff[512];
-
-/* *INDENT-OFF* */
-
-static const char atoi_tab[4000] = {
-    '0','0','0',0, '0','0','1',0, '0','0','2',0, '0','0','3',0, '0','0','4',0,
-    '0','0','5',0, '0','0','6',0, '0','0','7',0, '0','0','8',0, '0','0','9',0,
-    '0','1','0',0, '0','1','1',0, '0','1','2',0, '0','1','3',0, '0','1','4',0,
-    '0','1','5',0, '0','1','6',0, '0','1','7',0, '0','1','8',0, '0','1','9',0,
-    '0','2','0',0, '0','2','1',0, '0','2','2',0, '0','2','3',0, '0','2','4',0,
-    '0','2','5',0, '0','2','6',0, '0','2','7',0, '0','2','8',0, '0','2','9',0,
-    '0','3','0',0, '0','3','1',0, '0','3','2',0, '0','3','3',0, '0','3','4',0,
-    '0','3','5',0, '0','3','6',0, '0','3','7',0, '0','3','8',0, '0','3','9',0,
-    '0','4','0',0, '0','4','1',0, '0','4','2',0, '0','4','3',0, '0','4','4',0,
-    '0','4','5',0, '0','4','6',0, '0','4','7',0, '0','4','8',0, '0','4','9',0,
-    '0','5','0',0, '0','5','1',0, '0','5','2',0, '0','5','3',0, '0','5','4',0,
-    '0','5','5',0, '0','5','6',0, '0','5','7',0, '0','5','8',0, '0','5','9',0,
-    '0','6','0',0, '0','6','1',0, '0','6','2',0, '0','6','3',0, '0','6','4',0,
-    '0','6','5',0, '0','6','6',0, '0','6','7',0, '0','6','8',0, '0','6','9',0,
-    '0','7','0',0, '0','7','1',0, '0','7','2',0, '0','7','3',0, '0','7','4',0,
-    '0','7','5',0, '0','7','6',0, '0','7','7',0, '0','7','8',0, '0','7','9',0,
-    '0','8','0',0, '0','8','1',0, '0','8','2',0, '0','8','3',0, '0','8','4',0,
-    '0','8','5',0, '0','8','6',0, '0','8','7',0, '0','8','8',0, '0','8','9',0,
-    '0','9','0',0, '0','9','1',0, '0','9','2',0, '0','9','3',0, '0','9','4',0,
-    '0','9','5',0, '0','9','6',0, '0','9','7',0, '0','9','8',0, '0','9','9',0,
-    '1','0','0',0, '1','0','1',0, '1','0','2',0, '1','0','3',0, '1','0','4',0,
-    '1','0','5',0, '1','0','6',0, '1','0','7',0, '1','0','8',0, '1','0','9',0,
-    '1','1','0',0, '1','1','1',0, '1','1','2',0, '1','1','3',0, '1','1','4',0,
-    '1','1','5',0, '1','1','6',0, '1','1','7',0, '1','1','8',0, '1','1','9',0,
-    '1','2','0',0, '1','2','1',0, '1','2','2',0, '1','2','3',0, '1','2','4',0,
-    '1','2','5',0, '1','2','6',0, '1','2','7',0, '1','2','8',0, '1','2','9',0,
-    '1','3','0',0, '1','3','1',0, '1','3','2',0, '1','3','3',0, '1','3','4',0,
-    '1','3','5',0, '1','3','6',0, '1','3','7',0, '1','3','8',0, '1','3','9',0,
-    '1','4','0',0, '1','4','1',0, '1','4','2',0, '1','4','3',0, '1','4','4',0,
-    '1','4','5',0, '1','4','6',0, '1','4','7',0, '1','4','8',0, '1','4','9',0,
-    '1','5','0',0, '1','5','1',0, '1','5','2',0, '1','5','3',0, '1','5','4',0,
-    '1','5','5',0, '1','5','6',0, '1','5','7',0, '1','5','8',0, '1','5','9',0,
-    '1','6','0',0, '1','6','1',0, '1','6','2',0, '1','6','3',0, '1','6','4',0,
-    '1','6','5',0, '1','6','6',0, '1','6','7',0, '1','6','8',0, '1','6','9',0,
-    '1','7','0',0, '1','7','1',0, '1','7','2',0, '1','7','3',0, '1','7','4',0,
-    '1','7','5',0, '1','7','6',0, '1','7','7',0, '1','7','8',0, '1','7','9',0,
-    '1','8','0',0, '1','8','1',0, '1','8','2',0, '1','8','3',0, '1','8','4',0,
-    '1','8','5',0, '1','8','6',0, '1','8','7',0, '1','8','8',0, '1','8','9',0,
-    '1','9','0',0, '1','9','1',0, '1','9','2',0, '1','9','3',0, '1','9','4',0,
-    '1','9','5',0, '1','9','6',0, '1','9','7',0, '1','9','8',0, '1','9','9',0,
-    '2','0','0',0, '2','0','1',0, '2','0','2',0, '2','0','3',0, '2','0','4',0,
-    '2','0','5',0, '2','0','6',0, '2','0','7',0, '2','0','8',0, '2','0','9',0,
-    '2','1','0',0, '2','1','1',0, '2','1','2',0, '2','1','3',0, '2','1','4',0,
-    '2','1','5',0, '2','1','6',0, '2','1','7',0, '2','1','8',0, '2','1','9',0,
-    '2','2','0',0, '2','2','1',0, '2','2','2',0, '2','2','3',0, '2','2','4',0,
-    '2','2','5',0, '2','2','6',0, '2','2','7',0, '2','2','8',0, '2','2','9',0,
-    '2','3','0',0, '2','3','1',0, '2','3','2',0, '2','3','3',0, '2','3','4',0,
-    '2','3','5',0, '2','3','6',0, '2','3','7',0, '2','3','8',0, '2','3','9',0,
-    '2','4','0',0, '2','4','1',0, '2','4','2',0, '2','4','3',0, '2','4','4',0,
-    '2','4','5',0, '2','4','6',0, '2','4','7',0, '2','4','8',0, '2','4','9',0,
-    '2','5','0',0, '2','5','1',0, '2','5','2',0, '2','5','3',0, '2','5','4',0,
-    '2','5','5',0, '2','5','6',0, '2','5','7',0, '2','5','8',0, '2','5','9',0,
-    '2','6','0',0, '2','6','1',0, '2','6','2',0, '2','6','3',0, '2','6','4',0,
-    '2','6','5',0, '2','6','6',0, '2','6','7',0, '2','6','8',0, '2','6','9',0,
-    '2','7','0',0, '2','7','1',0, '2','7','2',0, '2','7','3',0, '2','7','4',0,
-    '2','7','5',0, '2','7','6',0, '2','7','7',0, '2','7','8',0, '2','7','9',0,
-    '2','8','0',0, '2','8','1',0, '2','8','2',0, '2','8','3',0, '2','8','4',0,
-    '2','8','5',0, '2','8','6',0, '2','8','7',0, '2','8','8',0, '2','8','9',0,
-    '2','9','0',0, '2','9','1',0, '2','9','2',0, '2','9','3',0, '2','9','4',0,
-    '2','9','5',0, '2','9','6',0, '2','9','7',0, '2','9','8',0, '2','9','9',0,
-    '3','0','0',0, '3','0','1',0, '3','0','2',0, '3','0','3',0, '3','0','4',0,
-    '3','0','5',0, '3','0','6',0, '3','0','7',0, '3','0','8',0, '3','0','9',0,
-    '3','1','0',0, '3','1','1',0, '3','1','2',0, '3','1','3',0, '3','1','4',0,
-    '3','1','5',0, '3','1','6',0, '3','1','7',0, '3','1','8',0, '3','1','9',0,
-    '3','2','0',0, '3','2','1',0, '3','2','2',0, '3','2','3',0, '3','2','4',0,
-    '3','2','5',0, '3','2','6',0, '3','2','7',0, '3','2','8',0, '3','2','9',0,
-    '3','3','0',0, '3','3','1',0, '3','3','2',0, '3','3','3',0, '3','3','4',0,
-    '3','3','5',0, '3','3','6',0, '3','3','7',0, '3','3','8',0, '3','3','9',0,
-    '3','4','0',0, '3','4','1',0, '3','4','2',0, '3','4','3',0, '3','4','4',0,
-    '3','4','5',0, '3','4','6',0, '3','4','7',0, '3','4','8',0, '3','4','9',0,
-    '3','5','0',0, '3','5','1',0, '3','5','2',0, '3','5','3',0, '3','5','4',0,
-    '3','5','5',0, '3','5','6',0, '3','5','7',0, '3','5','8',0, '3','5','9',0,
-    '3','6','0',0, '3','6','1',0, '3','6','2',0, '3','6','3',0, '3','6','4',0,
-    '3','6','5',0, '3','6','6',0, '3','6','7',0, '3','6','8',0, '3','6','9',0,
-    '3','7','0',0, '3','7','1',0, '3','7','2',0, '3','7','3',0, '3','7','4',0,
-    '3','7','5',0, '3','7','6',0, '3','7','7',0, '3','7','8',0, '3','7','9',0,
-    '3','8','0',0, '3','8','1',0, '3','8','2',0, '3','8','3',0, '3','8','4',0,
-    '3','8','5',0, '3','8','6',0, '3','8','7',0, '3','8','8',0, '3','8','9',0,
-    '3','9','0',0, '3','9','1',0, '3','9','2',0, '3','9','3',0, '3','9','4',0,
-    '3','9','5',0, '3','9','6',0, '3','9','7',0, '3','9','8',0, '3','9','9',0,
-    '4','0','0',0, '4','0','1',0, '4','0','2',0, '4','0','3',0, '4','0','4',0,
-    '4','0','5',0, '4','0','6',0, '4','0','7',0, '4','0','8',0, '4','0','9',0,
-    '4','1','0',0, '4','1','1',0, '4','1','2',0, '4','1','3',0, '4','1','4',0,
-    '4','1','5',0, '4','1','6',0, '4','1','7',0, '4','1','8',0, '4','1','9',0,
-    '4','2','0',0, '4','2','1',0, '4','2','2',0, '4','2','3',0, '4','2','4',0,
-    '4','2','5',0, '4','2','6',0, '4','2','7',0, '4','2','8',0, '4','2','9',0,
-    '4','3','0',0, '4','3','1',0, '4','3','2',0, '4','3','3',0, '4','3','4',0,
-    '4','3','5',0, '4','3','6',0, '4','3','7',0, '4','3','8',0, '4','3','9',0,
-    '4','4','0',0, '4','4','1',0, '4','4','2',0, '4','4','3',0, '4','4','4',0,
-    '4','4','5',0, '4','4','6',0, '4','4','7',0, '4','4','8',0, '4','4','9',0,
-    '4','5','0',0, '4','5','1',0, '4','5','2',0, '4','5','3',0, '4','5','4',0,
-    '4','5','5',0, '4','5','6',0, '4','5','7',0, '4','5','8',0, '4','5','9',0,
-    '4','6','0',0, '4','6','1',0, '4','6','2',0, '4','6','3',0, '4','6','4',0,
-    '4','6','5',0, '4','6','6',0, '4','6','7',0, '4','6','8',0, '4','6','9',0,
-    '4','7','0',0, '4','7','1',0, '4','7','2',0, '4','7','3',0, '4','7','4',0,
-    '4','7','5',0, '4','7','6',0, '4','7','7',0, '4','7','8',0, '4','7','9',0,
-    '4','8','0',0, '4','8','1',0, '4','8','2',0, '4','8','3',0, '4','8','4',0,
-    '4','8','5',0, '4','8','6',0, '4','8','7',0, '4','8','8',0, '4','8','9',0,
-    '4','9','0',0, '4','9','1',0, '4','9','2',0, '4','9','3',0, '4','9','4',0,
-    '4','9','5',0, '4','9','6',0, '4','9','7',0, '4','9','8',0, '4','9','9',0,
-    '5','0','0',0, '5','0','1',0, '5','0','2',0, '5','0','3',0, '5','0','4',0,
-    '5','0','5',0, '5','0','6',0, '5','0','7',0, '5','0','8',0, '5','0','9',0,
-    '5','1','0',0, '5','1','1',0, '5','1','2',0, '5','1','3',0, '5','1','4',0,
-    '5','1','5',0, '5','1','6',0, '5','1','7',0, '5','1','8',0, '5','1','9',0,
-    '5','2','0',0, '5','2','1',0, '5','2','2',0, '5','2','3',0, '5','2','4',0,
-    '5','2','5',0, '5','2','6',0, '5','2','7',0, '5','2','8',0, '5','2','9',0,
-    '5','3','0',0, '5','3','1',0, '5','3','2',0, '5','3','3',0, '5','3','4',0,
-    '5','3','5',0, '5','3','6',0, '5','3','7',0, '5','3','8',0, '5','3','9',0,
-    '5','4','0',0, '5','4','1',0, '5','4','2',0, '5','4','3',0, '5','4','4',0,
-    '5','4','5',0, '5','4','6',0, '5','4','7',0, '5','4','8',0, '5','4','9',0,
-    '5','5','0',0, '5','5','1',0, '5','5','2',0, '5','5','3',0, '5','5','4',0,
-    '5','5','5',0, '5','5','6',0, '5','5','7',0, '5','5','8',0, '5','5','9',0,
-    '5','6','0',0, '5','6','1',0, '5','6','2',0, '5','6','3',0, '5','6','4',0,
-    '5','6','5',0, '5','6','6',0, '5','6','7',0, '5','6','8',0, '5','6','9',0,
-    '5','7','0',0, '5','7','1',0, '5','7','2',0, '5','7','3',0, '5','7','4',0,
-    '5','7','5',0, '5','7','6',0, '5','7','7',0, '5','7','8',0, '5','7','9',0,
-    '5','8','0',0, '5','8','1',0, '5','8','2',0, '5','8','3',0, '5','8','4',0,
-    '5','8','5',0, '5','8','6',0, '5','8','7',0, '5','8','8',0, '5','8','9',0,
-    '5','9','0',0, '5','9','1',0, '5','9','2',0, '5','9','3',0, '5','9','4',0,
-    '5','9','5',0, '5','9','6',0, '5','9','7',0, '5','9','8',0, '5','9','9',0,
-    '6','0','0',0, '6','0','1',0, '6','0','2',0, '6','0','3',0, '6','0','4',0,
-    '6','0','5',0, '6','0','6',0, '6','0','7',0, '6','0','8',0, '6','0','9',0,
-    '6','1','0',0, '6','1','1',0, '6','1','2',0, '6','1','3',0, '6','1','4',0,
-    '6','1','5',0, '6','1','6',0, '6','1','7',0, '6','1','8',0, '6','1','9',0,
-    '6','2','0',0, '6','2','1',0, '6','2','2',0, '6','2','3',0, '6','2','4',0,
-    '6','2','5',0, '6','2','6',0, '6','2','7',0, '6','2','8',0, '6','2','9',0,
-    '6','3','0',0, '6','3','1',0, '6','3','2',0, '6','3','3',0, '6','3','4',0,
-    '6','3','5',0, '6','3','6',0, '6','3','7',0, '6','3','8',0, '6','3','9',0,
-    '6','4','0',0, '6','4','1',0, '6','4','2',0, '6','4','3',0, '6','4','4',0,
-    '6','4','5',0, '6','4','6',0, '6','4','7',0, '6','4','8',0, '6','4','9',0,
-    '6','5','0',0, '6','5','1',0, '6','5','2',0, '6','5','3',0, '6','5','4',0,
-    '6','5','5',0, '6','5','6',0, '6','5','7',0, '6','5','8',0, '6','5','9',0,
-    '6','6','0',0, '6','6','1',0, '6','6','2',0, '6','6','3',0, '6','6','4',0,
-    '6','6','5',0, '6','6','6',0, '6','6','7',0, '6','6','8',0, '6','6','9',0,
-    '6','7','0',0, '6','7','1',0, '6','7','2',0, '6','7','3',0, '6','7','4',0,
-    '6','7','5',0, '6','7','6',0, '6','7','7',0, '6','7','8',0, '6','7','9',0,
-    '6','8','0',0, '6','8','1',0, '6','8','2',0, '6','8','3',0, '6','8','4',0,
-    '6','8','5',0, '6','8','6',0, '6','8','7',0, '6','8','8',0, '6','8','9',0,
-    '6','9','0',0, '6','9','1',0, '6','9','2',0, '6','9','3',0, '6','9','4',0,
-    '6','9','5',0, '6','9','6',0, '6','9','7',0, '6','9','8',0, '6','9','9',0,
-    '7','0','0',0, '7','0','1',0, '7','0','2',0, '7','0','3',0, '7','0','4',0,
-    '7','0','5',0, '7','0','6',0, '7','0','7',0, '7','0','8',0, '7','0','9',0,
-    '7','1','0',0, '7','1','1',0, '7','1','2',0, '7','1','3',0, '7','1','4',0,
-    '7','1','5',0, '7','1','6',0, '7','1','7',0, '7','1','8',0, '7','1','9',0,
-    '7','2','0',0, '7','2','1',0, '7','2','2',0, '7','2','3',0, '7','2','4',0,
-    '7','2','5',0, '7','2','6',0, '7','2','7',0, '7','2','8',0, '7','2','9',0,
-    '7','3','0',0, '7','3','1',0, '7','3','2',0, '7','3','3',0, '7','3','4',0,
-    '7','3','5',0, '7','3','6',0, '7','3','7',0, '7','3','8',0, '7','3','9',0,
-    '7','4','0',0, '7','4','1',0, '7','4','2',0, '7','4','3',0, '7','4','4',0,
-    '7','4','5',0, '7','4','6',0, '7','4','7',0, '7','4','8',0, '7','4','9',0,
-    '7','5','0',0, '7','5','1',0, '7','5','2',0, '7','5','3',0, '7','5','4',0,
-    '7','5','5',0, '7','5','6',0, '7','5','7',0, '7','5','8',0, '7','5','9',0,
-    '7','6','0',0, '7','6','1',0, '7','6','2',0, '7','6','3',0, '7','6','4',0,
-    '7','6','5',0, '7','6','6',0, '7','6','7',0, '7','6','8',0, '7','6','9',0,
-    '7','7','0',0, '7','7','1',0, '7','7','2',0, '7','7','3',0, '7','7','4',0,
-    '7','7','5',0, '7','7','6',0, '7','7','7',0, '7','7','8',0, '7','7','9',0,
-    '7','8','0',0, '7','8','1',0, '7','8','2',0, '7','8','3',0, '7','8','4',0,
-    '7','8','5',0, '7','8','6',0, '7','8','7',0, '7','8','8',0, '7','8','9',0,
-    '7','9','0',0, '7','9','1',0, '7','9','2',0, '7','9','3',0, '7','9','4',0,
-    '7','9','5',0, '7','9','6',0, '7','9','7',0, '7','9','8',0, '7','9','9',0,
-    '8','0','0',0, '8','0','1',0, '8','0','2',0, '8','0','3',0, '8','0','4',0,
-    '8','0','5',0, '8','0','6',0, '8','0','7',0, '8','0','8',0, '8','0','9',0,
-    '8','1','0',0, '8','1','1',0, '8','1','2',0, '8','1','3',0, '8','1','4',0,
-    '8','1','5',0, '8','1','6',0, '8','1','7',0, '8','1','8',0, '8','1','9',0,
-    '8','2','0',0, '8','2','1',0, '8','2','2',0, '8','2','3',0, '8','2','4',0,
-    '8','2','5',0, '8','2','6',0, '8','2','7',0, '8','2','8',0, '8','2','9',0,
-    '8','3','0',0, '8','3','1',0, '8','3','2',0, '8','3','3',0, '8','3','4',0,
-    '8','3','5',0, '8','3','6',0, '8','3','7',0, '8','3','8',0, '8','3','9',0,
-    '8','4','0',0, '8','4','1',0, '8','4','2',0, '8','4','3',0, '8','4','4',0,
-    '8','4','5',0, '8','4','6',0, '8','4','7',0, '8','4','8',0, '8','4','9',0,
-    '8','5','0',0, '8','5','1',0, '8','5','2',0, '8','5','3',0, '8','5','4',0,
-    '8','5','5',0, '8','5','6',0, '8','5','7',0, '8','5','8',0, '8','5','9',0,
-    '8','6','0',0, '8','6','1',0, '8','6','2',0, '8','6','3',0, '8','6','4',0,
-    '8','6','5',0, '8','6','6',0, '8','6','7',0, '8','6','8',0, '8','6','9',0,
-    '8','7','0',0, '8','7','1',0, '8','7','2',0, '8','7','3',0, '8','7','4',0,
-    '8','7','5',0, '8','7','6',0, '8','7','7',0, '8','7','8',0, '8','7','9',0,
-    '8','8','0',0, '8','8','1',0, '8','8','2',0, '8','8','3',0, '8','8','4',0,
-    '8','8','5',0, '8','8','6',0, '8','8','7',0, '8','8','8',0, '8','8','9',0,
-    '8','9','0',0, '8','9','1',0, '8','9','2',0, '8','9','3',0, '8','9','4',0,
-    '8','9','5',0, '8','9','6',0, '8','9','7',0, '8','9','8',0, '8','9','9',0,
-    '9','0','0',0, '9','0','1',0, '9','0','2',0, '9','0','3',0, '9','0','4',0,
-    '9','0','5',0, '9','0','6',0, '9','0','7',0, '9','0','8',0, '9','0','9',0,
-    '9','1','0',0, '9','1','1',0, '9','1','2',0, '9','1','3',0, '9','1','4',0,
-    '9','1','5',0, '9','1','6',0, '9','1','7',0, '9','1','8',0, '9','1','9',0,
-    '9','2','0',0, '9','2','1',0, '9','2','2',0, '9','2','3',0, '9','2','4',0,
-    '9','2','5',0, '9','2','6',0, '9','2','7',0, '9','2','8',0, '9','2','9',0,
-    '9','3','0',0, '9','3','1',0, '9','3','2',0, '9','3','3',0, '9','3','4',0,
-    '9','3','5',0, '9','3','6',0, '9','3','7',0, '9','3','8',0, '9','3','9',0,
-    '9','4','0',0, '9','4','1',0, '9','4','2',0, '9','4','3',0, '9','4','4',0,
-    '9','4','5',0, '9','4','6',0, '9','4','7',0, '9','4','8',0, '9','4','9',0,
-    '9','5','0',0, '9','5','1',0, '9','5','2',0, '9','5','3',0, '9','5','4',0,
-    '9','5','5',0, '9','5','6',0, '9','5','7',0, '9','5','8',0, '9','5','9',0,
-    '9','6','0',0, '9','6','1',0, '9','6','2',0, '9','6','3',0, '9','6','4',0,
-    '9','6','5',0, '9','6','6',0, '9','6','7',0, '9','6','8',0, '9','6','9',0,
-    '9','7','0',0, '9','7','1',0, '9','7','2',0, '9','7','3',0, '9','7','4',0,
-    '9','7','5',0, '9','7','6',0, '9','7','7',0, '9','7','8',0, '9','7','9',0,
-    '9','8','0',0, '9','8','1',0, '9','8','2',0, '9','8','3',0, '9','8','4',0,
-    '9','8','5',0, '9','8','6',0, '9','8','7',0, '9','8','8',0, '9','8','9',0,
-    '9','9','0',0, '9','9','1',0, '9','9','2',0, '9','9','3',0, '9','9','4',0,
-    '9','9','5',0, '9','9','6',0, '9','9','7',0, '9','9','8',0, '9','9','9',0 };
-
-/* *INDENT-ON* */
-
-/* "inline" */
-#define prepbuf(buffer, num, tail)                      \
-{                                                       \
-  char *s = buffer + 4;                 \
-  const char *ap = atoi_tab + (num << 2);       \
-                                                        \
-  strcpy(buffer, ":%s 000 %s ");                        \
-  *s++ = *ap++;                                         \
-  *s++ = *ap++;                                         \
-  *s = *ap;                                             \
-  strcpy(s + 5, tail);                                  \
-}
-
-char* err_str(int n)
-{
-  Numeric* p;
-
-  assert(0 < n);
-  assert(n < ERR_LASTERROR);
-  assert(0 != replyTable[n].value);
-
-  p = &replyTable[n];
-  prepbuf(numbuff, p->value, p->format);
-
-  return numbuff;
-}
-
+/** Return a format string for a numeric response.
+ * @param n %Numeric to look up.
+ * @return Pointer to a static buffer containing the format string.
+ */
 char* rpl_str(int n)
 {
+  static char numbuff[512];
   Numeric* p;
 
   assert(0 < n);
@@ -1486,7 +1260,13 @@ char* rpl_str(int n)
   assert(0 != replyTable[n].value);
 
   p = &replyTable[n];
-  prepbuf(numbuff, p->value, p->format);
+  strcpy(numbuff, ":%s 000 %s ");
+  if (p->str) {
+    numbuff[4] = p->str[0];
+    numbuff[5] = p->str[1];
+    numbuff[6] = p->str[2];
+    strcpy(numbuff + 11, p->format);
+  }
 
   return numbuff;
 }