#!/usr/local/bin/perl
# search.cgi
# Find webmin actions

require './webminlog-lib.pl';
require 'timelocal.pl';
&ReadParse();
&error_setup($text{'search_err'});

if ($in{'tall'} == 2) {
	@now = localtime(time());
	$from = timelocal(0, 0, 0, $now[3], $now[4], $now[5]);
	$to = timelocal(59, 59, 23, $now[3], $now[4], $now[5]);
	$in{'tall'} = 0;
	}
elsif ($in{'tall'} == 0) {
	$from = &parse_time('from');
	$to = &parse_time('to');
	$to = $to ? $to + 24*60*60 - 1 : time();
	}

&ui_print_header(undef, $text{'search_title'}, "");
open(LOG, $webmin_logfile);
while(<LOG>) {
	if (($act = &parse_logline($_)) &&
	    ($in{'uall'} == 1 ||
	     $in{'uall'} == 0 && $in{'user'} eq $act->{'user'} ||
	     $in{'uall'} == 2 && $in{'nuser'} ne $act->{'user'}) &&
	    ($in{'mall'} || $in{'module'} eq $act->{'module'}) &&
	    (!$in{'sid'} || $in{'sid'} eq $act->{'sid'}) &&
	    ($in{'tall'} || $from < $act->{'time'} && $to > $act->{'time'}) &&
	    ($in{'wall'} || $in{'webmin'} eq $act->{'webmin'})) {
		if ($gconfig{'logfiles'} && !$in{'fall'}) {
			# Make sure the specified file was modified
			local $found = 0;
			foreach $d (&list_diffs($act)) {
				if ($d->{'object'} &&
				    $d->{'object'} eq $in{'file'}) {
					$found++;
					last;
					}
				}
			next if (!$found);
			}
		push(@match, $act);
		}
	}
close(LOG);

if (@match) {
	if ($in{'sid'}) {
		print "<b>",&text('search_sid', "<tt>$match[0]->{'user'}</tt>",
				  "<tt>$in{'sid'}</tt>")," ..</b><p>\n";
		}
	elsif ($in{'uall'} == 1 && $in{'mall'} && $in{'tall'}) {
		print "<b>$text{'search_critall'} ..</b><p>\n";
		}
	else {
		@from = localtime($from); @to = localtime($to);
		$fromstr = sprintf "%2.2d/%s/%4.4d",
			$from[3], $text{"smonth_".($from[4]+1)}, $from[5]+1900;
		$tostr = sprintf "%2.2d/%s/%4.4d",
			$to[3], $text{"smonth_".($to[4]+1)}, $to[5]+1900;
		%minfo = &get_module_info($in{'module'}) if (!$in{'mall'});
		printf "<b>%s %s %s %s ..</b><p>\n",
			$text{'search_crit'},
			$in{'uall'} == 0 ? &text('search_critu',
						 "<tt>$in{'user'}</tt>") :
			$in{'uall'} == 2 ? &text('search_critnu',
						 "<tt>$in{'nuser'}</tt>") : "",
			$in{'mall'} ? '' : &text('search_critm',
						 "<tt>$minfo{'desc'}</tt>"),
			$in{'tall'} ? '' : 
			  $fromstr eq $tostr ?  &text('search_critt2', $tostr) :
			    &text('search_critt', $fromstr, $tostr);
		}
	print "<table border width=100%>\n";
	print "<tr $tb> <td><b>$text{'search_action'}</b></td>\n",
	      "<td><b>$text{'search_module'}</b></td>\n",
	      "<td><b>$text{'search_user'}</b></td>\n",
	      "<td><b>$text{'search_host'}</b></td>\n",
	      ($config{'host_search'} ?
			"<td><b>$text{'search_webmin'}</b></td>\n" : ""),
	      "<td><b>$text{'search_date'}</b></td>\n",
	      "<td><b>$text{'search_time'}</b></td> </tr>\n";
	foreach $act (reverse(@match)) {
		local @tm = localtime($act->{'time'});
		local $m = $act->{'module'};
		local $d;
		$minfo = $minfo_cache{$m};
		if (!$minfo) {
			# first time seeing module ..
			local %minfo = &get_module_info($m);
			$minfo = $minfo_cache{$m} = \%minfo;
			if (-r "../$m/log_parser.pl") {
				&foreign_require($m, "log_parser.pl");
				$parser{$m}++;
				}
			}

		print "<tr $cb>\n";
		print "<td><a href='view.cgi?id=$act->{'id'}'>";
		$d = &foreign_call($m, "parse_webmin_log",
				  $act->{'user'}, $act->{'script'},
				  $act->{'action'}, $act->{'type'},
				  $act->{'object'}, $act->{'param'})
					if ($parser{$m});
		if ($d) {
			print $d;
			}
		elsif ($act->{'action'} eq '_config_') {
			print $text{'search_config'};
			}
		else {
			printf "%s %s %s\n",
				$act->{'action'},
				$act->{'type'} ? $act->{'type'} : '',
				$act->{'object'} ? $act->{'object'} : '';
			}
		print "</a></td>\n";
		print "<td>$minfo->{'desc'}</td>\n";
		print "<td>$act->{'user'}</td>\n";
		print "<td>$act->{'ip'}</td>\n";
		if ($config{'host_search'}) {
			if ($act->{'webmin'}) {
				print "<td>$act->{'webmin'}</td>\n";
				}
			else {
				print "<td><br></td>\n";
				}
			}
		printf "<td>%2.2d/%s/%4.4d</td>\n",
			$tm[3], $text{"smonth_".($tm[4]+1)}, $tm[5]+1900;
		printf "<td>%2.2d:%2.2d:%2.2d</td>\n",
			$tm[2], $tm[1], $tm[0];
		print "</tr>\n";
		}
	print "</table><p>\n";
	}
else {
	print "<p><b>$text{'search_none'}</b><p>\n";
	}
&ui_print_footer("", $text{'index_return'});

sub parse_time
{
local $d = $in{"$_[0]_d"};
local $m = $in{"$_[0]_m"};
local $y = $in{"$_[0]_y"};
return 0 if (!$d && !$y);
local $rv;
eval { $rv = timelocal(0, 0, 0, $d, $m, $y-1900) };
&error($text{'search_etime'}) if ($@);
return $rv;
}
