#!/usr/bin/perl -w
use strict;
use DB_File;
$|++;
use vars qw(%db %result %names @keywords @found @match @pairs
$isfound $start $original_Query $parse_over);
my $MAXHITS = 10;
my $query ="query";
# only a key name for %result
my $keyCount = "Just_Silly_Name";
my $script_name = &query_env('SCRIPT_NAME');
dbmopen(%db,"search_index.db",0) or die "dbmopen: $!";
&parse_form;
## store keywords and count of each matching file
foreach my $keyword (@keywords) {
if (defined (my $filelist = $db{lc $keyword})) {
$isfound =1;
# accumulate the number of keywords matched & record the keyword
foreach my $fileno ($filelist=~ /(-\d+)/g) {
$result{$fileno}{$keyCount}++;
$result{$fileno}{$keyword} = $keyword;
}
}
}
## print the result and matched keywords if found
if ($isfound) {
# start print links that match the most keywords to least.
foreach my $key (sort hashValueDesc keys(%result) ) {
push @found,$db{$key};
# collect the matching keywords
push @match,[grep { $_ ne $keyCount } keys %{ $result{$key} }];
}
my $low = $start;
$low = 0 if ($low < 0 or $low > $#found);
my $high = $low + $MAXHITS -1;
$high = $#found if $high > $#found;
print "Content-Type: text/html\n\n";
print "
Your search for @keywords found ".@found." results on easyya.com\n";
print "
Result ",$low+1," - ",$high+1," shown below.
\n";
print "
\n";
foreach ($low..$high) {
print "$found[$_] matches @{$match[$_]}
\n";
print " $1
\n" if $found[$_] =~ /"(.*?)"/;
}
print "
\n";
print "\n";
if ($low > 0) {
$start = $low - $MAXHITS;
$start =0 if ($start < 0);
print "Previous\n";
}
if ($high < $#found) {
print "| Next\n";
}
print "
\n";
} else {
print "Content-Type: text/html\n\n";
print "No result's been found.\n";
}
sub hashValueDesc {
$result{$b}{$keyCount} <=> $result{$a}{$keyCount};
}
sub parse_form {
if ("\U$ENV{'REQUEST_METHOD'}\E" eq 'GET') {
@pairs = split(/&/, $ENV{'QUERY_STRING'});
}
elsif ("\U$ENV{'REQUEST_METHOD'}\E" eq 'POST') {
read(STDIN,my $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
}
else {
&error('whoops! unknown request method');
} ## End of if
foreach my $pair (@pairs) {
my ($name, $value) = split(/=/,$pair);
$original_Query =$value if (!(defined $original_Query));
$name =~ tr/+/ /;
$value =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/\W+/ /g;
if (!(exists $names{$query})) {
# condition order is important!
if ($name ne $query or $value =~ /^\s*$/) {
print "Location: http://www.easyya.com\n\n";
} else {
$names{$query} = "";
@keywords = split /\s+/,$value;
}
} else {
# if doesn't match, we still get start=0
if ($value =~ /^\d+$/) {
$start = $value;
$parse_over = 1;
}
}
## exit after two pairs done. no wasting time if user fake out something!
last if $parse_over;
} ## End of foreach
}
sub error {
my ($msg) = @_;
print "Content-Type: text/html\n\n";
print "$msg
\n";
exit;
}
sub query_env {
my ($name,$default) = @_;
if (($ENV{$name}) and ($ENV{$name} =~ /^(.*)$/s)) {
return $1;
}
elsif (defined($default)) {
return $default;
}
else {
return '';
}
}
1;
__END__