#!/usr/bin/perl
 
########## Confixx(R) 3.0 Professional ############
####### Copyright SWsoft, Inc. 2004-2005 ##########
#### http://www.sw-soft.com - info@sw-soft.com ####


#############################
#                           #
#          SMTP             #
#    MailtrafficAnalyzer    #
#  Measures Confixx Traffik #
#     from SMTP Logfile     #
#    (sendmail, postfix)    #
#                           #
#############################

$LogFile = '/var/log/mail';  # change this to the path to your logfile!
$STDOUT = '0'; # print results to stdout 
$CONFIXX = '1'; # insert results into confixx database
$HOSTNAME = ''; # insert your hostname if it differs from "/bin/hostname -f"


## einige feste Variablen
%Monate = ('Jan' => '01',
           'Feb' => '02',
           'Mar' => '03',
           'Apr' => '04',
           'May' => '05',
           'Jun' => '06',
           'Jul' => '07',
           'Aug' => '08',
           'Sep' => '09',
           'Oct' => '10',
           'Nov' => '11',
           'Dec' => '12');


$cMonth = (localtime)[4] + 1;
$cYear = (localtime)[5] + 1900;
## /einige feste Variablen

if(!$STDOUT && !$CONFIXX){
  die("You need to set at least one type of output.\n");
}

unless($HOSTNAME ne ""){
  $HOSTNAME = `/bin/hostname -f`;
  chop $HOSTNAME;
}
$HOSTNAME =~ tr/A-Z/a-z/;

&loadConfFile;
use DBI;
$dbh = DBI->connect($db_address, $dbUser, $dbPw)
  or die( &ltext('db_connect', '#2001', "$DBI::errstr") );
&Get_Domains;
$GrepAusgabe = &GrepLastLine;
#$GrepAusgabe = 0;
$LastLine = &ParseLogFile;

if ( $LastLine ne "" ) {
  &Sortieren;
  ## choose which output to use
  $STDOUT && &Ausgabe_STDOUT;
  $CONFIXX && &Ausgabe_CONFIXX;
  ##// choose which output to use
  &WriteLastLine($LastLine);
}

$dbh->disconnect;


## SUBS
sub ParseLogFile {
  my ($count, $nextLine, $relay, $Month, $Day, $ID, $Domain, $SizeMails, $LastLine, $domain, $user, $mailer);
  unless (open(LINIE, "$LogFile")) {
    if (!(-e "$LogFile")) {
      die ("File $LogFile  does not exist.\n");
    }
    elsif (!(-r "$LogFile")) {
      die ("You are not allowed to read $LogFile.\n");
    }
    else{
      die ("$LogFile cannot be opened\n");
    }
  }
  if ( $GrepAusgabe != 0 ) {
    for ($count=0; $count <= $GrepAusgabe; $count++) {
      $Line = <LINIE>;
    }
  }
  $nextLine = <LINIE>;
  if ( $nextLine ne "" ) {
    while ( $nextLine ne "" ) {
      if ($nextLine =~ /^(\w\w\w)\s+(\d\d?).+: ([\d|\w]+): from=(<?\S+\@(\S*\.([a-z]|[A-Z]){1,4})>?|<>|[\d|\w]+), size=(\d+)[\s,]/ ) {
        $Month = $1;
        $Day = $2;
        $ID = $3;
        if ( ( $5 eq "" ) && ( $6 eq "" ) ) {
          $Domain = $4
        }
        else{
          $Domain = $5;
        }
        $SizeMails = $7;
        #$From{"$Month$Day"}{$ID}[0] = $SizeMails;
        #$From{"$Month$Day"}{$ID}[1] = $Domain;
        $ID{$ID}[0] = $SizeMails;
        $ID{$ID}[1] = $Domain;
        $ID{$ID}[1] =~ tr/A-Z/a-z/;
        $ID{$ID}[2] = "$Month$Day";
        $LastLine = "$Month.*$Day.*$ID.*$Domain.*$SizeMails";
      }
      elsif ($nextLine =~ /^(\w\w\w)\s+(\d\d?)\s+(\d\d:\d\d:\d\d).+: ([\d|\w]+): to=<?(\S+)\@(\S*\.([a-z]|[A-Z]){1,4})>?.+(mailer|relay)=(\S+),.+/ ) { 
        $Month = $1;
        $Day = $2;
        $Time = $3;
        $ID = $4;
        $user = $5;
        $user =~ tr/A-Z/a-z/;
        $Domain = $6;
        $domain = $Domain;
        $domain =~ tr/A-Z/a-z/;
        $mailer = $9;
        if ( $mailer eq "local" ) {
          if($user =~ /^$user_prefix\d+(p\d+)?$/ && $domain eq $HOSTNAME){
            $domain = $user; 
          }
          $Local{$ID}{$domain} += 1;
        }
        elsif ( $LocalDomains{$domain} ) {
          $Forward{$ID}{$domain} += 1;
        }
        else{
          $SMTP{$ID} += 1;
        }
        $LastLine = "$Month.*$Day.*$Time.*$ID.*$Domain.*$mailer";
      }
#     elsif ( $nextLine =~ /(sendmail|postfix)/ ) {
#       print "$nextLine\n";
#     }
      $nextLine = <LINIE>;
    }
  }
  close("LINE");
  return($LastLine);
}


