#!/usr/bin/perl
#
# ChanShell v1.0.4.
#
# Author: Cody Tubbs (loophole of hhp).
#   Site: http://www.hhp-programming.net/
#  Email: pigspigs@yahoo.com
#  iDate: 05/29/2001 8:25:34PM CST.
#   Date: 08/09/2001 6:37:23AM CST.
#   Chan: #ChanShell@EFnet
#
# Info:  ChanShell is short explanation = IRC<->BASH.
#        ChanShell  is  somewhat like an IRC bot with
#        bash  capabilities.  ChanShell  has the cap-
#        abilities as followed:
#
# setpass, ident, adduser, deluser, join, part, raw. 
#    0       0       1        1      1     1     1
#
# 0 = normal users can access.
# 1 = master command only.
#
# I will explain these commands one at a time now.
# For  first  time  usage, set your $db, $botnick,
# and  $identword to your preference.  Execute and
# go message your ChanShell your $identword, like:
# YOU: /msg <$csnick> howdy
# <$csnick> Hi loophole, set a password: pass <passwd>
# And it will recognise you, then type:
# YOU: /msg <$csnick> set pass <password>
# <$csnick> Password set to "<password>".
# (take note that set pass is two words here.)
# Then type:
# YOU: /msg <$csnick> ident <password>
# <$csnick> Ident succesfull.
#
# Ok,  the  first master has been added to the database
# and all passwords are encrypted via standard crypt(3)
# DES passwords(Don't create weak passwords).
#
# Ok, now to execute commands on ChanShell you need to
# type:
# $csnick# command
# Examples:
# <loophole> chanshell# id
# <$csnick> uid=1004(chanshell) gid=1004(chanshell)
# <loophole> chanshell# cd ..
# <loophole> chanshell# echo HEH > tmp.file ; cat tmp.file
# <chanshell> HEH
# <loophole> Get the picture?
#
# Just imagine '$csnick#' as your bash prompt.
#
# Alright, anytime you run ChanShell after being added
# to  the database, all you need to do is ident before
# you can access.  To add users there are two types of
# access, master and normal.
#
# I  would suggest not adding ANYONE to your chanshell
# unless  they  are  100%  trustworthy.  Remember that
# anyone  can  rm  the $db and this src if they wanted
# to.   I  did  not implement filtering in those areas
# because  that's not what this code is about.  I dont
# add  anyone I can't trust, neither should you... its
# shell access.
# (Report ANY bugs ASAP, there is probably a few? HEH)
#
# Alright keeping that in mind, here is how you add users.
# (This command is very strict, read carefully, it's not
# how eggdrop works).
#
# To add normal users:
# /msg $csnick adduser <nick> <ident> <hostname>
# To add master users:
# /msg $csnick adduser +<nick> <ident> <hostname>
# (You add a '+' in front of their nick).
# Examples:
# YOU: /msg $csnick adduser v9 v9 host-208-60-234-67.cha.bellsouth.net
# <$csnick> Added "v9:NULL:*!v9@*.cha.bellsouth.net" to db.
# YOU: /msg $csnick adduser +v9 v9 host-208-60-234-67.cha.bellsouth.net
# <$csnick> Added master "+v9:NULL:*!v9@*.cha.bellsouth.net" to db.
# NOTE: DO NOT USE *, !, @, ETC, IT IS AUTOMATIC.
# After you have added them, tell them to:
# /msg $csnick setpass <password>
# then:
# /msg $csnick ident <password>
# (Note setpass is ONE word here).
#
# Alright, if you are on another nick and not on your hostname
# and need to access your chanshell, you can:
# /msg $csnick ident <your_real_nick> <password>
# and then:
# /msg $csnick ident <password>
# (It will add you to the database).
#
# To delete a user do:
# /msg $csnick deluser <nick>
#
# To add a channel type:
# ~join #channel [key]
# In either msg or in a channel.
#
# To leave a channel type:
# ~part #channel
# In either msg or in a channel.
#
# To use the 'raw' command do:
# /msg $csnick raw <command>
# Examples:
# /msg $csnick raw PRIVMSG #channel :Hi, how's it going?
# or
# /msg $csnick raw MODE #channel +o loophole
#
# The  commands  lesson is now over.  The syntaxs are strict,
# be sure you type them correctly.  Also, make sure you don't
# execute  commands that will lockup the shell or go into any
# sort of login mode, you'll have to restart.
# 
# (((((Do a '$csnick# help' for help over irc.)))))
#
#
# Servers: This  was  tested on EFNET(mcs, prison,       
#          and solidstreaming).  Some servers wont 
#          work  due  to the way it sends back raw    
#          info.  irc.lagged.org doesn't work.
#
# REASON: I  coded  this  to mainly have a toy and quick shell
#         access  over  IRC, check domains, check aliveness of
#         hosts, check files in real-time to show others, etc.
#         I'm sure k1dd13z could ./scan from their channel.
#
# FOO:  Don't come to me complaining if someone f*cks up your
#       stuff  with  this, I've already warned you not to add
#       non  trustworthy people. (And I've added checking for
#       execution by root... and denied it).
#
# Changelog:
#   0.1.4 - Fixed a minor non-security threatfull bug.
#################################################################

