$feature_depends{'webalizer'} = [ 'web' ];
sub require_webalizer
{
return if ($require_webalizer++);
&foreign_require("webalizer", "webalizer-lib.pl");
%wconfig = &foreign_config("webalizer");
}
# setup_webalizer(&domain)
# Setup the Webalizer module for this domain, and create a Cron job to run it
sub setup_webalizer
{
&$first_print($text{'setup_webalizer'});
&require_webalizer();
local $alog = &get_apache_log($_[0]->{'dom'}, $_[0]->{'web_port'});
if (!$alog) {
&$second_print($text{'setup_nolog'});
return;
}
# Create directory for stats
local $tmpl = &get_template($_[0]->{'template'});
local $stats = &webalizer_stats_dir($_[0]);
if (!-d $stats) {
&system_logged("mkdir ".quotemeta($stats)." 2>/dev/null");
&system_logged("chmod 755 ".quotemeta($stats));
&system_logged("chown $_[0]->{'uid'}:$_[0]->{'ugid'} ".
quotemeta($stats));
}
local $htaccess_file = "$stats/.htaccess";
local $passwd_file = "$_[0]->{'home'}/.stats-htpasswd";
if ($tmpl->{'web_stats_pass'} && !-r $htaccess_file) {
# Setup .htaccess file for directory
&open_tempfile(HTACCESS, ">$htaccess_file");
&print_tempfile(HTACCESS, "AuthName \"$_[0]->{'dom'} statistics\"\n");
&print_tempfile(HTACCESS, "AuthType Basic\n");
&print_tempfile(HTACCESS, "AuthUserFile $passwd_file\n");
&print_tempfile(HTACCESS, "require valid-user\n");
&print_tempfile(HTACCESS, "<Files .htpasswd>\n");
&print_tempfile(HTACCESS, "deny from all\n");
&print_tempfile(HTACCESS, "</Files>\n");
&close_tempfile(HTACCESS);
&set_ownership_permissions($_[0]->{'uid'}, $_[0]->{'gid'},
undef, $htaccess_file);
}
if ($tmpl->{'web_stats_pass'}) {
&update_create_htpasswd($_[0], $passwd_file, $_[0]->{'user'});
$_[0]->{'stats_pass'} = $passwd_file;
}
else {
delete($_[0]->{'stats_pass'});
}
# Set up config for log in Webalizer module
local $lcn = &webalizer::log_config_name($alog);
&lock_file($lcn);
local $cfile = &webalizer::config_file_name($alog);
&lock_file($cfile);
if (!-r $lcn || !-r $cfile) {
$lconf = { 'dir' => $stats,
'sched' => 1,
'type' => 0,
'over' => 0,
'clear' => 0,
'user' => $_[0]->{'user'},
'mins' => int(rand()*60),
'hours' => int(rand()*6),
'days' => '*',
'months' => '*',
'weekdays' => '*' };
&webalizer::save_log_config($alog, $lconf);
# Create a custom webalizer.conf for the site
if ($tmpl->{'webalizer'} && -r $tmpl->{'webalizer'}) {
# Read the specified file and do substitution
local $wt = `cat $tmpl->{'webalizer'}`;
local %subs = %{$_[0]};
$subs{'stats'} = $stats;
$subs{'log'} = $alog;
$wt = &substitute_domain_template($wt, \%subs);
&open_tempfile(FILE, ">$cfile");
&print_tempfile(FILE, $wt);
&close_tempfile(FILE);
}
else {
# Copy webalizer.conf into place for site, and update
&execute_command("cp $wconfig{'webalizer_conf'} $cfile");
local $wconf = &webalizer::get_config($alog);
&webalizer::save_directive($wconf, "HistoryName", "$stats/webalizer.hist");
&webalizer::save_directive($wconf, "IncrementalName", "$stats/webalizer.current");
&webalizer::save_directive($wconf, "Incremental", "yes");
&webalizer::save_directive($wconf, "LogFile", $alog);
&webalizer::save_directive($wconf, "HostName", $_[0]->{'dom'});
&webalizer::save_directive($wconf, "HideReferrer", "*.$_[0]->{'dom'}");
&flush_file_lines();
}
local $group = $_[0]->{'group'} || $_[0]->{'ugroup'};
&system_logged("chown $_[0]->{'user'}:$group $cfile");
}
else {
# Already exists .. but update
$lconf = &webalizer::get_log_config($alog);
$lconf->{'dir'} = $stats;
&webalizer::save_log_config($alog, $lconf);
local $wconf = &webalizer::get_config($alog);
&webalizer::save_directive($wconf, "HistoryName", "$stats/webalizer.hist");
&webalizer::save_directive($wconf, "IncrementalName", "$stats/webalizer.current");
&flush_file_lines();
}
&unlock_file($lcn);
&unlock_file($cfile);
local $job = &find_virtualmin_cron_job("$webalizer::cron_cmd $alog");
if (!$job) {
# Create a Cron job to process the log
&setup_webalizer_cron($lconf, $alog);
}
&$second_print($text{'setup_done'});
}
# setup_webalizer_cron(&lconf, access-log)
sub setup_webalizer_cron
{
local ($lconf, $alog) = @_;
&foreign_require("cron", "cron-lib.pl");
local $job = { 'user' => 'root',
'active' => 1,
'mins' => $lconf->{'mins'},
'hours' => $lconf->{'hours'},
'days' => $lconf->{'days'},
'months' => $lconf->{'months'},
'weekdays' => $lconf->{'weekdays'},
'special' => $lconf->{'special'},
'command' => "$webalizer::cron_cmd $alog" };
if (!-r $webalizer::cron_cmd) {
&lock_file($webalizer::cron_cmd);
&cron::create_wrapper($webalizer::cron_cmd,
"webalizer", "webalizer.pl");
&unlock_file($webalizer::cron_cmd);
}
if (!$config{'webalizer_nocron'}) {
&lock_file(&cron::cron_file($job));
&cron::create_cron_job($job);
&unlock_file(&cron::cron_file($job));
}
}
# modify_webalizer(&domain, &olddomain)
sub modify_webalizer
{
&require_webalizer();
local $alog = &get_apache_log($_[0]->{'dom'}, $_[0]->{'web_port'});
if ($_[0]->{'home'} ne $_[1]->{'home'}) {
# Update Webalizer configuration to use new log file
&$first_print($text{'save_webalizerlog'});
# Rename the .conf file, which is in Webalizer config format. Also
# update any directives that use the old path.
local $oldalog = $alog;
$oldalog =~ s/$_[0]->{'home'}/$_[1]->{'home'}/; # because it will
# have been renamed
local $oldcfile = &webalizer::config_file_name($oldalog);
local $cfile = &webalizer::config_file_name($alog);
&rename_logged($oldcfile, $cfile);
&lock_file($cfile);
local $conf = &webalizer::get_config($alog);
local $changed;
foreach my $c (@$conf) {
if ($c->{'value'} =~ /\Q$_[1]->{'home'}\E/) {
$c->{'value'} =~ s/\Q$_[1]->{'home'}\E/$_[0]->{'home'}/g;
&webalizer::save_directive($conf, $c->{'name'},
$c->{'value'});
$changed = $c->{'file'};
}
}
&flush_file_lines($changed) if ($changed);
&unlock_file($cfile);
# Rename the .log file, which is in Webmin format. Also update the
# dir= line in that file
local $oldlcn = &webalizer::log_config_name($oldalog);
local $lcn = &webalizer::log_config_name($alog);
&rename_logged($oldlcn, $lcn);
&lock_file($lcn);
local $lconf = &webalizer::get_log_config($alog);
$lconf->{'dir'} =~ s/\Q$_[1]->{'home'}\E/$_[0]->{'home'}/g;
&webalizer::save_log_config($alog, $lconf);
&unlock_file($lcn);
# Change the log file path in the Cron job
&foreign_require("cron", "cron-lib.pl");
local ($job) = grep { $_->{'command'} eq "$webalizer::cron_cmd $oldalog" }
&cron::list_cron_jobs();
if ($job) {
$job->{'command'} = "$webalizer::cron_cmd $alog";
&lock_file(&cron::cron_file($job));
&cron::change_cron_job($job);
&unlock_file(&cron::cron_file($job));
}
&$second_print($text{'setup_done'});
}
if ($_[0]->{'dom'} ne $_[1]->{'dom'}) {
# Update hostname in Webalizer configuration
&$first_print($text{'save_webalizer'});
local $cfile = &webalizer::config_file_name($alog);
&lock_file($cfile);
local $wconf = &webalizer::get_config($alog);
&webalizer::save_directive($wconf, "HostName", $_[0]->{'dom'});
&webalizer::save_directive($wconf, "HideReferrer", "*.$_[0]->{'dom'}");
&flush_file_lines();
&unlock_file($cfile);
&$second_print($text{'setup_done'});
}
if ($_[0]->{'user'} ne $_[1]->{'user'}) {
# Update Unix user Webliazer is run as
&$first_print($text{'save_webalizeruser'});
local $lcn = &webalizer::log_config_name($alog);
&lock_file($lcn);
local $lconf = &webalizer::get_log_config($alog);
$lconf->{'user'} = $_[0]->{'user'};
&webalizer::save_log_config($alog, $lconf);
&unlock_file($lcn);
&$second_print($text{'setup_done'});
}
if ($_[0]->{'stats_pass'}) {
# Update password for stats dir
&update_create_htpasswd($_[0], $_[0]->{'stats_pass'}, $_[1]->{'user'});
}
}
# delete_webalizer(&domain)
# Delete the Webalizer config files and Cron job
sub delete_webalizer
{
&$first_print($text{'delete_webalizer'});
&require_webalizer();
local $alog = &get_apache_log($_[0]->{'dom'}, $_[0]->{'web_port'});
if (!$alog && -r "$_[0]->{'home'}/logs/access_log") {
# Website may have been already deleted, so we don't know the log
# file path! Try the template default.
$alog = &get_apache_template_log($_[0]);
}
if (!$alog) {
&$second_print($text{'delete_webalizerno'});
return;
}
if ($_[0]->{'deleting'}) {
# Delete config files
local $lfile = &webalizer::log_config_name($alog);
unlink($lfile);
local $cfile = &webalizer::config_file_name($alog);
unlink($cfile);
}
# Turn off cron job for webalizer config
&foreign_require("cron", "cron-lib.pl");
local ($job) = grep { $_->{'command'} eq "$webalizer::cron_cmd $alog" }
&cron::list_cron_jobs();
if ($job) {
&lock_file(&cron::cron_file($job));
&cron::delete_cron_job($job);
&unlock_file(&cron::cron_file($job));
}
&$second_print($text{'setup_done'});
}
# validate_webalizer(&domain)
# Returns an error message if Webalizer is not configured properly
sub validate_webalizer
{
local ($d) = @_;
&require_webalizer();
local $alog = &get_apache_log($d->{'dom'}, $d->{'web_port'});
return &text('validate_elogfile', "<tt>$d->{'dom'}</tt>") if (!$alog);
local $cfile = &webalizer::config_file_name($alog);
return &text('validate_ewebalizer', "<tt>$cfile</tt>") if (!-r $cfile);
if (!$config{'webalizer_nocron'}) {
&foreign_require("cron", "cron-lib.pl");
local ($job) = grep { $_->{'command'} eq "$webalizer::cron_cmd $alog" }
&cron::list_cron_jobs();
return &text('validate_ewebalizercron') if (!$job);
}
return undef;
}
# check_webalizer_clash()
# Does nothing, because the web clash check is all that is needed
sub check_webalizer_clash
{
return 0;
}
sub enable_webalizer
{
# Does nothing yet
}
sub disable_webalizer
{
# Does nothing yet
}
# backup_webalizer(&domain, file)
# Saves the server's Webalizer config file, module config file and schedule
sub backup_webalizer
{
&$first_print($text{'backup_webalizercp'});
&require_webalizer();
local $alog = &get_apache_log($_[0]->{'dom'}, $_[0]->{'web_port'});
if (!$alog) {
&$second_print($text{'setup_nolog'});
return 0;
}
else {
local $lcn = &webalizer::log_config_name($alog);
&execute_command("cp ".quotemeta($lcn)." ".quotemeta($_[1]));
local $cfile = &webalizer::config_file_name($alog);
&execute_command("cp ".quotemeta($cfile)." ".quotemeta($_[1])."_conf");
&$second_print($text{'setup_done'});
return 1;
}
}
# restore_webalizer(&domain, file, &options, &all-options, home-format, &olddomain)
# Copies back the server's Webalizer config files, and re-sets up the Cron job
sub restore_webalizer
{
&$first_print($text{'restore_webalizercp'});
&require_webalizer();
local $alog = &get_apache_log($_[0]->{'dom'}, $_[0]->{'web_port'});
if (!$alog) {
&$second_print($text{'setup_nolog'});
return 0;
}
else {
# Copy the Webmin config for webalizer, and update the home directory
local $lcn = &webalizer::log_config_name($alog);
&lock_file($lcn);
©_source_dest($_[1], $lcn);
if ($_[5] && $_[0]->{'home'} ne $_[5]->{'home'}) {
local $lconf = &webalizer::get_log_config($alog);
$lconf->{'dir'} =~ s/\Q$_[5]->{'home'}\E/$_[0]->{'home'}/g;
&webalizer::save_log_config($alog, $lconf);
}
&unlock_file($lcn);
# Copy the actual Webalizer config file, and update home directory
local $cfile = &webalizer::config_file_name($alog);
&lock_file($cfile);
©_source_dest($_[1]."_conf", $cfile);
if ($_[5] && $_[0]->{'home'} ne $_[5]->{'home'}) {
local $conf = &webalizer::get_config($alog);
local $changed;
foreach my $c (@$conf) {
if ($c->{'value'} =~ /\Q$_[5]->{'home'}\E/) {
$c->{'value'} =~ s/\Q$_[5]->{'home'}\E/$_[0]->{'home'}/g;
&webalizer::save_directive($conf, $c->{'name'},
$c->{'value'});
$changed = $c->{'file'};
}
}
&flush_file_lines($changed) if ($changed);
}
&unlock_file($cfile);
# Delete and re-create the cron job
&foreign_require("cron", "cron-lib.pl");
local ($job) = grep { $_->{'command'} eq "$webalizer::cron_cmd $alog" }
&cron::list_cron_jobs();
if ($job) {
&lock_file(&cron::cron_file($job));
&cron::delete_cron_job($job);
}
local $lcn = &webalizer::log_config_name($alog);
local $lconf;
if (!-r $lcn) {
&lock_file($lcn);
$lconf = { 'dir' => $stats,
'sched' => 1,
'type' => 0,
'over' => 0,
'clear' => 0,
'user' => $_[0]->{'user'},
'mins' => int(rand()*60),
'hours' => 0,
'days' => '*',
'months' => '*',
'weekdays' => '*' };
&webalizer::save_log_config($alog, $lconf);
&unlock_file($lcn);
}
else {
$lconf = &webalizer::get_log_config($alog);
}
&setup_webalizer_cron($lconf, $alog);
&$second_print($text{'setup_done'});
return 1;
}
}
# update_create_htpasswd(&domain, file, old-user)
sub update_create_htpasswd
{
local $pass;
if ($_[0]->{'parent'}) {
$pass = &get_domain($_[0]->{'parent'})->{'pass'};
}
else {
$pass = $_[0]->{'pass'};
}
&foreign_require("htaccess-htpasswd", "htaccess-lib.pl");
local $users = &htaccess_htpasswd::list_users($_[1]);
local ($user) = grep { $_->{'user'} eq $_[2] } @$users;
if ($user) {
$user->{'user'} = $_[0]->{'user'};
$user->{'pass'} = &htaccess_htpasswd::encrypt_password($pass);
&htaccess_htpasswd::modify_user($user);
}
else {
$user = { 'enabled' => 1,
'user' => $_[0]->{'user'},
'pass' => &htaccess_htpasswd::encrypt_password($pass) };
&htaccess_htpasswd::create_user($user, $_[1]);
&set_ownership_permissions($_[0]->{'uid'}, $_[0]->{'gid'}, undef,$_[1]);
}
}
# sysinfo_webalizer()
# Returns the Webalizer
sub sysinfo_webalizer
{
&require_webalizer();
local $vers = &webalizer::get_webalizer_version();
return ( [ $text{'sysinfo_webalizer'}, $vers ] );
}
sub links_webalizer
{
local ($d) = @_;
if ($config{'avail_webalizer'}) {
local $log = &resolve_links(&get_apache_log($d->{'dom'}, $d->{'web_port'}));
local %waccess = &get_module_acl(undef, "webalizer");
if ($waccess{'view'}) {
# Can view report only
return ( { 'mod' => 'webalizer',
'desc' => $text{'links_webalizer2'},
'page' => 'view_log.cgi/'.&urlize(&urlize($log)).
'/index.html',
'cat' => 'logs',
});
}
else {
# Can edit report
return ( { 'mod' => 'webalizer',
'desc' => $text{'links_webalizer'},
'page' => 'edit_log.cgi?file='.
&urlize($log).'&type=1',
'cat' => 'logs',
});
}
}
return ( );
}
# webalizer_stats_dir(&domain)
# Returns the full directory for Webalizer stats files
sub webalizer_stats_dir
{
local ($d) = @_;
local $tmpl = &get_template($d->{'template'});
local $hdir = &public_html_dir($d);
local $stats;
if ($tmpl->{'web_stats_hdir'}) {
$stats = "$d->{'home'}/$tmpl->{'web_stats_hdir'}";
}
elsif ($tmpl->{'web_stats_dir'}) {
$stats = "$hdir/$tmpl->{'web_stats_dir'}";
}
else {
$stats = "$hdir/stats";
}
return $stats;
}
$done_feature_script{'webalizer'} = 1;
1;
syntax highlighted by Code2HTML, v. 0.9.1