#!/usr/bin/perl
# einfaches CGI-Programm zum Suchen
use strict;
use warnings;
use CGI;

# nur fuer den Test!
use CGI::Carp qw(fatalsToBrowser);

$ |= 1;

my $query = new CGI;

# Suche erfolgt nur in den Dateien des Webangebots
my $BASE = $ENV{'DOCUMENT_ROOT'};

# Skript-URL
my $self_url = $query->self_url();


# Parameter aus dem Formular holen
my $searchvalue = $query->param('searchvalue') or '';
my $type = $query->param('type');

# Fundstellenzaehler
my $numberreturned = 0;

# Suche einschraenken auf ...
# Angeben im Formular als "dir1;dir2;dir3..."
my $dirs = $query->param('indirs');

# Ausschliessen von ...
# Angeben im Formular als "dir1;dir2;dir3..."
my $edirs = $query->param('exdirs');

# Parameter in einzelne Suchbegriffe zerlegen
my @search = split(/ /, $searchvalue);
$numberreturned = 0;

# Positivliste von Verzeichnissen
my @directories = ();
my $listdirs = 0;
if (defined($dirs))
  {
  @directories = split(/;/,$dirs);
  $listdirs = 1;
  }

# Negativliste von Verzeichnissen
my @excldirs = ();
my $exdirs = 0;
if (defined($exdirs))
  {
  @excldirs = split(/;/,$edirs);
  $exdirs = 1;
  }

# Hier beginnt die Ergebnisausgabe
print $query->header();
print qq~
  <HTHL>
  <HEAD><TITLE>Webserver-Suche</TITLE></HEAD>
  <BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF"
        VLINK="#0000CC" ALINK="#FF0000">
  <H1 ALIGN="CENTER">Suchergebnis</H1>
  ~;

# Suchformular ausgeben
Formular();

# Erster Aufruf, keine Parameter -> keine Suche
exit if ($searchvalue eq '');

my $dir = '';
print "<UL>\n";
if ($listdirs)
  {
  # nur die Positivliste abarbeiten
  foreach $dir (@directories)
    { CheckFiles($BASE."$dir"); }
  }
else
  # alles im Verzeichnis bearbeiten
  { CheckFiles($BASE); }
print "</UL>\n";

# Seitenende
if ($numberreturned == 0)
  { print "<p><b>Leider nichts gefunden!</b></p>"; }
else
  { print "<p><b>$numberreturned Fundstelle(n)</b></p>"; }
print "</BODY></HTML>\n";



sub Formular
  {
  # Suchformular (bestueckt mit akt. Werten) ausgeben
  my $selectall = $type eq 'all'? '"SELECTED"' : '';
  my $selectany = $type eq 'any'? '"SELECTED"' : '';
  print '<P><FORM METHOD="post" ACTION="' . $self_url . '">';
  print '<INPUT TYPE="hidden" NAME="indirs" VALUE="' . $dirs . '">'
     if (defined($dirs));
  print '<INPUT TYPE="hidden" NAME="exdirs" VALUE="' . $edirs . '">'
     if (defined($edirs));
  print qq~
    Suchbegriff(e): <INPUT TYPE="text" NAME="searchvalue" VALUE="$searchvalue">
    Verkn\&uuml;pfung: <SELECT NAME="type">
    <OPTION VALUE="all" $selectall> alle
    <OPTION VALUE="any" $selectany> mindestens einer
    </SELECT> der Begriffe.
    <INPUT TYPE="submit" VALUE="Suchen">
    </FORM>
    </P>
  ~;
  }


sub CheckFiles
  {
  # Alle Dateien im Verzeichnis (und in den Unterverzeichnissen) bearbeiten
  my $fullFilename = '';  # Dateiname mit Pfad
  my $line = '';          # nimmt Dateiinhalt auf
  my $title = '';         # nimmt Titel auf
  my $search = '';        # einzelnes Suchwort
  my $recurse = 0;        # Verzeichnis durchsuchen: ja/nein
  my $found = 0;          # Wahr, wenn Suchbegriff gefunden
  my ($tmp, $tmpath);

  my $path = shift;                # zu bearbeitendes Verzeichnis
  return unless (-d $path);
  opendir(ROOT,$path) or return;   # Verzeichnis lesen
  my @files = readdir(ROOT);
  closedir(ROOT);

  foreach (@files)                 # Verzeichniseintraege bearbeiten
    {
    next if /^\.|\.\.$/;           # Verzeichnisse "." und ".."
    $fullFilename = "$path/$_";
    if (-d $fullFilename)          # Unterverzeichnis bearbeiten
      {
      $recurse = 1;
      if ($exdirs)                 # Wenn es nicht ausgeschlossen wurde
        {                          # Unterverzeichnis bearbeiten
        $tmp = $fullFilename;
        $tmp =~ s/$BASE//;
        foreach $tmpath (@excldirs)
          { if ($tmp eq $tmpath) { $recurse = 0; last; } }
        }
      if ($recurse) { CheckFiles($fullFilename); }
      next;
      }
                                   # Dateien im Verzeichnis bearbeiten
    if ($fullFilename =~ m/\.htm/i)
      {
      open(FILE, $fullFilename) or return;
      $line = join(' ',<FILE>);    # Datei wird zu einer Zeile
      close(FILE);

      $line =~ s/\n//g;            # Newlines weg
      $line =~ s/&auml;/ä/g;       # Umlaute konvertieren
      $line =~ s/&ouml;/ö/g;
      $line =~ s/&uuml;/ü/g;
      $line =~ s/&Auml;/Ä/g;
      $line =~ s/&Ouml;/Ö/g;
      $line =~ s/&Uuml;/Ü/g;
      $line =~ s/&szlig;/ß/g;

      $title = '';                 # Titel ermitteln, sofern vorhanden
      if($line =~ m!<title>(.+)</title>!i)
        { $title = $1; };

      if ($type eq 'all' )         # UND-Verknuepfung
        {
        # falls nur ein Suchbegriff fehlt, wird $found = falsch
        $found = 1;
        foreach $search (@search)
         { if ($line !~ m/$search/i) { $found = 0; last; } }
        }
      else # type = any            # ODER-Verknuepfung
        {
        # falls nur ein Suchbegriff da ist, wird $found = wahr
        $found = 0;
        foreach $search (@search)
          { if ($line =~ m/$search/i) { $found = 1; last; } }
        }

      if ($found)                  # Falls ein Suchbegriff gefunden wurde,
        {                          # Dateinamen ausgeben
        $tmp = $fullFilename;
        $tmp =~ s/$BASE//;         # fuer den Link ohne Document-Root
        $title = $tmp if($title eq '');
        print "<LI><A HREF=\"$tmp\">$title</a>\n";
        $numberreturned++;
        }
      }
    }
  }