use IO::Socket;

$bsnick    = "chanshell";        #The name of your ChanShell.
$db        = "chanshell.users";  # User database filename.
$identword = "howdy";            # Special 'hello' introduce word.
$allowexec = 1;            #Set this at 0 if you don't want to allow
                           #the execution of commands, and use this
                           #just for a bot.

##### Don't edit below here. #####
$ver  = "v1.0.4";
$date = "08/09/2001";
$key  = "NULL";
$a    = 0;
$b    = 0;
$c    = 0;
$d    = 0;

if($<==0){
 print "ERROR: This program will not execute as root.\n";
 exit(0);
}

if((@ARGV!=3)&&(@ARGV!=4)){
 print "$0 <server> <port> <chan (without #)> [key]\n";
 exit 0;
}
if(@ARGV==4){
 ($server, $port, $chan, $key) = @ARGV;
}else{
 ($server, $port, $chan) = @ARGV;
}

&connect; #We create the connect subroutine so we can reconnect when disconnected
.

sub connect(){
 $sock = IO::Socket::INET->new(PeerAddr => $server,
                               PeerPort => $port,
                                  Proto => "tcp") or die "Can't connect to $serve
r.\n";
 print $sock "user $bsnick $bsnick $bsnick $bsnick\n";
 print $sock "pass $bsnick\n";
 print $sock "nick $bsnick\n";
 print "VERBOSE: Connected!\n";
 print $sock "join #$chan $key\n"; #$key won't hurt if non existant.
 print "VERBOSE: Joining channel!\n";
 print $sock "PRIVMSG #$chan :Hi, im $bsnick.\n";
}

while(<$sock>){
 chomp;
 $line   = $_;
 $backup = $line;
 $line   = lc($line);

 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG (\S+) :$bsnick# (.*).$/){
  if($allowexec==1){
   $tryname  = lc($1);
   $tryident = lc($2);
   $tryhost  = lc($3);
   $trychan  = lc($4);
   $com      = $5;
   $noac     = 0;
   if($trychan=~/^#/){
    if($trychan eq "#$chan"){
     $trychan = "#" . $chan;
    }
    checkhost($tryhost);
    foreach $niq (@identers){
     if($niq=~/^([+]*)$tryname:\*!$tryident\@($newhost\.\*|\*\.$newhost|$newhost)
$/){
      &docommand;
      $noac=1;
     }
    }
    if($noac==0){
     print "VERBOSE: $tryname!$tryident\@$tryhost attempted command: *$com* with 
no access!\n";
    }
   }else{
    print "VERBOSE: $tryname!$tryident\@$tryhost attempted a MSG command: *$com* 
with no access!\n"; 
   }
  }
 }

 if($line=~/^error :closing link:/){
  print "VERBOSE: Connection has been closed, trying to reconnect!...\n";
  &connect;
 }

 if($backup=~/^PING :(\S+)/){
  print $sock "PONG :$1\n";
 }

###CTCP Stuff. (The \001 will not paste correctly, watch out.)
 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :\001VERSION\001.$/){
  print $sock "NOTICE $1 :VERSION (ChanShell::$ver):>www.hhp-programming.net\n";
 }
 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :\001(PING|ECHO) (\S+)\001.$/)
{
  print $sock "NOTICE $1 :PING $5\n";
 }
 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :\001TIME\001.$/){ 
  print $sock "NOTICE $1 :TIME ...Time to Disco!\n";
 }
 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :\001FINGER\001.$/){
  print $sock "NOTICE $1 :FINGER www.hhp-programming.net [Idle 0 seconds]\n";
 }
 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :\001USERINFO\001.$/){
  print $sock "NOTICE $1 :USERINFO www.hhp-programming.net [Idle 0 seconds]\n";
 }
 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :\001CLIENTINFO\001.$/){
  print $sock "NOTICE $1 :CLIENTINFO VERSION PING TIME FINGER USERINFO CLIENTINFO
\n";
 }
