#!/usr/bin/perl
# rpm helper scriptlet to add an entry into default syslog implementation
# $Id$
use Getopt::Std;
use strict;

my @facilities = qw/auth authpriv cron daemon \
                    kern lpr mail mark news syslog \
                    user uucp local0 local1 local2 \
                    local3 local4 local5 local6 local7/;
my %facilities = map { $_ => 1 } @facilities;
my @priorities = qw/debug info notice warning err crit alert emerg/;
my $i;
my %priorities = map { $_ => $i++ } @priorities;

main(@ARGV) unless caller();

sub main {
    my %opts = ( 
        s => '/dev/log',
        m => 'debug',
        M => 'emerg'
    );
    getopts('s:m:M:', \%opts);
    my ($source, $min, $max) = @opts{qw/s m M/};

    die <<EOF if @ARGV < 4;
usage: $0 [options] <pkg> <nb> <facility> <dest>
Available options:
-s <source>   source (default: /dev/log)
-m <priority> min priority (default: debug)
-M <priority> max priority (default: emerg)
EOF
    my ($package, $number, $dest, $facility) = @ARGV;

    # don't do anything for upgrade
    exit(0) if $number == 2;

    # check arguments
    die "invalid facility '$facility'" if $facility && !$facilities{$facility};

    die "invalid min priority '$min'" if $min && ! defined $priorities{$min};
    die "invalid max priority '$max'" if $max && ! defined $priorities{$max};
    die "maximum priority '$max' lower than minimum priority '$min'"
        if $min && $max && ($priorities{$max} < $priorities{$min});

    add_rsyslog_entry($package, $source, $dest, $facility, $min, $max);
}

sub add_rsyslog_entry {
    my ($package, $source, $dest, $facility, $min, $max) = @_;

    # compute selector
    my $selector = get_selector($facility, $min, $max);

    # append entry
    open(my $out, '>', "/etc/rsyslog.d/$package.conf")
        or die "Can't open /etc/rsyslog.d/$package.conf for writing: $!";
    print $out "# Automatically added by $package installation\n";
    print $out "\$AddUnixListenSocket $source\n" if $source ne '/dev/log';
    print $out "$selector\t-$dest\n";
    close($out);

    # relaunch rsyslog
    system('service rsyslog condrestart 2>&1 >/dev/null');
}

sub add_new_source {
    my ($source, $file) = @_;

    my ($content, $changed);
    open(my $in, '<', $file)
        or die "Can't open $file for reading: $!";

    while (my $line = <$in>) {
        if ($line =~ /^SYSLOGD_OPTIONS=(.*)/) {
            my $options = $1;
            if ($options) {
                my $quote;
                if ($options !~ /-a\s+$source/) {
                    if ($options =~ /^(["'])(.*)\1$/) {
                        $quote = $1;
                        $options = $2;
                    } else {
                        $quote = '"';
                    }
                    $options = $quote . $options . " -a $source" . $quote;
                    $changed = 1;
                }
            } else {
                $options = "\"-a $source\"";
                $changed = 1;
            }

            $content .= "SYSLOGD_OPTIONS=$options\n";
        } else {
            $content .= $line;
        }
    }
    close($in);

    if ($changed) {
        open(my $out, '>', $file)
            or die "Can't open $file for writing: $!";
        print $out $content;
        close($out);
    }
}

sub get_selector {
    my ($facility, $min, $max) = @_;

    my $selector;
    if ($max eq 'emerg') {
        if ($min eq 'debug') {
            $selector = "$facility.*";
        } else {
            $selector = "$facility.$min";
        }
    } else {
        for my $i ($priorities{$min} .. $priorities{$max}) {
            $selector .= ';' if $selector;
            $selector .= "$facility.=$priorities[$i]";
        }
    }

    return $selector;
}

1;
