#!/usr/bin/perl # ATSlog version 2.1.1 build 664 www.atslog.com # Copyright (C) 2003 Denis CyxoB www.yamiyam.dp.ua # use Sys::Syslog qw(:DEFAULT setlogsock);# logging error messages to syslog use DBI;# DataBase common class use POSIX qw(locale_h); # For language settings use POSIX 'setsid'; # used in daemonize $prefix="@prefix@"; $config_file="@sysconfdir@/atslog.conf"; if(@ARGV[0] eq "--fastwrite"){ $fastwrite=1; } else{ $fastwrite=0; } open(IN,$config_file) || die print("Can't open config file $config_file.\n"); while() { next if /^#/; chomp; ($key,$val) = ( /([^=]+)=(.*)/ ); $key = lc($key); $vars{$key} = $val; } close(IN); $langfileprefix=$vars{sharedir}."/".$vars{langdir}."/"; $langfile=$langfileprefix.setlocale(LC_CTYPE); if ( ! -f $langfile){ $langfile=$langfileprefix."en_US"; } open(LN,$langfile) || die print("Can't open language file $langfile.\n"); while() { next if /^#/; chomp; ($key,$val) = ( /([^=]+)=\"(.*)\"/ ); $key = lc($key); $vars{$key} = $val; } close(LN); # Закоментрированное оставляю для отладки #$stringnumber=0; $callsCount=0; $toexit=0; # Разберёмся с уровнем для системного журнала if($vars{syslogfacility}){ $vars{syslogfacility} =~ /(.*)\.(.*)/; $sFas1 = $1; $sFas2 = $2; } # Опишем основные функции # Функция выводит сообщения об ошибках в системный журнал и в STDERR sub echoerrors(){ if($vars{syslogfacility}){ syslog("$sFas2", "$ERRORMESSAGE"); } warn ("$ERRORMESSAGE\n"); $toexit=1; } # ampto24 with russian and english language support sub AmPmTo24(){ my $return24=$_[0]; # last choice, if no symbols found my $hour=$_[0]; my $AmPm=$_[1]; if ($AmPm eq 'PM' || $AmPm eq '▐▐'){ if($hour < 12){ $return24=$hour+12; }elsif($hour == 12){ $return24=12; } }elsif($AmPm eq 'AM' || $AmPm eq '└▐'){ if($hour < 12){ $return24=$hour; }elsif($hour == 12){ $return24=0; } } return $return24; } # Let`s go! if($vars{syslogfacility}){ setlogsock('unix'); # syslogd socket type openlog("atslogdb", 'pid, ndelay, cons', "$sFas1");#Откроем сокет на syslogd } if($vars{sqltype} =~ /PostgreSQL/i){ $sqltype=Pg; }else{ $sqltype=mysql; } $host=""; if($vars{sqlhost} ne "localhost"){ $host = ";host=".$vars{sqlhost}; } open(DATA,"$vars{libdir}/modules.lst") || die print("Can open module list"); $libname="$vars{libdir}/".getLibName($vars{model}); close(DATA); # load library if ( (-e $libname) && (-r $libname) ) { require $libname; }else{ $ERRORMESSAGE="$vars{msg31}"; echoerrors(); if($vars{syslogfacility}){ closelog(); } exit $toexit; } if(!connecttodb()){ $toexit=1; exit $toexit; } # parsing calls if(!$fastwrite){ # pass stdin to the library open(PBX_DATA,"-"); if( connecttodb() ){ parsecurcalls(); } } else { &daemonize; $pid = open(PBX_DATA, "-|"); if ($pid) { # parent if($vars{debug} =~ /yes/i){ open(STDOUT, ">>$vars{logdir}/$vars{notwritelog}") || die "Can't redirect stdout"; select(STDOUT); $| = 1; # make unbuffered } if( connecttodb() ){ parsecurcalls(); if(!close(PBX_DATA)) { # warn "atslogd exited $?" $ERRORMESSAGE="\n$vars{atslogd} error code: $?"; echoerrors(); }; } } else { # child if($vars{port} !~ /r?tcp\:/i){ $vars{port}='/dev/'.$vars{port}; } # correcting port variable exec("$vars{bindir}/$vars{atslogd} $vars{atslogd_flags} -P $vars{pidfile} -o -f $vars{stopbits} -p $vars{parity} -c $vars{charsize} -s $vars{speed} -D $vars{logdir} -F $vars{callslogfile} -L $vars{logdir}/$vars{startlogfile} $vars{port}") || die "can't exec program: $!"; # NOTREACHED } } if($callsCount == 0){ $ERRORMESSAGE="\n$vars{msg32}"; echoerrors(); } $dbh->disconnect; if($vars{syslogfacility}){ closelog(); } exit $toexit; sub WriteRecord{ my ($time_of_call, $fwd, $int, $co, $way, $number, $duration) = @_ ; my $query = "INSERT INTO calls ( timeofcall, forwarded, internally, co, way, number, duration ) VALUES ( ?, ?, ?, ?, ?, ?, ?)"; my $sth = $dbh->prepare($query); $sth->execute($time_of_call, $fwd, $int, $co, $way, $number, $duration); if($sth->err){ # try to reconnect and send the query again $ERRORMESSAGE="\nError on sth->execute: ".$sth->errstr().", reconnecting\n"; echoerrors(); if(connecttodb()){ my $sth = $dbh->prepare($query); $sth->execute($time_of_call, $fwd, $int, $co, $way, $number, $duration); if(!$sth->err) { # success return 0; } } # error on SQL query. We need to record sql server message to # the syslog and failed record to the special file open(SQLFAIL,">>$vars{logdir}/sqlfail.log"); $ERRORMESSAGE="\nError on sth->execute: ".$sth->errstr()."\n"; print SQLFAIL $str; echoerrors(); close(SQLFAIL); # we dont want to keep this file open return -1; } return 0; } sub connecttodb { if ($dbh = DBI->connect("dbi:$sqltype:dbname=$vars{sqldatabase}$host",$vars{sqlmasteruser},$vars{sqlmaspasswd},{PrintError=>0})){ if($vars{sqltype} =~ /MySQL/i){ $dbh->{mysql_auto_reconnect} = 1; } return 1; }else{ $ERRORMESSAGE="$vars{msg33}:".$DBI::errstr; echoerrors(); return 0; } } sub getLibName{ my $model_name = $_[0]; while ($string =) { my @libarray=split(/:/,$string); my $libname=@libarray[0]; my @models=split(/,/,@libarray[1]); if (grep (/^${model_name}$/i, @models)) {return $libname;} } return 0; } sub daemonize { chdir '/' or die "Can't chdir to /: $!"; open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!"; defined(my $pid = fork) or die "Can't fork: $!"; exit if $pid; setsid or die "Can't start a new session: $!"; open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; }