###End of CTCP stuff.

 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :$identword.$/){
  if($a==0){
   #print "DEBUG: Going to identfirst()\n";
   &identfirst;
  }
 }
 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :pass (\S+).$/){
  if((!-e $db)||(-e $db)&&(-z $db)){
   if(($a==1)&&($b==0)){
    &passfirst;
   }
  }
 }

 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :ident (\S+).$/){
  $identname  = lc($1);
  $identident = lc($2);
  $identhost  = lc($3);
  $identpass  = $4;
  $identorig  = "NULL";
  &ident;
 }
 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :ident (\S+) (\S+).$/){
  $identname  = lc($1);
  $identident = lc($2);
  $identhost  = lc($3);
  $identorig  = lc($4);
  $identpass  = $5;
  &ident;
 }

 if($line=~/^:(\S+)!(\S+)\@(\S+) privmsg $bsnick :deluser (\S+).$/){
  &deluser;
 }

 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG (\S+) :raw (.*).$/){
  &rawcommand;
 }

 if($line=~/^:(\S+)!\S+\@\S+ kick (\S+) $bsnick :.*$/){
  $kicker  = $1;
  $retchan = $2;
  print $sock "join $retchan $key\n"; #$key wont hurt if non existant.
  print $sock "PRIVMSG $retchan :Please don't kick me $kicker, KTHNX!\n";
 }

 if($line=~/^:(\S+)!(\S+)\@(\S+) privmsg (\S+) :~join (.*).$/){
  $joinname  = $1;
  $joinident = $2;
  $joinhost  = $3;
  $joinreq   = $4;
  $joinchan  = $5;
  if($joinreq eq $bsnick){
   $joinreq = $joinname;
  }
  &joinchan;
 }

 if($line=~/^:(\S+)!(\S+)\@(\S+) privmsg (\S+) :~part (\S+).$/){   
  $partname  = $1;
  $partident = $2;
  $parthost  = $3;
  $partreq   = $4;  
  $partchan  = $5; 
  if($partreq eq $bsnick){
   $partreq = $partname;
  }
  &partchan;
 }

 if($line=~/^:(\S+)!(\S+)\@(\S+) privmsg $bsnick :adduser (\S+) (\S+) (\S+).$/){
  &adduser;
 }

 if($backup=~/^:(\S+)!(\S+)\@(\S+) PRIVMSG $bsnick :setpass (\S+).$/){
  &setpass;
 }
}
###End of connect(), other subroutines follow.

sub setpass(){
 $passname  = lc($1);
 $passident = lc($2);
 $passhost  = lc($3);
 $passpass  = $4;
 $notnull   = 0;
 $nogo      = 0;

 checkhost($passhost);
 open(TEMP,"$db");
 @file=<TEMP>;
 close(TEMP);
 #print "DEBUG: in setpass().\n";
 foreach $nib (@file){
  if($nib=~/^([+]*)$passname:(.*):\*!$passident\@($newhost\.\*|\*\.$newhost|$newh
ost)$/){
   #print "DEBUG: found line for setpass()\n";
   $master  = $1;
   $regname = $passname;
   $regpass = $2;
   foreach $neo (@identers){
    if($neo=~/([+]*)$passname:\*!$passident\@($newhost\.\*|\*\.$newhost|$newhost)
$/){
     $notnull=1;
    }
   }
   if(($regpass ne "NULL")&&($notnull==0)){
    print $sock "PRIVMSG $passname :You need to ident first silly!\n";
    $nogo=1;
   }
   if($nogo==0){
    $newsalt=join '',('a'..'z','A'..'Z',0..9,'.','/')[rand 64,rand 64];
    $cryptpass=crypt("$passpass","$newsalt");
    #while($cryptpass=~/\./){
    # $newsalt=join'',('a'..'z','A'..'Z',0..9,'.','/')[rand 64,rand 64];
    # $cryptpass=crypt("$passpass","$newsalt");
    #}
    print $sock "PRIVMSG $passname :$master$regname new password: \"$passpass\"\n
";
    $nib=~s/$regpass/$cryptpass/;
    open(TEMP,">$db");
    print TEMP @file;
    close(TEMP);
   }
  }
 }
}

