Blame Syslog.pm

Packit 972a07
package Sys::Syslog;
Packit 972a07
use strict;
Packit 972a07
use warnings;
Packit 972a07
use warnings::register;
Packit 972a07
use Carp;
Packit 972a07
use Config;
Packit 972a07
use Exporter        ();
Packit 972a07
use File::Basename;
Packit 972a07
use POSIX           qw< strftime setlocale LC_TIME >;
Packit 972a07
use Socket          qw< :all >;
Packit 972a07
require 5.005;
Packit 972a07
Packit 972a07
Packit 972a07
*import = \&Exporter::import;
Packit 972a07
Packit 972a07
Packit 972a07
{   no strict 'vars';
Packit 972a07
    $VERSION = '0.35';
Packit 972a07
Packit 972a07
    %EXPORT_TAGS = (
Packit 972a07
        standard => [qw(openlog syslog closelog setlogmask)],
Packit 972a07
        extended => [qw(setlogsock)],
Packit 972a07
        macros => [
Packit 972a07
            # levels
Packit 972a07
            qw(
Packit 972a07
                LOG_ALERT LOG_CRIT LOG_DEBUG LOG_EMERG LOG_ERR 
Packit 972a07
                LOG_INFO LOG_NOTICE LOG_WARNING
Packit 972a07
            ), 
Packit 972a07
Packit 972a07
            # standard facilities
Packit 972a07
            qw(
Packit 972a07
                LOG_AUTH LOG_AUTHPRIV LOG_CRON LOG_DAEMON LOG_FTP LOG_KERN
Packit 972a07
                LOG_LOCAL0 LOG_LOCAL1 LOG_LOCAL2 LOG_LOCAL3 LOG_LOCAL4
Packit 972a07
                LOG_LOCAL5 LOG_LOCAL6 LOG_LOCAL7 LOG_LPR LOG_MAIL LOG_NEWS
Packit 972a07
                LOG_SYSLOG LOG_USER LOG_UUCP
Packit 972a07
            ),
Packit 972a07
            # Mac OS X specific facilities
Packit 972a07
            qw( LOG_INSTALL LOG_LAUNCHD LOG_NETINFO LOG_RAS LOG_REMOTEAUTH ),
Packit 972a07
            # modern BSD specific facilities
Packit 972a07
            qw( LOG_CONSOLE LOG_NTP LOG_SECURITY ),
Packit 972a07
            # IRIX specific facilities
Packit 972a07
            qw( LOG_AUDIT LOG_LFMT ),
Packit 972a07
Packit 972a07
            # options
Packit 972a07
            qw(
Packit 972a07
                LOG_CONS LOG_PID LOG_NDELAY LOG_NOWAIT LOG_ODELAY LOG_PERROR 
Packit 972a07
            ), 
Packit 972a07
Packit 972a07
            # others macros
Packit 972a07
            qw(
Packit 972a07
                LOG_FACMASK LOG_NFACILITIES LOG_PRIMASK 
Packit 972a07
                LOG_MASK LOG_UPTO
Packit 972a07
            ), 
Packit 972a07
        ],
Packit 972a07
    );
Packit 972a07
Packit 972a07
    @EXPORT = (
Packit 972a07
        @{$EXPORT_TAGS{standard}}, 
Packit 972a07
    );
Packit 972a07
Packit 972a07
    @EXPORT_OK = (
Packit 972a07
        @{$EXPORT_TAGS{extended}}, 
Packit 972a07
        @{$EXPORT_TAGS{macros}}, 
Packit 972a07
    );
Packit 972a07
Packit 972a07
    eval {
Packit 972a07
        require XSLoader;
Packit 972a07
        XSLoader::load('Sys::Syslog', $VERSION);
Packit 972a07
        1
Packit 972a07
    } or do {
Packit 972a07
        require DynaLoader;
Packit 972a07
        push @ISA, 'DynaLoader';
Packit 972a07
        bootstrap Sys::Syslog $VERSION;
Packit 972a07
    };
Packit 972a07
}
Packit 972a07
Packit 972a07
Packit 972a07
#
Packit 972a07
# Constants
Packit 972a07
#
Packit 972a07
use constant HAVE_GETPROTOBYNAME     => $Config::Config{d_getpbyname};
Packit 972a07
use constant HAVE_GETPROTOBYNUMBER   => $Config::Config{d_getpbynumber};
Packit 972a07
use constant HAVE_SETLOCALE          => $Config::Config{d_setlocale};
Packit 972a07
use constant HAVE_IPPROTO_TCP        => defined &Socket::IPPROTO_TCP ? 1 : 0;
Packit 972a07
use constant HAVE_IPPROTO_UDP        => defined &Socket::IPPROTO_UDP ? 1 : 0;
Packit 972a07
use constant HAVE_TCP_NODELAY        => defined &Socket::TCP_NODELAY ? 1 : 0;
Packit 972a07
Packit 972a07
use constant SOCKET_IPPROTO_TCP =>
Packit 972a07
      HAVE_IPPROTO_TCP      ? Socket::IPPROTO_TCP
Packit 972a07
    : HAVE_GETPROTOBYNAME   ? scalar getprotobyname("tcp")
Packit 972a07
    : 6;
Packit 972a07
Packit 972a07
use constant SOCKET_IPPROTO_UDP =>
Packit 972a07
      HAVE_IPPROTO_UDP      ? Socket::IPPROTO_UDP
Packit 972a07
    : HAVE_GETPROTOBYNAME   ? scalar getprotobyname("udp")
Packit 972a07
    : 17;
