#! /usr/bin/perl

# Copyright (c) 1997-9,2001,3,7-8 by Martin Schulze <joey@infodrom.org>

# 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, USA.

use strict;
use warnings;
use Getopt::Long;

my $conf = "/etc/syslog.conf";
my $opt_daily = 1;
my $opt_all = 0;
my $opt_auth = 0;
my $opt_ign_size = 0;
my $opt_news = 0;
my $opt_skip = '';
my $opt_large = 1024*1024;

sub usage
{
    print STDERR
"
Debian GNU/Linux syslogd-listfiles.  Copyright (c) 1997-9,2001,3,7-8
Martin Schulze.  This is free software; see the GNU General Public Licence
version 2 or later for copying conditions.  There is NO warranty.

Usage: syslogd-listfiles <options>
Options: -f file	specifies another syslog.conf file
         -a | --all	list all files (including news)
         --auth		list all files containing auth.<some prio>
	 --ignore-size  don't rotate files which got too large
         --large nnn	define what is large in bytes (default: 1MB)
         --news		include news logfiles, too
         -w | --weekly	use weekly pattern instead of daily
         -s pattern	skip files matching pattern
";
    exit 0;
}

# Test if the file was already rotated within the last n hours
# with n=5
#
sub rotated
{
    my $file = shift;
    my $nfile;
    my $delta = 5 * 60 * 60;
    my $now = time();
    
    # /var/log/file -> /var/log/file.0
    $nfile = $file . ".0";
    if (-r $nfile) {
	if (($now - (stat $nfile)[9]) > $delta) {
	    return 0;
	} else {
	    return 1;
	}
    }

    # /var/log/file -> /var/log/OLD/file.0
    $nfile =~ s,(.*)/([^/]+),$1/OLD/$2,;
    if (-r $nfile) {
	if (($now - (stat $nfile)[9]) > $delta) {
	    return 0;
	} else {
	    return 1;
	}
    }

    return 0;
}

GetOptions('config|f=s' => \$conf,
	   'skip=s' => \$opt_skip,
	   'large=i' => \$opt_large,
	   'weekly' => sub { $opt_daily = 0; },
	   'all|a' => \$opt_all,
	   'auth' => \$opt_auth,
	   'ignore-size' => \$opt_ign_size,
	   'news' => \$opt_news,
	   'help' => \&usage) or usage();

open (C, $conf) || die "Can't open $conf, $!";
my $line = '';
my @lines;
while (<C>) {
    next if (/^(\#|$)/);
    chomp;

    s/\s*(\S.*)$/$1/ if ($line);

    $line .= $_;
    chop ($line) if (/\\$/);
    if (!/\\$/) {
	$line =~ s/\s+/\t/;
	$line =~ s/\t-/\t/;
	push (@lines, $line) if ($line =~ /\t\/(?!dev\/)/);
	$line = "";
    }
}
close (C);

my %output;
foreach my $line (@lines) {
    my ($pat,$file) = split (/\t/,$line);

    # These files are handled by news.daily from INN, so we ignore them
    next if (!$opt_news &&!$opt_all && ($pat =~ /news\.(\*|crit|err|info|notice)/));

    if ($opt_all) {
	$output{$file} = 1;
    } elsif ($opt_auth) {
	$output{$file} = 1 if ($pat =~ /auth[^\.]*\.(?!none).*/);
    } else {
	my $everything = ($pat =~ /\*\.\*/);
	$output{$file} = 1 if (($everything && $opt_daily)
			       || (!$everything && !$opt_daily && !rotated ($file))
			       || (!$opt_ign_size && (-r $file && (stat _)[7] >= $opt_large) && $opt_daily)
			       );
    }
}

foreach my $file (keys (%output)) {
    my $skip = $file;
    if (!length($opt_skip) ||  $skip !~ /$opt_skip/) {
	printf "%s\n", $file;
    }
}
