/*
 * notice.c: special stuff for parsing NOTICEs
 *
 * Written By Michael Sandrof
 *
 * Copyright(c) 1991
 *
 * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT 
 */

#include "irc.h"

#include "commands.h"
#include "whois.h"
#include "ctcp.h"
#include "window.h"
#include "lastlog.h"
#include "flood.h"
#include "vars.h"
#include "ircaux.h"
#include "hook.h"
#include "ignore.h"
#include "server.h"
#include "funny.h"
#include "output.h"
#include "names.h"
#include "parse.h"
#include "notify.h"
#include "misc.h"
#include "screen.h"
#include "status.h"
#include "notice.h"
#include "hash2.h"
#include "cset.h"
#include "input.h"
	
extern	char	*FromUserHost;
static	void	parse_server_notice _((char *, char *));
int	doing_notice = 0;

long	oper_kills = 0,
	nick_collisions = 0,
	serv_fakes = 0,
	serv_unauth = 0,
	serv_split = 0,
	serv_rejoin = 0,
	serv_squits = 0,
	serv_connects = 0,
	client_connects = 0,
	serv_rehash = 0,
	client_exits = 0,
	serv_klines = 0,
	client_floods = 0,
	client_invalid = 0,
	stats_req = 0,
	client_bot = 0,
	client_bot_alarm = 0,
	oper_requests = 0;