sub docommand(){
 $ex   = 0;
 $duo  = 0;
 $owna = 0;
 print "VERBOSE: $tryname!$tryident\@$tryhost Executed: *$com*\n";
 checkhost($tryhost);
 foreach $nio (@identers){
  if($nio=~/\+$tryname:\*!$tryident\@($newhost\.\*|\*\.$newhost|$newhost)$/){
   $owna=1;
  }
 }
 if($com=~/^version$/){
  print $sock "PRIVMSG $trychan :#(ChanShell $ver)::Author:>Cody Tubbs(loophole o
f hhp)[$date]\n";
  $ex=1;
 }
 if($com=~/^help$/){
  print $sock "PRIVMSG $trychan :#(ChanShell $ver)::Commands:> (THESE ARE USED VI
A MSG)\n";
  print $sock "PRIVMSG $trychan :#(ChanShell $ver)::setpass, ident, adduser, delu
ser, join, part, raw.\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver)::Try 'help <command>' for more
 iformation.\n";
  $ex=1;
 }
 if($com=~/^help setpass$/){
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: setpass:> syntax = \"setpass
 <password>\"\n";
  $ex=1;
 }
 if($com=~/^help ident$/){
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: ident:> syntax = \"ident [or
ig_nick] <password>\"\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: ident:> example1:> ident mys
ecret\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: ident:> example2:> ident bop
per mysecret\n";
  $ex=1;
 }
 if($com=~/^help adduser$/){
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: adduser:> You must be a mast
er for this command.\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: adduser:> syntax = \"adduser
 [+]<nick> <ident> <hostname>\"\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: adduser:> NOTE: DO NOT USE !
, *, OR @, IT IS AUTOMATIC.\n";
  sleep(1);
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: adduser:> There is two types
 of users, master and normal.\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: adduser:> Example adding of 
a normal user:\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: adduser:> \"adduser v9 fakeh
alo host-208.cha.bellsouth.net\"\n";
  sleep(1);
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: adduser:> Example adding of 
a master user:\n";   
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: adduser:> \"adduser +v9 fake
halo host-208.cha.bellsouth.net\"\n";
  $ex=1;
 }
 if($com=~/^help deluser$/){
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: deluser:> You must be a mast
er for this command.\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: deluser:> syntax = \"deluser
 <nick>\"\n";
  $ex=1;
 }
 if($com=~/^help join$/){
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: join:> You must be a master 
for this command.\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: join:> syntax \"~join <chann
el>\"\n";
  $ex=1;
 }
 if($com=~/^help part$/){
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: part:> You must be a master 
for this command.\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: part:> syntax \"~part <chann
el>\"\n";
  $ex=1;
 }
 if($com=~/^help raw$/){
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: raw:> You must be a master f
or this command.\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: raw:> syntax \"raw <command\
"\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: raw:> example usages of the 
raw command:\n";
  sleep(1);
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: raw:> \"raw PRIVMSG #channel
 :Hi, what's up?\"\n";
  print $sock "PRIVMSG $trychan :#(Chanshell $ver):: raw:> \"raw MODE #channel +o
 yournick\"\n";
  $ex=1;
 }
 if($com=~/^cd (\S+)$/){
  $pa = $1;
  if(($pa=~/;/)||($pa=~/|/)){
   break;
  }
  $path = `cd "$pa" ; pwd`;
  chomp $path;
 }else{
  if($ex==0){
   $slep=0;
   $ok = `cd "$path" ; $com`;
   $ok =~ s/\n/..:!hhp!:../g;
   foreach $lin (split(/..:!hhp!:../,$ok)){
    print $sock "PRIVMSG $trychan :$lin\n";
    $slep++;
    if($slep==3){
     sleep(1);
     $slep=0;
    }
   }
  }
 }
}