sub Ausgabe_STDOUT {
  my (%total);
  print"\n###### SENDMAIL TRAFFIK ####### \n";
  print "\nEmail Versand via SMTP \n";
  print "---------------------- \n";
  foreach $holder (keys(%TraffikFrom)) {
    $date = $holder;
    $date =~ s/:/\./g;
    print "\n$date\n";
    foreach $user (keys(%{$TraffikFrom{$holder}})) {
      $Traffik = (int ( ( $TraffikFrom{$holder}{$user} / 1024 ) * 100 ) ) / 100;
      if($Kunden{$user}){
        print "$Kunden{$user} ($user) ($Anbieter{$Kunden{$user}}) : $Traffik KB : $date\n";
        if($Kunden{$user} =~ /^$user_prefix\d+/){
          $total{$Kunden{$user}} += $Traffik; 
        }
      }
      else{
        print "$user () ($Anbieter{$user}) : $Traffik KB : $date\n";
        if($user =~ /^$user_prefix\d+/){
          $total{$user} += $Traffik;
        }
      }
    }
  }
  print "\nEmail Empfang via SMTP \n";
  print "---------------------- \n";
  foreach $holder (keys(%TraffikTo)) {
    $date = $holder;
    $date =~ s/:/\./g;
    print "\n$date\n";
    foreach $user (keys(%{$TraffikTo{$holder}})) {
      $Traffik = (int ( ( $TraffikTo{$holder}{$user} / 1024 ) * 100 ) ) / 100;
      if($Kunden{$user}){
        print "$Kunden{$user} ($user) ($Anbieter{$Kunden{$user}}) : $Traffik KB : $date\n";
        if($Kunden{$user} =~ /^$user_prefix\d+/){
          $total{$Kunden{$user}} += $Traffik; 
        }
      }
      else{
        print "$user () ($Anbieter{$user}) : $Traffik KB : $date\n";
        if($user =~ /^$user_prefix\d+/){
          $total{$user} += $Traffik;
        }
      }
    }
  }
  print "\nTotal \n";
  print "----- \n";
  my @users = sort { $total{$a} <=> $total{$b} } keys %total;
  foreach $user (@users){
    print "$user: $total{$user} KB\n";
  }
}


sub Ausgabe_CONFIXX {
  my (@nDate, $holder, $user, $Traffik);
  foreach $holder (keys(%Traffik)) {
    @nDate = split(/:/, $holder);
    foreach $user (keys(%{$Traffik{$holder}})) {
      if ( $user =~ /^$user_prefix\d+$/ ) {
        $Traffik = (int ( ( $Traffik{$holder}{$user} / 1024 ) * 100 ) ) / 100;
        &Update_MySQL ($user, $Anbieter{$user}, $nDate[0], $nDate[1], $nDate[2], $Traffik);
      }
    }  
  }
}


sub Get_Domains {
  my (@row, $sth);
  $sth = $dbh->prepare("SELECT domain,kunde,anbieter FROM domains WHERE richtigedomain=0 OR richtigedomain=1");
  $sth->execute;
  my $i=0;
  while (@row = $sth->fetchrow_array){
    $LocalDomains{$row[0]} = 1;
    $Kunden{$row[0]} = $row[1];
    $Anbieter{$row[1]} = $row[2];
  }
}


sub Update_MySQL {
  my ($kunde, $anbieter, $tag, $monat, $jahr, $traffik) = @_;
  my $sth = $dbh->prepare("SELECT email FROM transfer WHERE kunde='$kunde' AND tag=$tag AND monat=$monat AND jahr=$jahr");
  $sth->execute;
  my $exists = $sth->rows;
  if ($exists) {
    $dbh->do("UPDATE transfer SET email=email+$traffik WHERE kunde='$kunde' AND tag=$tag AND monat=$monat AND jahr=$jahr");
  }
  else{
    $dbh->do("INSERT INTO transfer (kunde, anbieter, tag, monat, jahr, email) VALUES ('$kunde', '$anbieter', $tag, $monat, $jahr, $traffik)");
  }
}


sub WriteLastLine {
  my ($writeline) = @_;
  $dbh->do("UPDATE grep SET pattern='$writeline' WHERE type='smtp'");
}


