#
# MailScanner - SMTP E-Mail Virus Scanner
# Copyright (C) 2002 Julian Field
#
# $Id: Log.pm 3724 2006-09-23 15:30:45Z sysjkf $
#
# This program 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, or
# (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# The author, Julian Field, can be contacted by email at
# Jules@JulianField.net
# or by paper mail at
# Julian Field
# Dept of Electronics & Computer Science
# University of Southampton
# Southampton
# SO17 1BJ
# United Kingdom
#
###########################################################
# Syslog library calls
###########################################################
package MailScanner::Log;
use strict;
use Sys::Syslog;
use Carp;
use vars qw($LogType $Banner);
$LogType |= 'syslog';
sub Configure {
my($banner,$type) = @_;
$Banner = $banner?$banner:undef;
$LogType = $type?$type:'syslog';
}
sub Start {
my($name, $facility) = @_;
# These are needed later if we need to restart the logging connection
# due to a SIGPIPE.
$MailScanner::Log::name = $name;
$MailScanner::Log::facility = $facility;
if ($LogType eq 'syslog') {
# Do this in an eval so it can fail quietly if setlogsock
# is not supported in the installed version of Sys::Syslog
#eval { $SIG{'__DIE__'} = 'IGNORE';
# Sys::Syslog::setlogsock('unix');
# }; # Doesn't need syslogd -r
#$SIG{'__DIE__'} = 'DEFAULT';
# This was too simple and didn't work on some Solaris and IRIX systems
#eval { Sys::Syslog::setlogsock('unix'); }; # This may fail!
eval {
if ($^O =~ /solaris|sunos|irix/i) {
Sys::Syslog::setlogsock('udp');
} else {
Sys::Syslog::setlogsock('unix');
}
};
eval { Sys::Syslog::openlog($name, 'pid, nowait', $facility); };
}
if (defined $Banner) {
InfoLog($Banner);
}
}
sub Stop {
Sys::Syslog::closelog() if $LogType eq 'syslog';
}
sub DieLog {
# closelog changes $! in @_
my(@x) = @_;
my $logmessage = sprintf shift @x, @x;
LogText($logmessage, 'err');
Sys::Syslog::closelog() if $LogType eq 'syslog';
croak "$logmessage";
}
sub WarnLog {
my(@x) = @_;
my $logmessage = sprintf shift @x, @x;
LogText($logmessage, 'warning');
carp $logmessage if $LogType eq 'stderr';
}
sub NoticeLog {
my(@x) = @_;
my $logmessage = sprintf shift @x, @x;
LogText($logmessage, 'notice');
print STDERR "$logmessage\n" if $LogType eq 'stderr';
}
sub InfoLog {
my(@x) = @_;
my $logmessage = sprintf shift @x, @x;
LogText($logmessage, 'info');
print STDERR "$logmessage\n" if $LogType eq 'stderr';
}
sub DebugLog {
my(@x) = @_;
if (MailScanner::Config::Value('debug')) {
my $logmessage = sprintf shift @x, @x;
LogText($logmessage, 'debug');
print STDERR "$logmessage\n" if $LogType eq 'stderr';
}
}
sub LogText {
my($logmessage, $level) = @_;
return unless $LogType eq 'syslog';
#my $old = $SIG{'PIPE'};
#$SIG{'PIPE'} = sub { $MailScanner::Log::SIGPIPE_RECEIVED++; };
# Force use of 8-bit characters, UTF16 breaks syslog badly.
use bytes;
foreach(split /\n/,$logmessage) {
s/%/%%/g;
eval { Sys::Syslog::syslog($level, $_) if $_ ne "" };
## If we got a SIGPIPE then something broke in the logging socket.
## So try to open a new one and use that from now on instead.
#if ($MailScanner::Log::SIGPIPE_RECEIVED) {
# # SIGPIPE received while trying to log. This probably means they
# # are using syslog-ng and it was hupped by a log-rolling script.
# # Close and re-open our syslog connection and have another go.
# Sys::Syslog::closelog();
# eval { Sys::Syslog::setlogsock('unix'); }; # This may fail!
# Sys::Syslog::openlog($MailScanner::Log::name, 'pid, nowait',
# $MailScanner::Log::facility);
# #Sys::Syslog::syslog($level, "SIGPIPE received - trying new log socket");
# Sys::Syslog::syslog($level, $_);
# # Whinge is logging is still broken
# warn "MailScanner logging failure, multiple SIGPIPEs received"
# if $MailScanner::Log::SIGPIPE_RECEIVED > 1;
# $MailScanner::Log::SIGPIPE_RECEIVED = 0;
#}
}
no bytes;
# Reset old SIGPIPE handler
#$SIG{'PIPE'} = $old if defined($old);
}
1;
syntax highlighted by Code2HTML, v. 0.9.1