1 /*
2 * numbers.c: handles all those strange numeric response dished out by that
3 * wacky, nutty program we call ircd
4 *
5 * Written by Michael Sandrof
6 *
7 * Copyright (c) 1990 Michael Sandrof.
8 * Copyright (c) 1991, 1992 Troy Rollo.
9 * Copyright (c) 1992-2021 Matthew R. Green.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include "irc.h"
37 IRCII_RCSID("@(#)$eterna: numbers.c,v 1.106 2021/02/24 10:38:03 mrg Exp $");
38
39 #include "input.h"
40 #include "edit.h"
41 #include "ircaux.h"
42 #include "vars.h"
43 #include "lastlog.h"
44 #include "hook.h"
45 #include "server.h"
46 #include "whois.h"
47 #include "numbers.h"
48 #include "window.h"
49 #include "screen.h"
50 #include "output.h"
51 #include "names.h"
52 #include "whois.h"
53 #include "funny.h"
54 #include "parse.h"
55 #include "notice.h"
56
57 static void reset_nickname(u_char *);
58 static void password_sendline(u_char *, u_char *);
59 static void get_password(void);
60 static void nickname_sendline(u_char *, u_char *);
61 static void channel_topic(u_char *, u_char **);
62 static void not_valid_channel(u_char *, u_char **);
63 static void cannot_join_channel(u_char *, u_char **);
64 static void version(u_char *, u_char *, u_char **);
65 static void invite(u_char *, u_char *, u_char **);
66
67 static int already_doing_reset_nickname = 0;
68 static int current_numeric_local; /* this is negative of the
69 * current numeric! */
70
71 /*
72 * numeric_banner: This returns in a static string of either "xxx" where
73 * xxx is the current numeric, or "***" if SHOW_NUMBERS is OFF
74 */
75 u_char *
numeric_banner(void)76 numeric_banner(void)
77 {
78 static u_char thing[4];
79
80 if (get_int_var(SHOW_NUMERICS_VAR))
81 snprintf(CP(thing), sizeof thing, "%3.3u", -current_numeric());
82 else
83 my_strcpy(thing, UP("***"));
84 return (thing);
85 }
86
87
88 /*
89 * display_msg: handles the displaying of messages from the variety of
90 * possible formats that the irc server spits out.
91 */
92 void
display_msg(u_char * from,u_char ** ArgList)93 display_msg(u_char *from, u_char **ArgList)
94 {
95 u_char *rest;
96 u_char *name = server_get_itsname(parsing_server());
97
98 if (my_strnicmp(name, from, my_strlen(name)) == 0)
99 from = NULL;
100
101 rest = paste_args(ArgList, 0);
102 if (rest == NULL)
103 rest = empty_string();
104
105 if (from)
106 put_it("%s %s (from %s)", numeric_banner(), rest, from);
107 else
108 put_it("%s %s", numeric_banner(), rest);
109 }
110
111 /*
112 * password_sendline: called by send_line() in get_password() to handle
113 * hitting of the return key, etc
114 */
115 static void
password_sendline(u_char * data,u_char * line)116 password_sendline(u_char *data, u_char *line)
117 {
118 int new_server;
119
120 new_server = my_atoi(data);
121 server_set_password(new_server, line);
122 connect_to_server(server_get_name(new_server),
123 server_get_port(new_server), server_get_nickname(new_server), -1);
124 }
125
126 /*
127 * get_password: when a host responds that the user needs to supply a
128 * password, it gets handled here! the user is prompted for a password and
129 * then reconnection is attempted with that password. but, the reality of
130 * the situation is that no one really uses user passwords. ah well
131 */
132 static void
get_password(void)133 get_password(void)
134 {
135 u_char server_num[8];
136
137 say("password required for connection to server %s",
138 server_get_name(parsing_server()));
139 close_server(parsing_server(), empty_string());
140 if (!term_basic())
141 {
142 snprintf(CP(server_num), sizeof server_num, "%d", parsing_server());
143 add_wait_prompt(UP("Server Password:"), password_sendline,
144 server_num, WAIT_PROMPT_LINE);
145 }
146 }
147
148 static void
nickname_sendline(u_char * data,u_char * nick)149 nickname_sendline(u_char *data, u_char *nick)
150 {
151 int new_server, server;
152
153 new_server = my_atoi(data);
154 server = parsing_server();
155 set_from_server(new_server);
156 if (nick && *nick)
157 {
158 send_to_server("NICK %s", nick);
159 if (new_server == get_primary_server())
160 set_nickname(nick);
161 server_set_nickname(new_server, nick);
162 }
163 set_from_server(server);
164 already_doing_reset_nickname = 0;
165 update_all_status();
166 }
167
168 /*
169 * reset_nickname: when the server reports that the selected nickname is not
170 * a good one, it gets reset here.
171 */
172 static void
reset_nickname(u_char * from)173 reset_nickname(u_char *from)
174 {
175 u_char server_num[10];
176 const int from_server = get_from_server();
177
178 if (already_doing_reset_nickname ||
179 is_server_connected(from_server) ||
180 !server_get_attempting_to_connect(from_server))
181 return;
182
183 say("You have specified an illegal nickname");
184 if (!term_basic() && !get_int_var(NO_ASK_NICKNAME_VAR))
185 {
186 already_doing_reset_nickname = 1;
187 say("Please enter your nickname");
188 snprintf(CP(server_num), sizeof server_num, "%d", parsing_server());
189 add_wait_prompt(UP("Nickname: "), nickname_sendline, server_num,
190 WAIT_PROMPT_LINE);
191 }
192 update_all_status();
193 }
194
195 static void
channel_topic(u_char * from,u_char ** ArgList)196 channel_topic(u_char *from, u_char **ArgList)
197 {
198 u_char *topic, *channel;
199
200 save_message_from();
201 if (ArgList[1] && is_channel(ArgList[0]))
202 {
203 topic = ArgList[1];
204 channel = ArgList[0];
205 message_from(channel, LOG_CRAP);
206 put_it("%s Topic for %s: %s", numeric_banner(), channel,
207 topic);
208 }
209 else
210 {
211 message_from(NULL, LOG_CURRENT);
212 paste_args(ArgList, 0);
213 put_it("%s Topic: %s", numeric_banner(), ArgList[0]);
214 }
215 restore_message_from();
216 }
217
218 static void
not_valid_channel(u_char * from,u_char ** ArgList)219 not_valid_channel(u_char *from, u_char **ArgList)
220 {
221 u_char *channel;
222 u_char *s;
223
224 if (ArgList[1] == NULL)
225 return;
226 channel = ArgList[0];
227 paste_args(ArgList, 1);
228 s = server_get_name(parsing_server());
229 if (0 == my_strnicmp(s, from, my_strlen(s)))
230 {
231 remove_channel(channel, parsing_server());
232 put_it("%s %s %s", numeric_banner(), channel, ArgList[1]);
233 }
234 }
235
236 static void
cannot_join_channel(u_char * from,u_char ** ArgList)237 cannot_join_channel(u_char *from, u_char **ArgList)
238 {
239 u_char *chan, *extra;
240
241 chan = ArgList[0];
242 if (!is_on_channel(chan, parsing_server(),
243 server_get_nickname(parsing_server())))
244 remove_channel(chan, parsing_server());
245 else
246 return;
247
248 paste_args(ArgList, 0);
249 if (do_hook(current_numeric(), "%s %s", from, ArgList[0])) {
250 switch(-current_numeric())
251 {
252 case 471: /* #define ERR_CHANNELISFULL 471 */
253 extra = UP(" (Channel is full)");
254 break;
255 case 473: /* #define ERR_INVITEONLYCHAN 473 */
256 extra = UP(" (Invite only channel)");
257 break;
258 case 474: /* #define ERR_BANNEDFROMCHAN 474 */
259 extra = UP(" (Banned from channel)");
260 break;
261 case 475: /* #define ERR_BADCHANNELKEY 475 */
262 extra = UP(" (Bad channel key)");
263 break;
264 case 476: /* #define ERR_BADCHANMASK 476 */
265 extra = UP(" (Bad channel mask)");
266 break;
267 default:
268 extra = empty_string();
269 }
270 put_it("%s %s%s", numeric_banner(), ArgList[0], extra);
271 }
272 }
273
274
275 static void
version(u_char * comm,u_char * from,u_char ** ArgList)276 version(u_char *comm, u_char *from, u_char **ArgList)
277 {
278 if (check_params(comm, from, 0, ArgList, 2))
279 return;
280
281 if (ArgList[2])
282 {
283 paste_args(ArgList, 2);
284 put_it("%s Server %s: %s %s", numeric_banner(), ArgList[1],
285 ArgList[0], ArgList[2]);
286 }
287 else
288 {
289 paste_args(ArgList, 1);
290 put_it("%s Server %s: %s", numeric_banner(), ArgList[1],
291 ArgList[0]);
292 }
293 }
294
295
296 static void
invite(u_char * comm,u_char * from,u_char ** ArgList)297 invite(u_char *comm, u_char *from, u_char **ArgList)
298 {
299 u_char *who,
300 *channel;
301
302 if (check_params(comm, from, 0, ArgList, 2))
303 return;
304
305 who = ArgList[0];
306 channel = ArgList[1];
307 if (channel)
308 {
309 save_message_from();
310 message_from(channel, LOG_CRAP);
311 if (do_hook(current_numeric(), "%s %s %s", from, who, channel))
312 put_it("%s Inviting %s to channel %s",
313 numeric_banner(), who, channel);
314 restore_message_from();
315 }
316 }
317
318
319 /*
320 * numbered_command: does (hopefully) the right thing with the numbered
321 * responses from the server. I wasn't real careful to be sure I got them
322 * all, but the default case should handle any I missed (sorry)
323 */
324 void
numbered_command(u_char * commstr,u_char * from,int comm,u_char ** ArgList)325 numbered_command(u_char *commstr, u_char *from, int comm, u_char **ArgList)
326 {
327 u_char *user;
328 u_char none_of_these = 0;
329 u_char *blah = NULL;
330 int flag,
331 lastlog_level;
332 const int from_server = parsing_server();
333 #if 0
334 int user_cnt,
335 inv_cnt,
336 server_cnt;
337 #endif /* 0 */
338
339 if (!from || !*from || !*ArgList)
340 return;
341 if (!*ArgList[0])
342 user = NULL;
343 else
344 user = ArgList[0];
345 if (!ArgList[1])
346 return;
347 ArgList++;
348 if (check_params(commstr, from, 0, ArgList, 1))
349 return;
350
351 /*
352 * At this point, unlike in irc2_parse_server(), ArgList[0] is now
353 * always valid, making all of commstr, from, and ArgList[0] valid.
354 */
355
356 lastlog_level = set_lastlog_msg_level(LOG_CRAP);
357 save_message_from();
358 message_from(NULL, LOG_CRAP);
359 current_numeric_local = -comm; /* must be negative of numeric! */
360 switch (comm)
361 {
362 case 001: /* #define RPL_WELCOME 001 */
363 paste_args(ArgList, 0);
364 if (my_strcmp(user, server_get_nickname(from_server)) != 0)
365 {
366 yell("=== Setting this servers nickname to \"%s\" from \"%s\"", user, server_get_nickname(from_server));
367 server_set_nickname(from_server, user);
368 }
369 if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
370 display_msg(from, ArgList);
371 clean_whois_queue();
372 break;
373 case 002: /* #define RPL_YOURHOST 002 */
374 paste_args(ArgList, 0);
375 malloc_snprintf(&blah, "*** %s", ArgList[0]);
376 got_initial_version(blah);
377 new_free(&blah);
378 if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
379 display_msg(from, ArgList);
380 break;
381
382 /* should do something with this some day, 2.8 had channel/user mode switches */
383 case 004: /* #define RPL_MYINFO 004 */
384 paste_args(ArgList, 0);
385 if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
386 display_msg(from, ArgList);
387 break;
388
389 /*
390 * this part of ircii has been broken for most of ircd 2.7, so someday I'll
391 * make it work for ircd 2.8 ... phone..
392 */
393 #if 0
394 case 251: /* #define RPL_LUSERCLIENT 251 */
395 display_msg(from, ArgList);
396 if (is_server_connected(from_server))
397 break;
398 if (ArgList[1] != NULL && from_server == get_primary_server() &&
399 ((sscanf(ArgList[1],
400 "There are %d users and %d invisible on %d servers",
401 &user_cnt, &inv_cnt, &server_cnt) == 3)))
402 {
403 user_cnt =+ inv_cnt;
404 if ((server_cnt < get_int_var(MINIMUM_SERVERS_VAR)) ||
405 (user_cnt < get_int_var(MINIMUM_USERS_VAR)))
406 {
407 say("Trying better populated server...");
408 get_connected(from_server + 1);
409 }
410 }
411 break;
412 #endif /* 0 */
413 case 301: /* #define RPL_AWAY 301 */
414 user_is_away(commstr, from, ArgList);
415 break;
416
417 case 302: /* #define RPL_USERHOST 302 */
418 userhost_returned(from, ArgList);
419 break;
420
421 case 303: /* #define RPL_ISON 303 */
422 ison_returned(from, ArgList);
423 break;
424
425 case 311: /* #define RPL_WHOISUSER 311 */
426 whois_name(commstr, from, ArgList);
427 break;
428
429 case 312: /* #define RPL_WHOISSERVER 312 */
430 whois_server(from, ArgList);
431 break;
432
433 case 313: /* #define RPL_WHOISOPERATOR 313 */
434 whois_oper(from, ArgList);
435 break;
436
437 case 314: /* #define RPL_WHOWASUSER 314 */
438 whowas_name(commstr, from, ArgList);
439 break;
440
441 case 316: /* #define RPL_WHOISCHANOP 316 */
442 whois_chop(from, ArgList);
443 break;
444
445 case 317: /* #define RPL_WHOISIDLE 317 */
446 whois_lastcom(commstr, from, ArgList);
447 break;
448
449 case 318: /* #define RPL_ENDOFWHOIS 318 */
450 end_of_whois(from, ArgList);
451 break;
452
453 case 319: /* #define RPL_WHOISCHANNELS 319 */
454 whois_channels(commstr, from, ArgList);
455 break;
456
457 case 321: /* #define RPL_LISTSTART 321 */
458 ArgList[0] = UP("Channel\0Users\0Topic");
459 ArgList[1] = ArgList[0] + 8;
460 ArgList[2] = ArgList[1] + 6;
461 ArgList[3] = NULL;
462 funny_list(commstr, from, ArgList);
463 break;
464
465 case 322: /* #define RPL_LIST 322 */
466 funny_list(commstr, from, ArgList);
467 break;
468
469 case 324: /* #define RPL_CHANNELMODEIS 324 */
470 funny_mode(from, ArgList);
471 break;
472
473 case 341: /* #define RPL_INVITING 341 */
474 invite(commstr, from, ArgList);
475 break;
476
477 case 352: /* #define RPL_WHOREPLY 352 */
478 whoreply(NULL, ArgList);
479 break;
480
481 case 353: /* #define RPL_NAMREPLY 353 */
482 funny_namreply(commstr, from, ArgList);
483 break;
484
485 case 366: /* #define RPL_ENDOFNAMES 366 */
486 {
487 u_char *tmp = NULL,
488 *chan;
489
490 paste_args(ArgList, 0);
491 malloc_strcpy(&tmp, ArgList[0]);
492 chan = next_arg(tmp, 0);
493 flag = do_hook(current_numeric(), "%s %s", from, ArgList[0]);
494
495 if (flag &&
496 channel_mode_lookup(chan, CHAN_NAMES | CHAN_MODE, 0) &&
497 get_int_var(SHOW_END_OF_MSGS_VAR) && flag)
498 display_msg(from, ArgList);
499
500 new_free(&tmp);
501 }
502 break;
503
504 case 381: /* #define RPL_YOUREOPER 381 */
505 paste_args(ArgList, 0);
506 if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
507 display_msg(from, ArgList);
508 server_set_operator(parsing_server(), 1);
509 update_all_status(); /* fix the status line */
510 break;
511
512 case 401: /* #define ERR_NOSUCHNICK 401 */
513 no_such_nickname(commstr, from, ArgList);
514 break;
515
516 case 405: /* #define ERR_TOOMANYCHANNELS 405 */
517 remove_channel(ArgList[0], parsing_server());
518 break;
519
520 case 421: /* #define ERR_UNKNOWNCOMMAND 421 */
521 if (check_screen_redirect(ArgList[0]))
522 break;
523 if (check_wait_command(ArgList[0]))
524 break;
525 paste_args(ArgList, 0);
526 flag = do_hook(current_numeric(), "%s %s", from, ArgList[0]);
527 if (!my_strncmp("ISON", ArgList[0], 4) || !my_strncmp("USERHOST",
528 ArgList[0], 8))
529 {
530 server_set_2_6_2(parsing_server(), 0);
531 convert_to_whois();
532 }
533 else if (flag)
534 display_msg(from, ArgList);
535 break;
536
537 case 432: /* #define ERR_ERRONEUSNICKNAME 432 */
538 case 433: /* #define ERR_NICKNAMEINUSE 433 */
539 paste_args(ArgList, 0);
540 if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
541 display_msg(from, ArgList);
542 reset_nickname(from);
543 break;
544
545 case 437: /* #define ERR_UNAVAILRESOURCE 437 */
546 paste_args(ArgList, 0);
547 if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
548 display_msg(from, ArgList);
549 if (!is_channel(ArgList[0]))
550 reset_nickname(from);
551 break;
552
553 case 463: /* #define ERR_NOPERMFORHOST 463 */
554 display_msg(from, ArgList);
555 close_server(parsing_server(), empty_string());
556 window_check_servers();
557 if (!connected_to_server())
558 get_connected(parsing_server() + 1);
559 break;
560
561 case 464: /* #define ERR_PASSWDMISMATCH 464 */
562 paste_args(ArgList, 0);
563 flag = do_hook(current_numeric(), "%s %s", from, ArgList[0]);
564 if (server_get_oper_command())
565 {
566 if (flag)
567 display_msg(from, ArgList);
568 }
569 else
570 get_password();
571 break;
572
573 case 465: /* #define ERR_YOUREBANNEDCREEP 465 */
574 {
575 int klined_server = parsing_server();
576
577 paste_args(ArgList, 0);
578 if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
579 display_msg(from, ArgList);
580 close_server(parsing_server(), empty_string());
581 window_check_servers();
582 if (number_of_servers() > 1)
583 remove_from_server_list(klined_server);
584 if (!connected_to_server())
585 say("You are not connected to a server. Use /SERVER to connect.");
586 break;
587 }
588
589 case 471: /* #define ERR_CHANNELISFULL 471 */
590 case 473: /* #define ERR_INVITEONLYCHAN 473 */
591 case 474: /* #define ERR_BANNEDFROMCHAN 474 */
592 case 475: /* #define ERR_BADCHANNELKEY 475 */
593 case 476: /* #define ERR_BADCHANMASK 476 */
594 cannot_join_channel(from, ArgList);
595 break;
596
597 case 484: /* #define ERR_RESTRICTED 484 */
598 if (do_hook(current_numeric(), "%s %s", from, ArgList[0]))
599 display_msg(from, ArgList);
600 server_set_flag(parsing_server(), USER_MODE_R, 1);
601 break;
602
603 /*
604 * The following accumulates the remaining arguments
605 * in ArgSpace for hook detection. We can't use
606 * paste_args here because we still need the arguments
607 * separated for use elsewhere.
608 */
609 default:
610 {
611 u_char *ArgSpace = NULL;
612 int i,
613 do_message_from = 0;
614 size_t len;
615
616 for (i = len = 0; ArgList[i];)
617 len += 1 + my_strlen(ArgList[i++]);
618 len += (i - 1);
619 ArgSpace = new_malloc(len + 1);
620 ArgSpace[0] = '\0';
621 /* this is cheating */
622 if (is_channel(ArgList[0]))
623 do_message_from = 1;
624 for (i = 0; ArgList[i]; i++)
625 {
626 if (i)
627 my_strcat(ArgSpace, " ");
628 my_strcat(ArgSpace, ArgList[i]);
629 }
630 if (do_message_from)
631 {
632 save_message_from();
633 message_from(ArgList[0], LOG_CRAP);
634 }
635 i = do_hook(current_numeric(), "%s %s", from, ArgSpace);
636 new_free(&ArgSpace);
637 if (do_message_from)
638 restore_message_from();
639 if (i == 0)
640 goto done;
641 none_of_these = 1;
642 }
643 }
644 /* the following do not hurt the ircII if intercepted by a hook */
645 if (none_of_these)
646 {
647 switch (comm)
648 {
649 case 221: /* #define RPL_UMODEIS 221 */
650 put_it("%s Your user mode is \"%s\"", numeric_banner(),
651 ArgList[0]);
652 break;
653
654 case 242: /* #define RPL_STATSUPTIME 242 */
655 paste_args(ArgList, 0);
656 if (from && !my_strnicmp(server_get_itsname(parsing_server()),
657 from, my_strlen(server_get_itsname(parsing_server()))))
658 from = NULL;
659 if (from)
660 put_it("%s %s from (%s)", numeric_banner(),
661 ArgList[0], from);
662 else
663 put_it("%s %s", numeric_banner(), ArgList[0]);
664 break;
665
666 case 332: /* #define RPL_TOPIC 332 */
667 channel_topic(from, ArgList);
668 break;
669
670 case 351: /* #define RPL_VERSION 351 */
671 version(commstr, from, ArgList);
672 break;
673
674 case 364: /* #define RPL_LINKS 364 */
675 if (check_params(commstr, from, 0, ArgList, 2))
676 return;
677 if (ArgList[2])
678 {
679 paste_args(ArgList, 2);
680 put_it("%s %-20s %-20s %s", numeric_banner(),
681 ArgList[0], ArgList[1], ArgList[2]);
682 }
683 else
684 {
685 paste_args(ArgList, 1);
686 put_it("%s %-20s %s", numeric_banner(),
687 ArgList[0], ArgList[1]);
688 }
689 break;
690
691 case 372: /* #define RPL_MOTD 372 */
692 if (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) ||
693 !server_get_motd(parsing_server()))
694 {
695 paste_args(ArgList, 0);
696 put_it("%s %s", numeric_banner(), ArgList[0]);
697 }
698 break;
699
700 case 375: /* #define RPL_MOTDSTART 375 */
701 if (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) ||
702 !server_get_motd(parsing_server()))
703 {
704 paste_args(ArgList, 0);
705 put_it("%s %s", numeric_banner(), ArgList[0]);
706 }
707 break;
708
709 case 376: /* #define RPL_ENDOFMOTD 376 */
710 if (server_get_attempting_to_connect(parsing_server()))
711 got_initial_version(UP("*** Your host is broken and not running any version"));
712 if (get_int_var(SHOW_END_OF_MSGS_VAR) &&
713 (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) ||
714 !server_get_motd(parsing_server())))
715 {
716 paste_args(ArgList, 0);
717 put_it("%s %s", numeric_banner(), ArgList[0]);
718 }
719 server_set_motd(parsing_server(), 0);
720 break;
721
722 case 384: /* #define RPL_MYPORTIS 384 */
723 paste_args(ArgList, 0);
724 put_it("%s %s %s", numeric_banner(), ArgList[0], user);
725 break;
726
727 case 385: /* #define RPL_NOTOPERANYMORE 385 */
728 server_set_operator(parsing_server(), 0);
729 display_msg(from, ArgList);
730 update_all_status();
731 break;
732
733 case 403: /* #define ERR_NOSUCHCHANNEL 403 */
734 not_valid_channel(from, ArgList);
735 break;
736
737 case 451: /* #define ERR_NOTREGISTERED 451 */
738 /*
739 * Sometimes the server doesn't catch the USER line, so
740 * here we send a simplified version again -lynx
741 */
742 send_to_server("USER %s %s . :%s", my_username(),
743 irc_umode(), my_realname());
744 send_to_server("NICK %s",
745 server_get_nickname(parsing_server()));
746 break;
747
748 case 462: /* #define ERR_ALREADYREGISTRED 462 */
749 display_msg(from, ArgList);
750 break;
751
752 #define RPL_CLOSEEND 363
753 #define RPL_SERVLISTEND 235
754 case 315: /* #define RPL_ENDOFWHO 315 */
755 case 323: /* #define RPL_LISTEND 323 */
756 funny_print_widelist();
757
758 case 219: /* #define RPL_ENDOFSTATS 219 */
759 case 232: /* #define RPL_ENDOFSERVICES 232 */
760 case 365: /* #define RPL_ENDOFLINKS 365 */
761 case 368: /* #define RPL_ENDOFBANLIST 368 */
762 case 369: /* #define RPL_ENDOFWHOWAS 369 */
763 case 374: /* #define RPL_ENDOFINFO 374 */
764 #if 0 /* this case needs special handing - see above */
765 case 376: /* #define RPL_ENDOFMOTD 376 */
766 #endif /* 0 */
767 case 394: /* #define RPL_ENDOFUSERS 394 */
768 if (!get_int_var(SHOW_END_OF_MSGS_VAR))
769 break;
770 default:
771 display_msg(from, ArgList);
772 }
773 }
774 set_lastlog_msg_level(lastlog_level);
775 done:
776 restore_message_from();
777 }
778
779 int
current_numeric(void)780 current_numeric(void)
781 {
782 return current_numeric_local;
783 }
784