#!/bin/bash
# Keep this DOS line (two UNIX lines) unchanged
# Copyright (c) 2011 by Emin Gabrielyan of switzernet.com
# Created and modified on 2011-02-19 by Emin, on 2011-02-21 by Emin,
# on 2011-02-22 by Emin, on 2011-02-23 by Emin
ver="110223/ba10"                                                        #
                                                                         #
                                                                         #
                                                                         #
sync="/home/var/log/radius"                                              #
work="/home/var/log/radius/work"                                         #
                                                                         #
                                                                         #
                                                                         #
running=`ps -o pid,comm,cmd -C calls.sh | grep "$work" | wc -l`          #
if [ $running -ge 1 ]                                                    #
then                                                                     #
  exit                                                                   #
fi                                                                       #
                                                                         #
cd $work                                                                 #
diff -q Downloads/calls.sh . > /dev/null || exec cp Downloads/calls.sh . #
                                                                         #
                                                                         #
                                                                         #
cd $sync                                                                 #
                                                                         #
runlog="`ls *,*,*,*,running,radius.log 2>/dev/null`"                     #
                                                                         #
if [ -z "$runlog" ]                                                      #
then                                                                     #
  exit                                                                   #
fi                                                                       #
                                                                         #
pref=`echo $runlog | cut -d, -f1-4`                                      #
                                                                         #
cdr="$pref,running,calls.csv"                                            #
                                                                         #
if [ -f "$cdr" ]                                                         #
then                                                                     #
  exit                                                                   #
fi                                                                       #
                                                                         #
                                                                         #
                                                                         #
opt="-c +0 --follow=name --sleep-interval=2 --max-unchanged-stats=10"    #
                                                                         #