sub adduserident(){
 $no="NULL";
 $cryptpass = @info[1];
 checkhost($identhost);
 open(TMP2,"$db");
 @scantmp=<TMP2>;
 close(TMP2);
 foreach $check (@scantmp){
  chomp($check);
  if($check=~/^([+])*$identname:$cryptpass:\*!$identident\@($newhost\.\*|\*\.$new
host|$newhost)$/){
   $no="matched";
   #print "DEBUG: attempted host to ident orignick exists.\n";
  }
 }
 if($no ne "matched"){
  checkhost($identhost);
  open(TMP,">>$db");
  if($ip==1){
   print TMP "$mahster$identname:$cryptpass:*!$identident\@$newhost.*\n";
   print $sock "PRIVMSG $identname :$mahster$identname:*!$identident\@$newhost.* 
>>database.\n";
  }
  if($starhost==1){
   print TMP "$mahster$identname:$cryptpass:*!$identident\@*.$newhost\n";
   print $sock "PRIVMSG $identname :$mahster$identname:*!$identident\@*.$newhost 
>>database.\n";
  }
  if($realhost==1){
   print TMP "$mahster$identname:$cryptpass:*!$identident\@$newhost\n";
   print $sock "PRIVMSG $identname :$mahster$identname:*!$identident\@$newhost >>
database.\n";
  }
  close(TMP);
 }
 #print $sock "PRIVMSG $identname :Password set to \"$identpass\".\n";
}

sub adduserfirst(){
 $salt = join '',('a'..'z','A'..'Z',0..9,'.','/')[rand 64,rand 64];
 $cryptpass=crypt("$pass","$salt");
 checkhost($host);
 if(($c==0)&&(!-e $db)||($c==0)&&(-e $db)&&(-z $db)){
  open(TMP,">>$db");
  if($ip==1){
   print TMP "+$name:$cryptpass:*!$ident\@$newhost.*\n";
   print $sock "PRIVMSG $name :\"+$name:*!$ident\@$newhost.*\" >>database.\n";
   $c=1;
  }
  if($starhost==1){
    print TMP "+$name:$cryptpass:*!$ident\@*.$newhost\n";
   print $sock "PRIVMSG $name :\"+$name:*!$ident\@*.$newhost\" >>database.\n";
   $c=1;
  }
  if($realhost==1){
   print TMP "+$name:$cryptpass:*!$ident\@$newhost\n";
   print $sock "PRIVMSG $name :\"+$name:*!$ident\@$newhost\" >>database.\n";
   $c=1;
  }
  close(TMP);
  print $sock "PRIVMSG $name :Password set to \"$pass\".\n";
 }
}

sub ident(){
 $shorter=0;
 $mahster="";
 if((-e $db)&&(!-z $db)){
  open(TMP,"$db");
  @scan=<TMP>;
  close(TMP);
  foreach $fl (@scan){
   chomp($fl);
   checkhost($identhost);
   if($identorig ne "NULL"){
    @info=split(":",$fl); 
    if((@info[0] eq $identorig)||(@info[0] eq "+$identorig")){
     if(@info[0] eq "+$identorig"){
      $mahster="+";
     }
     $infosalt=substr(@info[1],0,2);
     if(crypt($identpass,$infosalt) eq @info[1]){
      &adduserident;
      print $sock "PRIVMSG $identname :Ident succesfull.\n";
      $foundA=0;
      foreach $niq (@identers){
       if($niq =~ /^([+]*)$identname:\*!$identident\@($newhost\.\*|\*\.$newhost|$
newhost)/){
        $foundA=1;
       }
      }
      if($foundA==0){
       checkhost($identhost);
       if($mahster=""){
        if($ip==1){
         push(@identers, "$identname:*!$identident\@$newhost.*");
         print "Added $identname:*!$identident\@$newhost.* to ident array.\n";
        }
        if($starhost==1){
         push(@identers, "$identname:*!$identident\@*.$newhost");
         print "Added $identname:*!$identident\@$newhost to ident array.\n";
        }
        if($realhost==1){
         push(@identers, "$identname:*!$identident\@$newhost");
         print "Added $identname:*!$identident\@$newhost to ident array.\n";
        }
       }else{
        if($ip==1){
         push(@identers, "+$identname:*!$identident\@$newhost.*");
         print "Added +$identname:*!$identident\@$newhost.* to ident array.\n";
        }
        if($starhost==1){
         push(@identers, "+$identname:*!$identident\@*.$newhost");
         print "Added +$identname:*!$identident\@$newhost to ident array.\n";
        }
        if($realhost==1){
         push(@identers, "+$identname:*!$identident\@$newhost");
         print "Added +$identname:*!$identident\@$newhost to ident array.\n";
        }
       }
      }
     }else{
      print $sock "PRIVMSG $identname :Ident failed.\n";
     }
    }
   }
   if($identorig eq "NULL"){
    @info=split(":",$fl);
    if((@info[0] eq $identname)||(@info[0] eq "+$identname")){
     checkhost($identhost);
     if(@info[2] =~ /\*!$identident\@($newhost\.\*|\*\.$newhost|$newhost)/){
      $infosalt=substr(@info[1],0,2);
      if(crypt($identpass,$infosalt) eq @info[1]){
       print $sock "PRIVMSG $identname :Ident succesfull.\n";
       $foundB=0;
       foreach $niql (@identers){
        if($niql=~/^([+]*)@info[0]:\*!$identident\@($newhost\.\*|\*\.$newhost|$ne
whost)/){
         #print "DEBUG: \$identorig eq NULL: Found attempt in array\n";
         $foundB=2;
        }
       }
       if($foundB!=2){
        push(@identers,"@info[0]:@info[2]");
        #print "DEBUG: Added #@info[0]:@info[2]# to ident array!\n";
       }
      }else{
       print $sock "PRIVMSG $identname :Ident failed.\n";
      }
     }
    }
   }

  }
 } 
 $identname  = "NULL";
 $identident = "NULL";
 $identhost  = "NULL";
 $identorig  = "NULL";
 $identpass  = "NULL";
}