sub GrepLastLine {
  my $sth = $dbh->prepare("SELECT pattern FROM grep WHERE type='smtp'");
  $sth->execute;
  my $rows = $sth->rows;
  my $pattern = '###NEW###';
  if($rows){
    $pattern = $sth->fetchrow;
    chop($pattern);
  }
  else{
    $dbh->do("INSERT INTO grep (pattern,type) VALUES ('###NEW###','smtp')");
  }
  $sth->finish;
  $pattern =~ s/\[/\\\[/g;
  $pattern =~ s/\]/\\\]/g;
  my $grepAusgabe = `$bin_grep -na '$pattern' $LogFile`;
  if($grepAusgabe =~ /^(\d+):/){
    $grepAusgabe = $1 -1;
  }
  else{
    $grepAusgabe = '0';
  }
  return($grepAusgabe);
}


sub Sortieren {
  my ($Domain, $Traffik, $ID, $remote, $Wieviele, $remote, $nMonth, $nDay);
  foreach $ID (keys(%ID)) {
    $ID{$ID}[2] =~ /(\w\w\w)(\d\d?)/;
    $nMonth = $Monate{$1};
    $nDay = $2;
    if ( ( $cMonth < 6 ) && ( $nMonth > 6 ) ) {
      $nYear = $cYear - 1;
    }
    else {
      $nYear = $cYear;
    }
    $nDate = "$nDay:$nMonth:$nYear";
    $remote = 0;
    $Wieviele = 0;
    if ( $SMTP{$ID} ) {
      $remote = 1;
      $Traffik = (1 + $SMTP{$ID}) * $ID{$ID}[0];
      $TraffikFrom{$nDate}{$ID{$ID}[1]} += $Traffik;
      if ( $Kunden{$ID{$ID}[1]} ) {
        $Traffik{$nDate}{$Kunden{$ID{$ID}[1]}} += $Traffik;
      }
      else {
        $Traffik{$nDate}{$ID{$ID}[1]} += $Traffik;
      }
    }
    else {
      foreach $Domain (keys(%{$Local{$ID}})) {
        $Wieviele += $Local{$ID}{$Domain};
      }
      foreach $Domain (keys(%{$Forward{$ID}})) {
        $Wieviele += $Forward{$ID}{$Domain};
      }
    }
    foreach $Domain (keys(%{$Local{$ID}})) {
      if ( $Local{$ID}{$Domain} ne "" ) {
        if ( $remote ) {
          $TraffikFrom{$nDate}{$ID{$ID}[1]} += $Local{$ID}{$Domain} * $ID{$ID}[0];
        }
        else {
          $Traffik = ( $Local{$ID}{$Domain}  / $Wieviele )  * $ID{$ID}[0];
          $TraffikTo{$nDate}{$Domain} += $Traffik;
          if ( $Kunden{$Domain} ) {
            $Traffik{$nDate}{$Kunden{$Domain}} += $Traffik;
          }
          else {
            $Traffik{$nDate}{$Domain} += $Traffik;
          }
        }
      }
    }
    foreach $Domain (keys(%{$Forward{$ID}})) {
      if ( $Forward{$ID}{$Domain} ne "" ) {
        if ( $remote ) {
          $TraffikFrom{$nDate}{$ID{$ID}[1]} += $Forward{$ID}{$Domain} * $ID{$ID}[0];
        }
        else {
          $Traffik = ( ( $Forward{$ID}{$Domain}  / $Wieviele ) + $Forward{$ID}{$Domain} )  * $ID{$ID}[0];
          $TraffikTo{$nDate}{$Domain} += $Traffik;
          if ( $Kunden{$Domain} ) {
            $Traffik{$nDate}{$Kunden{$Domain}} += $Traffik;
          }
          else {
            $Traffik{$nDate}{$Domain} += $Traffik;
          }
        }
      }
    } 
  }
}


sub loadConfFile{
  my ($file, $base);
  if(-T "/root/confixx/confixx_main.conf"){
    $file = "/root/confixx/confixx_main.conf";
  }
  else{
   $0 = $^X unless ($^X =~ m%(^|[/\\])(perl)|(perl.exe)$%i);
   ($base) = $0 =~ m%^(.*)[/\\]%;
   $base ||= ".";
   $file = "$base/confixx_main.conf";
   unless(-T $file){
     die("Couldn't find confixx_main.conf");
   }
 }
 do $file;
}


sub ltext {
  my $text_name = shift;
  if (!%lang_text) {
    my $langFile = "$confixx_htmlDir/languages/$language/scripts.local";
    do $langFile;
  }
  if (!defined($lang_text{$text_name})) {
    return "Sorry, text $text_name not found!";
  }
  else {
    my @VAR = @_;
    my $text = $lang_text{$text_name};
    $text =~ s/\$VAR\[(\d+)\]/$VAR[$1]/g;
    if ($text) {
      return $text;
    }
    else {
      return "Sorry, localizing text $text_name failed!";
    }
  }
}
## /SUBS