#ifdef WANT_OPERVIEW
int charcount _((char *, int));
static	int  handle_oper_vision(char *from, char *cline, int *up_status)
{
	char *fr, *for_, *temp, *temp2;
	char *p;
	int done_one = 0;
	int i = strlen(cline);
	char *line;
	unsigned long flags;
		
	p = fr = for_ = temp = temp2 = NULL;

	if (strncmp(cline, "*** Notice -- ", 13) != 0 && strncmp(cline, "*** Notice -- ", 15) != 0)
		return 0;
	if (from_server == -1 || ((flags = server_list[from_server].ircop_flags) == 0))
		return 0;

	line = alloca(i+1);
	strcpy(line, cline);
	done_one++;
	
	if (!strncmp(line + 14, "Received KILL message for ", 26))
	{
		char *q = line + 40;
		int loc_check = 0;

		for_ = next_arg(q, &q);
		chop(for_, 1);
		q += 5;
		fr = next_arg(q, &q);
		q += 6; 

		if (strchr(fr, '.'))
		{
			nick_collisions++;
			if (!(flags & NICK_COLLIDE))
				goto done;  	
			serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_NICK_COLLISION_FSET), "%s %s %s %s", update_clock(GET_TIME), fr, for_, q));
		}
		else 
		{
			oper_kills++;
			if (!(flags & NICK_KILL))
				goto done;  	

			if ((temp2 = next_arg(q, &q)))
				loc_check = charcount(temp2, '!');
			if (q && *q)
				q++; chop(q, 1);
			if (loc_check <= 1)		
				serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_KILL_LOCAL_FSET), "%s %s %s %s", update_clock(GET_TIME), fr, for_, q));
			else
				serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_KILL_FSET), "%s %s %s %s", update_clock(GET_TIME), fr, for_, q));
		}
		(*up_status)++;
	}
	else if (!strncmp(line+14, "Nick collision on", 17) || !strncmp(line+14, "Nick change collision on", 24))
	{
#if 0
irc.cs.cmu.edu *** Notice -- Nick collision on Griffin(Griffin <-
               irc2.uiuc.edu[@128.174.5.43])(newer killed)
irc.cs.cmu.edu *** Notice -- Nick change collision on Griffin(Griffin <-
               irc2.uiuc.edu[@128.174.5.43])(newer killed)
#endif
		nick_collisions++;
		if (!(flags & NICK_COLLIDE))
			goto done;  	
		if (!strncmp(line+19, "change", 6))
			p = line + 38;
		else
			p = line + 31;
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_NICK_COLLISION_FSET), "%s %s", update_clock(GET_TIME), p));
		(*up_status)++;
	}
	else if (!strncmp(line+14, "IP# Mismatch:", 13))
	{
		if (!(flags & IP_MISMATCH))
			goto done;  	
#if 0
!irc.psinet.com Notice -- IP# Mismatch: 38.27.59.219 != ip219.cincinnati6.oh.pub-ip.psi.net[261b003b]
#endif
		for_ = line + 28;
		serversay(1, from_server, "%s", convert_output_format("IP Mismatch %C$1-", "%s %s", update_clock(GET_TIME), for_));
	}
	else if (!strncmp(line + 14, "Hacked ops on opless channel:", 29))
	{
		if (!(flags & HACK_OPS))
			goto done;  	
		for_ = line + 43;
		serversay(1, from_server, "%s", convert_output_format("Hacked ops on $0", "%s", for_));
	}
	else if (!strncmp(line + 14, "Identd response differs", 22))
	{
		if (!(flags & IDENTD))
			goto done;  	
		for_ = line + 38;
		serversay(1, from_server, "%s", convert_output_format("Identd response differs %K[%C$1-%K]", "%s %s", update_clock(GET_TIME), for_));
	}
  	else if (!strncmp(line+14, "Fake: ", 6)) /* MODE */
  	{
		serv_fakes++;
		if (!(flags & FAKE_MODE))
			goto done;  	
		p = line + 20;
		fr = next_arg(p, &temp);
		if (lookup_channel(fr, from_server, CHAN_NOUNLINK))
			serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_FAKE_FSET), "%s %s %s", update_clock(GET_TIME), fr, temp));
		else 
			serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_FAKE_FSET), "%s %s %s", update_clock(GET_TIME), fr, temp));
  	}
  	else if (!strncmp(line+14, "Unauthorized connection from",28))
  	{
		serv_unauth++;
		if (!(flags & UNAUTHS))
			goto done;  	
		for_ = line + 42;
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_UNAUTH_FSET), "%s %s", update_clock(GET_TIME), for_));
	}
  	else if (!strncmp(line+14, "Too many connections from",25))
  	{
		serv_unauth++;
		if (!(flags & TOO_MANY))
			goto done;  	
		for_ = line + 39;
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_UNAUTH_FSET), "%s %s", update_clock(GET_TIME), for_));
	}
	else if (strstr(line+14, "Entering high-traffic mode -") || !strncmp(line+14, "still high-traffic mode -", 25))
	{
#if 0
irc.cs.cmu.edu *** Notice -- Sheesh, still high-traffic mode 7 (TURBO) (22 delay): 25.5k/s
#endif               
		char *q;
 		serv_split++;
		if (!(flags & TRAFFIC))
			goto done;  	
		if (!strncmp(line+14, "Entering", 8))
		{
			p = line + 42;
			for_ = next_arg(p, &p);
			q = temp2 = p;
			if (temp2)
			{
				chop(temp2, 1);
				q = temp2+2;
			}
		}
		else if (!strncmp(line+24, "Entering", 8))
		{
			p = line + 52;
			for_ = next_arg(p, &p);
			q = temp2 = p;
			if (temp2)
			{
				chop(temp2, 1);
				q = temp2+2;
			}
		}
		else
		{
			p = line + 39;
			for_ = next_arg(p, &p);
			q = temp2 = p;
			if (temp2)
			{
				chop(temp2, 1);
				q = temp2+2;
			}
		}
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_TRAFFIC_HIGH_FSET), "%s %s %s", update_clock(GET_TIME), for_, q));
	}
	else if (!strncmp(line+14, "Resuming standard operation", 27))
	{
		serv_rejoin++;
		if (!(flags & TRAFFIC))
			goto done;  	
		p = line + 41;
		for_ = next_arg(p, &p);
		if (for_ && *for_ == '-')
			for_ = next_arg(p, &p); 
		temp = next_arg(p, &temp2);
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_TRAFFIC_NORM_FSET), "%s %s %s %s", update_clock(GET_TIME), for_, temp, temp2));
	}
	else if (match("% is rehashing Server config*", line+14))
	{
		serv_rehash++;
		if (!(flags & REHASH))
			goto done;  	
		p = line + 14;
		for_ = next_arg(p, &p);
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_REHASH_FSET), "%s %s", update_clock(GET_TIME), for_));
	}
	else if (match("% added K-Line for *", line+14))
	{
		char *serv = NULL;
		serv_klines++;

		if (!(flags & KLINE))
			goto done;  	

		p = line + 14;
		for_ = next_arg(p, &p);
		if (!strncmp(p, "from", 4))
		{
			next_arg(p, &p);
			serv = next_arg(p, &p);
		}
		p += 17;
		temp2 = next_arg(p, &temp);
		if (++temp2)
			chop(temp2, 2);
		if (serv)
			serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_GLINE_FSET), "%s %s %s %s %s", update_clock(GET_TIME), for_, temp2, serv, temp));
		else
			serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_KLINE_FSET), "%s %s %s %s", update_clock(GET_TIME), for_, temp2, temp));
	}
	else if (!strncmp(line+14, "Possible bot ", 13))
	{
		client_bot++;
		if (!(flags & POSSIBLE_BOT))
			goto done;  	
		p = line + 27;
		for_ = next_arg(p, &p);
		if ((temp2 = next_arg(p, &p)))
			chop(temp2, 1);
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_BOT_FSET), "%s %s %s", update_clock(GET_TIME), for_, temp2));
	}
	else if (match("Possible % bot *", line+14))
	{
/*	
*** Notice -- Possible eggdrop bot: root (root@panasync.canu
!jacobs.geeks.org CloneBot protection activated against jacobs.Geeks.ORG
!jacobs.geeks.org Rejecting clonebot: pana4 [pana4@jacobs.Geeks.ORG]
not handled yet
*/
		char *possible = NULL;
		client_bot++;
		if (!(flags & POSSIBLE_BOT))
			goto done;  	
		p = line + 9;
		possible = next_arg(p, &p);
		next_arg(p, &p);
		for_ = next_arg(p, &p);
		if ((temp2 = next_arg(p, &p)))
		{
			chop(temp2, 1);
			*temp2 = ' ';
		}
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_BOT1_FSET), "%s %s %s %s", update_clock(GET_TIME), possible?possible:"Unknown", for_, temp2));
	}
	else if (match("% % is now operator*", line+14))
	{
		oper_requests++;
		if (!(flags & OPER_MODE))
			goto done;  	
		p = line + 14;
		fr = next_arg(p, &p);
		if ((temp2 = next_arg(p, &p)))
		{
			chop(temp2, 1);
			if (*temp2 == '(')
				*temp2 = ' ';
		}
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_OPER_FSET), "%s %s %s", update_clock(GET_TIME), fr, temp2));
	} 
	else if (!strncmp(line+14, "Received SQUIT", 14))
	{
/*
!irc.stanford.edu!! Received SQUIT irc.best.net from Taner (this is lame)
*/
		serv_squits++;
		if (!(flags & SQUIT))
			goto done;  	
		p = line + 28;
		fr = next_arg(p, &p);
		for_ = next_arg(p, &temp2);
		if (temp2)
		{
			chop(temp2, 1);
			if (*temp2 == '(')
				*temp2 = ' ';
		}
		serversay(1, from_server, "%s", convert_output_format("SQUIT of $1 from $2 %K[%R$3-%K]", "%s %s %s %s", update_clock(GET_TIME), for_, fr, temp2));
	} 
	else if (!strncmp(line+14, "WALLOPS :Remote CONNECT", 23))
	{
/*
!ircd.concentric.net!! Remote CONNECT irc2.uiuc.edu 6666 from moogle
*/
		serv_connects++;
		if (!(flags & SERVER_CONNECT))
			goto done;  	
		p = line + 37;
		for_ = next_arg(p, &p);
		fr = next_arg(p, &p);
		next_arg(p, &temp2);
		serversay(1, from_server, "%s", convert_output_format("Remote Connect of $1:$2 from $3", "%s %s %s %s", update_clock(GET_TIME), for_, fr, temp2));
	}
	else if (!strncmp(line+14, "Client connecting", 17) || !strncmp(line+14, "Client exiting", 14))
	{
		char *q = empty_string;
		char *port = empty_string;
		int conn = !strncmp(line+21, "connect", 7) ? 1 : 0;
		int dalnet = 0;
	
	
	 	if (((conn && (*(line+31) == ':')) || (!conn && (*(line+28) == ':')))) dalnet = 0; else dalnet = 1;

		if (conn)
			client_connects++;
		else 
			client_exits++;

		if (!(flags & CLIENT_CONNECT))
			goto done;  	
#if 0
<Anybody> irc.klis.com *** Notice -- Client connecting: <DarkSun!anybody@ppp42.ocws.com>
dalnet There itc Client connecting on port 7000:
#endif          
		p = line + 14;
		next_arg(p, &p); next_arg(p, &p);
		if (!dalnet || (dalnet && !conn))
		{
			for_ = next_arg(p, &p);			
			q = temp2 = p;
			if (temp2)
			{
				chop(temp2, 1);
				q = temp2+1;
			}
		} 
		else if (conn && dalnet)
		{
			next_arg(p, &p); next_arg(p, &p); 
			port = next_arg(p, &p);
			for_ = next_arg(p, &p);
			q = temp2 = p;
			chop(port, 1);
			if (temp2)
			{
				chop(temp2, 1);
				q = temp2+1;
			}
		}
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(conn ? FORMAT_SERVER_NOTICE_CLIENT_CONNECT_FSET : FORMAT_SERVER_NOTICE_CLIENT_EXIT_FSET), "%s %s %s %s", update_clock(GET_TIME), for_, q, port));
	}
	else if (!strncmp(line+14, "Terminating client for excess", 29))
	{
		char *q;
		client_floods++;
		if (!(flags & TERM_FLOOD))
			goto done;  	

		p = line + 43;
		for_ = next_arg(p, &p);
		q = temp2 = p;
		if (temp2)
		{
			chop(temp2, 1);
			q = temp2+1;
		}
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_CLIENT_TERM_FSET), "%s %s %s", update_clock(GET_TIME), for_, q));
	}
	else if (!strncmp(line+14, "Invalid username:", 17))
	{
		client_invalid++;
		if (!(flags & INVALID_USER))
			goto done;  	
		p = line + 31;
		for_ = next_arg(p, &p);
		if ((temp2 = next_arg(p, &p)))
			chop(temp2, 1);
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_CLIENT_INVALID_FSET), "%s %s %s", update_clock(GET_TIME), for_, temp2));
	}
	else if (!strncmp(line+14, "STATS ", 6))
	{
		stats_req++;
		if (!(flags & STATS_REQUEST))
			goto done;  	
/*	
*** Notice -- STATS k requested by root (root@panasync.canu
 sendto_flagops(UFLAGS_OPERS,"STATS %s%c requested by %s (%s@%s)"
*/
		p = line + 20;
		temp = next_arg(p, &p);
		p += 12;
		for_ = next_arg(p, &p);
		if ( (temp2 = ++p) )
			chop(temp2, 1);
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_STATS_FSET), "%s %s %s %s", update_clock(GET_TIME), temp, for_, temp2));
	}
	else if (!strncmp(line+14, "Nick flooding detected by:", 26))
	{
/*
!ingenue.EECS.Berkeley.EDU Nick flooding detected by: KiNGPiN0 (falzar@204.174.128.37)
*/          
		if (!(flags & NICK_FLOODING))
			goto done;  	
		p = line + 40;
		serversay(1, from_server, "%s", convert_output_format("Nick Flooding %K[%B$1-%K]", "%s %s", update_clock(GET_TIME), for_));
	}
	else if (!strncmp(line+14, "Kill line active for", 20) || !strncmp(line+14, "K-line active for", 17))
	{
/*
!opus.bridge.net - Kill line active for SS3[taqi@168.187.104.37]
!irc.cs.cmu.edu -- K-line active for o0Lm8Jup5[tfb1@crown11.crown.net]
!irc.cs.cmu.edu -- K-line active for m1Upf4a8Q[tfb1@crown11.crown.net]
*/
		if (!(flags & KILL_ACTIVE))
			goto done;  	
		if (!strncmp(line + 14,"Kill", 4))
			for_ = line + 34;
		else
			for_ = line + 31;
		serversay(1, from_server, "%s", convert_output_format("Kill line for $1 active", "%s %s", update_clock(GET_TIME), for_));
	}
