Author: Isomer <isomer@coders.net>
[ircu2.10.12-pk.git] / ircd / s_err.c
1 /*
2  * IRC - Internet Relay Chat, ircd/s_err.c
3  * Copyright (C) 1992 Darren Reed
4  *
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)
8  * any later version.
9  *
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.
14  *
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.
18  *
19  * $Id$
20  */
21 #include "numeric.h"
22 #include "s_debug.h"
23 #include "sprintf_irc.h"
24
25 #include <assert.h>
26
27 static Numeric local_replies[] = {
28 /* 000 */
29   { 0 },
30 /* 001 */
31   { RPL_WELCOME, ":Welcome to the Internet Relay Network %s", "001" },
32 /* 002 */
33   { RPL_YOURHOST, ":Your host is %s, running version %s", "002" },
34 /* 003 */
35   { RPL_CREATED, ":This server was created %s", "003" },
36 /* 004 */
37   { RPL_MYINFO, "%s %s dioswkg biklmnopstv", "004" },
38 /* 005 */
39   { RPL_ISUPPORT, "%s :are supported by this server", "005" },
40 /* 006 */
41   { 0 },
42 /* 007 */
43   { 0 },
44 /* 008 */
45   { RPL_SNOMASK, "%d :: Server notice mask (%#x)", "008" },
46 /* 009 */
47   { RPL_STATMEMTOT, "%u %u :Bytes Blocks", "009" },
48 /* 010 */
49 #ifdef MEMSIZESTATS
50   { RPL_STATMEM, "%u %u %s %u", "010" },
51 #else
52   { RPL_STATMEM, "%u %u %s", "010" },
53 #endif
54 /* 011 */
55   { 0 },
56 /* 012 */
57   { 0 },
58 /* 013 */
59   { 0 },
60 /* 014 */
61   { 0 },
62 /* 015 */
63   { RPL_MAP, ":%s%s%s %s [%i clients]", "015" },
64 /* 016 */
65   { RPL_MAPMORE, ":%s%s --> *more*", "016" },
66 /* 017 */
67   { RPL_MAPEND, ":End of /MAP", "017" },
68   { 0 }
69 };
70
71 static Numeric numeric_errors[] = {
72 /* 400 */
73   { ERR_FIRSTERROR, "", "400" },
74 /* 401 */
75   { ERR_NOSUCHNICK, "%s :No such nick", "401" },
76 /* 402 */
77   { ERR_NOSUCHSERVER, "%s :No such server", "402" },
78 /* 403 */
79   { ERR_NOSUCHCHANNEL, "%s :No such channel", "403" },
80 /* 404 */
81   { ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel", "404" },
82 /* 405 */
83   { ERR_TOOMANYCHANNELS, "%s :You have joined too many channels", "405" },
84 /* 406 */
85   { ERR_WASNOSUCHNICK, "%s :There was no such nickname", "406" },
86 /* 407 */
87   { ERR_TOOMANYTARGETS, "%s :Duplicate recipients. No message delivered", "407" },
88 /* 408 */
89   { 0 },
90 /* 409 */
91   { ERR_NOORIGIN, ":No origin specified", "409" },
92 /* 410 */
93   { 0 },
94 /* 411 */
95   { ERR_NORECIPIENT, ":No recipient given (%s)", "411" },
96 /* 412 */
97   { ERR_NOTEXTTOSEND, ":No text to send", "412" },
98 /* 413 */
99   { ERR_NOTOPLEVEL, "%s :No toplevel domain specified", "413" },
100 /* 414 */
101   { ERR_WILDTOPLEVEL, "%s :Wildcard in toplevel Domain", "414" },
102 /* 415 */
103   { 0 },
104 /* 416 */
105   { ERR_QUERYTOOLONG, "%s :Too many lines in the output, restrict your query", "416" },
106 /* 417 */
107   { 0 },
108 /* 418 */
109   { 0 },
110 /* 419 */
111   { 0 },
112 /* 420 */
113   { 0 },
114 /* 421 */
115   { ERR_UNKNOWNCOMMAND, "%s :Unknown command", "421" },
116 /* 422 */
117   { ERR_NOMOTD, ":MOTD File is missing", "422" },
118 /* 423 */
119   { ERR_NOADMININFO, "%s :No administrative info available", "423" },
120 /* 424 */
121   { 0 },
122 /* 425 */
123   { 0 },
124 /* 426 */
125   { 0 },
126 /* 427 */
127   { 0 },
128 /* 428 */
129   { 0 },
130 /* 429 */
131   { 0 },
132 /* 430 */
133   { 0 },
134 /* 431 */
135   { ERR_NONICKNAMEGIVEN, ":No nickname given", "431" },
136 /* 432 */
137   { ERR_ERRONEUSNICKNAME, "%s :Erroneous Nickname", "432" },
138 /* 433 */
139   { ERR_NICKNAMEINUSE, "%s :Nickname is already in use.", "433" },
140 /* 434 */
141   { 0 },
142 /* 435 */
143   { 0 },
144 /* 436 */
145   { ERR_NICKCOLLISION, "%s :Nickname collision KILL", "436" },
146 /* 437 */
147   { ERR_BANNICKCHANGE, "%s :Cannot change nickname while banned on channel", "437" },
148 /* 438 */
149   { ERR_NICKTOOFAST, "%s :Nick change too fast. Please wait %d seconds.", "438" },
150 /* 439 */
151   { ERR_TARGETTOOFAST, "%s :Target change too fast. Please wait %d seconds.", "439" },
152 /* 440 */
153   { 0 },
154 /* 441 */
155   { ERR_USERNOTINCHANNEL, "%s %s :They aren't on that channel", "441" },
156 /* 442 */
157   { ERR_NOTONCHANNEL, "%s :You're not on that channel", "442" },
158 /* 443 */
159   { ERR_USERONCHANNEL, "%s %s :is already on channel", "443" },
160 /* 444 */
161   { 0 },
162 /* 445 */
163   { 0 },
164 /* 446 */
165   { 0 },
166 /* 447 */
167   { 0 },
168 /* 448 */
169   { 0 },
170 /* 449 */
171   { 0 },
172 /* 450 */
173   { 0 },
174 /* 451 */
175   { ERR_NOTREGISTERED, ":You have not registered", "451" },
176 /* 452 */
177   { 0 },
178 /* 453 */
179   { 0 },
180 /* 454 */
181   { 0 },
182 /* 455 */
183   { 0 },
184 /* 456 */
185   { 0 },
186 /* 457 */
187   { 0 },
188 /* 458 */
189   { 0 },
190 /* 459 */
191   { 0 },
192 /* 460 */
193   { 0 },
194 /* 461 */
195   { ERR_NEEDMOREPARAMS, "%s :Not enough parameters", "461" },
196 /* 462 */
197   { ERR_ALREADYREGISTRED, ":You may not reregister", "462" },
198 /* 463 */
199   { ERR_NOPERMFORHOST, ":Your host isn't among the privileged", "463" },
200 /* 464 */
201   { ERR_PASSWDMISMATCH, ":Password Incorrect", "464" },
202 /* 465 */
203   { ERR_YOUREBANNEDCREEP, ":You are banned from this server", "465" },
204 /* 466 */
205   { ERR_YOUWILLBEBANNED, "", "466" },
206 /* 467 */
207   { ERR_KEYSET, "%s :Channel key already set", "467" },
208 /* 468 */
209   { ERR_INVALIDUSERNAME, "", "468" },
210 /* 469 */
211   { 0 },
212 /* 470 */
213   { 0 },
214 /* 471 */
215   { ERR_CHANNELISFULL, "%s :Cannot join channel (+l)", "471" },
216 /* 472 */
217   { ERR_UNKNOWNMODE, "%c :is unknown mode char to me", "472" },
218 /* 473 */
219   { ERR_INVITEONLYCHAN, "%s :Cannot join channel (+i)", "473" },
220 /* 474 */
221   { ERR_BANNEDFROMCHAN, "%s :Cannot join channel (+b)", "474" },
222 /* 475 */
223   { ERR_BADCHANNELKEY, "%s :Cannot join channel (+k)", "475" },
224 /* 476 */
225   { ERR_BADCHANMASK, "%s :Bad Channel Mask", "476" },
226 /* 477 */
227   { 0 },
228 /* 478 */
229   { ERR_BANLISTFULL, "%s %s :Channel ban/ignore list is full", "478" },
230 /* 479 */
231   { ERR_BADCHANNAME, "%s :Cannot join channel (access denied on this server)", "479" },
232 /* 480 */
233   { 0 },
234 /* 481 */
235   { ERR_NOPRIVILEGES, ":Permission Denied: You're not an IRC operator", "481" },
236 /* 482 */
237   { ERR_CHANOPRIVSNEEDED, "%s :You're not channel operator", "482" },
238 /* 483 */
239   { ERR_CANTKILLSERVER, ":You cant kill a server!", "483" },
240 /* 484 */
241   { ERR_ISCHANSERVICE, "%s %s :Cannot kill, kick or deop channel service", "484" },
242 /* 485 */
243   { 0 },
244 /* 486 */
245   { 0 },
246 /* 487 */
247   { 0 },
248 /* 488 */
249   { 0 },
250 /* 489 */
251   { ERR_VOICENEEDED, "%s :You're neither voiced nor channel operator", "489" },
252 /* 490 */
253   { 0 },
254 /* 491 */
255   { ERR_NOOPERHOST, ":No O-lines for your host", "491" },
256 /* 492 */
257   { 0 },
258 /* 493 */
259   { 0 },
260 /* 494 */
261   { 0 },
262 /* 495 */
263   { 0 },
264 /* 496 */
265   { 0 },
266 /* 497 */
267   { 0 },
268 /* 498 */
269   { ERR_ISOPERLCHAN, "%s %s :Cannot kick or deop an IRC Operator on a local channel", "498" },
270 /* 499 */
271   { 0 },
272 /* 500 */
273   { 0 },
274 /* 501 */
275   { ERR_UMODEUNKNOWNFLAG, ":Unknown MODE flag", "501" },
276 /* 502 */
277   { ERR_USERSDONTMATCH, ":Cant change mode for other users", "502" },
278 /* 503 */
279   { 0 },
280 /* 504 */
281   { 0 },
282 /* 505 */
283   { 0 },
284 /* 506 */
285   { 0 },
286 /* 507 */
287   { 0 },
288 /* 508 */
289   { 0 },
290 /* 509 */
291   { 0 },
292 /* 510 */
293   { 0 },
294 /* 511 */
295   { ERR_SILELISTFULL, "%s :Your silence list is full", "511" },
296 /* 512 */
297   { ERR_NOSUCHGLINE, "%s@%s :No such gline", "512" },
298 /* 513 */
299   { ERR_BADPING, "", "513" },
300 /* 514 */
301   { ERR_NOSUCHJUPE, "%s :No such jupe", "514" },
302 /* 515 */
303   { ERR_BADEXPIRE, TIME_T_FMT " :Bad expire time", "515" }
304 };
305
306 static Numeric numeric_replies[] = {
307 /* 300 */
308   { RPL_NONE, 0, "300" },
309 /* 301 */
310   { RPL_AWAY, "%s :%s", "301" },
311 /* 302 */
312   { RPL_USERHOST, ":", "302" },
313 /* 303 */
314   { RPL_ISON, ":", "303" },
315 /* 304 */
316   { RPL_TEXT, 0, "304" },
317 /* 305 */
318   { RPL_UNAWAY, ":You are no longer marked as being away", "305" },
319 /* 306 */
320   { RPL_NOWAWAY, ":You have been marked as being away", "306" },
321 /* 307 */
322   { RPL_USERIP, ":", "307" },
323 /* 308 */
324   { 0 },
325 /* 309 */
326   { 0 },
327 /* 310 */
328   { 0 },
329 /* 311 */
330   { RPL_WHOISUSER, "%s %s %s * :%s", "311" },
331 /* 312 */
332   { RPL_WHOISSERVER, "%s %s :%s", "312" },
333 /* 313 */
334   { RPL_WHOISOPERATOR, "%s :is an IRC Operator", "313" },
335 /* 314 */
336   { RPL_WHOWASUSER, "%s %s %s * :%s", "314" },
337 /* 315 */
338   { RPL_ENDOFWHO, "%s :End of /WHO list.", "315" },
339 /* 316 */
340   { 0 },
341 /* 317 */
342   { RPL_WHOISIDLE, "%s %ld %ld :seconds idle, signon time", "317" },
343 /* 318 */
344   { RPL_ENDOFWHOIS, "%s :End of /WHOIS list.", "318" },
345 /* 319 */
346   { RPL_WHOISCHANNELS, "%s :%s", "319" },
347 /* 320 */
348   { 0 },
349 /* 321 */
350   { RPL_LISTSTART, "Channel :Users  Name", "321" },
351 /* 322 */
352   { RPL_LIST, "%s %d :%s", "322" },
353 /* 323 */
354   { RPL_LISTEND, ":End of /LIST", "323" },
355 /* 324 */
356   { RPL_CHANNELMODEIS, "%s %s %s", "324" },
357 /* 325 */
358   { 0 },
359 /* 326 */
360   { 0 },
361 /* 327 */
362   { 0 },
363 /* 328 */
364   { 0 },
365 /* 329 */
366   { RPL_CREATIONTIME, "%s " TIME_T_FMT, "329" },
367 /* 330 */
368   { 0 },
369 /* 331 */
370   { RPL_NOTOPIC, "%s :No topic is set.", "331" },
371 /* 332 */
372   { RPL_TOPIC, "%s :%s", "332" },
373 /* 333 */
374   { RPL_TOPICWHOTIME, "%s %s " TIME_T_FMT, "333" },
375 /* 334 */
376   { RPL_LISTUSAGE, ":%s", "334" },
377 /* 335 */
378   { 0 },
379 /* 336 */
380   { 0 },
381 /* 337 */
382   { 0 },
383 /* 338 */
384   { 0 },
385 /* 339 */
386   { 0 },
387 /* 340 */
388   { 0 },
389 /* 341 */
390   { RPL_INVITING, "%s %s", "341" },
391 /* 342 */
392   { 0 },
393 /* 343 */
394   { 0 },
395 /* 344 */
396   { 0 },
397 /* 345 */
398   { 0 },
399 /* 346 */
400   { RPL_INVITELIST, ":%s", "346" },
401 /* 347 */
402   { RPL_ENDOFINVITELIST, ":End of Invite List", "347" },
403 /* 348 */
404   { 0 },
405 /* 349 */
406   { 0 },
407 /* 350 */
408   { 0 },
409 /* 351 */
410   { RPL_VERSION, "%s.%s %s :%s", "351" },
411 /* 352 */
412   { RPL_WHOREPLY, "%s", "352" },
413 /* 353 */
414   { RPL_NAMREPLY, "%s", "353" },
415 /* 354 */
416   { RPL_WHOSPCRPL, "%s", "354" },
417 /* 355 */
418   { 0 },
419 /* 356 */
420   { 0 },
421 /* 357 */
422   { 0 },
423 /* 358 */
424   { 0 },
425 /* 359 */
426   { 0 },
427 /* 360 */
428   { 0 },
429 /* 361 */
430   { RPL_KILLDONE, 0, "361" }, /* Not used */
431 /* 362 */
432   { RPL_CLOSING, "%s :Operator enforced Close", "362" },
433 /* 363 */
434   { RPL_CLOSEEND, "%d :Connections Closed", "363" },
435 /* 364 */
436 #ifndef GODMODE
437   { RPL_LINKS, "%s %s :%d P%u %s", "364" },
438 #else /* GODMODE */
439   { RPL_LINKS, "%s %s :%d P%u " TIME_T_FMT " (%s) %s", "364" },
440 #endif /* GODMODE */
441 /* 365 */
442   { RPL_ENDOFLINKS, "%s :End of /LINKS list.", "365" },
443 /* 366 */
444   { RPL_ENDOFNAMES, "%s :End of /NAMES list.", "366" },
445 /* 367 */
446   { RPL_BANLIST, "%s %s %s " TIME_T_FMT, "367" },
447 /* 368 */
448   { RPL_ENDOFBANLIST, "%s :End of Channel Ban List", "368" },
449 /* 369 */
450   { RPL_ENDOFWHOWAS, "%s :End of WHOWAS", "369" },
451 /* 370 */
452   { 0 },
453 /* 371 */
454   { RPL_INFO, ":%s", "371" },
455 /* 372 */
456   { RPL_MOTD, ":- %s", "372" },
457 /* 373 */
458   { RPL_INFOSTART, ":Server INFO", "373" },
459 /* 374 */
460   { RPL_ENDOFINFO, ":End of /INFO list.", "374" },
461 /* 375 */
462   { RPL_MOTDSTART, ":- %s Message of the Day - ", "375" },
463 /* 376 */
464   { RPL_ENDOFMOTD, ":End of /MOTD command.", "376" },
465 /* 377 */
466   { 0 },
467 /* 378 */
468   { 0 },
469 /* 379 */
470   { 0 },
471 /* 380 */
472   { 0 },
473 /* 381 */
474   { RPL_YOUREOPER, ":You are now an IRC Operator", "381" },
475 /* 382 */
476   { RPL_REHASHING, "%s :Rehashing", "382" },
477 /* 383 */
478   { 0 },
479 /* 384 */
480   { RPL_MYPORTIS, "%d :Port to local server is", "384" }, /* not used */
481 /* 385 */
482   { RPL_NOTOPERANYMORE, 0, "385" }, /* not used */
483 /* 386 */
484   { 0 },
485 /* 387 */
486   { 0 },
487 /* 388 */
488   { 0 },
489 /* 389 */
490   { 0 },
491 /* 390 */
492   { 0 },
493 /* 391 */
494   { RPL_TIME, "%s " TIME_T_FMT " %ld :%s", "391" },
495 /* 392 */
496   { 0 },
497 /* 393 */
498   { 0 },
499 /* 394 */
500   { 0 },
501 /* 395 */
502   { 0 },
503 /* 396 */
504   { 0 },
505 /* 397 */
506   { 0 },
507 /* 398 */
508   { 0 },
509 /* 399 */
510   { 0 },
511 /* 200 */
512 #ifndef GODMODE
513   { RPL_TRACELINK, "Link %s%s %s %s", "200" },
514 #else /* GODMODE */
515   { RPL_TRACELINK, "Link %s%s %s %s " TIME_T_FMT, "200" },
516 #endif /* GODMODE */
517 /* 201 */
518   { RPL_TRACECONNECTING, "Try. %d %s", "201" },
519 /* 202 */
520   { RPL_TRACEHANDSHAKE, "H.S. %d %s", "202" },
521 /* 203 */
522   { RPL_TRACEUNKNOWN, "???? %d %s", "203" },
523 /* 204 */
524   { RPL_TRACEOPERATOR, "Oper %d %s %ld", "204" },
525 /* 205 */
526   { RPL_TRACEUSER, "User %d %s %ld", "205" },
527 /* 206 */
528   { RPL_TRACESERVER, "Serv %d %dS %dC %s %s!%s@%s %ld %ld", "206" },
529 /* 207 */
530   { 0 },
531 /* 208 */
532   { RPL_TRACENEWTYPE, "<newtype> 0 %s", "208" },
533 /* 209 */
534   { RPL_TRACECLASS, "Class %d %d", "209" },
535 /* 210 */
536   { 0 },
537 /* 211 */
538   { RPL_STATSLINKINFO, 0, "211" },
539 /* 212 */
540   { RPL_STATSCOMMANDS, "%s %u %u", "212" },
541 /* 213 */
542   { RPL_STATSCLINE, "%c %s * %s %d %d", "213" },
543 /* 214 */
544   { RPL_STATSNLINE, "%c %s * %s %d %d", "214" },
545 /* 215 */
546   { RPL_STATSILINE, "%c %s * %s %d %d", "215" },
547 /* 216 */
548   { RPL_STATSKLINE, "%c %s %s %s %d %d", "216" },
549 /* 217 */
550   { RPL_STATSPLINE, "P %d %d %s %s", "217" },
551 /* 218 */
552   { RPL_STATSYLINE, "%c %d %d %d %d %ld", "218" },
553 /* 219 */
554   { RPL_ENDOFSTATS, "%c :End of /STATS report", "219" },
555 /* 220 */
556   { 0 },
557 /* 221 */
558   { RPL_UMODEIS, "%s", "221" },
559 /* 222 */
560   { 0 },
561 /* 223 */
562   { 0 },
563 /* 224 */
564   { 0 },
565 /* 225 */
566   { 0 },
567 /* 226 */
568   { 0 },
569 /* 227 */
570   { 0 },
571 /* 228 */
572   { 0 },
573 /* 229 */
574   { 0 },
575 /* 230 */
576   { 0 },
577 /* 231 */
578   { RPL_SERVICEINFO, 0, "231" },
579 /* 232 */
580   { RPL_ENDOFSERVICES, 0, "232" },
581 /* 233 */
582   { RPL_SERVICE, 0, "233" },
583 /* 234 */
584   { RPL_SERVLIST, 0, "234" },
585 /* 235 */
586   { RPL_SERVLISTEND, 0, "235" },
587 /* 236 */
588   { 0 },
589 /* 237 */
590   { 0 },
591 /* 238 */
592   { 0 },
593 /* 239 */
594   { 0 },
595 /* 240 */
596   { 0 },
597 /* 241 */
598   { RPL_STATSLLINE, "%c %s * %s %d %d", "241" },
599 /* 242 */
600   { RPL_STATSUPTIME, ":Server Up %d days, %d:%02d:%02d", "242" },
601 /* 243 */
602   { RPL_STATSOLINE, "%c %s * %s %d %d", "243" },
603 /* 244 */
604   { RPL_STATSHLINE, "%c %s * %s %d %d", "244" },
605 /* 245 */
606   { 0 },
607 /* 246 */
608   { RPL_STATSTLINE, "%c %s %s", "246" },
609 /* 247 */
610   { RPL_STATSGLINE, "%c %s@%s " TIME_T_FMT " :%s", "247" },
611 /* 248 */
612   { RPL_STATSULINE, "%c %s %s %s %d %d", "248" },
613 /* 249 */
614   { 0 },
615 /* 250 */
616   { RPL_STATSCONN, ":Highest connection count: %d (%d clients)", "250" },
617 /* 251 */
618   { RPL_LUSERCLIENT, ":There are %d users and %d invisible on %d servers", "251" },
619 /* 252 */
620   { RPL_LUSEROP, "%d :operator(s) online", "252" },
621 /* 253 */
622   { RPL_LUSERUNKNOWN, "%d :unknown connection(s)", "253" },
623 /* 254 */
624   { RPL_LUSERCHANNELS, "%d :channels formed", "254" },
625 /* 255 */
626   { RPL_LUSERME, ":I have %d clients and %d servers", "255" },
627 /* 256 */
628   { RPL_ADMINME, ":Administrative info about %s", "256" },
629 /* 257 */
630   { RPL_ADMINLOC1, ":%s", "257" },
631 /* 258 */
632   { RPL_ADMINLOC2, ":%s", "258" },
633 /* 259 */
634   { RPL_ADMINEMAIL, ":%s", "259" },
635 /* 260 */
636   { 0 },
637 /* 261 */
638   { RPL_TRACELOG, "File %s %d", "261" },
639 /* 262 */
640   { RPL_TRACEPING, "Ping %s %s", "262" },
641 /* 263 */
642   { 0 },
643 /* 264 */
644   { 0 },
645 /* 265 */
646   { 0 },
647 /* 266 */
648   { 0 },
649 /* 267 */
650   { 0 },
651 /* 268 */
652   { 0 },
653 /* 269 */
654   { 0 },
655 /* 270 */
656   { 0 },
657 /* 271 */
658   { RPL_SILELIST, "%s %s", "271" },
659 /* 272 */
660   { RPL_ENDOFSILELIST, "%s :End of Silence List", "272" },
661 /* 273 */
662   { 0 },
663 /* 274 */
664   { 0 },
665 /* 275 */
666   { RPL_STATSDLINE, "%c %s %s", "275" },
667 /* 276 */
668   { 0 },
669 /* 277 */
670   { 0 },
671 /* 278 */
672   { 0 },
673 /* 279 */
674   { 0 },
675 /* 280 */
676   { RPL_GLIST, "%s@%s " TIME_T_FMT " %s%s", "280" },
677 /* 281 */
678   { RPL_ENDOFGLIST, ":End of G-line List", "281" },
679 /* 282 */
680   { RPL_JUPELIST, "%s " TIME_T_FMT " %s %c :%s", "282" },
681 /* 283 */
682   { RPL_ENDOFJUPELIST, ":End of Jupe List", "283" },
683 /* 284 */
684   { 0 }
685 };
686
687 const struct Numeric* get_error_numeric(int numeric)
688 {
689   int num = numeric;
690   assert(ERR_FIRSTERROR < num);
691   assert(num < ERR_INVALID_ERROR);
692
693   num -= ERR_FIRSTERROR;
694   assert(0 != numeric_errors[num].value);
695
696   return &numeric_errors[num];
697 }
698
699 static char numbuff[512];
700
701 /* "inline" */
702 #define prepbuf(buffer, num, tail)                      \
703 {                                                       \
704   char *s = buffer + 4;                 \
705   const char *ap = atoi_tab + (num << 2);       \
706                                                         \
707   strcpy(buffer, ":%s 000 %s ");                        \
708   *s++ = *ap++;                                         \
709   *s++ = *ap++;                                         \
710   *s = *ap;                                             \
711   strcpy(s + 5, tail);                                  \
712 }
713
714 char *err_str(int numeric)
715 {
716   Numeric *nptr;
717   int num = numeric;
718
719   num -= numeric_errors[0].value;
720
721 #ifdef DEBUGMODE
722   if (num < 0 || num > ERR_USERSDONTMATCH)
723     sprintf_irc(numbuff,
724         ":%%s %d %%s :INTERNAL ERROR: BAD NUMERIC! %d", numeric, num);
725   else
726   {
727     nptr = &numeric_errors[num];
728     if (!nptr->format || !nptr->value)
729       sprintf_irc(numbuff, ":%%s %d %%s :NO ERROR FOR NUMERIC ERROR %d",
730           numeric, num);
731     else
732       prepbuf(numbuff, nptr->value, nptr->format);
733   }
734 #else
735   nptr = &numeric_errors[num];
736   prepbuf(numbuff, nptr->value, nptr->format);
737 #endif
738
739   return numbuff;
740 }
741
742 char *rpl_str(int numeric)
743 {
744   Numeric *nptr;
745   int num = numeric;
746
747   if (num > (int)(sizeof(local_replies) / sizeof(Numeric) - 2))
748     num -= (num > 300) ? 300 : 100;
749
750 #ifdef DEBUGMODE
751   if (num < 0 || num > 200)
752     sprintf_irc(numbuff, ":%%s %d %%s :INTERNAL REPLY ERROR: BAD NUMERIC! %d",
753         numeric, num);
754   else
755   {
756     if (numeric > 99)
757       nptr = &numeric_replies[num];
758     else
759       nptr = &local_replies[num];
760     Debug((DEBUG_NUM, "rpl_str: numeric %d num %d %d %s",
761         numeric, num, nptr->value, nptr->format ? nptr->format : ""));
762     if (!nptr->format || !nptr->value)
763       sprintf_irc(numbuff, ":%%s %d %%s :NO REPLY FOR NUMERIC ERROR %d",
764           numeric, num);
765     else
766       prepbuf(numbuff, nptr->value, nptr->format);
767   }
768 #else
769   if (numeric > 99)
770     nptr = &numeric_replies[num];
771   else
772     nptr = &local_replies[num];
773   prepbuf(numbuff, nptr->value, nptr->format);
774 #endif
775
776   return numbuff;
777 }