#!/usr/bin/perl
#####################################################################################
# SEARCH V1.1: Durchsucht Webseiten nach Stichworten, berücksichtigt Frames (Perl5) #
# Stichworte sollten in den üblichen Searchengine-Meta-Tags im HTML-Code stehen: #
# <META NAME="DESCRIPTION" CONTENT="Beschreibung der Seite"> #
# <META NAME="KEYWORDS" CONTENT="Stichworte Stichworte Stichworte"> #
# Wenn man Treffer in Frames dem Hauptframe zuordnen will, benutzt man: #
# <META NAME="FRAMESTART" CONTENT="index.html"> #
# #
# Parameter: search = Suchbegriff, mehrere Begriffe durch Spaces getrennt #
# #
# Mehr Informationen in der HTML-Anleitung :+üöpöj-ä#
# (C) Jan 1998 Mark.Seuffert@pirate.de http://www.pirate.de #
#####################################################################################
# Folgende Variablen bitte angleichen:
$baseurl = "http://www.smi-frankfurt.de";
$basecgi = "http://www.smi-frankfurt.de/cgi-bin/search.pl";
$shortcgiurl = "/cgi-bin"; #kurzer CGI-Pfad in HTML-Dateien (ohne Base-CGI)
$basedir = "../Deutsch";
$htmlfile = "$basedir/search.htm"; #Name der Ausgabeseite
$searchfile = "$basedir/stat/search.log"; #Logfile
$searchlines = 0; #Anzahl Zeilen die durchsucht werden (Volltextsuche bei 0)
@files = ('*.htm','*.html','*.shtml','*.xhtml'); #Diese Dateien werden durchsucht
# Eigene Optionen einstellen:
$logfile = 0; #Suchbegriffe mitloggen? 1 = YES; 0 = no
# Deutsche Texte für die Ausgabe:
@tip = ("Suchbegriffe variieren, Einzahl/Mehrzahl benutzen",
"Man kann auch mehrere Stichwörter eingeben",
"Stichwörter oder Suchbegriffe eingeben");
$text1 = "Treffer Count:";
$text2 = "Dokumente gefunden: %d die zur Anfrage passen";
$text3 = "die besten Treffer zuerst";
$nosearch = "Kein Suchbegriff eingegeben";
$nofound = "Eine allgemeine Suche für's Internet bietet <A HREF=\"<A href="http://www.google.de\">Google</A">http://www.google.de\">Google</A>";
$nodes = "Keine Beschreibung";
# Bemerkung: Das Logfile (searchfile) muss schreibbar sein. Eine Stichwortsuche
# (in den ersten 10 Zeilen) ist viel schneller als Volltextsuche.
#################################################################################
# Dateien durchsuchen
&getweb; #CGI-Parameter einlesen
if ($shortcgiurl !~ /^\//) { $basecgi.= "http://www.smi-frankfurt.de/cgi-bin/search.pl"} #CGI-Pfad evtl aufbereiten
chdir($basedir); #Ab ins Web-Verzeichnis
foreach $file (@files) { #Alle in Frage kommenden Dateien merken
@ls = glob($file);
foreach $temp_file (@ls) { #Überprüfen ob auch Text-Datei
if (-T $temp_file) { push(@FILES,$temp_file) }
}
}
undef (@ls); #Speicher wieder freimachen (wir sind heute brav)
if ($FORM{'search'}) { &search; } #Suchen, falls Suchbegriff existiert
else { $terms[0] = $nosearch; }
if ($FORM{'search'} && $logfile) { #Suchbegriffe mitloggen, wenn gewünscht
open (OUTF, ">>$searchfile");
flock(OUTF,2); #versuchen Datei für andere zu sperren
seek (OUTF,0,2); #ans Dateiende, falls inzwischen Schreibzugriff
print OUTF "$FORM{'search'} ".($#found+1)."\n";
flock(OUTF,8); #Datei wieder freigeben
close (OUTF);
}
# Suchergebnisse ausgeben
print "Content-Type: text/html\n\n"; #CGI HTML-Header
srand(time|$$); #Zufallszahlen initialisieren
open(INF,$htmlfile) || die "Can't open $htmlfile: $!\n"; #Datei öffnen
while(<INF>) { #HTML-Datei durchgehen, Links usw ergänzen
s/BACKGROUND=\"$shortcgiurl/BACKGROUND=\"$basecgi$shortcgiurl\//gi; s/BACKGROUND=\"([^:]*?)\"/BACKGROUND=\"$baseurl\/$1\"/gi;
s/HREF=\"$shortcgiurl/HREF=\"$basecgi$shortcgiurl/gi; s/HREF=\"([^:]*?)\"/HREF=\"$baseurl\/$1\"/gi;
s/SRC=\"$shortcgiurl/SRC=\"$basecgi$shortcgiurl/gi; s/SRC=\"([^:]*?)\"/SRC=\"$baseurl\/$1\"/gi;
s/ACTION=\"$shortcgiurl/ACTION=\"$basecgi$shortcgiurl/gi; s/ACTION=\"([^:]*?)\"/ACTION=\"$baseurl\/$1\"/gi;
s/VALUE=""/VALUE="$FORM{'search'}"/; #Suchwert wieder übergeben
s/Tip:(.*?)</Tip: $tip[int(rand($#tip))]</; #Neuen Tip eintragen
if (/<!-- SEARCH RESULTS -->/i) { #Suchergebnisse ausgeben
print "$text1 $terms[0] $counts[0]"; #Counts auflisten
for ($t=1;$t<=$#terms;$t++) { print ", $terms[$t] $counts[$t]" }
print "<BR>\n";
printf $text2, $#found+1; #Anzahl gefundener Dokumente ausgeben
if($#found >=1) { print ", $text3" }
print ".<BR>\n";
if($#found <0) { print "<BR>$nofound.<BR>\n" }
print "<DL>\n"; #gefundene Seiten ausgeben
foreach $found (@found) {
($count, $title, $file, $description, $size) = split(/\+/, $found);
print "<DT><A HREF=\"$baseurl/$file\"><B>$title</B></A><BR>\n";
print "<DD>$description <FONT SIZE=-1> - count $count</FONT><P>\n";
}
print "</DL>\n";
} else { print } #Den Rest der HTML-Datei übernehmen
}
exit;
#################################################################################
# SEARCH: Dateien nach Stichworte durchsuchen
sub search {
local ($FILE, %FOUND, $string);
@terms = split(/\s+/, $FORM{'search'});
foreach $FILE (@FILES) { #Alle Dateien nacheinander durchgehen
open(FILE,"$FILE"); #Datei öfnnen
$t=$searchlines; #Anzahl Zeilen die eingelesen werden
while (<FILE>){
$string .= $_;
$t--; if(!$t) { last } #weiter einlesen?
}
$string =~ s/\n/ /g; #unnötige Newlines entfernen
close(FILE);
#Dem passendem Frame zuordnen, wenn möglich
if ($string =~ /<META NAME=\"FRAMESTART\" CONTENT=\"([^"]*)\">/i) {
$frame = "$1" } else { $frame = "$FILE"
}
$string =~ s/<!--(.*?)-->/$1/g; #HTML-Style Bemerkungen zulassen
$string =~ s/<IMG(.*?)ALT=\"(.*?)"(.*?)>/$2/ig; #HTML Image Bemerkungen zulassen (ALT-Tag bei Grafiken)
$string =~ s/<META NAME=\"DESCRIPTION\" CONTENT=\"(.*?)\">/$1/ig; #HTML Beschreibung zulassen (META-Tag)
$string =~ s/<META NAME=\"KEYWORDS\" CONTENT=\"(.*?)\">/$1/ig; #HTML Stichworte zulassen (META-Tag)
$string =~ s/<([^>]|\n)*>//g; #alle anderen HTML-Tags rausschneiden
$count_sum=0; #Dummywert, noch nix gefunden
for ($t=0;$t<=$#terms;$t++) { #Nach Suchworten durchsuchen
$term=$terms[$t]; $count=0;
while( $string =~ /$term/ig ) { $count ++; } #zähle Anzahl der Vorkommen
$counts[$t]+=$count; #merke wie oft Suchwort insgesamt vorkommt
$count_sum+=$count;
}
if ($count_sum) { $FOUND{$frame}+=$count_sum } #Falls Treffer, merke Startframe und Counts
undef ($string); #Variable wieder freigeben
}
foreach $file (keys(%FOUND)) { #Gefundene Dateien nochmals durchgehen, geht auch ganz schnell :)
open(FILE,"$file");
$t=$searchlines; #Anzahl Zeilen die eingelesen werden
while (<FILE>){
$string .= $_;
$t--; if(!$t) { last } #weiter einlesen?
}
$string =~ s/\n/ /g;
close(FILE);
if ($string =~ /<TITLE>(.*?)<\/TITLE>/i) { #Titel und Beschreibung rausschneiden
$title = "$1" } else { $title = "$file"
}
if ($string =~ /<META NAME=\"DESCRIPTION\" CONTENT=\"([^"]*)\">/i) {
$description = "$1" } else { $description = "$nodes"
}
$description =~ s/\+/+/g; $title =~ s/\+/+/g; #Plus-Zeichen kodieren (brauchen wir als Trennzeichen)
push (@found, "$FOUND{$file}+$title+$file+$description"); #Alle erhaltenen Infos merken
undef ($string); #Variable wieder freigeben
}
@found = sort { $b <=> $a } @found; #Liste numerisch sortieren
}
#################################################################################
# GETWEB: CGI-Übergabewerte einlesen
sub getweb {
if ($#ARGV>=0) { #Übergabe von Kommandozeile (für Debugging)?
foreach $pair (@ARGV) {
($name, $value) = split(/=/, $pair);
if (!$FORM{$name}) {$FORM{$name} = $value} #Daten merken
else {$FORM{$name} .= "+$value"} #oder anhängen
push (@forms, $name); #Reihenfolge auch
}
} else { #CGI-Übergabe mit GET-Method?
if ($ENV{'REQUEST_METHOD'} eq "GET") {
$buffer = $ENV{'QUERY_STRING'};
} else { #CGI-Übergabe mit PUT oder POST?
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}
@pairs = split(/&/, $buffer); #Namen und Werte spliten
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /; #Entwebben von Pluszeichen und %-Kodierungen
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
if (!$FORM{$name}) {$FORM{$name} = $value} #Daten merken
else {$FORM{$name} .= "+$value"} #oder anhängen
push (@forms, $name); #Reihenfolge auch merken
}
}
}