#if 0
#ifdef NEWNET_IRCOP
	else if ((i > 8) && !my_stricmp(*(newargs + 3), "HACK:"))
	{
		PasteArgs(newargs, 6);
		serversay(1, "%s", convert_output_format("Hack Mode $0 by $1 $2", "%s", *(newargs+6)));
	}
	else if ((i > 6) && !my_stricmp(*(newargs + 4), "break:"))
	{
		PasteArgs(newargs, 5);
		serversay(1, from_server, "%s", convert_output_format("NetSplit $0 $1: $2-", "%s", *(newargs+5)));
	}
	else if ((i > 5) && !my_stricmp(*(newargs + 4), "junction:"))
	{
		PasteArgs(newargs, 5);
		serversay(1, from_server, "%s", convert_output_format("NetJoin $0 by $1", "%s", *(newargs+5)));
	}
/*
!ircd.acilink.net!! HACK: thenew.gamesbbs.com MODE #just4fun +tno StarGate 830229003
!irc.klis.com -- Net break: hub.eskimo.com thenew.gamesbbs.com (Ping timeout)
!irc.klis.com -- Net junction: hub.eskimo.com irc.accessus.net
!services.newnet.net!! <LadyBear!ladybear@ladybear.acilink.net> requested:
          mode #hottub +o LadyBear
*/          
#endif
#endif