tail $opt $runlog | perl -e '
%mm=("Jan",1,"Feb",2,"Mar",3,"Apr",4,"May",5,"Jun",6,"Jul",7,"Aug",8,"Sep",9,"Oct",10,"Nov",11,"Dec",12);
sub z{
  ($a,$node,$call,$stop)=("",0,0,0);
}
&z;
$rec=0;
$recout=600;
$fields="%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n";
sub headers{
  printf $fields,
    "h323",
    "date",
    "Route E164",
    "sec",
    "Vendor",
    "cost",
    "n/Route/Vendor",
    "rec",
    "nas",
    "usr",
    "dst",
    "cli",
    "orig",
    "zone",
    "code",
    "dur",
    "ip",
}
&headers;
sub dump{
  for my $i (keys %rec)
  {
    if($rec{$i}<$rec-$recout)
    {
      printf $fields,
        $i,$date{$i},$e164{$i},$sec{$i},$vendor{$i},$cost{$i},$leg{$i},$rec{$i},
        $nas{$i},$usr{$i},$dst{$i},$cli{$i},$orig{$i},$zone{$i},$code{$i},$dur{$i},$ip{$i};
      delete $date{$i};
      delete $e164{$i};
      delete $sec{$i};
      delete $vendor{$i};
      delete $cost{$i};
      delete $leg{$i};
      delete $rec{$i};
      delete $nas{$i};
      delete $usr{$i};
      delete $dst{$i};
      delete $cli{$i};
      delete $orig{$i};
      delete $zone{$i};
      delete $code{$i};
      delete $dur{$i};
      delete $ip{$i};
    }
  }
}
sub cache{
  $nas{$h323}.="<".$nas;
  $usr{$h323}.="<".$usr;
  $dst{$h323}.="<".$dst;
  $cli{$h323}.="<".$cli;
  $orig{$h323}.=$orig;
  $date{$h323}=sprintf("%d-%02d-%02d %s",$yyyy,$mm{$mmm},$dd,$time) if($zone eq "GMT" || !$date{$h323});
  $zone{$h323}.="<".$zone;
  $code{$h323}.="<".$code;
  $dur{$h323}.="<".$dur;
  $ip{$h323}.="<".$ip;
  if(defined $sec)
  {
    $e164{$h323}.="<".$e164;
    $sec{$h323}=$sec;
  }
  if(defined $cost)
  {
    $vendor{$h323}.="<".$vindex." ".$vname;
    $cost{$h323}+=$cost;
  }
  $leg{$h323}.=$e164?($vindex?"V":"R"):"n";
  $rec{$h323}=++$rec;
}
sub debug{
  print "\n[".(($e164)?"V":"C")."]\n";
  print "nas=$nas\n";
  print "usr=$usr\n";
  print "dst=$dst\n";
  print "cli=$cli\n";
  print "orig=$orig\n";
  print "date=$yyyy-$mmm-$dd $time\n";
  print "code=$code\n";
  print "h323=$h323\n";
  print "dur=$dur\n";
  print "ip=$ip\n";
  print "e164=$e164\n";
  print "sec=$sec\n";
  print "vindex=$vindex\n";
  print "vname=$vname\n";
  print "cost=$cost\n";
  print $a;
}
sub retrieve{
  ($nas,$usr,$dst,$cli,$time,$zone,$mmm,$dd,$yyyy,$dur,$ip,$e164,$sec,$vindex,$vname,$cost)=("");
  $nas=$1 if($a=~/^NAS-IP-Address *= *'\''(.*)'\''/m);
  $usr=$1 if($a=~/^User-Name *= *'\''(.*)'\''/m);
  $dst=$1 if($a=~/^Called-Station-Id *= *'\''(.*)'\''/m);
  $cli=$1 if($a=~/^Calling-Station-Id *= *'\''(.*)'\''/m);
  $orig=$1 if($a=~/^h323-call-origin *= *'\''(.).*'\''/m);
  ($time,$zone,$mmm,$dd,$yyyy)=($1,$2,$3,$4,$5) if($a=~/^h323-connect-time *= *'\''[.]?([0-9:.]*) +([^ ]+) +[^ ]+ +([^ ]+) +([0-9]+) +([0-9]+)'\''/m);
  $code=$1 if($a=~/^h323-disconnect-cause *= *'\''(.*)'\''/m);
  $h323=$1 if($a=~/^h323-conf-id *= *'\''(.*)'\''/m);
  $dur=$1 if($a=~/^Acct-Session-Time *= *'\''(.*)'\''/m);
  $ip=$1 if($a=~/^h323-remote-address *= *'\''(.*)'\''/m);
  ($e164,$sec)=($1,$2) if($a=~/: Call to '\''([^'\'']*)'\'' with duration ([0-9]+) seconds /);
  ($vindex,$vname,$cost)=($1,$2,$3) if($a=~/: Charging vendor ([0-9]*) '\''(.*)'\'' ([0-9.]*)/);
}
sub flush{
  if($node&&$call&&$stop){
    &retrieve;
    &debug if(0);
    &cache;
    &dump;
  }
  &z;
}
while(<>){
  &flush if(/^$/);
  $node=1 if(/^NAS-IP-Address/);
  if($node)
  {
    $a.=$_ if(/^(NAS-IP-Address|User-Name|Called-Station-Id|Calling-Station-Id|h323-call-origin|h323-connect-time|h323-disconnect-cause|h323-conf-id|Acct-Session-Time|h323-remote-address)|:( Call to | Charging vendor )/);
    $call=1 if(/^h323-conf-id *= *'\''.{35}'\''/);
    $stop=1 if(/^Acct-Status-Type.*Stop/);
  }
}
&flush;
$rec+=$recout+1;
&dump;
print "EOF\n";
' > $cdr                                                                 #
echo "Call recreator version $ver" >> $cdr                               #
                                                                         #
                                                                         #
                                                                         #
cdrclose="$pref,rotated,calls.csv"                                       #
                                                                         #
mv "$cdr" "$cdrclose"                                                    #
                                                                         #
                                                                         #
logs=`ls *,*,*,*,rotated,radius.log 2>/dev/null | wc -l`                 #
unzipped=25                                                              #
if [ $logs -gt $unzipped ]                                               #
then                                                                     #
  tozip=$((logs-unzipped))                                               #
  ls *,*,*,*,rotated,radius.log | head -$tozip | while read f            #
  do                                                                     #
    gzip $f                                                              #
  done                                                                   #
fi                                                                       #
                                                                         #
                                                                         #
ncsv=`ls *,*,*,*,rotated,calls.csv 2>/dev/null | wc -l`                  #
unzipped=50                                                              #
if [ $ncsv -gt $unzipped ]                                               #
then                                                                     #
  tozip=$((ncsv-unzipped))                                               #
  ls *,*,*,*,rotated,calls.csv | head -$tozip | while read f             #
  do                                                                     #
    gzip $f                                                              #
  done                                                                   #
fi                                                                       #
                                                                         #
                                                                         #
                                                                         #
                                                                         #