#!/usr/bin/perl use Encode qw(decode_utf8); use HTML::Escape qw(escape_html); my $search_text = ''; if ($ENV{QUERY_STRING} =~ /^q=([^&]*)/) { $search_text = decode_utf8($1 // ""); $search_text =~ s/\P{Print}//g; # toss any non-printable utf-8 characters $search_text = substr($search_text, 0, 64); $search_text =~ s/^\s+|\s+$//g; } my @results; # Search only index.html files inside the first level of subdirectories my $start_dir = '../log'; my @files = glob("$start_dir/*/index.html"); foreach my $path (@files) { # Skip if the path is a symlink or not a file next if -l $path || ! -f $path; next unless open(my $fh, '<:utf8', $path); my $html = do { local $/; <$fh> }; close($fh); my ($text) = $html =~ m|
(.*?)
|is; $text =~ s|<[^>]+>| |g; $text =~ s|\s+| |g; next unless $text =~ /(.{0,40})(\Q$search_text\E)(.{0,40})/is; my ($before, $actual, $after) = ($1, $2, $3); # Trim if we cut into the middle of a sentence $after =~ s/\s\S*$// if length($after) > 25; $before =~ s/^.*?\s// if length($before) > 25; if ($before =~ /\S/) { # If before has non-whitespace characters $before = ucfirst($before); } else { $before = ""; # Clear any stray spaces $actual = ucfirst($actual); } my $safe_before = escape_html($before); my $safe_actual = escape_html($actual); my $safe_after = escape_html($after); my $snippet = "${safe_before}${safe_actual}${safe_after}..."; my ($title) = $html =~ m|(.*?)|is; my $safe_title = escape_html($title); $path =~ s|^\.\./||; push @results, { path => $path, title => $safe_title, snippet => $snippet }; } print "Content-Type: text/html\n\n"; my $list; if ($search_text eq '') { $list = "

Please enter a search term above.

"; } elsif (@results == 0) { $list = "

No results found for \"$search_text\".

"; } else { $list = ""; } my $safe_search_text = escape_html($search_text); my $year = (localtime)[5] + 1900; print <<"HTML"; Search

Search

$list
HTML