#if 0
panasync.canuck.ca Link with jacobs.geeks.org[blackjac@209.98.1.1] (TS)
                    established.
panasync.canuck.ca ERROR :from jacobs.geeks.org -- Closing Link:
                    panasync.canuck.ca[avro33.sk.sympatico.ca] BlackJac
                                        (panas server smells)
<BlackJac> jacobs.geeks.org *** Notice -- Received SQUIT panasync.canuck.ca
           from BlackJac[blackjac@jacobs.Geeks.ORG] (panas server smells)
!panasync.canuck.ca Link with jacobs.geeks.org[blackjac@209.98.1.1] (TS) established.
!panasync.canuck.ca ERROR :from jacobs.geeks.org -- Closing Link: panasync.canuck.ca[avro33.sk.sympatico.ca] BlackJac_ (last time i think)
!panasync.canuck.ca Server jacobs.geeks.org closed the connection
!panasync.canuck.ca jacobs.geeks.org had been connected for 0 days,  0:01:05
^on ^server_notice "% *** Notice -- % (%@%) tried % recipients" #
^on ^server_notice "% *** Notice -- connect failure: %[%@%] *" #
^on ^server_notice "% *** Notice -- getsockopt*" #
^on ^server_notice "% *** Notice -- Invis count updated, was off by %" #
^on ^server_notice "% *** Notice -- IP# Mismatch: % != %[%]" #
^on ^server_notice "% *** Notice -- Rejecting idle exceeder *" #
^on ^server_notice "% *** Notice -- Rejecting *bot: % [%@%]" #
^on ^server_notice "% *** Notice -- User % % tried to msg % users" #
!irc.cs.cmu.edu Link with irc2.uiuc.edu[@128.174.5.43] established: TS link