Packit 972a07
Packit 972a07
use constant SOCKET_TCP_NODELAY => HAVE_TCP_NODELAY ? Socket::TCP_NODELAY : 1;
Packit 972a07
Packit 972a07
Packit 972a07
# 
Packit 972a07
# Public variables
Packit 972a07
# 
Packit 972a07
use vars qw($host);             # host to send syslog messages to (see notes at end)
Packit 972a07
Packit 972a07
#
Packit 972a07
# Prototypes
Packit 972a07
#
Packit 972a07
sub silent_eval (&);
Packit 972a07
Packit 972a07
# 
Packit 972a07
# Global variables
Packit 972a07
# 
Packit 972a07
use vars qw($facility);
Packit 972a07
my $connected       = 0;        # flag to indicate if we're connected or not
Packit 972a07
my $syslog_send;                # coderef of the function used to send messages
Packit 972a07
my $syslog_path     = undef;    # syslog path for "stream" and "unix" mechanisms
Packit 972a07
my $syslog_xobj     = undef;    # if defined, holds the external object used to send messages
Packit 972a07
my $transmit_ok     = 0;        # flag to indicate if the last message was transmitted
Packit 972a07
my $sock_port       = undef;    # socket port
Packit 972a07
my $sock_timeout    = 0;        # socket timeout, see below
Packit 972a07
my $current_proto   = undef;    # current mechanism used to transmit messages
Packit 972a07
my $ident           = '';       # identifiant prepended to each message
Packit 972a07
$facility           = '';       # current facility
Packit 972a07
my $maskpri         = LOG_UPTO(&LOG_DEBUG);     # current log mask
Packit 972a07
Packit 972a07
my %options = (
Packit 972a07
    ndelay  => 0, 
Packit 972a07
    noeol   => 0,
Packit 972a07
    nofatal => 0, 
Packit 972a07
    nonul   => 0,
Packit 972a07
    nowait  => 0, 
Packit 972a07
    perror  => 0, 
Packit 972a07
    pid     => 0, 
Packit 972a07
);
Packit 972a07
Packit 972a07
# Default is now to first use the native mechanism, so Perl programs 
Packit 972a07
# behave like other normal Unix programs, then try other mechanisms.
Packit 972a07
my @connectMethods = qw(native tcp udp unix pipe stream console);
Packit 972a07
if ($^O eq "freebsd" or $^O eq "linux") {
Packit 972a07
    @connectMethods = grep { $_ ne 'udp' } @connectMethods;
Packit 972a07
}
Packit 972a07
Packit 972a07
# And on Win32 systems, we try to use the native mechanism for this 
Packit 972a07
# platform, the events logger, available through Win32::EventLog.
Packit 972a07
EVENTLOG: {
Packit 972a07
    my $verbose_if_Win32 = $^O =~ /Win32/i;
Packit 972a07
Packit 972a07
    if (can_load_sys_syslog_win32($verbose_if_Win32)) {
Packit 972a07
        unshift @connectMethods, 'eventlog';
Packit 972a07
    }
Packit 972a07
}
Packit 972a07
Packit 972a07
my @defaultMethods = @connectMethods;
Packit 972a07
my @fallbackMethods = ();
Packit 972a07
Packit 972a07
# The timeout in connection_ok() was pushed up to 0.25 sec in 
Packit 972a07
# Sys::Syslog v0.19 in order to address a heisenbug on MacOSX:
Packit 972a07
# http://london.pm.org/pipermail/london.pm/Week-of-Mon-20061211/005961.html
Packit 972a07
# 
Packit 972a07
# However, this also had the effect of slowing this test for 
Packit 972a07
# all other operating systems, which apparently impacted some 
Packit 972a07
# users (cf. CPAN-RT #34753). So, in order to make everybody 
Packit 972a07
# happy, the timeout is now zero by default on all systems 
Packit 972a07
# except on OSX where it is set to 250 msec, and can be set 
Packit 972a07
# with the infamous setlogsock() function.
Packit 972a07
#
Packit 972a07
# Update 2011-08: this issue is also been seen on multiprocessor
Packit 972a07
# Debian GNU/kFreeBSD systems. See http://bugs.debian.org/627821
Packit 972a07
# and https://rt.cpan.org/Ticket/Display.html?id=69997
Packit 972a07
# Also, lowering the delay to 1 ms, which should be enough.
Packit 972a07
Packit 972a07
$sock_timeout = 0.001 if $^O =~ /darwin|gnukfreebsd/;
Packit 972a07
Packit 972a07
Packit 972a07
# Perl 5.6.0's warnings.pm doesn't have warnings::warnif()
Packit 972a07
if (not defined &warnings::warnif) {
Packit 972a07
    *warnings::warnif = sub {
Packit 972a07
        goto &warnings::warn if warnings::enabled(__PACKAGE__)
Packit 972a07
    }
Packit 972a07
}
Packit 972a07
Packit 972a07
# coderef for a nicer handling of errors
Packit 972a07
my $err_sub = $options{nofatal} ? \&warnings::warnif : \&croa;;
Packit 972a07
Packit 972a07
Packit 972a07
sub AUTOLOAD {
Packit 972a07
    # This AUTOLOAD is used to 'autoload' constants from the constant()
Packit 972a07
    # XS function.
Packit 972a07
    no strict 'vars';
Packit 972a07
    my $constname;
Packit 972a07
    ($constname = $AUTOLOAD) =~ s/.*:://;
Packit 972a07
    croak "Sys::Syslog::constant() not defined" if $constname eq 'constant';
Packit 972a07
    my ($error, $val) = constant($constname);
Packit 972a07
    croak $error if $error;
Packit 972a07
    no strict 'refs';
Packit 972a07
    *$AUTOLOAD = sub { $val };
Packit 972a07
    goto &$AUTOLOAD;
Packit 972a07
}
Packit 972a07
Packit 972a07
Packit 972a07
sub openlog {
Packit 972a07
    ($ident, my $logopt, $facility) = @_;
Packit 972a07
Packit 972a07
    # default values
Packit 972a07
    $ident    ||= basename($0) || getlogin() || getpwuid($<) || 'syslog';
Packit 972a07
    $logopt   ||= '';
Packit 972a07
    $facility ||= LOG_USER();
Packit 972a07
Packit 972a07
    for my $opt (split /\b/, $logopt) {
Packit 972a07
        $options{$opt} = 1 if exists $options{$opt}
Packit 972a07
    }
Packit 972a07
Packit 972a07
    $err_sub = delete $options{nofatal} ? \&warnings::warnif : \&croa;;
Packit 972a07
    return 1 unless $options{ndelay};
Packit 972a07
    connect_log();
Packit 972a07
} 
Packit 972a07
Packit 972a07
sub closelog {
Packit 972a07
    disconnect_log() if $connected;
Packit 972a07
    $options{$_} = 0 for keys %options;
Packit 972a07
    $facility = $ident = "";
Packit 972a07
    $connected = 0;
Packit 972a07
    return 1
Packit 972a07
} 
Packit 972a07
Packit 972a07
sub setlogmask {
Packit 972a07
    my $oldmask = $maskpri;
Packit 972a07
    $maskpri = shift unless $_[0] == 0;
Packit 972a07
    $oldmask;
Packit 972a07
}
Packit 972a07
Packit 972a07
Packit 972a07
my %mechanism = (
Packit 972a07
    console => {
Packit 972a07
        check   => sub { 1 },
Packit 972a07
    },
Packit 972a07
    eventlog => {
Packit 972a07
        check   => sub { return can_load_sys_syslog_win32() },
Packit 972a07
        err_msg => "no Win32 API available",
Packit 972a07
    },
Packit 972a07
    inet => {
Packit 972a07
        check   => sub { 1 },
Packit 972a07
    },
Packit 972a07
    native => {
Packit 972a07
        check   => sub { 1 },
Packit 972a07
    },
Packit 972a07
    pipe => {
Packit 972a07
        check   => sub {
Packit 972a07
            ($syslog_path) = grep { defined && length && -p && -w _ }
Packit 972a07
                                $syslog_path, &_PATH_LOG, "/dev/log";
Packit 972a07
            return $syslog_path ? 1 : 0
Packit 972a07
        },
Packit 972a07
        err_msg => "path not available",
Packit 972a07
    },
Packit 972a07
    stream => {
Packit 972a07
        check   => sub {
Packit 972a07
            if (not defined $syslog_path) {
Packit 972a07
                my @try = qw(/dev/log /dev/conslog);
Packit 972a07
                unshift @try, &_PATH_LOG  if length &_PATH_LOG;
Packit 972a07
                ($syslog_path) = grep { -w } @try;
Packit 972a07
            }
Packit 972a07
            return defined $syslog_path && -w $syslog_path
Packit 972a07
        },
Packit 972a07
        err_msg => "could not find any writable device",
Packit 972a07
    },
Packit 972a07
    tcp => {
Packit 972a07
        check   => sub {
Packit 972a07
            return 1 if defined $sock_port;
Packit 972a07
Packit 972a07
            if (eval { local $SIG{__DIE__};
Packit 972a07
                getservbyname('syslog','tcp') || getservbyname('syslogng','tcp')
Packit 972a07
            }) {
Packit 972a07
                $host = $syslog_path;
Packit 972a07
                return 1
Packit 972a07
            }
Packit 972a07
            else {
Packit 972a07
                return
Packit 972a07
            }
Packit 972a07
        },
Packit 972a07
        err_msg => "TCP service unavailable",
Packit 972a07
    },
Packit 972a07
    udp => {
Packit 972a07
        check   => sub {
Packit 972a07
            return 1 if defined $sock_port;
Packit 972a07
Packit 972a07
            if (eval { local $SIG{__DIE__}; getservbyname('syslog', 'udp') }) {
Packit 972a07
                $host = $syslog_path;
Packit 972a07
                return 1
Packit 972a07
            }
Packit 972a07
            else {
Packit 972a07
                return
Packit 972a07
            }
Packit 972a07
        },
Packit 972a07
        err_msg => "UDP service unavailable",
Packit 972a07
    },
Packit 972a07
    unix => {
Packit 972a07
        check   => sub {
Packit 972a07
            my @try = ($syslog_path, &_PATH_LOG);
Packit 972a07
            ($syslog_path) = grep { defined && length && -w } @try;
Packit 972a07
            return defined $syslog_path && -w $syslog_path
Packit 972a07
        },
Packit 972a07
        err_msg => "path not available",
Packit 972a07
    },
Packit 972a07
);
Packit 972a07
 
