#!/usr/bin/perl #------------------------------------------------------------------------------ # Launch update process for all config files found in a particular directory. # See COPYING.TXT file about AWStats GNU General Public License. #------------------------------------------------------------------------------ # $Revision: 1.15 $ - $Author: eldy $ - $Date: 2006/07/23 22:57:48 $ use File::Copy; use Parallel::ForkManager; #------------------------------------------------------------------------------ # Defines #------------------------------------------------------------------------------ my $REVISION='$Revision: 1.15 $'; $REVISION =~ /\s(.*)\s/; $REVISION=$1; my $VERSION="1.0 (build $REVISION)"; # Default value of DIRCONFIG my $DIRCONFIG = "/etc/awstats"; my $Debug=0; my $max_processes = 2; my $Awstats='/pack/awstats/awstats.pl'; my $AwstatsProg='/pack/awstats/awstats_buildstaticpages.pl'; my $LastLine=''; my $wwwroot='/var/www'; my $folder='web/awstats'; my $indexfile=''; use vars qw($dataDir $outputdir); #------------------------------------------------------------------------------ # Functions #------------------------------------------------------------------------------ #------------------------------------------------------------------------------ # Function: Write error message and exit # Parameters: $message # Input: None # Output: None # Return: None #------------------------------------------------------------------------------ sub error { print STDERR "Error: $_[0].\n"; exit 1; } #------------------------------------------------------------------------------ # Function: Write debug message and exit # Parameters: $string $level # Input: %HTMLOutput $Debug=required level $DEBUGFORCED=required level forced # Output: None # Return: None #------------------------------------------------------------------------------ sub debug { my $level = $_[1] || 1; if ($Debug >= $level) { my $debugstring = $_[0]; if ($ENV{"GATEWAY_INTERFACE"}) { $debugstring =~ s/^ /   /; $debugstring .= "
"; } print localtime(time)." - DEBUG $level - $debugstring\n"; } } sub parse_conf { my $CONF = $_[0]; my $configFile = $_[1]; while (<$CONF>) { chomp $_; s/\r//; # Empty lines if ($_ =~ /^\s*$/) { next; } # Includes if ($_ =~ /^Include \"([^\"]+)\"/ || $_ =~ /^#include \"([^\"]+)\"/) { my $includeFile = $1; if ($includeFile !~ /^[\\\/]/) { if ($configFile =~ /^(.*[\\\/])[^\\\/]*$/) { $includeFile = "$1$includeFile"; } } debug("Include $includeFile"); open(CONFIG, $includeFile) || error("Unable to open included configuration file $includeFile - $!"); &parse_conf(*CONFIG, $includeFile); close(CONFIG); } # Output directory if ($_ =~ /^#output \"([^\"]+)\"/) { $outputdir = $1; } # Comments if ($_ =~ /^\s*#/) { next; } $_ =~ s/\s#.*$//; my ($param, $value) = split(/=/, $_, 2); $param =~ s/^\s+//; $param =~ s/\s+$//; if (! $param) { next; } if (! defined $value) { next; } if ($value) { $value =~ s/^\s+//; $value =~ s/\s+$//; $value =~ s/^\"//; $value =~ s/\"$//; } if ($param =~ /^DirData/) { $dataDir = $value; } } } #------------------------------------------------------------------------------ # MAIN #------------------------------------------------------------------------------ # Change default value if options are used my $helpfound=0;my $nowfound=0; my %confexcluded=(); for (0..@ARGV-1) { if ($ARGV[$_] =~ /^-*h/i) { $helpfound=1; last; } if ($ARGV[$_] =~ /^-*awstatsprog=(.*)/i) { $Awstats="$1"; next; } if ($ARGV[$_] =~ /^-*configdir=(.*)/i) { $DIRCONFIG="$1"; next; } if ($ARGV[$_] =~ /^-*excludeconf=(.*)/i) { #try to get the different files to exclude @conftoexclude = split(/,/, $1); foreach (@conftoexclude) { $confexcluded{"$_"}=1; } next; } if ($ARGV[$_] =~ /^-*debug=(\d+)/i) { $Debug=$1; next; } if ($ARGV[$_] =~ /^-*lastline=(\d+)/i) { $LastLine=$1; next; } if ($ARGV[$_] =~ /^now/i) { $nowfound=1; next; } } # Show usage help my $DIR; my $PROG; my $Extension; ($DIR=$0) =~ s/([^\/\\]*)$//; ($PROG=$1) =~ s/\.([^\.]*)$//; $Extension=$1; if (!$nowfound || $helpfound || ! @ARGV) { print "----- $PROG $VERSION (c) Laurent Destailleur -----\n"; print "awstats_updateall launches update process for all AWStats config files (except\n"; print "awstats.model.conf) found in a particular directory, so you can easily setup a\n"; print "cron/scheduler job. The scanned directory is by default $DIRCONFIG.\n"; print "\n"; print "Usage: $PROG.$Extension now [options]\n"; print "\n"; print "Where options are:\n"; print " -awstatsprog=pathtoawstatspl\n"; print " -configdir=directorytoscan\n"; print " -excludeconf=conftoexclude[,conftoexclude2,...] (Note: awstats.model.conf is always excluded)\n"; print "\n"; exit 0; } debug("Scan directory $DIRCONFIG"); # Scan directory $DIRCONFIG opendir(DIR, $DIRCONFIG) || error("Can't scan directory $DIRCONFIG"); my @filesindir = grep { /^awstats\.(.+)\.conf$/ } sort readdir(DIR); closedir(DIR); debug("List of files found :".join(", ",@filesindir)); # Build file list my @files=(); foreach my $file (@filesindir) { if ($confexcluded{$file}) { next; } # Should be useless if ($file =~ /^awstats\.(.+)\.conf$/) { my $conf=$1; $conf =~ s/\.$//; if ($conf eq 'model') { next; } if ($confexcluded{$conf}) { next; } } push @files, $file; } debug("List of files qualified :".join(", ",@files)); # Run update process for each config file found if (@files) { # Check if AWSTATS prog is found my $AwstatsFound=0; if (-s "$Awstats") { $AwstatsFound=1; } elsif (-s "/usr/local/awstats/wwwroot/cgi-bin/awstats.pl") { $Awstats="/usr/local/awstats/wwwroot/cgi-bin/awstats.pl"; $AwstatsFound=1; } if (! $AwstatsFound) { error("Can't find AWStats program ('$Awstats').\nUse -awstatsprog option to solve this"); } debug("Awstats=$Awstats"); # Check AwstatsProg if (-s $AwstatsProg) { debug("AwstatsProg=$AwstatsProg"); } else { error("Can't find AwstatsProg - modify awstats_updateall.pl"); } my ($nowsec, $nowmin, $nowhour, $nowday, $nowmonth, $nowyear, $nowwday, $nowyday, $nowisdst) = localtime(time); $nowmonth++; if ($nowyear < 100) { $nowyear += 2000; } else { $nowyear += 1900; } my %periods = (); $periods{$nowyear}{$nowmonth} = 1; if ($nowday == 1) { if ($nowmonth == 1) { $periods{$nowyear-1}{12} = 1; } else { $periods{$nowyear}{$nowmonth-1} = 1; } } $periods{$nowyear}{"all"} = 1; my $pm = new Parallel::ForkManager($max_processes); foreach (@files) { if ($_ =~ /^awstats\.(.+)\.conf$/) { $pm->start and next; my $domain = $1||"default"; $domain =~ s/\.$//; my $conf = "$DIRCONFIG/$_"; $outputdir = ""; $dataDir = ""; # Parsing configuration file debug("Parsing configuration file $conf"); open(CONF, $conf) || error("Unable to open configuration file $conf - $!"); &parse_conf(*CONF, $conf); close(CONF); if ($dataDir eq "") { error("No DirData found"); } debug("DirData: $dataDir"); if ($outputdir eq "") { $outputdir = "$wwwroot/$domain/$folder"; } if ($outputdir !~ /[\\\/]$/) { $outputdir .= "/"; } debug("output: $outputdir"); # Update stats my $command = "$Awstats -config=$domain -configdir=$DIRCONFIG -update"; if ($LastLine) { $command.=" -lastline=$LastLine"; } debug("Running '$command' to update stats for $domain"); my $output = `$command 2>&1`; if ($Debug >= 2) { print $output; } # Create directory if it doesn't exist if (! -d $outputdir) { my $res = mkdir($outputdir, 0755); if (! $res) { error("Can't create directory $outputdir"); } } # indexfile if ($indexfile ne '') { my $tmp = $indexfile; $tmp =~ s/^.*[\\\/]([^\\\/]*)$/$1/; $tmp = "$outputdir$tmp"; if (! -s $tmp) { copy($indexfile, $tmp); } } # Generate stats foreach my $year (sort keys %periods) { foreach my $month (sort keys %{$periods{$year}}) { if ($month ne "all" && $month < 10) { $month = "0$month"; } my $command = "$AwstatsProg -awstatsprog=$Awstats -config=$domain -configdir=$DIRCONFIG"; $command .= " -dir=$outputdir -month=$month -year=$year"; debug("Running '$command' to update stats for $domain"); my $output = `$command 2>&1`; if ($Debug >= 2) { print $output; } } } $pm->finish; } } $pm->wait_all_children; } else { print "No AWStats config file found in $DIRCONFIG\n"; } 0; # Do not remove this line