#endif                    
	else 
	{
		if (!(flags & SERVER_CRAP))
			goto done;  	
		p = line + 14;
/*		put_it("%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_FSET), "%s %s %s", update_clock(GET_TIME), from, stripansicodes(p)));*/
		serversay(1, from_server, "%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_FSET), "%s %s %s", update_clock(GET_TIME), from, stripansicodes(p)));
		add_last_type(&last_servermsg[0], MAX_LAST_MSG, NULL, NULL, NULL, p);
	} 
done:
	return done_one;
}
#endif

static	void parse_server_notice(char *from, char *line)
{
	int	lastlog_level = 0;
	int	flag = 0;
	int	up_status = 0;
	
				
	
	if (!from || !*from)
		from = server_list[from_server].itsname ?
			server_list[from_server].itsname :
			server_list[from_server].name;
	if (!strncmp(line, "*** Notice --", 13))
	{
		message_from(NULL, LOG_OPNOTE);
		lastlog_level = set_lastlog_msg_level(LOG_OPNOTE);
	}

	message_from(NULL, LOG_SNOTE);
	lastlog_level = set_lastlog_msg_level(LOG_SNOTE);
	
	if (*line != '*'  && *line != '#' && strncmp(line, "MOTD ", 4))
		flag = 1;
	else
		flag = 0;

	if (do_hook(SERVER_NOTICE_LIST, flag?"%s *** %s":"%s %s", from, line))
	{
#ifdef WANT_OPERVIEW
		if (handle_oper_vision(from, line, &up_status))
			;
		else 
#endif
		if (strstr(line, "***"))
		{
			if (!(server_list[from_server].ircop_flags & SERVER_CRAP))
				goto done1;
			if (do_hook(SERVER_NOTICE_LIST, flag ? "%s *** %s" : "%s %s", from, line))
			{
				char *for_;
				for_ = next_arg(line,&line);
				put_it("%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_FSET), "%s %s %s", update_clock(GET_TIME), from, stripansicodes(line)));
				add_last_type(&last_servermsg[0], MAX_LAST_MSG, NULL, NULL, NULL, line);
			}
		}
		else
		{
			if (!(server_list[from_server].ircop_flags & SERVER_CRAP))
				goto done1;
			if (do_hook(SERVER_NOTICE_LIST, flag ? "%s *** %s" : "%s %s", from, line))
				put_it("%s", convert_output_format(fget_string_var(FORMAT_SERVER_NOTICE_FSET), "%s %s %s", update_clock(GET_TIME), from, stripansicodes(line)));
			add_last_type(&last_servermsg[0], MAX_LAST_MSG, NULL, NULL, NULL, line);
		}
	}
	if (up_status)
		update_all_status(curr_scr_win, NULL, 0);
done1:
	if (lastlog_level)
	{
		set_lastlog_msg_level(lastlog_level);
		message_from(NULL, lastlog_level);
	}
}

void parse_notice(char *from, char **Args)
{
	int	level,
		type;
	char	*to;
	int	no_flooding;
	int	flag;
	char	*high,
		not_from_server = 1;
	char	*line;

	NickList *nick = NULL;	
	ChannelList *tmpc;

		
	PasteArgs(Args, 1);
	to = Args[0];
	line = Args[1];
	if (!to || !line)
		return;
	doing_notice = 1;
	
	if (*to)
	{
		if (is_channel(to))
		{
			message_from(to, LOG_NOTICE);
			type = PUBLIC_NOTICE_LIST;
		}
		else
		{
			message_from(from, LOG_NOTICE);
			type = NOTICE_LIST;
		}
		if ((tmpc = lookup_channel(to, from_server, CHAN_NOUNLINK)))
			nick = find_nicklist_in_channellist(from, tmpc, 0);
		update_stats(NOTICELIST, to, nick, tmpc, 0);		
		if (from && *from && strcmp(get_server_itsname(from_server), from))
		{
			int not_reply = 0;
			char *newline = NULL;
			if (check_auto_reply(line))
				not_reply++;
			switch ((flag = check_ignore(from, FromUserHost, to, IGNORE_NOTICES, line)))
			{
				case IGNORED:
				{
					doing_notice = 0;
					return;
				}
				case HIGHLIGHTED:
					high = highlight_char;
					break;
				default:
					high = empty_string;
			}
		/*
		 * only dots in servernames, right ?
		 *
		 * But a server name doesn't nessicarily have to have
		 * a 'dot' in it..  - phone, jan 1993.
		 */
			if (strchr(from, '.'))
				not_from_server = 0;
			line = do_notice_ctcp(from, to, line);
			if (!line || !*line)
			{
				doing_notice = 0;
				return;
			}
			level = set_lastlog_msg_level(LOG_NOTICE);
			no_flooding = check_flooding(from, NOTICE_FLOOD, line, NULL);
			
			if (sed == 1)
			{
				if (do_hook(ENCRYPTED_NOTICE_LIST, "%s %s %s", from, to, line))
					put_it("%s", convert_output_format(fget_string_var(FORMAT_ENCRYPTED_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME), from, FromUserHost, line));
				sed = 0;
			}
			else
			{
				char *free_me = NULL;
				free_me = newline = stripansi(line);

				if (no_flooding)
				{
					if (match("[*Wall*", line))
					{
						char *channel = NULL, *p, *q;
						if (do_hook(type, "%s %s", from, line))
						{
							q = p = next_arg(newline, &newline);
							if ((p = strchr(p, '/')))
							{
								channel = m_strdup(++p);
								if ((p = strchr(channel, ']')))
									*p++ = 0;
								q = channel;
							} 
							put_it("%s", convert_output_format(fget_string_var(FORMAT_BWALL_FSET), "%s %s %s %s %s", update_clock(GET_TIME), q, from, FromUserHost, newline));
						}
						add_last_type(&last_wall[0], 1, from, FromUserHost, NULL, line);
						logmsg(LOG_WALL, from, line, 0);
						new_free(&channel);
					}
					else if (type == NOTICE_LIST)
					{
						logmsg(LOG_NOTICE, from, line, 0);
						if (do_hook(type, "%s %s", from, line))
						put_it("%s", convert_output_format(fget_string_var(FORMAT_NOTICE_FSET), "%s %s %s %s", update_clock(GET_TIME), from, FromUserHost, newline));
						add_last_type(&last_notice[0], MAX_LAST_MSG, from, FromUserHost, to, line);
					}
					else
					{
						if (do_hook(type, "%s %s %s", from, to, line))
							put_it("%s", convert_output_format(fget_string_var(not_reply?FORMAT_PUBLIC_NOTICE_AR_FSET:FORMAT_PUBLIC_NOTICE_FSET), "%s %s %s %s %s", update_clock(GET_TIME), from, FromUserHost, to, newline));
						if (beep_on_level & LOG_NOTICE)
							beep_em(1);
						logmsg(LOG_NOTICE, from, line, 0);
						add_last_type(&last_notice[0], MAX_LAST_MSG, from, FromUserHost, to, line);
					}
				}
				new_free(&free_me);
				set_lastlog_msg_level(level);
				if (not_from_server)
					notify_mark(from, 1, 0);
			}
		}
		else 
			parse_server_notice(from, line);
	}
	else
		put_it("%s", convert_output_format(fget_string_var(FORMAT_SERVER_MSG2_FSET), "%s %s %s", update_clock(GET_TIME), from, line+1));
	doing_notice = 0;
	message_from(NULL, LOG_CRAP);
}


void load_scripts(void)
{
	char buffer[BIG_BUFFER_SIZE+1];
	static int done = 0;
	if (!done++)
	{
		never_connected = 0;
#ifndef WINNT
		strcpy(buffer, "bxglobal");
		loading_global = 1;
		load("LOAD", buffer, empty_string, NULL);
		loading_global = 0;
#endif
		/* read the .ircrc file */
		if (access(bircrc_file, R_OK) == 0 && !quick_startup)
			load("LOAD", bircrc_file, empty_string, NULL);
		else if (access(ircrc_file, R_OK) == 0 && !quick_startup)
			load("LOAD", ircrc_file, empty_string, NULL);
		if (!quick_startup)
			reload_save(NULL, NULL, NULL, NULL);
	}
	if (get_server_away(from_server))
		set_server_away(from_server, get_server_away(from_server));
}

/*
 * got_initial_version_28: this is called when ircii gets the serial
 * number 004 reply.  We do this becuase the 004 numeric gives us the
 * server name and version in a very easy to use fashion, and doesnt
 * rely on the syntax or construction of the 002 numeric.
 *
 * Hacked as neccesary by jfn, May 1995
 */
extern void got_initial_version_28 (char **ArgList)
{
	char *server, *sversion;

	server = ArgList[0];
	sversion = ArgList[1];
	
	if (!strncmp(version, "2.8", 3))
	{
		if (strstr(version, "mu") || strstr(version, "me"))
			set_server_version(from_server, Server_u2_8);
		else
			set_server_version(from_server, Server2_8);
	}
	else if (!strncmp(version, "u2.9", 4))
		set_server_version(from_server, Server_u2_9);
	else if (!strncmp(version, "u2.10", 4))
		set_server_version(from_server, Server_u2_10);
	else if (!strncmp(version, "u3.0", 4))
		set_server_version(from_server, Server_u3_0);
	else
		set_server_version(from_server, Server2_8);

	malloc_strcpy(&server_list[from_server].version_string, sversion);
	set_server_itsname(from_server, server);
	reconnect_all_channels(from_server);
	message_from(NULL, LOG_CRAP);
	reinstate_user_modes();

	update_all_status(curr_scr_win, NULL, 0);
	do_hook(CONNECT_LIST, "%s %d", get_server_name(from_server), get_server_port(from_server));
}

#define IGNORE_DONT 1
 
void print_ircop_flags(int server)
{
long flag = server_list[server].ircop_flags;
char buffer[BIG_BUFFER_SIZE+1];

	*buffer = 0;
	if (flag & NICK_COLLIDE)
		strmcat(buffer, " COLLIDE", BIG_BUFFER_SIZE);
	if (flag & NICK_KILL)
		strmcat(buffer, " KILLS", BIG_BUFFER_SIZE);
	if (flag & IP_MISMATCH)
		strmcat(buffer, " MISMATCH", BIG_BUFFER_SIZE);
	if (flag & HACK_OPS)
		strmcat(buffer, " HACK", BIG_BUFFER_SIZE);
	if (flag & IDENTD)
		strmcat(buffer, " IDENTD", BIG_BUFFER_SIZE);
	if (flag & FAKE_MODE)
		strmcat(buffer, " FAKES", BIG_BUFFER_SIZE);
	if (flag & UNAUTHS)
		strmcat(buffer, " UNAUTHS", BIG_BUFFER_SIZE);
	if (flag & TOO_MANY)
		strmcat(buffer, " CLIENTS", BIG_BUFFER_SIZE);
	if (flag & TRAFFIC)
		strmcat(buffer, " TRAFFIC", BIG_BUFFER_SIZE);
	if (flag & REHASH)
		strmcat(buffer, " REHASH", BIG_BUFFER_SIZE);
	if (flag & KLINE)
		strmcat(buffer, " KLINE", BIG_BUFFER_SIZE);
	if (flag & POSSIBLE_BOT)
		strmcat(buffer, " BOTS", BIG_BUFFER_SIZE);
	if (flag & OPER_MODE)
		strmcat(buffer, " OPER", BIG_BUFFER_SIZE);
	if (flag & SQUIT)
		strmcat(buffer, " SQUIT", BIG_BUFFER_SIZE);
	if (flag & SERVER_CONNECT)
		strmcat(buffer, " SERVER", BIG_BUFFER_SIZE);
	if (flag & CLIENT_CONNECT)
		strmcat(buffer, " CONNECT", BIG_BUFFER_SIZE);
	if (flag & TERM_FLOOD)
		strmcat(buffer, " FLOOD", BIG_BUFFER_SIZE);
	if (flag & INVALID_USER)
		strmcat(buffer, " USER", BIG_BUFFER_SIZE);
	if (flag & STATS_REQUEST)
		strmcat(buffer, " STATS", BIG_BUFFER_SIZE);
	if (flag & NICK_FLOODING)
		strmcat(buffer, " NICK", BIG_BUFFER_SIZE);
	if (flag & KILL_ACTIVE)
		strmcat(buffer, " ACTIVEK", BIG_BUFFER_SIZE);
	if (flag & SERVER_CRAP)
		strmcat(buffer, " CRAP", BIG_BUFFER_SIZE);
	if (!*buffer)
		strmcat(buffer, " NONE", BIG_BUFFER_SIZE);
	put_it("%s", convert_output_format("$G %bOper%BView%n: $0-", "%s", buffer));
}

void set_operview_flags(int server, unsigned long flags, int neg)
{
	switch(neg)
	{
		case IGNORE_DONT:
			server_list[server].ircop_flags &= (~flags);
			break;
		default:
			server_list[server].ircop_flags |= flags;
			break;
	}
}

BUILT_IN_COMMAND(s_watch)
{
char *arg;
unsigned long flag = 0;
int done = 0;
int neg = 0;
	if (from_server == -1)
	{
		put_it("%s", convert_output_format("$G Try connecting to a server first", NULL, NULL));
		return;
	}
	while((arg = next_arg(args, &args)))
	{
		switch(*arg)
		{
			case '-':
				neg = IGNORE_DONT;
				arg++;
				break;
			default:
				neg = 0;
		}
		if (arg && *arg)
		{
			done = 1;
			flag = 0;
			upper(arg);
			if (!strcmp(arg, "ALL"))
				flag |= -1;
			else if (!strcmp(arg, "COLLIDE"))
				flag |= NICK_COLLIDE;
			else if (!strcmp(arg, "KILLS"))
				flag |= NICK_KILL;
			else if (!strcmp(arg, "MISMATCH"))
				flag |= IP_MISMATCH;
			else if (!strcmp(arg, "HACK"))
				flag |= HACK_OPS;
			else if (!strcmp(arg, "IDENTD"))
				flag |= IDENTD;
			else if (!strcmp(arg, "FAKES"))
				flag |= FAKE_MODE;
			else if (!strcmp(arg, "UNAUTHS"))
				flag |= UNAUTHS;
			else if (!strcmp(arg, "CLIENTS"))
				flag |= TOO_MANY;
			else if (!strcmp(arg, "TRAFFIC"))
				flag |= TRAFFIC;
			else if (!strcmp(arg, "REHASH"))
				flag |= REHASH;
			else if (!strcmp(arg, "KLINE"))
				flag |= KLINE;
			else if (!strcmp(arg, "BOTS"))
				flag |= POSSIBLE_BOT;
			else if (!strcmp(arg, "OPER"))
				flag |= OPER_MODE;
			else if (!strcmp(arg, "SQUIT"))
				flag |= SQUIT;
			else if (!strcmp(arg, "SERVER"))
				flag |= SERVER_CONNECT;
			else if (!strcmp(arg, "CONNECT"))
				flag |= CLIENT_CONNECT;
			else if (!strcmp(arg, "FLOOD"))
				flag |= TERM_FLOOD;
			else if (!strcmp(arg, "USER"))
				flag |= INVALID_USER;
			else if (!strcmp(arg, "STATS"))
				flag |= STATS_REQUEST;
			else if (!strcmp(arg, "NICK"))
				flag |= NICK_FLOODING;
			else if (!strcmp(arg, "ACTIVEK"))
				flag |= KILL_ACTIVE;
			else if (!strcmp(arg, "CRAP"))
				flag |= SERVER_CRAP;
			else if (!strcmp(arg, "NONE"))
			{
				server_list[from_server].ircop_flags = 0;
				put_it("%s", convert_output_format("$G reset oper view flags", NULL, NULL));
				return;
			}
			else
			{
				bitchsay("You must specify from the following");
				say("\tCOLLIDE KILLS MISMATCH HACK IDENTD FAKES UNAUTHS CLIENTS TRAFFIC CRAP REHASH KLINE BOTS OPER SQUIT SERVER CONNECT FLOOD USER STATS NICK ACTIVEK NONE");
				return;
			}
			set_operview_flags(from_server, flag, neg);
		}
	}
	if (done)
		set_operview_flags(from_server, flag, neg);
	print_ircop_flags(from_server);
}

void setup_ov_mode(int on, int hide)
{
char *default_oper = "wsckf";
Window *win = NULL;

	if (on)
	{
		if ((win = get_window_by_name("oper_view")))
		{
			delete_window(win);
			update_all_windows();
			set_input_prompt(curr_scr_win, get_string_var(INPUT_PROMPT_VAR), 0);
			cursor_to_input();
			                        
		}
		send_to_server("MODE %s -%s%s", get_server_nickname(from_server), get_string_var(OPER_MODES_VAR)?get_string_var(OPER_MODES_VAR):default_oper, send_umode);
	} 
	else 
	{
		Window *tmp = NULL;
		if ((tmp = new_window()))
		{
			win = tmp;
			malloc_strcpy(&win->name, "oper_view");
			win->double_status = 0;
			if (hide)
				hide_window(win);
			else
				resize_window(1, win, -5);
			set_current_window(NULL);
			win->window_level = LOG_WALLOP|LOG_OPNOTE|LOG_SNOTE;
			win->absolute_size = 1;
			set_wset_string_var(win->wset, STATUS_FORMAT1_WSET, "[41m%S %>[1;30m[[1;32mOper[1;37mView[1;30;41m] ");
			build_status(win, NULL, 0);
			update_all_windows();
			set_input_prompt(curr_scr_win, get_string_var(INPUT_PROMPT_VAR), 0);
			cursor_to_input();
			send_to_server("MODE %s +%s", get_server_nickname(from_server), get_string_var(OPER_MODES_VAR)?get_string_var(OPER_MODES_VAR):default_oper);
		}
	}
}

extern int old_ov_mode;
BUILT_IN_COMMAND(ov_window)
{
char *arg;
int ov = get_int_var(OV_VAR);
static int hide = DEFAULT_OPERVIEW_HIDE;
int count = 0;
int old_hide = hide;  
	while ((arg = next_arg(args, &args)))
	{
		if (!my_stricmp(arg, "ON"))
			ov = 1;
		else if (!my_stricmp(arg, "OFF"))
			ov = 0;
		else if (!my_stricmp(arg, "+HIDE"))
			hide = 1;
		else if (!my_stricmp(arg, "-HIDE"))
			hide = 0;
		else if (!my_stricmp(arg, "HIDE"))
			hide = 1;
		count++;
	}
	if (count == 0)
		put_it("%s", convert_output_format("$G %BOper%bView%n is %K[%W$0%K]", "%s", on_off(get_int_var(OV_VAR))));
	else
	{
		if ((!ov && get_int_var(OV_VAR)) || (ov && !get_int_var(OV_VAR)))
		{
			setup_ov_mode(ov ?  0 : 1, hide);
			old_ov_mode = ov;
			set_int_var(OV_VAR, ov);
			put_it("%s", convert_output_format("$G %BOper%bView%n is now toggled %K[%W$0%K]", "%s", on_off(get_int_var(OV_VAR))));
		} 
		else if (get_int_var(OV_VAR) && old_hide != hide)
		{
			Window *tmp = get_window_by_name("oper_view");
			Window *old = curr_scr_win;
			if (tmp)
			{
				if (!old_hide && hide)
				{
					hide_window(tmp);
				}
				else
				{
					show_window(tmp);
					resize_window(1, tmp, -5);
				}
				set_current_window(old);
				update_all_windows();
				cursor_to_input();
			}
		}
		else
		{
			put_it("%s", convert_output_format("$G %BOper%bView%n is already %K[%W$0%K]", "%s", on_off(get_int_var(OV_VAR))));
			hide = old_hide;
		}
	}
}