Packit 972a07
sub setlogsock {
Packit 972a07
    my %opt;
Packit 972a07
Packit 972a07
    # handle arguments
Packit 972a07
    # - old API: setlogsock($sock_type, $sock_path, $sock_timeout)
Packit 972a07
    # - new API: setlogsock(\%options)
Packit 972a07
    croak "setlogsock(): Invalid number of arguments"
Packit 972a07
        unless @_ >= 1 and @_ <= 3;
Packit 972a07
Packit 972a07
    if (my $ref = ref $_[0]) {
Packit 972a07
        if ($ref eq "HASH") {
Packit 972a07
            %opt = %{ $_[0] };
Packit 972a07
            croak "setlogsock(): No argument given" unless keys %opt;
Packit 972a07
        }
Packit 972a07
        elsif ($ref eq "ARRAY") {
Packit 972a07
            @opt{qw< type path timeout >} = @_;
Packit 972a07
        }
Packit 972a07
        else {
Packit 972a07
            croak "setlogsock(): Unexpected \L$ref\E reference"
Packit 972a07
        }
Packit 972a07
    }
Packit 972a07
    else {
Packit 972a07
        @opt{qw< type path timeout >} = @_;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    # check socket type, remove invalid ones
Packit 972a07
    my $diag_invalid_type = "setlogsock(): Invalid type%s; must be one of "
Packit 972a07
                          . join ", ", map { "'$_'" } sort keys %mechanism;
Packit 972a07
    croak sprintf $diag_invalid_type, "" unless defined $opt{type};
Packit 972a07
    my @sock_types = ref $opt{type} eq "ARRAY" ? @{$opt{type}} : ($opt{type});
Packit 972a07
    my @tmp;
Packit 972a07
Packit 972a07
    for my $sock_type (@sock_types) {
Packit 972a07
        carp sprintf $diag_invalid_type, " '$sock_type'" and next
Packit 972a07
            unless exists $mechanism{$sock_type};
Packit 972a07
        push @tmp, "tcp", "udp" and next  if $sock_type eq "inet";
Packit 972a07
        push @tmp, $sock_type;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    @sock_types = @tmp;
Packit 972a07
Packit 972a07
    # set global options
Packit 972a07
    $syslog_path  = $opt{path}    if defined $opt{path};
Packit 972a07
    $host         = $opt{host}    if defined $opt{host};
Packit 972a07
    $sock_timeout = $opt{timeout} if defined $opt{timeout};
Packit 972a07
    $sock_port    = $opt{port}    if defined $opt{port};
Packit 972a07
Packit 972a07
    disconnect_log() if $connected;
Packit 972a07
    $transmit_ok = 0;
Packit 972a07
    @fallbackMethods = ();
Packit 972a07
    @connectMethods = ();
Packit 972a07
    my $found = 0;
Packit 972a07
Packit 972a07
    # check each given mechanism and test if it can be used on the current system
Packit 972a07
    for my $sock_type (@sock_types) {
Packit 972a07
        if ( $mechanism{$sock_type}{check}->() ) {
Packit 972a07
            push @connectMethods, $sock_type;
Packit 972a07
            $found = 1;
Packit 972a07
        }
Packit 972a07
        else {
Packit 972a07
            warnings::warnif("setlogsock(): type='$sock_type': "
Packit 972a07
                           . $mechanism{$sock_type}{err_msg});
Packit 972a07
        }
Packit 972a07
    }
Packit 972a07
Packit 972a07
    # if no mechanism worked from the given ones, use the default ones
Packit 972a07
    @connectMethods = @defaultMethods unless @connectMethods;
Packit 972a07
Packit 972a07
    return $found;
Packit 972a07
}
Packit 972a07
Packit 972a07
sub syslog {
Packit 972a07
    my ($priority, $mask, @args) = @_;
Packit 972a07
    my ($message, $buf);
Packit 972a07
    my (@words, $num, $numpri, $numfac, $sum);
Packit 972a07
    my $failed = undef;
Packit 972a07
    my $fail_time = undef;
Packit 972a07
    my $error = $!;
Packit 972a07
Packit 972a07
    # if $ident is undefined, it means openlog() wasn't previously called
Packit 972a07
    # so do it now in order to have sensible defaults
Packit 972a07
    openlog() unless $ident;
Packit 972a07
Packit 972a07
    local $facility = $facility;    # may need to change temporarily.
Packit 972a07
Packit 972a07
    croak "syslog: expecting argument \$priority" unless defined $priority;
Packit 972a07
    croak "syslog: expecting argument \$format"   unless defined $mask;
Packit 972a07
Packit 972a07
    if ($priority =~ /^\d+$/) {
Packit 972a07
        $numpri = LOG_PRI($priority);
Packit 972a07
        $numfac = LOG_FAC($priority) << 3;
Packit 972a07
        undef $numfac if $numfac == 0;  # no facility given => use default
Packit 972a07
    }
Packit 972a07
    elsif ($priority =~ /^\w+/) {
Packit 972a07
        # Allow "level" or "level|facility".
Packit 972a07
        @words = split /\W+/, $priority, 2;
Packit 972a07
Packit 972a07
        undef $numpri;
Packit 972a07
        undef $numfac;
Packit 972a07
Packit 972a07
        for my $word (@words) {
Packit 972a07
            next if length $word == 0;
Packit 972a07
Packit 972a07
            # Translate word to number.
Packit 972a07
            $num = xlate($word);
Packit 972a07
Packit 972a07
            if ($num < 0) {
Packit 972a07
                croak "syslog: invalid level/facility: $word"
Packit 972a07
            }
Packit 972a07
            elsif ($num <= LOG_PRIMASK() and $word ne "kern") {
Packit 972a07
                croak "syslog: too many levels given: $word"
Packit 972a07
                    if defined $numpri;
Packit 972a07
                $numpri = $num;
Packit 972a07
            }
Packit 972a07
            else {
Packit 972a07
                croak "syslog: too many facilities given: $word"
Packit 972a07
                    if defined $numfac;
Packit 972a07
                $facility = $word if $word =~ /^[A-Za-z]/;
Packit 972a07
                $numfac = $num;
Packit 972a07
            }
Packit 972a07
        }
Packit 972a07
    }
Packit 972a07
    else {
Packit 972a07
        croak "syslog: invalid level/facility: $priority"
Packit 972a07
    }
Packit 972a07
Packit 972a07
    croak "syslog: level must be given" unless defined $numpri;
Packit 972a07
Packit 972a07
    # don't log if priority is below mask level
Packit 972a07
    return 0 unless LOG_MASK($numpri) & $maskpri;
Packit 972a07
Packit 972a07
    if (not defined $numfac) {  # Facility not specified in this call.
Packit 972a07
	$facility = 'user' unless $facility;
Packit 972a07
	$numfac = xlate($facility);
Packit 972a07
    }
Packit 972a07
Packit 972a07
    connect_log() unless $connected;
Packit 972a07
Packit 972a07
    if ($mask =~ /%m/) {
Packit 972a07
        # escape percent signs for sprintf()
Packit 972a07
        $error =~ s/%/%%/g if @args;
Packit 972a07
        # replace %m with $error, if preceded by an even number of percent signs
Packit 972a07
        $mask =~ s/(?
Packit 972a07
    }
Packit 972a07
Packit 972a07
    # add (or not) a newline
Packit 972a07
    $mask .= "\n" if !$options{noeol} and rindex($mask, "\n") == -1;
Packit 972a07
    $message = @args ? sprintf($mask, @args) : $mask;
Packit 972a07
Packit 972a07
    if ($current_proto eq 'native') {
Packit 972a07
        $buf = $message;
Packit 972a07
    }
Packit 972a07
    elsif ($current_proto eq 'eventlog') {
Packit 972a07
        $buf = $message;
Packit 972a07
    }
Packit 972a07
    else {
Packit 972a07
        my $whoami = $ident;
Packit 972a07
        $whoami .= "[$$]" if $options{pid};
Packit 972a07
Packit 972a07
        $sum = $numpri + $numfac;
Packit 972a07
Packit 972a07
        my $oldlocale;
Packit 972a07
        if (HAVE_SETLOCALE) {
Packit 972a07
            $oldlocale = setlocale(LC_TIME);
Packit 972a07
            setlocale(LC_TIME, 'C');
Packit 972a07
        }
Packit 972a07
Packit 972a07
        # %e format isn't available on all systems (Win32, cf. CPAN RT #69310)
Packit 972a07
        my $day = strftime "%e", localtime;
Packit 972a07
Packit 972a07
        if (index($day, "%") == 0) {
Packit 972a07
            $day = strftime "%d", localtime;
Packit 972a07
            $day =~ s/^0/ /;
Packit 972a07
        }
Packit 972a07
Packit 972a07
        my $timestamp = strftime "%b $day %H:%M:%S", localtime;
Packit 972a07
        setlocale(LC_TIME, $oldlocale) if HAVE_SETLOCALE;
Packit 972a07
Packit 972a07
        # construct the stream that will be transmitted
Packit 972a07
        $buf = "<$sum>$timestamp $whoami: $message";
Packit 972a07
Packit 972a07
        # add (or not) a NUL character
Packit 972a07
        $buf .= "\0" if !$options{nonul};
Packit 972a07
    }
Packit 972a07
Packit 972a07
    # handle PERROR option
Packit 972a07
    # "native" mechanism already handles it by itself
Packit 972a07
    if ($options{perror} and $current_proto ne 'native') {
Packit 972a07
        my $whoami = $ident;
Packit 972a07
        $whoami .= "[$$]" if $options{pid};
Packit 972a07
        print STDERR "$whoami: $message";
Packit 972a07
        print STDERR "\n" if rindex($message, "\n") == -1;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    # it's possible that we'll get an error from sending
Packit 972a07
    # (e.g. if method is UDP and there is no UDP listener,
Packit 972a07
    # then we'll get ECONNREFUSED on the send). So what we
Packit 972a07
    # want to do at this point is to fallback onto a different
Packit 972a07
    # connection method.
Packit 972a07
    while (scalar @fallbackMethods || $syslog_send) {
Packit 972a07
	if ($failed && (time - $fail_time) > 60) {
Packit 972a07
	    # it's been a while... maybe things have been fixed
Packit 972a07
	    @fallbackMethods = ();
Packit 972a07
	    disconnect_log();
Packit 972a07
	    $transmit_ok = 0; # make it look like a fresh attempt
Packit 972a07
	    connect_log();
Packit 972a07
        }
Packit 972a07
Packit 972a07
	if ($connected && !connection_ok()) {
Packit 972a07
	    # Something was OK, but has now broken. Remember coz we'll
Packit 972a07
	    # want to go back to what used to be OK.
Packit 972a07
	    $failed = $current_proto unless $failed;
Packit 972a07
	    $fail_time = time;
Packit 972a07
	    disconnect_log();
Packit 972a07
	}
Packit 972a07
Packit 972a07
	connect_log() unless $connected;
Packit 972a07
	$failed = undef if ($current_proto && $failed && $current_proto eq $failed);
Packit 972a07
Packit 972a07
	if ($syslog_send) {
Packit 972a07
            if ($syslog_send->($buf, $numpri, $numfac)) {
Packit 972a07
		$transmit_ok++;
Packit 972a07
		return 1;
Packit 972a07
	    }
Packit 972a07
	    # typically doesn't happen, since errors are rare from write().
Packit 972a07
	    disconnect_log();
Packit 972a07
	}
Packit 972a07
    }
Packit 972a07
    # could not send, could not fallback onto a working
Packit 972a07
    # connection method. Lose.
Packit 972a07
    return 0;
Packit 972a07
}
Packit 972a07
Packit 972a07
sub _syslog_send_console {
Packit 972a07
    my ($buf) = @_;
Packit 972a07
Packit 972a07
    # The console print is a method which could block
Packit 972a07
    # so we do it in a child process and always return success
Packit 972a07
    # to the caller.
Packit 972a07
    if (my $pid = fork) {
Packit 972a07
Packit 972a07
	if ($options{nowait}) {
Packit 972a07
	    return 1;
Packit 972a07
	} else {
Packit 972a07
	    if (waitpid($pid, 0) >= 0) {
Packit 972a07
	    	return ($? >> 8);
Packit 972a07
	    } else {
Packit 972a07
		# it's possible that the caller has other
Packit 972a07
		# plans for SIGCHLD, so let's not interfere
Packit 972a07
		return 1;
Packit 972a07
	    }
Packit 972a07
	}
Packit 972a07
    } else {
Packit 972a07
        if (open(CONS, ">/dev/console")) {
Packit 972a07
	    my $ret = print CONS $buf . "\r";  # XXX: should this be \x0A ?
Packit 972a07
	    POSIX::_exit($ret) if defined $pid;
Packit 972a07
	    close CONS;
Packit 972a07
	}
Packit 972a07
Packit 972a07
	POSIX::_exit(0) if defined $pid;
Packit 972a07
    }
Packit 972a07
}
Packit 972a07
Packit 972a07
sub _syslog_send_stream {
Packit 972a07
    my ($buf) = @_;
Packit 972a07
    # XXX: this only works if the OS stream implementation makes a write 
Packit 972a07
    # look like a putmsg() with simple header. For instance it works on 
Packit 972a07
    # Solaris 8 but not Solaris 7.
Packit 972a07
    # To be correct, it should use a STREAMS API, but perl doesn't have one.
Packit 972a07
    return syswrite(SYSLOG, $buf, length($buf));
Packit 972a07
}
Packit 972a07
Packit 972a07
sub _syslog_send_pipe {
Packit 972a07
    my ($buf) = @_;
Packit 972a07
    return print SYSLOG $buf;
Packit 972a07
}
Packit 972a07
Packit 972a07
sub _syslog_send_socket {
Packit 972a07
    my ($buf) = @_;
Packit 972a07
    return syswrite(SYSLOG, $buf, length($buf));
Packit 972a07
    #return send(SYSLOG, $buf, 0);
Packit 972a07
}
Packit 972a07
Packit 972a07
sub _syslog_send_native {
Packit 972a07
    my ($buf, $numpri, $numfac) = @_;
Packit 972a07
    syslog_xs($numpri|$numfac, $buf);
Packit 972a07
    return 1;
Packit 972a07
}
Packit 972a07
Packit 972a07
Packit 972a07
# xlate()
Packit 972a07
# -----
Packit 972a07
# private function to translate names to numeric values
Packit 972a07
# 
Packit 972a07
sub xlate {
Packit 972a07
    my ($name) = @_;
Packit 972a07
Packit 972a07
    return $name+0 if $name =~ /^\s*\d+\s*$/;
Packit 972a07
    $name = uc $name;
Packit 972a07
    $name = "LOG_$name" unless $name =~ /^LOG_/;
Packit 972a07
Packit 972a07
    # ExtUtils::Constant 0.20 introduced a new way to implement
Packit 972a07
    # constants, called ProxySubs.  When it was used to generate
Packit 972a07
    # the C code, the constant() function no longer returns the 
Packit 972a07
    # correct value.  Therefore, we first try a direct call to 
Packit 972a07
    # constant(), and if the value is an error we try to call the 
Packit 972a07
    # constant by its full name. 
Packit 972a07
    my $value = constant($name);
Packit 972a07
Packit 972a07
    if (index($value, "not a valid") >= 0) {
Packit 972a07
        $name = "Sys::Syslog::$name";
Packit 972a07
        $value = eval { no strict "refs"; &$name };
Packit 972a07
        $value = $@ unless defined $value;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    $value = -1 if index($value, "not a valid") >= 0;
Packit 972a07
Packit 972a07
    return defined $value ? $value : -1;
Packit 972a07
}
Packit 972a07
Packit 972a07
Packit 972a07
# connect_log()
Packit 972a07
# -----------
Packit 972a07
# This function acts as a kind of front-end: it tries to connect to 
Packit 972a07
# a syslog service using the selected methods, trying each one in the 
Packit 972a07
# selected order. 
Packit 972a07
# 
Packit 972a07
sub connect_log {
Packit 972a07
    @fallbackMethods = @connectMethods unless scalar @fallbackMethods;
Packit 972a07
Packit 972a07
    if ($transmit_ok && $current_proto) {
Packit 972a07
        # Retry what we were on, because it has worked in the past.
Packit 972a07
	unshift(@fallbackMethods, $current_proto);
Packit 972a07
    }
Packit 972a07
Packit 972a07
    $connected = 0;
Packit 972a07
    my @errs = ();
Packit 972a07
    my $proto = undef;
Packit 972a07
Packit 972a07
    while ($proto = shift @fallbackMethods) {
Packit 972a07
	no strict 'refs';
Packit 972a07
	my $fn = "connect_$proto";
Packit 972a07
	$connected = &$fn(\@errs) if defined &$fn;
Packit 972a07
	last if $connected;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    $transmit_ok = 0;
Packit 972a07
    if ($connected) {
Packit 972a07
	$current_proto = $proto;
Packit 972a07
        my ($old) = select(SYSLOG); $| = 1; select($old);
Packit 972a07
    } else {
Packit 972a07
	@fallbackMethods = ();
Packit 972a07
        $err_sub->(join "\n\t- ", "no connection to syslog available", @errs);
Packit 972a07
        return undef;
Packit 972a07
    }
Packit 972a07
}
Packit 972a07
Packit 972a07
sub connect_tcp {
Packit 972a07
    my ($errs) = @_;
Packit 972a07
Packit 972a07
    my $port = $sock_port
Packit 972a07
            || eval { local $SIG{__DIE__}; getservbyname('syslog',   'tcp') }
Packit 972a07
            || eval { local $SIG{__DIE__}; getservbyname('syslogng', 'tcp') };
Packit 972a07
    if (!defined $port) {
Packit 972a07
	push @$errs, "getservbyname failed for syslog/tcp and syslogng/tcp";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    my $addr;
Packit 972a07
    if (defined $host) {
Packit 972a07
        $addr = inet_aton($host);
Packit 972a07
        if (!$addr) {
Packit 972a07
	    push @$errs, "can't lookup $host";
Packit 972a07
	    return 0;
Packit 972a07
	}
Packit 972a07
    } else {
Packit 972a07
        $addr = INADDR_LOOPBACK;
Packit 972a07
    }
Packit 972a07
    $addr = sockaddr_in($port, $addr);
Packit 972a07
Packit 972a07
    if (!socket(SYSLOG, AF_INET, SOCK_STREAM, SOCKET_IPPROTO_TCP)) {
Packit 972a07
	push @$errs, "tcp socket: $!";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    setsockopt(SYSLOG, SOL_SOCKET, SO_KEEPALIVE, 1);
Packit 972a07
    setsockopt(SYSLOG, SOCKET_IPPROTO_TCP, SOCKET_TCP_NODELAY, 1);
Packit 972a07
Packit 972a07
    if (!connect(SYSLOG, $addr)) {
Packit 972a07
	push @$errs, "tcp connect: $!";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    $syslog_send = \&_syslog_send_socket;
Packit 972a07
Packit 972a07
    return 1;
Packit 972a07
}
Packit 972a07
Packit 972a07
sub connect_udp {
Packit 972a07
    my ($errs) = @_;
Packit 972a07
Packit 972a07
    my $port = $sock_port
Packit 972a07
            || eval { local $SIG{__DIE__}; getservbyname('syslog', 'udp') };
Packit 972a07
    if (!defined $port) {
Packit 972a07
	push @$errs, "getservbyname failed for syslog/udp";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    my $addr;
Packit 972a07
    if (defined $host) {
Packit 972a07
        $addr = inet_aton($host);
Packit 972a07
        if (!$addr) {
Packit 972a07
	    push @$errs, "can't lookup $host";
Packit 972a07
	    return 0;
Packit 972a07
	}
Packit 972a07
    } else {
Packit 972a07
        $addr = INADDR_LOOPBACK;
Packit 972a07
    }
Packit 972a07
    $addr = sockaddr_in($port, $addr);
Packit 972a07
Packit 972a07
    if (!socket(SYSLOG, AF_INET, SOCK_DGRAM, SOCKET_IPPROTO_UDP)) {
Packit 972a07
	push @$errs, "udp socket: $!";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
    if (!connect(SYSLOG, $addr)) {
Packit 972a07
	push @$errs, "udp connect: $!";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    # We want to check that the UDP connect worked. However the only
Packit 972a07
    # way to do that is to send a message and see if an ICMP is returned
Packit 972a07
    _syslog_send_socket("");
Packit 972a07
    if (!connection_ok()) {
Packit 972a07
	push @$errs, "udp connect: nobody listening";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    $syslog_send = \&_syslog_send_socket;
Packit 972a07
Packit 972a07
    return 1;
Packit 972a07
}
Packit 972a07
Packit 972a07
sub connect_stream {
Packit 972a07
    my ($errs) = @_;
Packit 972a07
    # might want syslog_path to be variable based on syslog.h (if only
Packit 972a07
    # it were in there!)
Packit 972a07
    $syslog_path = '/dev/conslog' unless defined $syslog_path; 
Packit 972a07
Packit 972a07
    if (!-w $syslog_path) {
Packit 972a07
	push @$errs, "stream $syslog_path is not writable";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    require Fcntl;
Packit 972a07
Packit 972a07
    if (!sysopen(SYSLOG, $syslog_path, Fcntl::O_WRONLY(), 0400)) {
Packit 972a07
	push @$errs, "stream can't open $syslog_path: $!";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    $syslog_send = \&_syslog_send_stream;
Packit 972a07
Packit 972a07
    return 1;
Packit 972a07
}
Packit 972a07
Packit 972a07
sub connect_pipe {
Packit 972a07
    my ($errs) = @_;
Packit 972a07
Packit 972a07
    $syslog_path ||= &_PATH_LOG || "/dev/log";
Packit 972a07
Packit 972a07
    if (not -w $syslog_path) {
Packit 972a07
        push @$errs, "$syslog_path is not writable";
Packit 972a07
        return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    if (not open(SYSLOG, ">$syslog_path")) {
Packit 972a07
        push @$errs, "can't write to $syslog_path: $!";
Packit 972a07
        return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    $syslog_send = \&_syslog_send_pipe;
Packit 972a07
Packit 972a07
    return 1;
Packit 972a07
}
Packit 972a07
Packit 972a07
sub connect_unix {
Packit 972a07
    my ($errs) = @_;
Packit 972a07
Packit 972a07
    $syslog_path ||= _PATH_LOG() if length _PATH_LOG();
Packit 972a07
Packit 972a07
    if (not defined $syslog_path) {
Packit 972a07
        push @$errs, "_PATH_LOG not available in syslog.h and no user-supplied socket path";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    if (not (-S $syslog_path or -c _)) {
Packit 972a07
        push @$errs, "$syslog_path is not a socket";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    my $addr = sockaddr_un($syslog_path);
Packit 972a07
    if (!$addr) {
Packit 972a07
	push @$errs, "can't locate $syslog_path";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
    if (!socket(SYSLOG, AF_UNIX, SOCK_STREAM, 0)) {
Packit 972a07
        push @$errs, "unix stream socket: $!";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    if (!connect(SYSLOG, $addr)) {
Packit 972a07
        if (!socket(SYSLOG, AF_UNIX, SOCK_DGRAM, 0)) {
Packit 972a07
	    push @$errs, "unix dgram socket: $!";
Packit 972a07
	    return 0;
Packit 972a07
	}
Packit 972a07
        if (!connect(SYSLOG, $addr)) {
Packit 972a07
	    push @$errs, "unix dgram connect: $!";
Packit 972a07
	    return 0;
Packit 972a07
	}
Packit 972a07
    }
Packit 972a07
Packit 972a07
    $syslog_send = \&_syslog_send_socket;
Packit 972a07
Packit 972a07
    return 1;
Packit 972a07
}
Packit 972a07
Packit 972a07
sub connect_native {
Packit 972a07
    my ($errs) = @_;
Packit 972a07
    my $logopt = 0;
Packit 972a07
Packit 972a07
    # reconstruct the numeric equivalent of the options
Packit 972a07
    for my $opt (keys %options) {
Packit 972a07
        $logopt += xlate($opt) if $options{$opt}
Packit 972a07
    }
Packit 972a07
Packit 972a07
    openlog_xs($ident, $logopt, xlate($facility));
Packit 972a07
    $syslog_send = \&_syslog_send_native;
Packit 972a07
Packit 972a07
    return 1;
Packit 972a07
}
Packit 972a07
Packit 972a07
sub connect_eventlog {
Packit 972a07
    my ($errs) = @_;
Packit 972a07
Packit 972a07
    $syslog_xobj = Sys::Syslog::Win32::_install();
Packit 972a07
    $syslog_send = \&Sys::Syslog::Win32::_syslog_send;
Packit 972a07
Packit 972a07
    return 1;
Packit 972a07
}
Packit 972a07
Packit 972a07
sub connect_console {
Packit 972a07
    my ($errs) = @_;
Packit 972a07
    if (!-w '/dev/console') {
Packit 972a07
	push @$errs, "console is not writable";
Packit 972a07
	return 0;
Packit 972a07
    }
Packit 972a07
    $syslog_send = \&_syslog_send_console;
Packit 972a07
    return 1;
Packit 972a07
}
Packit 972a07
Packit 972a07
# To test if the connection is still good, we need to check if any
Packit 972a07
# errors are present on the connection. The errors will not be raised
Packit 972a07
# by a write. Instead, sockets are made readable and the next read
Packit 972a07
# would cause the error to be returned. Unfortunately the syslog 
Packit 972a07
# 'protocol' never provides anything for us to read. But with 
Packit 972a07
# judicious use of select(), we can see if it would be readable...
Packit 972a07
sub connection_ok {
Packit 972a07
    return 1 if defined $current_proto and (
Packit 972a07
        $current_proto eq 'native' or $current_proto eq 'console'
Packit 972a07
        or $current_proto eq 'eventlog'
Packit 972a07
    );
Packit 972a07
Packit 972a07
    my $rin = '';
Packit 972a07
    vec($rin, fileno(SYSLOG), 1) = 1;
Packit 972a07
    my $ret = select $rin, undef, $rin, $sock_timeout;
Packit 972a07
    return ($ret ? 0 : 1);
Packit 972a07
}
Packit 972a07
Packit 972a07
sub disconnect_log {
Packit 972a07
    $connected = 0;
Packit 972a07
    $syslog_send = undef;
Packit 972a07
Packit 972a07
    if (defined $current_proto and $current_proto eq 'native') {
Packit 972a07
        closelog_xs();
Packit 972a07
        unshift @fallbackMethods, $current_proto;
Packit 972a07
        $current_proto = undef;
Packit 972a07
        return 1;
Packit 972a07
    }
Packit 972a07
    elsif (defined $current_proto and $current_proto eq 'eventlog') {
Packit 972a07
        $syslog_xobj->Close();
Packit 972a07
        unshift @fallbackMethods, $current_proto;
Packit 972a07
        $current_proto = undef;
Packit 972a07
        return 1;
Packit 972a07
    }
Packit 972a07
Packit 972a07
    return close SYSLOG;
Packit 972a07
}
Packit 972a07
Packit 972a07
Packit 972a07
#
Packit 972a07
# Wrappers around eval() that makes sure that nobody, ever knows that
Packit 972a07
# we wanted to poke & test if something was here or not. This is needed
Packit 972a07
# because some applications are trying to be too smart, install their
Packit 972a07
# own __DIE__ handler, and mysteriously, things are starting to fail
Packit 972a07
# when they shouldn't. SpamAssassin among them.
Packit 972a07
#
Packit 972a07
sub silent_eval (&) {
Packit 972a07
    local($SIG{__DIE__}, $SIG{__WARN__}, $@);
Packit 972a07
    return eval { $_[0]->() }
Packit 972a07
}
Packit 972a07
Packit 972a07
sub can_load_sys_syslog_win32 {
Packit 972a07
    my ($verbose) = @_;
Packit 972a07
    local($SIG{__DIE__}, $SIG{__WARN__}, $@);
Packit 972a07
    (my $module_path = __FILE__) =~ s:Syslog.pm$:Syslog/Win32.pm:;
Packit 972a07
    my $loaded = eval { require $module_path } ? 1 : 0;
Packit 972a07
    warn $@ if not $loaded and $verbose;
Packit 972a07
    return $loaded
Packit 972a07
}
Packit 972a07
Packit 972a07
Packit 972a07
"Eighth Rule: read the documentation."
Packit 972a07
Packit 972a07
__END__
Packit 972a07
Packit 972a07
=head1 NAME
Packit 972a07
Packit 972a07
Sys::Syslog - Perl interface to the UNIX syslog(3) calls
Packit 972a07
Packit 972a07
=head1 VERSION
Packit 972a07
Packit 972a07
This is the documentation of version 0.35
Packit 972a07
Packit 972a07
=head1 SYNOPSIS
Packit 972a07
Packit 972a07
    use Sys::Syslog;                        # all except setlogsock()
Packit 972a07
    use Sys::Syslog qw(:standard :macros);  # standard functions & macros
Packit 972a07
Packit 972a07
    openlog($ident, $logopt, $facility);    # don't forget this
Packit 972a07
    syslog($priority, $format, @args);
Packit 972a07
    $oldmask = setlogmask($mask_priority);
Packit 972a07
    closelog();
Packit 972a07
Packit 972a07
Packit 972a07
=head1 DESCRIPTION
Packit 972a07
Packit 972a07
C<Sys::Syslog> is an interface to the UNIX C<syslog(3)> program.
Packit 972a07
Call C<syslog()> with a string priority and a list of C<printf()> args
Packit 972a07
just like C<syslog(3)>.
Packit 972a07
Packit 972a07
Packit 972a07
=head1 EXPORTS
Packit 972a07
Packit 972a07
C<Sys::Syslog> exports the following C<Exporter> tags: 
Packit 972a07
Packit 972a07
=over 4
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<:standard> exports the standard C<syslog(3)> functions: 
Packit 972a07
Packit 972a07
    openlog closelog setlogmask syslog
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<:extended> exports the Perl specific functions for C<syslog(3)>: 
Packit 972a07
Packit 972a07
    setlogsock
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<:macros> exports the symbols corresponding to most of your C<syslog(3)> 
Packit 972a07
macros and the C<LOG_UPTO()> and C<LOG_MASK()> functions. 
Packit 972a07
See L<"CONSTANTS"> for the supported constants and their meaning. 
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
By default, C<Sys::Syslog> exports the symbols from the C<:standard> tag. 
Packit 972a07
Packit 972a07
Packit 972a07
=head1 FUNCTIONS
Packit 972a07
Packit 972a07
=over 4
Packit 972a07
Packit 972a07
=item B<openlog($ident, $logopt, $facility)>
Packit 972a07
Packit 972a07
Opens the syslog.
Packit 972a07
C<$ident> is prepended to every message.  C<$logopt> contains zero or
Packit 972a07
more of the options detailed below.  C<$facility> specifies the part 
Packit 972a07
of the system to report about, for example C<LOG_USER> or C<LOG_LOCAL0>:
Packit 972a07
see L<"Facilities"> for a list of well-known facilities, and your 
Packit 972a07
C<syslog(3)> documentation for the facilities available in your system. 
Packit 972a07
Check L<"SEE ALSO"> for useful links. Facility can be given as a string 
Packit 972a07
or a numeric macro. 
Packit 972a07
Packit 972a07
This function will croak if it can't connect to the syslog daemon.
Packit 972a07
Packit 972a07
Note that C<openlog()> now takes three arguments, just like C<openlog(3)>.
Packit 972a07
Packit 972a07
B<You should use C<openlog()> before calling C<syslog()>.>
Packit 972a07
Packit 972a07
B<Options>
Packit 972a07
Packit 972a07
=over 4
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<cons> - This option is ignored, since the failover mechanism will drop 
Packit 972a07
down to the console automatically if all other media fail.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<ndelay> - Open the connection immediately (normally, the connection is
Packit 972a07
opened when the first message is logged).
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<noeol> - When set to true, no end of line character (C<\n>) will be
Packit 972a07
appended to the message. This can be useful for some syslog daemons.
Packit 972a07
Added in C<Sys::Syslog> 0.29.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<nofatal> - When set to true, C<openlog()> and C<syslog()> will only 
Packit 972a07
emit warnings instead of dying if the connection to the syslog can't 
Packit 972a07
be established. Added in C<Sys::Syslog> 0.15.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<nonul> - When set to true, no C<NUL> character (C<\0>) will be
Packit 972a07
appended to the message. This can be useful for some syslog daemons.
Packit 972a07
Added in C<Sys::Syslog> 0.29.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<nowait> - Don't wait for child processes that may have been created 
Packit 972a07
while logging the message.  (The GNU C library does not create a child
Packit 972a07
process, so this option has no effect on Linux.)
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<perror> - Write the message to standard error output as well to the
Packit 972a07
system log. Added in C<Sys::Syslog> 0.22.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<pid> - Include PID with each message.
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
B<Examples>
Packit 972a07
Packit 972a07
Open the syslog with options C<ndelay> and C<pid>, and with facility C<LOCAL0>: 
Packit 972a07
Packit 972a07
    openlog($name, "ndelay,pid", "local0");
Packit 972a07
Packit 972a07
Same thing, but this time using the macro corresponding to C<LOCAL0>: 
Packit 972a07
Packit 972a07
    openlog($name, "ndelay,pid", LOG_LOCAL0);
Packit 972a07
Packit 972a07
Packit 972a07
=item B<syslog($priority, $message)>
Packit 972a07
Packit 972a07
=item B<syslog($priority, $format, @args)>
Packit 972a07
Packit 972a07
If C<$priority> permits, logs C<$message> or C<sprintf($format, @args)>
Packit 972a07
with the addition that C<%m> in $message or C<$format> is replaced with
Packit 972a07
C<"$!"> (the latest error message). 
Packit 972a07
Packit 972a07
C<$priority> can specify a level, or a level and a facility.  Levels and 
Packit 972a07
facilities can be given as strings or as macros.  When using the C<eventlog>
Packit 972a07
mechanism, priorities C<DEBUG> and C<INFO> are mapped to event type 
Packit 972a07
C<informational>, C<NOTICE> and C<WARNING> to C<warning> and C<ERR> to 
Packit 972a07
C<EMERG> to C<error>.
Packit 972a07
Packit 972a07
If you didn't use C<openlog()> before using C<syslog()>, C<syslog()> will 
Packit 972a07
try to guess the C<$ident> by extracting the shortest prefix of 
Packit 972a07
C<$format> that ends in a C<":">.
Packit 972a07
Packit 972a07
B<Examples>
Packit 972a07
Packit 972a07
    # informational level
Packit 972a07
    syslog("info", $message);
Packit 972a07
    syslog(LOG_INFO, $message);
Packit 972a07
Packit 972a07
    # information level, Local0 facility
Packit 972a07
    syslog("info|local0", $message);
Packit 972a07
    syslog(LOG_INFO|LOG_LOCAL0, $message);
Packit 972a07
Packit 972a07
=over 4
Packit 972a07
Packit 972a07
=item B<Note>
Packit 972a07
Packit 972a07
C<Sys::Syslog> version v0.07 and older passed the C<$message> as the 
Packit 972a07
formatting string to C<sprintf()> even when no formatting arguments
Packit 972a07
were provided.  If the code calling C<syslog()> might execute with 
Packit 972a07
older versions of this module, make sure to call the function as
Packit 972a07
C<syslog($priority, "%s", $message)> instead of C
Packit 972a07
$message)>.  This protects against hostile formatting sequences that
Packit 972a07
might show up if $message contains tainted data.
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
Packit 972a07
=item B<setlogmask($mask_priority)>
Packit 972a07
Packit 972a07
Sets the log mask for the current process to C<$mask_priority> and 
Packit 972a07
returns the old mask.  If the mask argument is 0, the current log mask 
Packit 972a07
is not modified.  See L<"Levels"> for the list of available levels. 
Packit 972a07
You can use the C<LOG_UPTO()> function to allow all levels up to a 
Packit 972a07
given priority (but it only accept the numeric macros as arguments).
Packit 972a07
Packit 972a07
B<Examples>
Packit 972a07
Packit 972a07
Only log errors: 
Packit 972a07
Packit 972a07
    setlogmask( LOG_MASK(LOG_ERR) );
Packit 972a07
Packit 972a07
Log everything except informational messages: 
Packit 972a07
Packit 972a07
    setlogmask( ~(LOG_MASK(LOG_INFO)) );
Packit 972a07
Packit 972a07
Log critical messages, errors and warnings: 
Packit 972a07
Packit 972a07
    setlogmask( LOG_MASK(LOG_CRIT)
Packit 972a07
              | LOG_MASK(LOG_ERR)
Packit 972a07
              | LOG_MASK(LOG_WARNING) );
Packit 972a07
Packit 972a07
Log all messages up to debug: 
Packit 972a07
Packit 972a07
    setlogmask( LOG_UPTO(LOG_DEBUG) );
Packit 972a07
Packit 972a07
Packit 972a07
=item B<setlogsock()>
Packit 972a07
Packit 972a07
Sets the socket type and options to be used for the next call to C<openlog()>
Packit 972a07
or C<syslog()>.  Returns true on success, C<undef> on failure.
Packit 972a07
Packit 972a07
Being Perl-specific, this function has evolved along time.  It can currently
Packit 972a07
be called as follow:
Packit 972a07
Packit 972a07
=over
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<setlogsock($sock_type)>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<setlogsock($sock_type, $stream_location)> (added in Perl 5.004_02)
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<setlogsock($sock_type, $stream_location, $sock_timeout)> (added in
Packit 972a07
C<Sys::Syslog> 0.25)
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<setlogsock(\%options)> (added in C<Sys::Syslog> 0.28)
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
The available options are:
Packit 972a07
Packit 972a07
=over
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<type> - equivalent to C<$sock_type>, selects the socket type (or
Packit 972a07
"mechanism").  An array reference can be passed to specify several
Packit 972a07
mechanisms to try, in the given order.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<path> - equivalent to C<$stream_location>, sets the stream location.
Packit 972a07
Defaults to standard Unix location, or C<_PATH_LOG>.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<timeout> - equivalent to C<$sock_timeout>, sets the socket timeout
Packit 972a07
in seconds.  Defaults to 0 on all systems except S<Mac OS X> where it
Packit 972a07
is set to 0.25 sec.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<host> - sets the hostname to send the messages to.  Defaults to 
Packit 972a07
the local host.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<port> - sets the TCP or UDP port to connect to.  Defaults to the
Packit 972a07
first standard syslog port available on the system.
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
Packit 972a07
The available mechanisms are: 
Packit 972a07
Packit 972a07
=over
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<"native"> - use the native C functions from your C<syslog(3)> library
Packit 972a07
(added in C<Sys::Syslog> 0.15).
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<"eventlog"> - send messages to the Win32 events logger (Win32 only; 
Packit 972a07
added in C<Sys::Syslog> 0.19).
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<"tcp"> - connect to a TCP socket, on the C<syslog/tcp> or C<syslogng/tcp> 
Packit 972a07
service.  See also the C<host>, C<port> and C<timeout> options.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<"udp"> - connect to a UDP socket, on the C<syslog/udp> service.
Packit 972a07
See also the C<host>, C<port> and C<timeout> options.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<"inet"> - connect to an INET socket, either TCP or UDP, tried in that 
Packit 972a07
order.  See also the C<host>, C<port> and C<timeout> options.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<"unix"> - connect to a UNIX domain socket (in some systems a character 
Packit 972a07
special device).  The name of that socket is given by the C<path> option
Packit 972a07
or, if omitted, the value returned by the C<_PATH_LOG> macro (if your
Packit 972a07
system defines it), F</dev/log> or F</dev/conslog>, whichever is writable.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<"stream"> - connect to the stream indicated by the C<path> option, or,
Packit 972a07
if omitted, the value returned by the C<_PATH_LOG> macro (if your system
Packit 972a07
defines it), F</dev/log> or F</dev/conslog>, whichever is writable.  For
Packit 972a07
example Solaris and IRIX system may prefer C<"stream"> instead of C<"unix">. 
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<"pipe"> - connect to the named pipe indicated by the C<path> option,
Packit 972a07
or, if omitted, to the value returned by the C<_PATH_LOG> macro (if your
Packit 972a07
system defines it), or F</dev/log> (added in C<Sys::Syslog> 0.21).
Packit 972a07
HP-UX is a system which uses such a named pipe.
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<"console"> - send messages directly to the console, as for the C<"cons"> 
Packit 972a07
option of C<openlog()>.
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
The default is to try C<native>, C<tcp>, C<udp>, C<unix>, C<pipe>, C<stream>, 
Packit 972a07
C<console>.
Packit 972a07
Under systems with the Win32 API, C<eventlog> will be added as the first 
Packit 972a07
mechanism to try if C<Win32::EventLog> is available.
Packit 972a07
Packit 972a07
Giving an invalid value for C<$sock_type> will C<croak>.
Packit 972a07
Packit 972a07
B<Examples>
Packit 972a07
Packit 972a07
Select the UDP socket mechanism:
Packit 972a07
Packit 972a07
    setlogsock("udp");
Packit 972a07
Packit 972a07
Send messages using the TCP socket mechanism on a custom port:
Packit 972a07
Packit 972a07
    setlogsock({ type => "tcp", port => 2486 });
Packit 972a07
Packit 972a07
Send messages to a remote host using the TCP socket mechanism:
Packit 972a07
Packit 972a07
    setlogsock({ type => "tcp", host => $loghost });
Packit 972a07
Packit 972a07
Try the native, UDP socket then UNIX domain socket mechanisms: 
Packit 972a07
Packit 972a07
    setlogsock(["native", "udp", "unix"]);
Packit 972a07
Packit 972a07
=over
Packit 972a07
Packit 972a07
=item B<Note>
Packit 972a07
Packit 972a07
Now that the "native" mechanism is supported by C<Sys::Syslog> and selected 
Packit 972a07
by default, the use of the C<setlogsock()> function is discouraged because 
Packit 972a07
other mechanisms are less portable across operating systems.  Authors of 
Packit 972a07
modules and programs that use this function, especially its cargo-cult form 
Packit 972a07
C<setlogsock("unix")>, are advised to remove any occurrence of it unless they 
Packit 972a07
specifically want to use a given mechanism (like TCP or UDP to connect to 
Packit 972a07
a remote host).
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
=item B<closelog()>
Packit 972a07
Packit 972a07
Closes the log file and returns true on success.
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
Packit 972a07
=head1 THE RULES OF SYS::SYSLOG
Packit 972a07
Packit 972a07
I<The First Rule of Sys::Syslog is:>
Packit 972a07
You do not call C<setlogsock>.
Packit 972a07
Packit 972a07
I<The Second Rule of Sys::Syslog is:>
Packit 972a07
You B<do not> call C<setlogsock>.
Packit 972a07
Packit 972a07
I<The Third Rule of Sys::Syslog is:>
Packit 972a07
The program crashes, C<die>s, calls C<closelog>, the log is over.
Packit 972a07
Packit 972a07
I<The Fourth Rule of Sys::Syslog is:>
Packit 972a07
One facility, one priority.
Packit 972a07
Packit 972a07
I<The Fifth Rule of Sys::Syslog is:>
Packit 972a07
One log at a time.
Packit 972a07
Packit 972a07
I<The Sixth Rule of Sys::Syslog is:>
Packit 972a07
No C<syslog> before C<openlog>.
Packit 972a07
Packit 972a07
I<The Seventh Rule of Sys::Syslog is:>
Packit 972a07
Logs will go on as long as they have to. 
Packit 972a07
Packit 972a07
I<The Eighth, and Final Rule of Sys::Syslog is:>
Packit 972a07
If this is your first use of Sys::Syslog, you must read the doc.
Packit 972a07
Packit 972a07
Packit 972a07
=head1 EXAMPLES
Packit 972a07
Packit 972a07
An example:
Packit 972a07
Packit 972a07
    openlog($program, 'cons,pid', 'user');
Packit 972a07
    syslog('info', '%s', 'this is another test');
Packit 972a07
    syslog('mail|warning', 'this is a better test: %d', time);
Packit 972a07
    closelog();
Packit 972a07
Packit 972a07
    syslog('debug', 'this is the last test');
Packit 972a07
Packit 972a07
Another example:
Packit 972a07
Packit 972a07
    openlog("$program $$", 'ndelay', 'user');
Packit 972a07
    syslog('notice', 'fooprogram: this is really done');
Packit 972a07
Packit 972a07
Example of use of C<%m>:
Packit 972a07
Packit 972a07
    $! = 55;
Packit 972a07
    syslog('info', 'problem was %m');   # %m == $! in syslog(3)
Packit 972a07
Packit 972a07
Log to UDP port on C<$remotehost> instead of logging locally:
Packit 972a07
Packit 972a07
    setlogsock("udp", $remotehost);
Packit 972a07
    openlog($program, 'ndelay', 'user');
Packit 972a07
    syslog('info', 'something happened over here');
Packit 972a07
Packit 972a07
Packit 972a07
=head1 CONSTANTS
Packit 972a07
Packit 972a07
=head2 Facilities
Packit 972a07
Packit 972a07
=over 4
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_AUDIT> - audit daemon (IRIX); falls back to C<LOG_AUTH>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_AUTH> - security/authorization messages
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_AUTHPRIV> - security/authorization messages (private)
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_CONSOLE> - C</dev/console> output (FreeBSD); falls back to C<LOG_USER>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_CRON> - clock daemons (B<cron> and B<at>)
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_DAEMON> - system daemons without separate facility value
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_FTP> - FTP daemon
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_KERN> - kernel messages
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_INSTALL> - installer subsystem (Mac OS X); falls back to C<LOG_USER>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_LAUNCHD> - launchd - general bootstrap daemon (Mac OS X);
Packit 972a07
falls back to C<LOG_DAEMON>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_LFMT> - logalert facility; falls back to C<LOG_USER>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_LOCAL0> through C<LOG_LOCAL7> - reserved for local use
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_LPR> - line printer subsystem
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_MAIL> - mail subsystem
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_NETINFO> - NetInfo subsystem (Mac OS X); falls back to C<LOG_DAEMON>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_NEWS> - USENET news subsystem
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_NTP> - NTP subsystem (FreeBSD, NetBSD); falls back to C<LOG_DAEMON>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_RAS> - Remote Access Service (VPN / PPP) (Mac OS X);
Packit 972a07
falls back to C<LOG_AUTH>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_REMOTEAUTH> - remote authentication/authorization (Mac OS X);
Packit 972a07
falls back to C<LOG_AUTH>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_SECURITY> - security subsystems (firewalling, etc.) (FreeBSD);
Packit 972a07
falls back to C<LOG_AUTH>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_SYSLOG> - messages generated internally by B<syslogd>
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_USER> (default) - generic user-level messages
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_UUCP> - UUCP subsystem
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
Packit 972a07
=head2 Levels
Packit 972a07
Packit 972a07
=over 4
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_EMERG> - system is unusable
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_ALERT> - action must be taken immediately
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_CRIT> - critical conditions
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_ERR> - error conditions
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_WARNING> - warning conditions
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_NOTICE> - normal, but significant, condition
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_INFO> - informational message
Packit 972a07
Packit 972a07
=item *
Packit 972a07
Packit 972a07
C<LOG_DEBUG> - debug-level message
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
Packit 972a07
=head1 DIAGNOSTICS
Packit 972a07
Packit 972a07
=over
Packit 972a07
Packit 972a07
=item C<Invalid argument passed to setlogsock>
Packit 972a07
Packit 972a07
B<(F)> You gave C<setlogsock()> an invalid value for C<$sock_type>. 
Packit 972a07
Packit 972a07
=item C<eventlog passed to setlogsock, but no Win32 API available>
Packit 972a07
Packit 972a07
B<(W)> You asked C<setlogsock()> to use the Win32 event logger but the 
Packit 972a07
operating system running the program isn't Win32 or does not provides Win32
Packit 972a07
compatible facilities.
Packit 972a07
Packit 972a07
=item C<no connection to syslog available>
Packit 972a07
Packit 972a07
B<(F)> C<syslog()> failed to connect to the specified socket.
Packit 972a07
Packit 972a07
=item C<stream passed to setlogsock, but %s is not writable>
Packit 972a07
Packit 972a07
B<(W)> You asked C<setlogsock()> to use a stream socket, but the given 
Packit 972a07
path is not writable. 
Packit 972a07
Packit 972a07
=item C<stream passed to setlogsock, but could not find any device>
Packit 972a07
Packit 972a07
B<(W)> You asked C<setlogsock()> to use a stream socket, but didn't 
Packit 972a07
provide a path, and C<Sys::Syslog> was unable to find an appropriate one.
Packit 972a07
Packit 972a07
=item C<tcp passed to setlogsock, but tcp service unavailable>
Packit 972a07
Packit 972a07
B<(W)> You asked C<setlogsock()> to use a TCP socket, but the service 
Packit 972a07
is not available on the system. 
Packit 972a07
Packit 972a07
=item C<syslog: expecting argument %s>
Packit 972a07
Packit 972a07
B<(F)> You forgot to give C<syslog()> the indicated argument.
Packit 972a07
Packit 972a07
=item C<syslog: invalid level/facility: %s>
Packit 972a07
Packit 972a07
B<(F)> You specified an invalid level or facility.
Packit 972a07
Packit 972a07
=item C<syslog: too many levels given: %s>
Packit 972a07
Packit 972a07
B<(F)> You specified too many levels. 
Packit 972a07
Packit 972a07
=item C<syslog: too many facilities given: %s>
Packit 972a07
Packit 972a07
B<(F)> You specified too many facilities. 
Packit 972a07
Packit 972a07
=item C<syslog: level must be given>
Packit 972a07
Packit 972a07
B<(F)> You forgot to specify a level.
Packit 972a07
Packit 972a07
=item C<udp passed to setlogsock, but udp service unavailable>
Packit 972a07
Packit 972a07
B<(W)> You asked C<setlogsock()> to use a UDP socket, but the service 
Packit 972a07
is not available on the system. 
Packit 972a07
Packit 972a07
=item C<unix passed to setlogsock, but path not available>
Packit 972a07
Packit 972a07
B<(W)> You asked C<setlogsock()> to use a UNIX socket, but C<Sys::Syslog> 
Packit 972a07
was unable to find an appropriate an appropriate device.
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
Packit 972a07
=head1 HISTORY
Packit 972a07
Packit 972a07
C<Sys::Syslog> is a core module, part of the standard Perl distribution
Packit 972a07
since 1990.  At this time, modules as we know them didn't exist, the
Packit 972a07
Perl library was a collection of F<.pl> files, and the one for sending
Packit 972a07
syslog messages with was simply F<lib/syslog.pl>, included with Perl 3.0.
Packit 972a07
It was converted as a module with Perl 5.0, but had a version number
Packit 972a07
only starting with Perl 5.6.  Here is a small table with the matching
Packit 972a07
Perl and C<Sys::Syslog> versions.
Packit 972a07
Packit 972a07
    Sys::Syslog     Perl
Packit 972a07
    -----------     ----
Packit 972a07
       undef        5.0.0 ~ 5.5.4
Packit 972a07
       0.01         5.6.*
Packit 972a07
       0.03         5.8.0
Packit 972a07
       0.04         5.8.1, 5.8.2, 5.8.3
Packit 972a07
       0.05         5.8.4, 5.8.5, 5.8.6
Packit 972a07
       0.06         5.8.7
Packit 972a07
       0.13         5.8.8
Packit 972a07
       0.22         5.10.0
Packit 972a07
       0.27         5.8.9, 5.10.1 ~ 5.14.*
Packit 972a07
       0.29         5.16.*
Packit 972a07
       0.32         5.18.*
Packit 972a07
       0.33         5.20.*
Packit 972a07
       0.33         5.22.*
Packit 972a07
Packit 972a07
Packit 972a07
=head1 SEE ALSO
Packit 972a07
Packit 972a07
=head2 Other modules
Packit 972a07
Packit 972a07
L<Log::Log4perl> - Perl implementation of the Log4j API
Packit 972a07
Packit 972a07
L<Log::Dispatch> - Dispatches messages to one or more outputs
Packit 972a07
Packit 972a07
L<Log::Report> - Report a problem, with exceptions and language support
Packit 972a07
Packit 972a07
=head2 Manual Pages
Packit 972a07
Packit 972a07
L<syslog(3)>
Packit 972a07
Packit 972a07
SUSv3 issue 6, IEEE Std 1003.1, 2004 edition,
Packit 972a07
L<http://www.opengroup.org/onlinepubs/000095399/basedefs/syslog.h.html>
Packit 972a07
Packit 972a07
GNU C Library documentation on syslog,
Packit 972a07
L<http://www.gnu.org/software/libc/manual/html_node/Syslog.html>
Packit 972a07
Packit 972a07
FreeBSD documentation on syslog,
Packit 972a07
L<https://www.freebsd.org/cgi/man.cgi?query=syslog>
Packit 972a07
Packit 972a07
Solaris 11 documentation on syslog,
Packit 972a07
L<https://docs.oracle.com/cd/E53394_01/html/E54766/syslog-3c.html>
Packit 972a07
Packit 972a07
Mac OS X documentation on syslog,
Packit 972a07
L<http://developer.apple.com/documentation/Darwin/Reference/ManPages/man3/syslog.3.html>
Packit 972a07
Packit 972a07
IRIX documentation on syslog,
Packit 972a07
L<http://nixdoc.net/man-pages/IRIX/man3/syslog.3c.html>
Packit 972a07
Packit 972a07
AIX 5L 5.3 documentation on syslog,
Packit 972a07
L<http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf2/syslog.htm>
Packit 972a07
Packit 972a07
HP-UX 11i documentation on syslog,
Packit 972a07
L<http://docs.hp.com/en/B2355-60130/syslog.3C.html>
Packit 972a07
Packit 972a07
Tru64 documentation on syslog,
Packit 972a07
L<http://nixdoc.net/man-pages/Tru64/man3/syslog.3.html>
Packit 972a07
Packit 972a07
Stratus VOS 15.1,
Packit 972a07
L<http://stratadoc.stratus.com/vos/15.1.1/r502-01/wwhelp/wwhimpl/js/html/wwhelp.htm?context=r502-01&file=ch5r502-01bi.html>
Packit 972a07
Packit 972a07
=head2 RFCs
Packit 972a07
Packit 972a07
I<RFC 3164 - The BSD syslog Protocol>, L<http://www.faqs.org/rfcs/rfc3164.html>
Packit 972a07
-- Please note that this is an informational RFC, and therefore does not 
Packit 972a07
specify a standard of any kind.
Packit 972a07
Packit 972a07
I<RFC 3195 - Reliable Delivery for syslog>, L<http://www.faqs.org/rfcs/rfc3195.html>
Packit 972a07
Packit 972a07
=head2 Articles
Packit 972a07
Packit 972a07
I<Syslogging with Perl>, L<http://lexington.pm.org/meetings/022001.html>
Packit 972a07
Packit 972a07
=head2 Event Log
Packit 972a07
Packit 972a07
Windows Event Log,
Packit 972a07
L<http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wes/wes/windows_event_log.asp>
Packit 972a07
Packit 972a07
Packit 972a07
=head1 AUTHORS & ACKNOWLEDGEMENTS
Packit 972a07
Packit 972a07
Tom Christiansen E<lt>F<tchrist (at) perl.com>E<gt> and Larry Wall
Packit 972a07
E<lt>F<larry (at) wall.org>E<gt>.
Packit 972a07
Packit 972a07
UNIX domain sockets added by Sean Robinson
Packit 972a07
E<lt>F<robinson_s (at) sc.maricopa.edu>E<gt> with support from Tim Bunce 
Packit 972a07
E<lt>F<Tim.Bunce (at) ig.co.uk>E<gt> and the C<perl5-porters> mailing list.
Packit 972a07
Packit 972a07
Dependency on F<syslog.ph> replaced with XS code by Tom Hughes
Packit 972a07
E<lt>F<tom (at) compton.nu>E<gt>.
Packit 972a07
Packit 972a07
Code for C<constant()>s regenerated by Nicholas Clark E<lt>F<nick (at) ccl4.org>E<gt>.
Packit 972a07
Packit 972a07
Failover to different communication modes by Nick Williams
Packit 972a07
E<lt>F<Nick.Williams (at) morganstanley.com>E<gt>.
Packit 972a07
Packit 972a07
Extracted from core distribution for publishing on the CPAN by 
Packit 972a07
SE<eacute>bastien Aperghis-Tramoni E<lt>sebastien (at) aperghis.netE<gt>.
Packit 972a07
Packit 972a07
XS code for using native C functions borrowed from C<L<Unix::Syslog>>, 
Packit 972a07
written by Marcus Harnisch E<lt>F<marcus.harnisch (at) gmx.net>E<gt>.
Packit 972a07
Packit 972a07
Yves Orton suggested and helped for making C<Sys::Syslog> use the native 
Packit 972a07
event logger under Win32 systems.
Packit 972a07
Packit 972a07
Jerry D. Hedden and Reini Urban provided greatly appreciated help to 
Packit 972a07
debug and polish C<Sys::Syslog> under Cygwin.
Packit 972a07
Packit 972a07
Packit 972a07
=head1 BUGS
Packit 972a07
Packit 972a07
Please report any bugs or feature requests to
Packit 972a07
C<bug-sys-syslog (at) rt.cpan.org>, or through the web interface at
Packit 972a07
L<http://rt.cpan.org/Public/Dist/Display.html?Name=Sys-Syslog>.
Packit 972a07
I will be notified, and then you'll automatically be notified of progress on
Packit 972a07
your bug as I make changes.
Packit 972a07
Packit 972a07
Packit 972a07
=head1 SUPPORT
Packit 972a07
Packit 972a07
You can find documentation for this module with the perldoc command.
Packit 972a07
Packit 972a07
    perldoc Sys::Syslog
Packit 972a07
Packit 972a07
You can also look for information at:
Packit 972a07
Packit 972a07
=over
Packit 972a07
Packit 972a07
=item * Perl Documentation
Packit 972a07
Packit 972a07
L<http://perldoc.perl.org/Sys/Syslog.html>
Packit 972a07
Packit 972a07
=item * MetaCPAN
Packit 972a07
Packit 972a07
L<https://metacpan.org/module/Sys::Syslog>
Packit 972a07
Packit 972a07
=item * Search CPAN
Packit 972a07
Packit 972a07
L<http://search.cpan.org/dist/Sys-Syslog/>
Packit 972a07
Packit 972a07
=item * AnnoCPAN: Annotated CPAN documentation
Packit 972a07
Packit 972a07
L<http://annocpan.org/dist/Sys-Syslog>
Packit 972a07
Packit 972a07
=item * CPAN Ratings
Packit 972a07
Packit 972a07
L<http://cpanratings.perl.org/d/Sys-Syslog>
Packit 972a07
Packit 972a07
=item * RT: CPAN's request tracker
Packit 972a07
Packit 972a07
L<http://rt.cpan.org/Dist/Display.html?Queue=Sys-Syslog>
Packit 972a07
Packit 972a07
=back
Packit 972a07
Packit 972a07
The source code is available on Git Hub:
Packit 972a07
L<https://github.com/maddingue/Sys-Syslog/>
Packit 972a07
Packit 972a07
Packit 972a07
=head1 COPYRIGHT
Packit 972a07
Packit 972a07
Copyright (C) 1990-2012 by Larry Wall and others.
Packit 972a07
Packit 972a07
Packit 972a07
=head1 LICENSE
Packit 972a07
Packit 972a07
This program is free software; you can redistribute it and/or modify it
Packit 972a07
under the same terms as Perl itself.
Packit 972a07
Packit 972a07
=cut
Packit 972a07
Packit 972a07
=begin comment
Packit 972a07
Packit 972a07
Notes for the future maintainer (even if it's still me..)
Packit 972a07
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Packit 972a07
Packit 972a07
Using Google Code Search, I search who on Earth was relying on $host being 
Packit 972a07
public. It found 5 hits: 
Packit 972a07
Packit 972a07
* First was inside Indigo Star Perl2exe documentation. Just an old version 
Packit 972a07
of Sys::Syslog. 
Packit 972a07
Packit 972a07
Packit 972a07
* One real hit was inside DalWeathDB, a weather related program. It simply 
Packit 972a07
does a 
Packit 972a07
Packit 972a07
    $Sys::Syslog::host = '127.0.0.1';
Packit 972a07
Packit 972a07
- L<http://www.gallistel.net/nparker/weather/code/>
Packit 972a07
Packit 972a07
Packit 972a07
* Two hits were in TPC, a fax server thingy. It does a 
Packit 972a07
Packit 972a07
    $Sys::Syslog::host = $TPC::LOGHOST;
Packit 972a07
Packit 972a07
but also has this strange piece of code:
Packit 972a07
Packit 972a07
    # work around perl5.003 bug
Packit 972a07
    sub Sys::Syslog::hostname {}
Packit 972a07
Packit 972a07
I don't know what bug the author referred to.
Packit 972a07
Packit 972a07
- L<http://www.tpc.int/>
Packit 972a07
- L<ftp://ftp-usa.tpc.int/pub/tpc/server/UNIX/>
Packit 972a07
Packit 972a07
Packit 972a07
* Last hit was in Filefix, which seems to be a FIDOnet mail program (!).
Packit 972a07
This one does not use $host, but has the following piece of code:
Packit 972a07
Packit 972a07
    sub Sys::Syslog::hostname
Packit 972a07
    {
Packit 972a07
        use Sys::Hostname;
Packit 972a07
        return hostname;
Packit 972a07
    }
Packit 972a07
Packit 972a07
I guess this was a more elaborate form of the previous bit, maybe because 
Packit 972a07
of a bug in Sys::Syslog back then?
Packit 972a07
Packit 972a07
- L<ftp://ftp.kiae.su/pub/unix/fido/>
Packit 972a07
Packit 972a07
Packit 972a07
Links
Packit 972a07
-----
Packit 972a07
Linux Fast-STREAMS
Packit 972a07
- L<http://www.openss7.org/streams.html>
Packit 972a07
Packit 972a07
II12021: SYSLOGD HOWTO TCPIPINFO (z/OS, OS/390, MVS)
Packit 972a07
- L<http://www-1.ibm.com/support/docview.wss?uid=isg1II12021>
Packit 972a07
Packit 972a07
Getting the most out of the Event Viewer
Packit 972a07
- L<http://www.codeproject.com/dotnet/evtvwr.asp?print=true>
Packit 972a07
Packit 972a07
Log events to the Windows NT Event Log with JNI
Packit 972a07
- L<http://www.javaworld.com/javaworld/jw-09-2001/jw-0928-ntmessages.html>
Packit 972a07
Packit 972a07
=end comment
Packit 972a07