# webalizer-lib.pl # Common functions for editing the webalizer config file use strict; use warnings; no warnings 'redefine'; no warnings 'uninitialized'; BEGIN { push(@INC, ".."); }; use WebminCore; &init_config(); our ($module_root_directory, %text, %config, $module_config_directory); our $cron_cmd = "$module_config_directory/webalizer.pl"; our $custom_logs_file = "$module_config_directory/custom-logs"; our %access = &get_module_acl(); # Use sample config if needed if (!-r $config{'webalizer_conf'} && $config{'alt_conf'} && -r $config{'alt_conf'}) { ©_source_dest($config{'alt_conf'}, $config{'webalizer_conf'}); } # get_config([logfile]) # Parse the webalizer config file for a single logfile or global sub get_config { my ($logfile) = @_; my $file; if ($logfile) { $file = &config_file_name($logfile); } $file = $config{'webalizer_conf'} if (!$file || !-r $file); -r $file || &error("Webalizer config file $file does not exist!"); my @rv; my $lnum = 0; open(FILE, "<".$file); while(<FILE>) { s/\r|\n//g; s/#.*$//; if (/^\s*(\S+)\s+(.*)/) { push(@rv, { 'name' => $1, 'value' => $2, 'line' => $lnum, 'file' => $file, 'index' => scalar(@rv) }); } $lnum++; } close(FILE); return \@rv; } # save_directive(&config, name, [value]*) sub save_directive { my ($conf, $name, @values) = @_; my @old = &find($name, $conf); my $lref = &read_file_lines($conf->[0]->{'file'}); for(my $i=0; $i<@old || $i<@values; $i++) { if ($i < @old && $i < @values) { # Just replacing a line $lref->[$old[$i]->{'line'}] = "$name $values[$i]"; } elsif ($i < @old) { # Deleting a line splice(@$lref, $old[$i]->{'line'}, 1); &renumber($conf, $old[$i]->{'line'}, -1); } elsif ($i < @values) { # Adding a line if (@old) { # after the last one of the same type splice(@$lref, $old[$#old]->{'line'}+1, 0, "$name $values[$i]"); &renumber($conf, $old[$#old]->{'line'}+1, 1); } else { # at end of file push(@$lref, "$name $values[$i]"); } } } } # renumber(&config, line, offset) sub renumber { my ($conf, $line, $offset) = @_; foreach my $c (@$conf) { $c->{'line'} += $offset if ($c->{'line'} >= $line); } } # config_file_name(logfile) sub config_file_name { my ($p) = @_; $p =~ s/^\///; $p =~ s/\//_/g; return "$module_config_directory/$p.conf"; } # find(name, &config) sub find { my ($name, $conf) = @_; my @rv; foreach my $c (@$conf) { push(@rv, $c) if (lc($c->{'name'}) eq lc($name)); } return wantarray ? @rv : $rv[0]; } # find_value(name, &config) sub find_value { my @rv = map { $_->{'value'} } &find(@_); return wantarray ? @rv : $rv[0]; } # all_log_files(file) # Given a base log file name, returns a list of all log files in the same # directory that start with the same name sub all_log_files { my ($file) = @_; $file =~ /^(.*)\/([^\/]+)$/; my $dir = $1; my $base = $2; my @rv; opendir(DIR, $dir); foreach my $f (readdir(DIR)) { if ($f =~ /^\Q$base\E/ && -f "$dir/$f") { push(@rv, "$dir/$f"); } } closedir(DIR); return @rv; } # get_log_config(path) # Get the configuration for some log file sub get_log_config { my ($path) = @_; my %rv; &read_file(&log_config_name($path), \%rv) || return undef; return \%rv; } # save_log_config(path, &config) sub save_log_config { my ($path, $conf) = @_; return &write_file(&log_config_name($path), $conf); } # log_config_name(path) sub log_config_name { my ($p) = @_; $p =~ s/^\///; $p =~ s/\//_/g; return "$module_config_directory/$p.log"; } # generate_report(file, handle, escape) # Generates a new webalizer report to the configured directory, and sends # any output to the given file handle. Returns 1 if any of the log files # worked OK. sub generate_report { my $h = $_[1]; my $lconf = &get_log_config($_[0]); my @all = $config{'skip_old'} ? ( $_[0] ) : &all_log_files($_[0]); if (!@all) { print $h "Log file $_[0] does not exist\n"; return; } my %mtime; foreach my $a (@all) { my @st = stat($a); $mtime{$a} = $st[9]; } my $prog = &get_webalizer_prog(); my $type = $lconf->{'type'} == 1 ? "" : $lconf->{'type'} == 2 ? "-F squid" : $lconf->{'type'} == 3 ? "-F ftp" : ""; my $cfile = &config_file_name($_[0]); my $conf = -r $cfile ? "-c $cfile" : ""; if ($lconf->{'over'} && !&is_readonly_mode()) { unlink("$lconf->{'dir'}/webalizer.current"); unlink("$lconf->{'dir'}/webalizer.hist"); } unlink("$lconf->{'dir'}/__db.dns_cache.db"); my $user = $lconf->{'user'} || "root"; if ($user ne "root" && -r $cfile) { chmod(0644, $cfile); } if (!-d $lconf->{'dir'}) { mkdir($lconf->{'dir'}, 0755); if ($user ne "root") { my @uinfo = getpwnam($user); chown($uinfo[2], $uinfo[3], $lconf->{'dir'}); } } my $anyok = 0; foreach my $f (sort { $mtime{$a} <=> $mtime{$b} } @all) { my $cmd = "$config{'webalizer'} $conf -o ". quotemeta($lconf->{'dir'})." $type -p ".quotemeta($f); if ($user ne "root") { $cmd = &command_as_user($user, 0, $cmd); } my $fh = "OUT"; &open_execute_command($fh, "$cmd 2>&1", 1); while(<$fh>) { print $h $_[2] ? &html_escape($_) : $_; } close($fh); $anyok = 1 if (!$?); &additional_log("exec", undef, $cmd); } return $anyok; } # spaced_buttons(button, ...) sub spaced_buttons { my $pc = int(100 / scalar(@_)); print "<table width=100%><tr>\n"; foreach $b (@_) { my $al = $b eq $_[0] ? "align=left" : $b eq $_[@_-1] ? "align=right" : "align=center"; print "<td width=$pc% $al>$b</td>\n"; } print "</table>\n"; } # read_custom_logs() sub read_custom_logs { open(LOGS, "<".$custom_logs_file) || return (); my @rv = map { /^(.*\S)\s+(\S+)/; { 'file' => $1, 'type' => $2 } } <LOGS>; close(LOGS); return @rv; } # write_custom_logs(log, ...) sub write_custom_logs { my $fh = "LOGS"; &open_tempfile($fh, ">$custom_logs_file"); &print_tempfile($fh, map { "$_->{'file'} $_->{'type'}\n" } @_); &close_tempfile($fh); } # can_edit_log(file) sub can_edit_log { foreach my $d (split(/\s+/, $access{'dir'})) { my $ok = &is_under_directory($d, $_[0]); return 1 if ($ok); } return 0; } # get_webalizer_version(&out) # Returns the Webalizer version number, and puts output into the given scalar # reference. sub get_webalizer_version { my $out = &backquote_command("$config{'webalizer'} -V 2>&1 </dev/null"); ${$_[0]} = $out; return $out =~ /\sV(\S+)/ ? $1 : undef; } # get_webalizer_prog() # Returns either 'webalizer' or 'awffull' sub get_webalizer_prog { return $config{'webalizer'} =~ /awffull/i ? "awffull" : "webalizer"; } # get_all_logs() # Returns a list of all log files the module can report on sub get_all_logs { # Query apache and squid for their logfiles my %auto = map { $_, 1 } split(/,/, $config{'auto'}); my @logs; if (&foreign_installed("apache") && $auto{'apache'}) { &foreign_require("apache", "apache-lib.pl"); my $conf = &apache::get_config(); my @dirs = ( &apache::find_all_directives($conf, "CustomLog"), &apache::find_all_directives($conf, "TransferLog") ); my $root = &apache::find_directive_struct("ServerRoot", $conf); my $d; foreach $d (@dirs) { my $lf = $d->{'words'}->[0]; if ($lf =~ /^\|\S+writelogs.pl\s+\S+\s+(\S+)/) { # Virtualmin log writer .. use real file $lf = $1; } next if ($lf =~ /^\|/); if ($lf !~ /^\//) { $lf = "$root->{'words'}->[0]/$lf"; } open(FILE, "<".$lf); my $line = <FILE>; close(FILE); if (!$line || $line =~ /^([a-zA-Z0-9\.\-\:]+)\s+\S+\s+\S+\s+\[\d+\/[a-zA-z]+\/\d+:\d+:\d+:\d+\s+[0-9\+\-]+\]/) { push(@logs, { 'file' => $lf, 'type' => 1 }); } } } # Add log file from Squid if (&foreign_installed("squid") && $auto{'squid'}) { &foreign_require("squid", "squid-lib.pl"); my $conf = &squid::get_config(); my $log = &squid::find_value("cache_access_log", $conf); $log = "$squid::config{'log_dir'}/access.log" if (!$log && -d $squid::config{'log_dir'}); push(@logs, { 'file' => $log, 'type' => 2 }) if ($log); } # Add log file from proftpd if (&foreign_installed("proftpd") && $auto{'proftpd'}) { &foreign_require("proftpd", "proftpd-lib.pl"); my $conf = &proftpd::get_config(); my $global = &proftpd::find_directive_struct("Global", $conf); my $log = &proftpd::find_directive("TransferLog", $global->{'members'}) || "/var/log/xferlog"; push(@logs, { 'file' => $log, 'type' => 3 }); } # Add log file from wu-ftpd if (&foreign_installed("wuftpd") && $auto{'wuftpd'}) { my %wconfig = &foreign_config("wuftpd"); push(@logs, { 'file' => $wconfig{'log_file'}, 'type' => 3 }); } # Add custom logfiles push(@logs, map { $_->{'custom'} = 1; $_ } &read_custom_logs()); foreach my $l (@logs) { $l->{'custom'} ||= 0; } return @logs; } # lconf_to_cron(&lconf, &job) # Copy fields from a webalizer config to a cron job sub lconf_to_cron { my ($lconf, $job) = @_; $job->{'special'} = $lconf->{'special'}; $job->{'mins'} = $lconf->{'mins'}; $job->{'hours'} = $lconf->{'hours'}; $job->{'days'} = $lconf->{'days'}; $job->{'months'} = $lconf->{'months'}; $job->{'weekdays'} = $lconf->{'weekdays'}; } 1;
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
images | Folder | 0755 |
|
|
lang | Folder | 0755 |
|
|
CHANGELOG | File | 855 B | 0644 |
|
acl_security.pl | File | 1.2 KB | 0755 |
|
backup_config.pl | File | 1.63 KB | 0755 |
|
cgi_args.pl | File | 840 B | 0755 |
|
config | File | 158 B | 0644 |
|
config-ALL-linux | File | 107 B | 0644 |
|
config-debian-linux-4.0-ALL | File | 172 B | 0644 |
|
config-freebsd | File | 176 B | 0644 |
|
config-gentoo-linux | File | 107 B | 0644 |
|
config-mandrake-linux-10.3-ALL | File | 107 B | 0644 |
|
config-netbsd | File | 120 B | 0644 |
|
config-openbsd | File | 179 B | 0644 |
|
config-openmamba-linux | File | 113 B | 0644 |
|
config-solaris-10-ALL | File | 175 B | 0644 |
|
config-syno-linux | File | 222 B | 0644 |
|
config.info | File | 425 B | 0644 |
|
config.info.ca | File | 514 B | 0644 |
|
config.info.cs | File | 226 B | 0644 |
|
config.info.de | File | 471 B | 0644 |
|
config.info.es | File | 310 B | 0644 |
|
config.info.fa | File | 365 B | 0644 |
|
config.info.fi | File | 0 B | 0644 |
|
config.info.fr | File | 465 B | 0644 |
|
config.info.hr | File | 0 B | 0644 |
|
config.info.hu | File | 407 B | 0644 |
|
config.info.ms | File | 387 B | 0644 |
|
config.info.nl | File | 396 B | 0644 |
|
config.info.no | File | 379 B | 0644 |
|
config.info.pl | File | 488 B | 0644 |
|
config.info.ru | File | 308 B | 0644 |
|
config.info.tr | File | 372 B | 0644 |
|
config.info.uk | File | 314 B | 0644 |
|
defaultacl | File | 46 B | 0644 |
|
edit_global.cgi | File | 4.8 KB | 0755 |
|
edit_log.cgi | File | 3.67 KB | 0755 |
|
index.cgi | File | 5.13 KB | 0755 |
|
install_check.pl | File | 545 B | 0755 |
|
log_parser.pl | File | 707 B | 0755 |
|
mass.cgi | File | 1.81 KB | 0755 |
|
module.info | File | 201 B | 0644 |
|
module.info.af | File | 0 B | 0644 |
|
module.info.af.auto | File | 131 B | 0644 |
|
module.info.ar | File | 0 B | 0644 |
|
module.info.ar.auto | File | 184 B | 0644 |
|
module.info.be | File | 0 B | 0644 |
|
module.info.be.auto | File | 224 B | 0644 |
|
module.info.bg | File | 0 B | 0644 |
|
module.info.bg.auto | File | 203 B | 0644 |
|
module.info.ca | File | 156 B | 0644 |
|
module.info.ca.auto | File | 21 B | 0644 |
|
module.info.cs | File | 46 B | 0644 |
|
module.info.cs.auto | File | 108 B | 0644 |
|
module.info.da | File | 0 B | 0644 |
|
module.info.da.auto | File | 119 B | 0644 |
|
module.info.de | File | 113 B | 0644 |
|
module.info.de.auto | File | 18 B | 0644 |
|
module.info.el | File | 0 B | 0644 |
|
module.info.el.auto | File | 248 B | 0644 |
|
module.info.es | File | 52 B | 0644 |
|
module.info.es.auto | File | 118 B | 0644 |
|
module.info.eu | File | 0 B | 0644 |
|
module.info.eu.auto | File | 153 B | 0644 |
|
module.info.fa | File | 0 B | 0644 |
|
module.info.fa.auto | File | 230 B | 0644 |
|
module.info.fi | File | 0 B | 0644 |
|
module.info.fi.auto | File | 151 B | 0644 |
|
module.info.fr | File | 45 B | 0644 |
|
module.info.fr.auto | File | 125 B | 0644 |
|
module.info.he | File | 0 B | 0644 |
|
module.info.he.auto | File | 154 B | 0644 |
|
module.info.hr | File | 0 B | 0644 |
|
module.info.hr.auto | File | 142 B | 0644 |
|
module.info.hu | File | 37 B | 0644 |
|
module.info.hu.auto | File | 116 B | 0644 |
|
module.info.it | File | 0 B | 0644 |
|
module.info.it.auto | File | 142 B | 0644 |
|
module.info.ja | File | 0 B | 0644 |
|
module.info.ja.auto | File | 181 B | 0644 |
|
module.info.ko | File | 0 B | 0644 |
|
module.info.ko.auto | File | 147 B | 0644 |
|
module.info.lt | File | 0 B | 0644 |
|
module.info.lt.auto | File | 164 B | 0644 |
|
module.info.lv | File | 0 B | 0644 |
|
module.info.lv.auto | File | 153 B | 0644 |
|
module.info.ms | File | 118 B | 0644 |
|
module.info.ms.auto | File | 18 B | 0644 |
|
module.info.mt | File | 0 B | 0644 |
|
module.info.mt.auto | File | 138 B | 0644 |
|
module.info.nl | File | 34 B | 0644 |
|
module.info.nl.auto | File | 101 B | 0644 |
|
module.info.no | File | 33 B | 0644 |
|
module.info.no.auto | File | 93 B | 0644 |
|
module.info.pl | File | 91 B | 0644 |
|
module.info.pl.auto | File | 18 B | 0644 |
|
module.info.pt | File | 0 B | 0644 |
|
module.info.pt.auto | File | 152 B | 0644 |
|
module.info.pt_BR | File | 0 B | 0644 |
|
module.info.pt_BR.auto | File | 161 B | 0644 |
|
module.info.ro | File | 0 B | 0644 |
|
module.info.ro.auto | File | 145 B | 0644 |
|
module.info.ru | File | 53 B | 0644 |
|
module.info.ru.auto | File | 153 B | 0644 |
|
module.info.sk | File | 0 B | 0644 |
|
module.info.sk.auto | File | 174 B | 0644 |
|
module.info.sl | File | 0 B | 0644 |
|
module.info.sl.auto | File | 160 B | 0644 |
|
module.info.sv | File | 0 B | 0644 |
|
module.info.sv.auto | File | 130 B | 0644 |
|
module.info.th | File | 0 B | 0644 |
|
module.info.th.auto | File | 294 B | 0644 |
|
module.info.tr | File | 0 B | 0644 |
|
module.info.tr.auto | File | 154 B | 0644 |
|
module.info.uk | File | 0 B | 0644 |
|
module.info.uk.auto | File | 225 B | 0644 |
|
module.info.ur | File | 0 B | 0644 |
|
module.info.ur.auto | File | 194 B | 0644 |
|
module.info.vi | File | 0 B | 0644 |
|
module.info.vi.auto | File | 147 B | 0644 |
|
module.info.zh | File | 0 B | 0644 |
|
module.info.zh.auto | File | 130 B | 0644 |
|
module.info.zh_TW | File | 24 B | 0644 |
|
module.info.zh_TW.auto | File | 100 B | 0644 |
|
save_global.cgi | File | 4.14 KB | 0755 |
|
save_log.cgi | File | 5.38 KB | 0755 |
|
view_log.cgi | File | 1.74 KB | 0755 |
|
webalizer-lib.pl | File | 8.74 KB | 0755 |
|
webalizer.pl | File | 822 B | 0755 |
|