sub adduser(){
 $addname       = $1;
 $addident      = $2;
 $addhost       = $3;
 $addnewby      = $4;
 $addnewbyident = $5;
 $addnewbyhost  = $6;
 $masta         = 0;
 checkhost($addhost);
 $allow=0;
 foreach $nip (@identers){
  if($nip=~/^\+$addname:\*!$addident\@($newhost\.\*|\*\.$newhost|$newhost)$/){
   $allow=1;
  }
 }
 if($allow==1){
  $count = 0;
  $bs    = 0;
  $dont  = 0;  
  $dontt = 0;
  checkhost($addnewbyhost);
  if($addnewby=~/^\+/){
   $masta=1;
   $addnewby=~s/\+//;
  }
  open(TEMP,"$db");
  @file=<TEMP>;
  close(TEMP);
  foreach $nih (@file){
  if($nih=~/[+]*$addnewby:.*:\*!$addnewbyident\@($newhost\.\*|\*\.$newhost|$newho
st)$/){
    $dont=1;
    #print "DEBUG: adduser()... already in db.\n";
   }
  }
  checkhost($addnewbyhost);
  if($dont==0){
   open(TEMP,">>$db");
   if($masta==1){
    if($ip==1){
     print TEMP "+$addnewby:NULL:*!$addnewbyident\@$newhost.*\n";
     print $sock "PRIVMSG $addname :Added master \"+$addnewby:NULL:*!$addnewbyide
nt\@$newhost.*\" to db.\n";
    }
    if($starhost==1){
     print TEMP "+$addnewby:NULL:*!$addnewbyident\@*.$newhost\n";
     print $sock "PRIVMSG $addname :Added master \"+$addnewby:NULL:*!$addnewbyide
nt\@*.$newhost\" to db.\n";
    }
    if($realhost==1){
     print TEMP "+$addnewby:NULL:*!$addnewbyident\@$newhost\n";
     print $sock "PRIVMSG $addname :Added master \"+$addnewby:NULL:*!$addnewbyide
nt\@$newhost\" to db.\n";
    }
   }else{
    if($ip==1){
     print TEMP "$addnewby:NULL:*!$addnewbyident\@$newhost.*\n";
     print $sock "PRIVMSG $addname :Added \"$addnewby:NULL:*!$addnewbyident\@$new
host.*\" to db.\n";
    }
    if($starhost==1){
     print TEMP "$addnewby:NULL:*!$addnewbyident\@*.$newhost\n";
     print $sock "PRIVMSG $addname :Added \"$addnewby:NULL:*!$addnewbyident\@*.$n
ewhost\" to db.\n";
    }
    if($realhost==1){
     print TEMP "$addnewby:NULL:*!$addnewbyident\@$newhost\n";
     print $sock "PRIVMSG $addname :Added \"$addnewby:NULL:*!$addnewbyident\@$new
host\" to db.\n";
    }
   }
   close(TEMP);
  }
 }
}

