
#################################################################################
#                                                                               #
#    This file is part of GISMB.                                                #
#    GISMB Stands for 'GenEthic IRC Server Monitoring Bot'                      #
#                                                                               #
#    GISMB is free software; you can redistribute it and/or modify              #
#    it under the terms of the GNU General Public License as published by       #
#    the Free Software Foundation; either version 2 of the License.             #
#                                                                               #
#    GISMB is distributed in the hope that it will be useful,                   #
#    but WITHOUT ANY WARRANTY; without even the implied warranty of             #
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              #
#    GNU General Public License for more details.                               #
#                                                                               #
#    You should have received a copy of the GNU General Public License          #
#    along with GISMB; if not, write to the Free Software                       #
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  #
#                                                                               #
#################################################################################

# NOTHING SHOULD BE CHANGED IN THIS FILE

use IO::Socket;


# loading configuration file into variables

$path = $ARGV[0];

load_conf();

# testing if TCP connection is possible

$ircserver = IO::Socket::INET->new(
		PeerAddr   => $C{'CONN_DST_IP'},
		PeerPort   => $C{'CONN_DST_PORT'},
		Proto      => 'tcp',
		LocalAddr  => $C{'CONN_SRC_IP'}  ) || die "Check your config, TCP connection not possible";

# setting some time vars
$time{'old1'} = time;
$time{'old2'} = time;
$time{'old3'} = time;
$time{'old4'} = time;
$time{'old5'} = time;

# connecting to IRC Server and entering in main loop

