#ident "%W%" /* * numbers.c:handles all those strange numeric response dished out by that * wacky, nutty program we call ircd * * * written by michael sandrof * * copyright(c) 1990 * * see the copyright file, or do a help ircii copyright */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "irc.h" #include "dcc.h" #include "input.h" #include "commands.h" #include "ircaux.h" #include "vars.h" #include "lastlog.h" #include "list.h" #include "hook.h" #include "server.h" #include "whois.h" #include "numbers.h" #include "window.h" #include "screen.h" #include "output.h" #include "names.h" #include "whois.h" #include "funny.h" #include "parse.h" #include "misc.h" #include "status.h" #include "struct.h" #include "timer.h" #include "fset.h" static void channel_topic(char *, char **, int); static void not_valid_channel(char *, char **); static void cannot_join_channel(char *, char **); static int number_of_bans = 0; extern void parse_364(char *, char *, char *); extern void parse_365(char *, char *, char *); extern void add_to_irc_map(char *, char *); extern void show_server_map(void); extern int stats_k_grep(char **); extern int doing_who; extern void remove_from_server_list(int); #ifdef HAVE_GETTIMEOFDAY extern struct timeval in_sping; #else extern time_t in_sping; #endif /* * numeric_banner: This returns in a static string of either "xxx" where * xxx is the current numeric, or "***" if SHOW_NUMBERS is OFF */ static char *numeric_banner(void) { static char thing[4]; if (!get_int_var(SHOW_NUMERICS_VAR)) return line_thing; sprintf(thing, "%3.3u", -current_numeric); return thing; } int check_sync(int comm, char *channel, char *nick, char *whom, char *bantime, struct channel *chan) { struct channel *tmp = NULL; BanList *new; if (!chan) if (!(tmp = lookup_channel(channel, from_server, CHAN_NOUNLINK))) return -1; /* channel lookup problem */ if (!in_join_list(channel, from_server)) return -1; if (tmp == NULL) tmp = chan; switch (comm) { case 367: /* bans on channel */ { if (tmp) { new = (BanList *) new_malloc(sizeof(BanList)); malloc_strcpy(&new->ban, nick); if (bantime) new->time = strtoul(bantime, NULL, 10); else new->time = time(NULL); if (whom) new->setby = m_strdup(whom); add_to_list((struct list **) &tmp->bans, (struct list *) new); } } default: break; } return 0; } static int handle_stats(int comm, char *from, char **ArgList) { char *format_str = NULL; char *format2_str = NULL; char *args; args = PasteArgs(ArgList, 0); switch (comm) { /* ^on ^raw_irc "% 211 *" {suecho \(L:line\) $[20]sklnick($3) : $4|$5|$6|$7|$8|$strip(: 9)|$strip(: $10);suecho $[8]11 $[30]sklhost($3)} ^on ^raw_irc "% 212 *" {suecho $[9]3: $4 $5} ^on ^raw_irc "% 213 *" {suecho \($3:line\) \($[20]4\)\($[20]6\) \($[5]7\)\($strip(: $[4]8)\)} ^on ^raw_irc "% 214 *" {suecho \($3:line\) \($[20]4\)\($[20]6\) \($[5]7\)\($strip(: $[4]8)\)} ^on ^raw_irc "% 215 *" {suecho \($3:line\) \($[20]4\)\($[20]6\) \($[5]7\)\($strip(: $[4]8)\)} ^on ^raw_irc "% 216 *" {suecho \($3:line\) \($[20]4\) \($[15]6\)} ^on ^raw_irc "% 218 *" {suecho \($3:line\) \($[5]4\) \($[5]5\) \($[5]6\) \($[5]7\) \($strip(: $[8]8)\)} ^on ^raw_irc "% 242 *" {suecho $0 has been up for $5- } ^on ^raw_irc "% 243 *" {suecho \($3:line\) \($[20]4\) \($[9]6\)} ^on ^raw_irc "% 244 *" {suecho \($3:line\) \($[25]4\) \($[25]6\)} */ /* c - Shows C/N lines * ^ b - Shows B lines * ^ d - Shows D lines * ^ e - Shows E lines * ^ f - Shows F lines * g - Shows G lines * h - Shows H/L lines * i - Shows I lines * K - Shows K lines (or matched klines) * k - Shows temporary K lines (or matched temp klines) * L - Shows IP and generic info about [nick] * l - Shows hostname and generic info about [nick] * m - Shows commands and their usage * o - Shows O/o lines * p - Shows opers connected and their idle times * r - Shows resource usage by ircd (only in DEBUGMODE) * * t - Shows generic server stats * u - Shows server uptime * v - Shows connected servers and their idle times * y - Shows Y lines * * z - Shows memory stats * ? - Shows connected servers and sendq info about them */ case 211: format_str = "L:line $[20]left($rindex([ $1) $1) :$[-5]2 $[-5]3 $[-6]4 $[-5]5 $[-6]6 $[-8]strip(: $7) $strip(: $8)"; format2_str = "$[8]9 $[30]mid(${rindex([ $1)+1} ${rindex(] $1) - $rindex([ $1) + 1} $1)"; break; case 212: format_str = "$[10]1 $[-10]2 $[-10]3"; break; case 213: case 214: case 215: format_str = "$1:line $[25]2 $[25]4 $[-5]5 $[-5]6"; break; case 216: format_str = "$1:line $[25]2 $[20]4 $3"; break; case 218: format_str = "$1:line $[-5]2 $[-6]3 $[-6]4 $[-6]5 $[-10]6"; break; case 241: format_str = "$1:line $2-"; break; case 242: format_str = "%G$0%n has been up for %W$3-"; break; case 243: format_str = "$1:line $[25]2 $[9]4"; break; case 244: format_str = "$1:line $[25]2 $[25]4"; default: break; } if (format_str && args) put_it("%s", convert_output_format(format_str, "%s %s", from, args)); if (format2_str && args) put_it("%s", convert_output_format(format2_str, "%s %s", from, args)); return 0; } static int trace_oper(char *from, char **ArgList) { char *rest = PasteArgs(ArgList, 0); put_it("%s", convert_output_format(get_format(FORMAT_TRACE_OPER_FSET), "%s %s", from, rest)); return 0; } static int trace_server(char *from, char **ArgList) { char *rest = PasteArgs(ArgList, 0); put_it("%s", convert_output_format(get_format(FORMAT_TRACE_SERVER_FSET), "%s %s", from, rest)); return 0; } static int trace_user(char *from, char **ArgList) { char *rest = PasteArgs(ArgList, 0); put_it("%s", convert_output_format(get_format(FORMAT_TRACE_USER_FSET), "%s %s", from, rest)); return 0; } static int check_server_sync(char *from, char **ArgList) { static char *desync = NULL; if (!desync || (desync && !match(desync, from))) { if (!match(from, get_server_name(from_server))) { malloc_strcpy(&desync, from); if (do_hook(DESYNC_MESSAGE_LIST, "%s %s", from, ArgList[0])) put_it("%s", convert_output_format(get_format(FORMAT_DESYNC_FSET), "%s %s %s", update_clock(GET_TIME), ArgList[0], from)); return 1; } } return 0; } /* * display_msg: handles the displaying of messages from the variety of * possible formats that the irc server spits out. you'd think someone would * simplify this */ void display_msg(char *from, char **ArgList) { char *ptr; char *rest; int drem; rest = PasteArgs(ArgList, 0); if (from && (my_strnicmp(get_server_itsname(from_server), from, strlen(get_server_itsname(from_server))) == 0)) from = NULL; if ((ptr = strchr(rest, ':'))) *ptr++ = 0; drem = !!from /* && (!get_int_var(SUPPRESS_FROM_REMOTE_SERVER)) */ ; put_it("%s %s%s%s%s%s%s", numeric_banner(), strlen(rest) ? rest : empty_str, /* strlen(rest) && ptr ? ":" : empty_str, */ strlen(rest) ? space_str : empty_str, ptr ? ptr : empty_str, drem ? "(from " : empty_str, drem ? from : empty_str, drem ? ")" : empty_str); } static void channel_topic(char *from, char **ArgList, int what) { char *topic, *channel; struct channel *chan; if (ArgList[1] && is_channel(ArgList[0])) { channel = ArgList[0]; topic = ArgList[1]; message_from(channel, LOG_CRAP); if (what == 333 && ArgList[2]) put_it("%s", convert_output_format(get_format(FORMAT_TOPIC_SETBY_FSET), "%s %s %s %l", update_clock(GET_TIME), channel, topic, strtoul(ArgList[2], NULL, 10))); else if (what != 333) { if ((chan = lookup_channel(channel, from_server, 0))) malloc_strcpy(&chan->topic, topic); put_it("%s", convert_output_format(get_format(FORMAT_TOPIC_FSET), "%s %s %s", update_clock(GET_TIME), channel, topic)); } } else { PasteArgs(ArgList, 0); message_from(NULL, LOG_CURRENT); put_it("%s", convert_output_format(get_format(FORMAT_TOPIC_FSET), "%s %s", update_clock(GET_TIME), ArgList[0])); } } static void not_valid_channel(char *from, char **ArgList) { char *channel; char *s; if (!(channel = ArgList[0]) || !ArgList[1]) return; PasteArgs(ArgList, 1); s = get_server_name(from_server); if (0 == my_strnicmp(s, from, strlen(s))) { remove_channel(channel, from_server); put_it("%s", convert_output_format(get_format(FORMAT_SERVER_MSG2_FSET), "%s %s %s", update_clock(GET_TIME), channel, ArgList[1])); } } /* from ircd .../include/numeric.h */ /* #define ERR_CHANNELISFULL 471 #define ERR_INVITEONLYCHAN 473 #define ERR_BANNEDFROMCHAN 474 #define ERR_BADCHANNELKEY 475 #define ERR_BADCHANMASK 476 */ static void cannot_join_channel(char *from, char **ArgList) { char buffer[BIG_BUFFER_SIZE + 1]; const char *f = NULL; char *chan; if (ArgList[0]) chan = ArgList[0]; else chan = get_chan_from_join_list(from_server); remove_from_join_list(chan, from_server); if (!is_on_channel(chan, from_server, get_server_nickname(from_server))) remove_channel(chan, from_server); else return; PasteArgs(ArgList, 0); strcpy(buffer, ArgList[0]); switch (-current_numeric) { case 437: strcat(buffer, " (Channel is temporarily unavailable)"); break; case 471: strcat(buffer, " (Channel is full)"); f = get_format(FORMAT_471_FSET); break; case 473: strcat(buffer, " (You must be invited)"); f = get_format(FORMAT_473_FSET); break; case 474: strcat(buffer, " (You are banned)"); f = get_format(FORMAT_474_FSET); break; case 475: strcat(buffer, " (Bad channel key)"); f = get_format(FORMAT_475_FSET); break; case 476: strcat(buffer, " (Bad channel mask)"); f = get_format(FORMAT_476_FSET); break; default: return; } if (f) put_it("%s", convert_output_format(f, "%s %s", update_clock(GET_TIME), ArgList[0])); else put_it("%s %s", numeric_banner(), buffer); } static int handle_server_ping(int comm, char *from, char **ArgList) { #ifdef HAVE_GETTIMEOFDAY struct timeval diff = { 0 }; #else time_t diff = 0; #endif char buf[80]; get_time(&diff); *buf = 0; #ifdef HAVE_GETTIMEOFDAY if (!in_sping.tv_sec) return 0; if (comm == 351) { sprintf(buf, "%2.4f second%s", time_diff(in_sping, diff), (int) time_diff(in_sping, diff) ? "s" : empty_str); #else if (!in_sping) return 0; if (comm == 351) { sprintf(buf, "%d second%s", diff - in_sping, diff - in_sping ? "s" : empty_str); #endif put_it("%s", convert_output_format("$G Server PONG from %W$0%n $1-", "%s %s", from, buf)); #ifdef HAVE_GETTIMEOFDAY memset(&in_sping, 0, sizeof(struct timeval)); #else in_sping = 0; #endif } else put_it("%s", convert_output_format("No such server to ping", NULL, NULL)); return 1; } static int handle_server_stats(char *from, char **ArgList, int comm) { static int norm = 0, invisible = 0, servers = 0, ircops = 0, unknown = 0, chans = 0, local_users = 0, total_users; char tmp[80]; int ret = 1; char *line = alloca(strlen(ArgList[0]) + 1); strcpy(line, ArgList[0]); switch (comm) { case 251: /* number of users */ BreakArgs(line, NULL, ArgList, 1); if (ArgList[2] && ArgList[5] && ArgList[8]) { servers = ircops = unknown = chans = 0; norm = my_atol(ArgList[2]); invisible = my_atol(ArgList[5]); servers = my_atol(ArgList[8]); } break; case 252: /* number of ircops */ if (ArgList[0]) { ircops = my_atol(ArgList[0]); } break; case 253: /* number of unknown */ if (ArgList[0]) { unknown = my_atol(ArgList[0]); } break; case 254: /* number of channels */ if (ArgList[0]) { chans = my_atol(ArgList[0]); } break; case 255: /* number of local print it out */ BreakArgs(line, NULL, ArgList, 1); if (ArgList[2]) local_users = my_atol(ArgList[2]); total_users = norm + invisible; if (total_users) { sprintf(tmp, "%3.0f", (float) (((float) local_users / (float) total_users) * 100)); put_it("%s", convert_output_format("$G %K[%nlocal users on irc%K(%n\002$0\002%K)]%n $1%%", "%d %s", local_users, tmp)); sprintf(tmp, "%3.0f", (float) (((float) norm / (float) total_users) * 100)); put_it("%s", convert_output_format("$G %K[%nglobal users on irc%K(%n\002$0\002%K)]%n $1%%", "%d %s", norm, tmp)); sprintf(tmp, "%3.0f", (float) (((float) invisible / (float) total_users) * 100)); put_it("%s", convert_output_format("$G %K[%ninvisible users on irc%K(%n\002$0\002%K)]%n $1%%", "%d %s", invisible, tmp)); sprintf(tmp, "%3.0f", (float) (((float) ircops / (float) total_users) * 100)); put_it("%s", convert_output_format("$G %K[%nircops on irc%K(%n\002$0\002%K)]%n $1%%", "%d %s", ircops, tmp)); } put_it("%s", convert_output_format("$G %K[%ntotal users on irc%K(%n\002$0\002%K)]%n", "%d", total_users)); put_it("%s", convert_output_format("$G %K[%nunknown connections%K(%n\002$0\002%K)]%n", "%d", unknown)); put_it("%s", convert_output_format("$G %K[%ntotal servers on irc%K(%n\002$0\002%K)]%n %K(%navg. $1 users per server%K)", "%d %d", servers, (servers) ? (int) (total_users / servers) : 0)); put_it("%s", convert_output_format("$G %K[%ntotal channels created%K(%n\002$0\002%K)]%n %K(%navg. $1 users per channel%K)", "%d %d", chans, (chans) ? (int) (total_users / chans) : 0)); break; case 250: { char *p; BreakArgs(line, NULL, ArgList, 1); if (ArgList[3] && ArgList[4]) { p = ArgList[4]; p++; put_it("%s", convert_output_format("$G %K[%nHighest client connection count%K(%n\002$0\002%K) %K(%n\002$1\002%K)]%n", "%s %s", ArgList[3], p)); } break; } default: ret = 0; break; } return ret; } static void whohas_nick(WhoisStuff * stuff, char *nick, char *args) { if (!stuff || !stuff->nick || !nick || !strcmp(stuff->user, "")) return; put_it("%s", convert_output_format("$G Your nick %R[%n$0%R]%n is owned by %W$1@$2", "%s %s %s", nick, stuff->user, stuff->host)); return; } /* * numbered_command: does (hopefully) the right thing with the numbered * responses from the server. I wasn't real careful to be sure I got them * all, but the default case should handle any I missed (sorry) */ void numbered_command(char *from, int comm, char **ArgList) { char *user; char none_of_these = 0; int flag, lastlog_level; if (!ArgList[1] || !from || !*from) return; user = (*ArgList[0]) ? ArgList[0] : NULL; lastlog_level = set_lastlog_msg_level(LOG_CRAP); message_from(NULL, LOG_CRAP); ArgList++; current_numeric = -comm; /* must be negative of numeric! */ switch (comm) { case 001: /* #define RPL_WELCOME 001 */ { yell("For more information about \002Xaric\002 type \002/about\002"); accept_server_nickname(from_server, user); set_server_motd(from_server, 1); server_is_connected(from_server, 1); load_scripts(); PasteArgs(ArgList, 0); if (do_hook(current_numeric, "%s %s", from, *ArgList)) display_msg(from, ArgList); if (send_umode && *send_umode == '+') send_to_server(SERVER(from_server), "MODE %s %s", user, send_umode); break; } case 004: /* #define RPL_MYINFO 004 */ { got_initial_version(ArgList); load_scripts(); PasteArgs(ArgList, 0); if (do_hook(current_numeric, "%s %s", from, *ArgList)) display_msg(from, ArgList); break; } case 250: case 251: case 252: case 253: case 254: case 255: if (do_hook(current_numeric, "%s %s", from, *ArgList)) { if (!handle_server_stats(from, ArgList, comm)) display_msg(from, ArgList); } break; case 301: /* #define RPL_AWAY 301 */ user_is_away(from, ArgList); break; case 302: /* #define RPL_USERHOST 302 */ userhost_returned(from, ArgList); break; case 303: /* #define RPL_ISON 303 */ ison_returned(from, ArgList); break; case 311: /* #define RPL_WHOISUSER 311 */ whois_name(from, ArgList); break; case 312: /* #define RPL_WHOISSERVER 312 */ whois_server(from, ArgList); break; case 313: /* #define RPL_WHOISOPERATOR 313 */ whois_oper(from, ArgList); break; case 314: /* #define RPL_WHOWASUSER 314 */ whowas_name(from, ArgList); break; case 316: /* #define RPL_WHOISCHANOP 316 */ break; case 317: /* #define RPL_WHOISIDLE 317 */ whois_lastcom(from, ArgList); break; case 318: /* #define RPL_ENDOFWHOIS 318 */ end_of_whois(from, ArgList); break; case 319: /* #define RPL_WHOISCHANNELS 319 */ whois_channels(from, ArgList); break; case 321: /* #define RPL_LISTSTART 321 */ ArgList[0] = "Channel\0Users\0Topic"; ArgList[1] = ArgList[0] + 8; ArgList[2] = ArgList[1] + 6; ArgList[3] = NULL; funny_list(from, ArgList); break; case 322: /* #define RPL_LIST 322 */ if (is_server_connected(from_server) && strcmp(from, server_list[from_server].itsname)) { say("322 crash attempt from hacked server %s", from); break; } funny_list(from, ArgList); break; case 324: /* #define RPL_CHANNELMODEIS 324 */ funny_mode(from, ArgList); break; case 340: /* #define RPL_INVITING_OTHER 340 */ { if (ArgList[2]) { message_from(ArgList[0], LOG_CRAP); if (do_hook(current_numeric, "%s %s %s %s", from, ArgList[0], ArgList[1], ArgList[2])) put_it("%s %s has invited %s to channel %s", numeric_banner(), ArgList[0], ArgList[1], ArgList[2]); } break; } case 341: /* #define RPL_INVITING 341 */ if (ArgList[1]) { message_from(ArgList[1], LOG_CRAP); if (do_hook(current_numeric, "%s %s %s", from, ArgList[0], ArgList[1])) put_it("%s", convert_output_format(get_format(FORMAT_INVITE_USER_FSET), "%s %s %s", update_clock(GET_TIME), ArgList[0], ArgList[1])); } break; case 352: /* #define RPL_WHOREPLY 352 */ whoreply(NULL, ArgList); break; case 353: /* #define RPL_NAMREPLY 353 */ funny_namreply(from, ArgList); break; case 366: /* #define RPL_ENDOFNAMES 366 */ { int need_display = 1; char *tmp = NULL, *chan; PasteArgs(ArgList, 1); message_from(ArgList[0], LOG_CURRENT); if (get_int_var(SHOW_END_OF_MSGS_VAR)) need_display = do_hook(current_numeric, "%s %s %s", from, ArgList[0], ArgList[1]); message_from(NULL, LOG_CRAP); malloc_strcpy(&tmp, ArgList[0]); chan = strtok(tmp, " "); /* do we really need this check? -laeos */ if (!in_join_list(chan, from_server)) { PasteArgs(ArgList, 0); if (get_int_var(SHOW_END_OF_MSGS_VAR) && need_display) display_msg(from, ArgList); } else got_info(chan, from_server, GOTNAMES); new_free(&tmp); } break; case 381: /* #define RPL_YOUREOPER 381 */ PasteArgs(ArgList, 0); if (!is_server_connected(from_server)) say("Odd Server stuff from %s: %s", from, ArgList[0]); else if (do_hook(current_numeric, "%s %s", from, *ArgList)) { if (get_format(FORMAT_381_FSET)) put_it("%s", convert_output_format(get_format(FORMAT_381_FSET), "%s %s %s", update_clock(GET_TIME), from, *ArgList)); else display_msg(from, ArgList); } if (get_string_var(OPER_MODES_VAR)) send_to_server(SERVER(from_server), "MODE %s %s", get_server_nickname(from_server), get_string_var(OPER_MODES_VAR)); break; case 401: /* #define ERR_NOSUCHNICK 401 */ if (ArgList[0] && !check_dcc_list(ArgList[0])) no_such_nickname(from, ArgList); break; case 421: /* #define ERR_UNKNOWNCOMMAND 421 */ PasteArgs(ArgList, 0); if ((flag = do_hook(current_numeric, "%s %s", from, *ArgList))) display_msg(from, ArgList); break; case 432: /* #define ERR_ERRONEUSNICKNAME 432 */ PasteArgs(ArgList, 0); if (do_hook(current_numeric, "%s %s", from, *ArgList)) display_msg(from, ArgList); fudge_nickname(SERVER(from_server)); break; case 433: /* #define ERR_NICKNAMEINUSE 433 */ if (is_server_connected(from_server) && server_list[from_server].itsname && strcmp(from, server_list[from_server].itsname)) { say("433 nicknameinuse attempt from hacked server %s", from); break; } fudge_nickname(SERVER(from_server)); if (server_list[from_server].itsname) add_to_whois_queue(ArgList[0], whohas_nick, "%s", ArgList[0]); PasteArgs(ArgList, 0); if (!never_connected && do_hook(current_numeric, "%s", *ArgList)) display_msg(from, ArgList); break; case 451: /* #define ERR_NOTREGISTERED 451 */ /* * Sometimes the server doesn't catch the USER line, so * here we send a simplified version again -lynx */ register_server(from_server, NULL); PasteArgs(ArgList, 0); if (do_hook(current_numeric, "%s %s", from, *ArgList)) display_msg(from, ArgList); break; case 462: /* #define ERR_ALREADYREGISTRED 462 */ change_server_nickname(SERVER(from_server), NULL); PasteArgs(ArgList, 0); if (do_hook(current_numeric, "%s %s", from, *ArgList)) display_msg(from, ArgList); break; case 463: /* CDE added for ERR_NOPERMFORHOST */ { PasteArgs(ArgList, 0); if (do_hook(current_numeric, "%s %s", from, *ArgList)) display_msg(from, ArgList); close_server(from_server, empty_str); window_check_servers(); if (from_server == primary_server) get_connected(from_server + 1); break; } case 464: /* #define ERR_PASSWDMISMATCH 464 */ if (is_server_connected(from_server) && server_list[from_server].itsname && strcmp(from, server_list[from_server].itsname)) { say("464 crash attempt from hacked server %s", from); break; } PasteArgs(ArgList, 0); if (!is_server_connected(from_server)) { say("Odd Server stuff from %s: %s", from, ArgList[0]); return; } flag = do_hook(current_numeric, "%s %s", from, ArgList[0]); if (oper_command) { if (flag) display_msg(from, ArgList); oper_command = 0; } else { char server_num[8]; say("Password required for connection to server %s", get_server_name(from_server)); close_server(from_server, empty_str); strcpy(server_num, ltoa(from_server)); add_wait_prompt("Server Password:", password_sendline, server_num, WAIT_PROMPT_LINE); } break; case 465: /* #define ERR_YOUREBANNEDCREEP 465 */ { int klined = from_server; if (is_server_connected(from_server) && server_list[from_server].itsname && strcmp(from, server_list[from_server].itsname)) { say("465 crash attempt from hacked server %s", from); break; } PasteArgs(ArgList, 0); if (!is_server_connected(from_server)) return; if (do_hook(current_numeric, "%s %s", from, ArgList[0])) display_msg(from, ArgList); close_server(from_server, empty_str); window_check_servers(); if (server_list_size() > 1) remove_from_server_list(klined); if (klined == primary_server && (server_list_size() > 0)) get_connected(klined); break; } case 484: { if (do_hook(current_numeric, "%s %s", from, ArgList[0])) display_msg(from, ArgList); set_server_flag(from_server, USER_MODE_R, 1); break; } case 367: number_of_bans++; if (check_sync(comm, ArgList[0], ArgList[1], ArgList[2], ArgList[3], NULL) == 0) break; if (ArgList[2]) { time_t tme = (time_t) strtoul(ArgList[3], NULL, 10); if (do_hook(current_numeric, "%s %s %s %s %s", from, ArgList[0], ArgList[1], ArgList[2], ArgList[3])) put_it("%s", convert_output_format(get_format(FORMAT_BANS_FSET), "%d %s %s %s %l", number_of_bans, ArgList[0], ArgList[1], ArgList[2], tme)); } else if (do_hook(current_numeric, "%s %s %s", from, ArgList[0], ArgList[1])) put_it("%s", convert_output_format(get_format(FORMAT_BANS_FSET), "%d %s %s %s %l", number_of_bans, ArgList[0], ArgList[1], "unknown", time(NULL))); break; case 368: /* #define RPL_ENDOFBANLIST 368 */ { if (!got_info(ArgList[0], from_server, GOTBANS)) break; if (get_int_var(SHOW_END_OF_MSGS_VAR)) { if (do_hook(current_numeric, "%s %d %s", from, number_of_bans, *ArgList)) { put_it("%s Total Number of Bans on %s [%d]", numeric_banner(), ArgList[0], number_of_bans); } } number_of_bans = 0; break; } case 364: #if 0 if (is_server_connected(from_server) && server_list[from_server].itsname && strcmp(from, server_list[from_server].itsname)) { say("364 links attempt from hacked server %s", from); break; } #endif if (comm == 364) { if (get_int_var(LLOOK_VAR) && (server_list[from_server].link_look == 1)) { parse_364(ArgList[0], ArgList[1], ArgList[2] ? ArgList[2] : "0"); break; } else if (server_list[from_server].link_look == 2) { add_to_irc_map(ArgList[0], ArgList[2]); break; } if ((do_hook(current_numeric, "%s %s %s", ArgList[0], ArgList[1], ArgList[2]))) { if (get_format(FORMAT_LINKS_FSET)) { put_it("%s", convert_output_format(get_format(FORMAT_LINKS_FSET), "%s %s %s", ArgList[0], ArgList[1], ArgList[2] ? ArgList[2] : "0")); break; } } } case 365: /* #define RPL_ENDOFLINKS 365 */ if (comm == 365) { if (get_int_var(LLOOK_VAR) && (server_list[from_server].link_look == 1)) { parse_365(ArgList[0], ArgList[1], NULL); server_list[from_server].link_look = 0; break; } else if (server_list[from_server].link_look == 2) { show_server_map(); server_list[from_server].link_look = 0; break; } } case 404: case 442: case 482: if (comm == 404 || comm == 482 || comm == 442) { if (check_server_sync(from, ArgList)) { send_to_server(SERVER(from_server), "WHO -server %s %s", from, ArgList[0]); break; } } case 204: if (server_list[from_server].trace_flags & TRACE_OPER) { trace_oper(from, ArgList); break; } else if (server_list[from_server].trace_flags) break; case 203: case 205: if (server_list[from_server].trace_flags & TRACE_USER) { trace_user(from, ArgList); break; } else if (server_list[from_server].trace_flags) break; case 206: if (server_list[from_server].trace_flags & TRACE_SERVER) { trace_server(from, ArgList); break; } else if (server_list[from_server].trace_flags) break; case 200: case 207: case 209: if (server_list[from_server].trace_flags) break; case 262: case 402: if (comm == 402 && handle_server_ping(comm, from, ArgList)) break; if ((comm == 262 || comm == 402) && server_list[from_server].trace_flags) { server_list[from_server].trace_flags = 0; break; } /* * The following accumulates the remaining arguments * in ArgSpace for hook detection. We can't use * PasteArgs here because we still need the arguments * separated for use elsewhere. */ default: { char *ArgSpace = NULL; int i, len, do_message_from = 0; for (i = len = 0; ArgList[i]; len += strlen(ArgList[i++])) ; len += (i - 1); ArgSpace = new_malloc(len + 1); ArgSpace[0] = '\0'; /* this is cheating */ if (ArgList[0] && is_channel(ArgList[0])) do_message_from = 1; for (i = 0; ArgList[i]; i++) { if (i) strcat(ArgSpace, " "); strcat(ArgSpace, ArgList[i]); } if (do_message_from) message_from(ArgList[0], LOG_CRAP); if (!do_hook(current_numeric, "%s %s", from, ArgSpace)) { new_free(&ArgSpace); if (do_message_from) message_from(NULL, lastlog_level); return; } if (do_message_from) message_from(NULL, lastlog_level); new_free(&ArgSpace); none_of_these = 1; } } /* the following do not hurt the ircII if intercepted by a hook */ if (none_of_these) { switch (comm) { case 211: case 212: case 213: case 214: case 215: case 216: case 218: case 241: case 242: case 243: case 244: if (server_list[from_server].stats_flags && ((comm > 210 && comm < 219) || (comm > 240 && comm < 245))) { handle_stats(comm, from, ArgList); break; } else if (!server_list[from_server].stats_flags && comm == 242) { /* case 242: #define RPL_STATSUPTIME 242 */ PasteArgs(ArgList, 0); if (from && !my_strnicmp(get_server_itsname(from_server), from, strlen(get_server_itsname(from_server)))) from = NULL; if (from) put_it("%s %s from (%s)", numeric_banner(), *ArgList, from); else put_it("%s %s", numeric_banner(), *ArgList); break; } else { PasteArgs(ArgList, 0); put_it("%s %s %s", numeric_banner(), from, *ArgList); } break; case 219: /* #define RPL_ENDOFSTATS 219 */ #if 0 if (!server_list[from_server].stats_flags && comm == 219) stats_k_grep_end(); #endif if (server_list[from_server].stats_flags && comm == 219) server_list[from_server].stats_flags = 0; break; case 221: /* #define RPL_UMODEIS 221 */ put_it("%s Your user mode is [%s]", numeric_banner(), ArgList ? ArgList[0] : " "); break; case 272: /* ENDOFSILENCE */ PasteArgs(ArgList, 0); put_it("%s", convert_output_format(get_format(FORMAT_SILENCE_FSET), update_clock(GET_TIME), ArgList[0])); break; case 329: /* #define CREATION_TIME 329 */ { unsigned long tme; char *this_sucks; struct channel *chan = NULL; if (!ArgList[1] || !*ArgList[1]) break; sscanf(ArgList[1], "%lu", &tme); this_sucks = ctime((time_t *)&tme); this_sucks[strlen(this_sucks) - 1] = '\0'; message_from(ArgList[0], LOG_CRAP); put_it("%s Channel %s was created at %s", numeric_banner(), ArgList[0], this_sucks); if ((chan = lookup_channel(ArgList[0], from_server, 0))) chan->channel_create.tv_sec = tme; message_from(NULL, LOG_CURRENT); break; } case 332: /* #define RPL_TOPIC 332 */ channel_topic(from, ArgList, 332); break; case 333: channel_topic(from, ArgList, 333); break; case 351: /* #define RPL_VERSION 351 */ if (!handle_server_ping(comm, from, ArgList)) { PasteArgs(ArgList, 2); put_it("%s", convert_output_format(get_format(FORMAT_SERVER_FSET), "Server %s %s %s", ArgList[0], ArgList[1], ArgList[2])); } break; case 364: /* #define RPL_LINKS 364 */ { if (ArgList[2]) { PasteArgs(ArgList, 2); put_it("%s %-20s %-20s %s", numeric_banner(), ArgList[0], ArgList[1], ArgList[2]); } else { PasteArgs(ArgList, 1); put_it("%s %-20s %s", numeric_banner(), ArgList[0], ArgList[1]); } } break; case 377: case 372: /* #define RPL_MOTD 372 */ if (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) || !get_server_motd(from_server)) { PasteArgs(ArgList, 0); put_it("%s %s", numeric_banner(), ArgList[0]); } break; case 375: /* #define RPL_MOTDSTART 375 */ if (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) || !get_server_motd(from_server)) { PasteArgs(ArgList, 0); put_it("%s %s", numeric_banner(), ArgList[0]); } break; case 376: /* #define RPL_ENDOFMOTD 376 */ if (get_int_var(SHOW_END_OF_MSGS_VAR) && (!get_int_var(SUPPRESS_SERVER_MOTD_VAR) || !get_server_motd(from_server))) { PasteArgs(ArgList, 0); put_it("%s %s", numeric_banner(), ArgList[0]); } set_server_motd(from_server, 0); break; case 384: /* #define RPL_MYPORTIS 384 */ PasteArgs(ArgList, 0); put_it("%s %s %s", numeric_banner(), ArgList[0], user); break; case 385: /* #define RPL_NOTOPERANYMORE 385 */ set_server_operator(from_server, 0); display_msg(from, ArgList); update_all_status(curr_scr_win, NULL, 0); break; case 403: /* #define ERR_NOSUCHCHANNEL 403 */ not_valid_channel(from, ArgList); break; case 432: /* #define ERR_ERRONEUSNICKNAME 432 */ display_msg(from, ArgList); reset_nickname(SERVER(from_server)); break; case 471: /* #define ERR_CHANNELISFULL 471 */ case 473: /* #define ERR_INVITEONLYCHAN 473 */ case 474: /* #define ERR_BANNEDFROMCHAN 474 */ case 475: /* #define ERR_BADCHANNELKEY 475 */ case 476: /* #define ERR_BADCHANMASK 476 */ cannot_join_channel(from, ArgList); break; #define RPL_CLOSEEND 363 #define RPL_SERVLISTEND 235 case 315: /* #define RPL_ENDOFWHO 315 */ { if (doing_who) doing_who--; if (get_int_var(SHOW_END_OF_MSGS_VAR)) if (do_hook(current_numeric, "%s %s", from, ArgList[0])) put_it("%s %s %s", numeric_banner(), from, ArgList[0]); } case 316: break; case 323: /* #define RPL_LISTEND 323 */ funny_print_widelist(); case 232: /* #define RPL_ENDOFSERVICES 232 */ case 365: /* #define RPL_ENDOFLINKS 365 */ if (comm == 365 && get_int_var(LLOOK_VAR) && server_list[from_server].link_look) { parse_365(ArgList[0], ArgList[1], NULL); server_list[from_server].link_look--; break; } case 369: /* #define RPL_ENDOFWHOWAS 369 */ case 374: /* #define RPL_ENDOFINFO 374 */ case 394: /* #define RPL_ENDOFUSERS 394 */ if (get_int_var(SHOW_END_OF_MSGS_VAR)) { PasteArgs(ArgList, 0); if (do_hook(current_numeric, "%s %s", from, *ArgList)) display_msg(from, ArgList); } break; default: display_msg(from, ArgList); } } set_lastlog_msg_level(lastlog_level); }