sub deluser(){
 $delname  = $1;
 $delident = $2;
 $delhost  = $3;
 $delme    = $4;
 $dontdel  = 0;
 $alloww   = 0;
 $delete   = 0;
 checkhost($delhost);
 foreach $niw (@identers){
  if($niw=~/^\+$delname:\*!$delident\@($newhost\.\*|\*\.$newhost|$newhost)$/){
   $alloww=1;
  }
 }
 if($alloww==1){
  open(TEMP,"$db");
  @file=<TEMP>;
  close(TEMP);
  foreach $nim (@file){ 
   if($nim=~/^\+$delme:/){
    $dontdel=1;
    print $sock "PRIVMSG $delname :You can not delete ($delme), he is a set maste
r.\n";
   }
  }
  if($dontdel==0){
   $deletesucess=0;
   open(TEMP,"$db");
   @file=<TEMP>;
   close(TEMP);

   $tot=0;
   foreach $tmp (@file){
    $tot++;
   }

   while(@file[0] !~ /^$delme:/){
    unshift(@file, pop(@file));
    $tot--;
    if($tot == 0){ break; }
    $deletesucess=1;
   }

   if($deletesucess==1){
    shift(@file); #delete specified user from database.
    $num     = 0;
    $idented = 0;
    foreach $ammount (@identers){
     $num++;
    }
    for(;$num>0;$num--){
     if(@identers[$num]=~/^$delme:/){
      $idented=1;
     }
    }
    if($idented==1){
     while(@identers[0]!~/^$delme:/){
      unshift(@identers,pop(@identers));
     }
     shift(@identers); #delete specified user from ident array.
    }
    open(TEMP,">$db");
    print TEMP @file;
    close(TEMP);
    print $sock "PRIVMSG $delname :Deleted ($delme) sucessfully!\n";
   }else{
    print $sock "PRIVMSG $delname :Could not find ($delme) for deletion, user doe
s not exist.\n";
   }  
  }
 }
}

sub rawcommand(){
 $rawname  = lc($1);
 $rawident = lc($2);
 $rawhost  = lc($3);
 $rawreq   = lc($4);
 $rawcode  = $5;
 checkhost($rawhost);
 foreach $nif (@identers){
  if($nif=~/\+$rawname:\*!$rawident\@($newhost\.\*|\*\.$newhost|$newhost)$/){
   print $sock "PRIVMSG $rawreq :Doing ($rawcode).\n";
   print $sock "$rawcode\n";
  }
 }
}

sub joinchan(){
 checkhost($joinhost);
 foreach $nix (@identers){
  if($nix=~/\+$joinname:\*!$joinident\@($newhost\.\*|\*\.$newhost|$newhost)$/){
   print $sock "JOIN $joinchan\n";
   print $sock "PRIVMSG $joinreq :Joining $joinchan.\n";
  }
 }
}

sub partchan(){
 checkhost($parthost);
 foreach $diqliq (@identers){
  if($diqliq=~/\+$partname:\*!$partident\@($newhost\.\*|\*\.$newhost|$newhost)$/)
{
   print $sock "PART $partchan\n";
   print $sock "PRIVMSG $partreq :Parting $partchan.\n";
  }
 }
}

sub passfirst(){
 if((lc($1) eq $name)&&(lc($2) eq $ident)&&(lc($3) eq $host)){
  $pass=$4;
  &adduserfirst;
  $b=1;
 }
}

sub identfirst(){
 $name  = lc($1);
 $ident = lc($2);
 $host  = lc($3);
 if((!-e $db)||(-e $db)&&(-z $db)){
  print $sock "PRIVMSG $name :Hi $name, set a password: pass <passwd>\n";
  $a=1;
 }else{
  print $sock "PRIVMSG $name :Hi $name, get outta town, people exist.\n";
 }
} 

sub checkhost{ #Determining if we are going to use *.host, ip.* or the real hostn
ame.
 my($tryhost) = @_;
 $ip          = 0;
 $starhost    = 0;
 $realhost    = 0;
 if($tryhost=~/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.\d{1,3}/){
  $classa=$1;
  $classb=$2;
  $classc=$3;
  $newhost = $classa . "\x2e" . $classb . "\x2e" . $classc;
  $ip=1;
 }
 if($ip==0){
  if($tryhost=~/.*\.(\S+)\.(\S+)\.(\S+)/){
   $one=$1;
   $two=$2;
   $tre=$3;
   $newhost = $one . "\x2e" . $two . "\x2e" . $tre;
   $starhost=1;
  }else{
   $newhost=$tryhost;
   $realhost=1;
  }
 }
}
#EOF