while(<$ircserver>) {
	chop; chop;
	$line = $_;
#	if ( $line =~ /352/ ) { $do='nothing'; } else { print "IN  $line\n"; }

# getting time for this loop
	$time{'log'} = time;

# some special chars allowed in nicknames and text are substituted by others
# to be sure nothing bad can be done...

        $line =~ s/\[/\%20/g;
        $line =~ s/\]/\%21/g;
        $line =~ s/\|/\%22/g;
        $line =~ s/\^/\%23/g;
	$line =~ s/\`/\%24/g;

# stuff needed to connect

	if ( $first eq "" ) {
		if ( $C{'USER_PASS'} ne "" ) { quicksend("PASS $C{'USER_PASS'}"); }
		quicksend("USER $C{'USER_IDENT'} not_used not_used :$C{'USER_RNAME'}");
		quicksend("NICK $botnick");
		$first = "connected";
	}

# taking care to reply to PINGS

	if ( $line =~ /^PING / ) {
		$ping = $line;
		$ping =~ s/^PING /PONG /;
		quicksend("$ping");
	}

# in this part i manage 'time base event'
# that's why, having an Y line with 10 seconds
# pings is very important

	# lets do some stuff every X time, to get informations
	# from the server, around 20 seconds before i show
	# the stats..
	if ( $time{'log'}-$time{'old1'} > $C{'INFO_TIME'}-20 ) {
		ircsend("MAP");
		@MAP = ''; $null = shift(@MAP);
		ircsend("LUSERS");
		ircsend("STATS u");
		$time{'old1'} = $time{'log'};
	}

	# lets show the stats and put them into logfile
	if ( $time{'log'}-$time{'old2'} > $C{'INFO_TIME'} ) {
		$mapcount = 0;
		foreach(reverse(sort(@MAP))) {
			($mapclient,$mapserver)=split(/:/);
			$mapcount++;
			if ( $mapserver =~ /^$C{'SERVER_NAME'}$/i ) {
				$mappos = $mapcount;
			}
		}
		if ( $oldchannels < 1 ) { $oldchannels = $channels; }
		$chandiff = $channels - $oldchannels;
		if (  $chandiff =~ /^[0-9]/ ) { $chandiff = "+$chandiff"; }
		$mapper = int(($locusers/($user1+$user2))*10000)/100;
		if ( $ircduptime ne '' ) {
			ircsend("NOTICE $C{'CHAN_NAME'} :$locusers($mapper\%) of $users (+$usersmore2/-$usersless2 in $C{'INFO_TIME'} sec). No $mappos of $mapcount. $channels($chandiff) chans, ircd uptime $ircduptime");
#			ircsend("NOTICE $C{'CHAN_NAME'} :$locusers (+$usersmore2/-$usersless2)Loc, $mapper\%($mappos\/$mapcount), $users Glo, $channels Chans, IRCD: $ircduptime");
		}
		$oldchannels = $channels;

		# looking if we have to display some external data.
		if ( $C{'EXTERNAL_FILE'} ne "" ) {
			$ex_display = '';
			open(EXTERNAL,$C{'EXTERNAL_FILE'});
			while(<EXTERNAL>) {
				chop;
				($ex_name,$ex_opt,$ex_data)=split(/;/);
				if ( $ex_opt eq "ALL" ) {
					$ex_display = "$ex_display $ex_name: $ex_data";
				} elsif ( $ex_opt =~ /^\+[0-9]+$/ ) {
					$ex_opt =~ s/^.//;
					if ( $ex_data > $ex_opt ) {
						$ex_display = "$ex_display $ex_name: $ex_data";
					}
				} elsif ( $ex_opt =~ /^\-[0-9]+$/ ) {
					$ex_opt =~ s/^.//;
					if ( $ex_data < $ex_opt ) {
						$ex_display = "$ex_display $ex_name: $ex_data";
					}
				}
			} close(EXTERNAL);
			$ex_display =~ s/^ //;

			if ( $ex_display ne "" ) {
				ircsend("NOTICE $C{'CHAN_NAME'} :$ex_display");
			}
		}

		# this file can then be used to do some MRTG graphs or so...
		open(LOG,">$path/var/genethic.log");
		print LOG <<EOF;
LOCAL_USERS:$locusers
GLOBAL_USERS:$users
MAX_LOCAL_USERS:$maxusers
CHANNEL:$channels
POSITION:$mappos
USERS_PERCENT:$mapper
USERS_MORE:$usersmore2
USERS_LESS:$usersless2
EOF
		close(LOG);

		$usersmore2 = 0;
		$usersless2 = 0;
		$time{'old1'} = $time{'log'};
		$time{'old2'} = $time{'log'};
	}

# trying to handle all types of incomming messages :-P
# sort them, put them in vars,etc etc....

	$from=''; $type=''; $type2=''; $content=''; $nick='';$user='';$host='';$fullhost='';$msgsrc='';
	if ( $line =~ /^:/ ) {
		$line =~ s/^://g;
		$from = $line; $from =~ s/ .*//g;
		$type  = $line; $type =~ s/^$from //g; $type =~ s/ .*//g;
		$type2 = $line; $type2 =~ s/^$from $type //g; $type2 =~ s/ .*//g;
		if ( $type2 =~ /^:/ ) { $type2 = ''; }
		$content = $line; $content =~ s/^$from $type $type2.//g; $content =~ s/^://g;

		if ( $from =~ /\@/ && $from =~ /\!/ ) {
			$msgsrc = "user";
			($nick,$fullhost)=split(/\!/,$from);
			($user,$host)=split(/\@/,$fullhost);
		} else {
			$msgsrc = "server";
			$nick = "";
			$user = "";
			$host = "";
		}
	}

# lets check if you're not under floodbots attack :-) or any other mass (dis)connects...

        if ( $locusers ne "" && $oldlocusers eq "" ) { $oldlocusers = $locusers; $time{'lastusers'} = $time{'log'}; }

        $usersdiff = $locusers - $oldlocusers;
        $tdiff = $time{'log'} - $time{'lastusers'};
        if ( abs($usersdiff) >= $C{'USER_THRESHOLD'} && $tdiff >= $C{'TIME_THRESHOLD'} ) {
                if ( $usersdiff =~ /^[0-9]/ ) { $usersdiff = "+" . $usersdiff; }
                if ( abs($usersdiff/$tdiff)*100 >= $C{'USER_SEC_THRESHOLD'} ) {
			ircsend("NOTICE $C{'CHAN_NAME'} :WARNING Possible attack: $usersdiff (+$usersmore1/-$usersless1) users in $tdiff seconds ($locusers users)");
                } elsif ( $C{'PRINT_ONLY_WARNING'} ne "TRUE" ) {
                        ircsend("NOTICE $C{'CHAN_NAME'} :$usersdiff (+$usersmore1/-$usersless1) users in $tdiff seconds ($locusers users)");
                }
                $oldlocusers = $locusers;
                $time{'lastusers'} = $time{'log'};
		$usersmore1 = 0;
		$usersless1 = 0;
        }


# ok now, the big part, taking care of what to do with all this information....

	if ( $msgsrc eq "server" ) {
		# nickname already used, changing to next one
		if ( $type eq "433" ) {
			$botnick = shift(@NICKS);
			if ( $botnick eq '' ) {
				print STDERR "Fatal Error, no more nicknames available, change your config!\n";
				exit 1;
			}
#			print "changing nick to $botnick because: $line\n";
			quicksend("NICK $botnick");
		# Hey, i m connected now, lets do some stuff now..
		} elsif ( $type eq "001" ) {
			if ( $C{'X_AUTH'} eq "TRUE" ) {
				ircsend("PRIVMSG $C{'X_HOST'} :login $C{'X_USER'} $C{'X_PASS'}");
			}
			ircsend("OPER $C{'O_USER'} :$C{'O_PASS'}");
			ircsend("MODE $botnick +id");
			ircsend("MODE $botnick +s 32767");
			ircsend("JOIN $C{'CHAN_NAME'} :OVERRIDE");
			ircsend("MODE $C{'CHAN_NAME'} +o $botnick");
			if (  $C{'CHAN_KEEP_MODES'} eq "TRUE" ) {
				ircsend("MODE $C{'CHAN_NAME'} $C{'CHAN_MODES'}");
			}
			if ( $C{'MANAGE_USERS'} eq "TRUE" ) {
				ircsend("NOTICE $C{'CHAN_NAME'} :Getting complete server user_list, please wait...");
				ircsend("WHO $C{'SERVER_NAME'} x");
			}
		# end of WHO
		} elsif ( $type eq "315" ) {
			ircsend("NOTICE $C{'CHAN_NAME'} :Received complete user_list($tempcounter), resuming normal operation.");
		# receiving WHO result, and working on it... fucking hard...
		} elsif ( $type eq "352" ) {
			($null,$null,$whohost)=split(/ /,$content);
			$usertable{$whohost}++;
			$tempcounter = 0;
			foreach(@USERTABLE) { $tempcounter++; }
			if (  $tempcounter/1000 eq int($tempcounter/1000) ) {
				ircsend("NOTICE $C{'CHAN_NAME'} :Already got $tempcounter users.");
			}
			push(@USERTABLE,"$whohost");
			
		# getting list of users when entering in channel, whois'ing them
		} elsif (  $type eq "353" ) {
			$content =~ s/.*://g;
			$content =~ s/\@//g;
			foreach(split(/ /,$content)) { ircsend("WHOIS $_"); }
		# hey, i m sure this guy  is an oper
		} elsif ( $type eq "313" ) {
			if ( $content =~ /is an IRC Operator/ ) {
				$content =~ s/ .*//;
				$opers{$content} = 'yes';
			}
		# end of whois...humm.. perhaps an action to take
		} elsif ( $type eq "318" ) {
			$content  =~ s/ :.*//;
			if ( $C{'CHAN_OPER_ONLY'} eq "TRUE" ) {
				if ( $opers{$content} eq "yes" ) {
					ircsend("NOTICE $content :You are an authorized user. /NOTICE $botnick help");
					ircsend("MODE $C{'CHAN_NAME'} +o $content");
				} else {
					if ( $C{'CHAN_OPER_ACTION'} eq "KICK" ) {
						ircsend("KICK $C{'CHAN_NAME'} $content :$C{'CHAN_OPER_ACTION_REASON'}");
					} elsif ( $C{'CHAN_OPER_ACTION'} eq "KILL" ) {
						ircsend("KILL $content :$C{'CHAN_OPER_ACTION_REASON'}");
					}	
				}
			} else {
				ircsend("MODE $C{'CHAN_NAME'} -o $content");
				ircsend("MODE $C{'CHAN_NAME'} -v $content");
			}
		# Humm, i m receiving a MAP result, lets work on that
		} elsif ( $type eq "015" ) {
			$mapserver = $content;
			$mapserver =~ s/.*(-|:)//;
			$mapserver =~ s/ .*//;
			$mapclient = $content;
			$mapclient =~ s/.* %20/00000/;
			$mapclient =~ s/ .*//;
			$mapclient =~ s/^.*(......)$/$1/;
			if ( $mapclient >= $C{'MAP_THRESHOLD'} ) {
				push(@MAP,"$mapclient:$mapserver");
			}
		# LUSERS result
		} elsif ( $type eq "251" ) {
			($null,$null,$user1,$null,$null,$user2,$null,$null,$servers,$null)=split(/ /,$content);
			$users = $user1 + $user2;
		# get ircd uptime
		} elsif ( $type eq "242" ) {
			$ircduptime = $content;
			$ircduptime =~ s/^Server Up //;
		# get number of channels from LUSERS
		} elsif ( $type eq "254" ) {
			$channels = $content;
			$channels =~ s/ .*//;
		# get number of local users from LUSERS
		} elsif ( $type eq "255" ) {
			$locusers = $content;
			$locusers =~ s/I have (.*) clients.*/$1/;
		# channel modes changes
		} elsif ( $type eq "MODE" && $type2 =~ /^$C{'CHAN_NAME'}$/i ) {
			ircsend("MODE $C{'CHAN_NAME'} $C{'CHAN_MODES'}");
		# and now some server notices...
		} elsif ( $type eq "NOTICE" ) {
			# max users..
			if ( $content =~ /^Highest connection count/ ) {
				$maxusers = $content;
				$maxusers =~ s/.*\((.*) clients\)/$1/;
				if ( $maxusers > $oldmaxusers ) {
					ircsend("MODE $C{'CHAN_NAME'} +l $maxusers");
				}
				$oldmaxusers = $maxusers;
			# connecting users
			} elsif ( $content =~ /\*\*\* Notice -- Client connecting: / ) {
				$content =~ s/.*\(//;
				$content =~ s/\).*//;
				$content =~ s/.*\@//;
				$usertable{$content}++;
				$locusers++;
				$usersmore1++;
				$usersmore2++;
				push(@USERTABLE,"$content");
			# disconnecting users
			} elsif ( $content =~ /\*\*\* Notice -- Client exiting: / ) {
				$content =~ s/.*\(//;
				$content =~ s/\).*//;
				$content =~ s/.*\@//;
				$usertable{$content}--;
				$locusers--;
				$usersless1++;
				$usersless2++;
			} elsif ( $content =~ /\*\*\* Notice -- Failed OPER attempt by / && $C{'OPER_FAIL_CHECK'} eq "TRUE" ) {
				$content =~ s/.*Failed OPER attempt by //;
				$content =~ s/\(|\)//g;
				($opernick,$operhost)=split(/ /,$content);
				$operfail{$operhost}++;
				if ( $C{'OPER_FAIL_MAX'} <= $operfail{$operhost} ) {
					if ( $C{'OPER_FAIL_ACTION'} eq "KILL" ) {
						ircsend("KILL $opernick :$C{'OPER_FAIL_ACTION_REASON'}");
					} elsif ( $C{'OPER_FAIL_ACTION'} eq "LGLINE" ) {
						ircsend("GLINE $operhost $C{'OPER_FAIL_GLINE_TIME'} :$C{'OPER_FAIL_ACTION_REASON'} (banned for $C{'OPER_FAIL_GLINE_TIME'} seconds)");
					}
					ircsend("NOTICE $C{'CHAN_NAME'} :MAX OPER Fail by $opernick\!$operhost ($C{'OPER_FAIL_ACTION'})");
					$operfail{$operhost}=0;
				} else {
					ircsend("NOTICE $opernick :$C{'OPER_FAIL_WARNING'}");
					ircsend("NOTICE $C{'CHAN_NAME'} :OPER Fail by $opernick\!$operhost");
				}
			} elsif ( $content =~ /\*\*\* Notice -- Net break: / ) {
				$content =~ s/.*\*\*\* Notice -- Net break: //;
				ircsend("NOTICE $C{'CHAN_NAME'} :SPLIT: $content");
			} elsif ( $content =~ /\*\*\* Notice -- Net junction: / ) {
				$content =~ s/.*\*\*\* Notice -- Net junction: //;
				ircsend("NOTICE $C{'CHAN_NAME'} :JOIN: $content");
			} elsif (  $content =~ / is now operator / ) {
				$content =~ s/.*Notice -- //;
				($opernick,$operhost,$null,$null,$null,$opertype)=split(/ /,$content);
				$operhost =~ s/\(|\)//g;
				if ( $opertype eq "(o)" ) { $opertype = "LocalOPER"; } else { $opertype = "GlobalOPER"; }
				ircsend("NOTICE $C{'CHAN_NAME'} :$opernick\!$operhost is now $opertype");
			}
		}
	} elsif ( $msgsrc eq "user" && $nick ne $botnick ) {
		# hey, a guy is joining, but who is he?
		if ( $type eq "JOIN" ) {
			ircsend("WHOIS $nick");
			if ( $C{'X_AUTH'} eq "TRUE" ) {
				ircsend("PRIVMSG $C{'X_NICK'} :VERIFY $nick");
			}
		#  that guy is leaving, unauthing...
		} elsif ( $type eq "PART" || $type eq "QUIT" ) {
			$opers{$nick} = '';
		# Detecting authenticated users nick change.
		} elsif ( $type eq "NICK" ) {
			if ( $opers{$nick} eq "yes" ) {
				$opers{$nick} = '';
				$opers{$content} = "yes";
				ircsend("NOTICE $C{'CHAN_NAME'} :Nick change detected, $nick -> $content");
			}
		# CSBot has information for me ;-) lets share that...
		} elsif (  $type eq "NOTICE" && $nick eq "$C{'X_NICK'}" ) {
			ircsend("NOTICE $C{'CHAN_NAME'} :From $nick: $content");
		# yes, a guy is talking to me ;p
		} elsif (( $type eq "PRIVMSG" || $type eq "NOTICE" ) && $opers{$nick} eq "yes" ) {
			# lets manage common CTCP replies
			if ( $content =~ // ) {
				$content =~ s/^.(.*).$/$1/;
				if (  $content =~ /^PING / ) {
					ircsend("NOTICE $nick :$content");
				} elsif ( $content =~ /^VERSION/ && $C{'VERSION'} ne '' ) {
                                	ircsend("NOTICE $nick :VERSION $C{'VERSION'}");
                        	} elsif ( $content =~ /^TIME/ ) {
                                	ircsend("NOTICE $nick :TIME $time{'log'}");
                        	} elsif ( $content =~ /^FINGER/ && $C{'FINGER'} ne '' ) {
                                	ircsend("NOTICE $nick :FINGER $C{'FINGER'}");
                        	}
			# lets give him sime help as requested..
			} elsif (  $content =~ /^help$/i ) {
				$totalhelp ='';
				foreach(@HELP) {
					($hindex,$hdetail)=split(/\;/);
					$totalhelp = "$totalhelp $hindex";
				}
				$totalhelp =~ s/^ //;
				ircsend("NOTICE $nick :HELP INDEX: $totalhelp");
				ircsend("NOTICE $nick :Try /notice $botnick help <command>");
			# or detailed help
			} elsif (  $content =~ /^help /i ) {
				foreach(@HELP) {
					($hindex,$hdetail)=split(/\;/);
					if ( $content =~ /^help $hindex$/i || $content =~ /^help all$/i ) {
						$hdetail =~ s/^ *//;
						ircsend("NOTICE $nick :$hdetail");
					}
				}
			# the user want to reload my config
			} elsif ( $content =~ /^reload$/i ) {
				load_conf();
				ircsend("NOTICE $nick :Config files reloaded...");
			# the user want me to change nickname
			} elsif (  $content =~ /^nick /i ) {
				$content =~ s/^nick //i;
				ircsend("NICK $content");
			# let the user send some RAW commands
			# can be userfull for debugging, or others?
			} elsif ( $content =~ /^raw /i ) {
				$content =~ s/^raw //i;
				ircsend("$content");
			# wanna talk  in the channel?
			} elsif ( $content =~ /^chan /i ) {
				$content =~ s/^chan //i;
				ircsend("PRIVMSG $C{'CHAN_NAME'} :$content");
			# how to suicide ;)
			} elsif ( $content =~ /^quit /i ) {
				$content =~ s/^quit /quit :/i;
				ircsend("NOTICE $C{'CHAN_NAME'} :Quitting, requested by $nick");
				ircsend("$content");
			# lets see if see some clones around
			} elsif ( $content =~ /^clones /i ) {
				$content =~ s/^clones //;
				if ( $content =~ /^[0-9]+/ && $content ne "0" ) {
					$clonecount=0;
					foreach(sort(@USERTABLE)) {
						if ( $oldhost ne $_ && $usertable{$_} >= $content ) {
							$clonecount++;
							$oldhost = $_;
						}
					}
					if ( $clonecount > 30 ) {
						ircsend("NOTICE $nick :Sorry too many output detected ($clonecount match, max 30)");
					} else {
						ircsend("NOTICE $nick :Clones searched, found $clonecount match for your request");
						foreach(sort(@USERTABLE)) {
							if ( $oldhost ne $_ && $usertable{$_} >= $content ) {
								ircsend("NOTICE $nick :Detected that $_ has $usertable{$_} active connections");
								$oldhost = $_;
							}
						}
					}
				} else {
					ircsend("NOTICE $nick :Syntax error");
				}
			# same as clones check, but with web result
			} elsif ( $content =~ /^clonesweb /i ) {
				if ( $C{'WEB_RESULT_PATH'} ne '' && $C{'WEB_RESULT_URL'} ne '' ) {
					$content =~ s/^clonesweb //;
					if ( $content =~ /^[0-9]+/ && $content ne "0" ) {
						$clonecount=0;
						foreach(sort(@USERTABLE)) {
							if ( $oldhost ne $_ && $usertable{$_} >= $content ) {
								$clonecount++;
								$oldhost = $_;
							}
						}
						open(HTML,">$C{'WEB_RESULT_PATH'}");
						print HTML "<html><pre>Clones check result asked by $nick\!$user\@$host\n\n";
						foreach(sort(@USERTABLE)) {
							if ( $oldhost ne $_ && $usertable{$_} >= $content ) {
								print HTML "$_ has $usertable{$_} active connections\n";
								$oldhost = $_;
							}
						}
						close(HTML);
						ircsend("NOTICE $nick :Web result is published to http://$C{'WEB_RESULT_URL'}");
					}
				} else {
					ircsend("NOTICE $nick :Syntax error");
				}
						
			# humm... showing the map can be huge, the user is the king, let do.
			} elsif ( $content =~ /^map$/i ) {
				ircsend("NOTICE $nick :Network MAP ordered by users");
				$counter = 0;
				foreach(reverse(sort(@MAP))) {
					($mapuser,$mapserv)=split(/:/);
					$counter++;
					$counter = "00$counter"; $counter =~ s/.*(..)$/$1/;
					if ( $mapserv =~ /^$C{'SERVER_NAME'}$/i ) {
						ircsend("NOTICE $nick :$counter($mapuser) $mapserv");
					} else {
						ircsend("NOTICE $nick :$counter($mapuser) $mapserv");
					}
				}
				ircsend("NOTICE $nick :End of MAP");
			}
		}
	} elsif ( $nick eq $botnick ) {
		# but why should i change my own nickname? who knows...
		if ( $type eq "NICK" ) {
			$botnick = $content;
		}
	}
	checktosend();
}

# SUB to manage the outgoing messages queue
# and to slow it down if needed, to avoid
# Excess_flood disconnects..

sub ircsend {
	$msg4srv = shift;
	$msg4srv =~ s/\%20/\[/g;
	$msg4srv =~ s/\%21/\]/g;
	$msg4srv =~ s/\%22/\|/g;
	$msg4srv =~ s/\%23/\^/g;
	$msg4srv =~ s/\%24/\`/g;

#	print "DEBUG: Pushed msg \"$msg4srv\" to queue\n";
	if ( $C{'OPS_INFO_ONLY'} eq "TRUE" || $C{'CHAN_OPER_ONLY'} ne "TRUE" ) {
		$msg4srv =~ s/^NOTICE $C{'CHAN_NAME'} :/NOTICE \@$C{'CHAN_NAME'} :/;
	}
	push(@TOSEND,"$msg4srv");
}

sub checktosend {
	if ( $msgcount eq '' ) { $msgcount = 1; }
	if ( $time{'log'}-$time{'old3'} >= $msgcount ) {
		$msgcount = 1;
		for($loop=0; $loop<4; $loop++ ) {
			$tosend=shift(@TOSEND);
			if ( $tosend ne '' ) {
				$msgcount++;
				print $ircserver "$tosend\n";
#				print "OUT $tosend\n";
			}	
		}
	$time{'old3'} = $time{'log'};
	}
}

# SUB to manage the URGENT outgoing messages
# Should ONLY be used for server PING replies
# had to do it, cause if the outqueue is full
# the ping reply to the server  may take a while
# and the bot disconnects ;(

sub quicksend {
	$text_to_send = shift;
	print $ircserver "$text_to_send\n";
#	print "OUT $text_to_send\n";
}

# SUB For loading/reloading the config file
# be carefull, an error in config may the bot STOP running

sub load_conf {

	open(CONF,"$path/etc/genethic.conf") || die "Configuration file not found";
	while(<CONF>) {
		chop;
       		 if ( $_ =~  /^[A-Z]+/ ) {
			($name,$value)=split(/:/);
			$C{$name} = $value;
#			print "CONFIG: $name = \"$value\"\n";
		}
	} close(CONF);

	@HELP=''; $null = shift(@HELP);
	open(HELP,"$path/etc/help.txt") || die "$path/etc/help.txt not found";
	while(<HELP>) { chop; push(@HELP,$_); } close(HELP);

	foreach(split(/ /,$C{'NICKS'})) {
		push(@NICKS,$_);
	}

	if ( $first eq "" ) {
		$botnick = shift(@NICKS);
	}

	# checking some stuff in config, hope you configured correctly ;p

	if ( $C{'CONN_DST_IP'} =~ /^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$/ ) { null; } else { print STDERR "CONN_DST_IP error\n"; $err++; }
	if ( $C{'CONN_DST_PORT'} < 1 || $C{'CONN_DST_PORT'} > 65535 ) { print STDERR "CONN_DST_PORT error\n"; $err++; }
	if ( $C{'CONN_SRC_IP'} =~ /^[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*$/ ) { null; } else { print STDERR "CONN_SRC_IP error\n"; $err++; }
	if ( $C{'USER_IDENT'} eq "" ) { print STDERR "USER_IDENT error\n"; $err++; }
	if ( $C{'USER_RNAME'} eq "" ) { print STDERR "USER_RNAME error\n"; $err++; }
	if ( $C{'NICKS'} eq "" ) { print STDERR "NICKS error\n"; $err++; }
	if ( $C{'X_AUTH'} != /^(TRUE|FALSE)$/ ) {  print STDERR "X_AUTH error\n"; $err++; }
	if ( $C{'O_USER'} eq "" ) { print STDERR "O_USER error\n"; $err++; }
	if ( $C{'O_PASS'} eq "" ) { print STDERR "O_PASS error\n"; $err++; }
	if ( $C{'CHAN_NAME'} != /^\&/ ) { print STDERR "CHAN_NAME error\n";  $err++; }
	if ( $C{'CHAN_KEEP_MODES'} != /^(TRUE|FALSE)$/ ) {  print STDERR "CHAN_KEEP_MODES error\n";  $err++; }
	if ( $C{'CHAN_OPER_ONLY'} != /^(TRUE|FALSE)$/ ) {  print STDERR "CHAN_OPER_ONLY error\n";  $err++; }

	if (  $err >= 1 ) {
		if ( $first eq "" ) {
			print STDERR "$err errors found in configuration!\n";
			print STDERR "Please check your config file\n";
			exit 1;
		} else {
			ircsend("NOTICE $nick :!!!WARNING!!! at least $err errors found in configuration file");
			ircsend("NOTICE $nick :I will now have to quit, sorry ;-(");
			ircsend("QUIT :Configuration error");
		}
	}
}
