#!/usr/local/bin/perl
# tdsearch.cgi - searches all the text files in a directory and
# displays links to matching files as well as context of matching lines.
# This script is based partly on some example code by Larry Wall.
# Copyright (C) 1996 Stephen Lines <spraxlo@ai.mit.edu>

require "ctime.pl";
require "FormData.pl";
#$txtdir = "../web/me";         # Relative path to the directory.

#open(STDERR,">>error.log");

open(FILE,"vidlist.txt") || die("$0: couldn't open vidlist.txt for reading($!)\n");
@array = <FILE>;
close(FILE);

foreach $line (@array){
chop($line);
($key,$value) = split(',',$line);
$Files2Names{$key} = $value;
}

$FileNum = 0;
foreach (sort(keys(%Files2Names))) {
  $ValidFiles[ $FileNum ] = $_;
  $ValidNames[ $FileNum ] = $NextName = $Files2Names{$_};
  $Names2Numbs{$NextName} = $FileNum++; # Used to validate names.
}

unless (defined($ENV{'SCRIPT_NAME'})) {   # this is only a test...
  $ENV{'SCRIPT_NAME'}    = $0;
  $ENV{'REQUEST_METHOD'} = 'GET';
  $ENV{'QUERY_STRING'}   = 'Query=Cologne&StripHTML=CHECKED';
  $ENV{'CONTENT_LENGTH'} = length($ENV{'QUERY_STRING'});
}

&getFormData(*Form);
$Context    =  $Form{'Context'}   || 1;
$Query      =  $Form{'Query'}     || '';
$RegExp     =  $Form{'RegExp'}    || '';  # Options default to "off"
$MatchCase  =  $Form{'MatchCase'} || '';
$WholeWord  =  $Form{'WholeWord'} || '';
$StripHTML  =  $Form{'StripHTML'} || 1;

if($Query eq 'C:admin'){

print "Content-type: text/html\n\n";
print <<EOF;
<HTML>
<HEAD><TITLE> MVD Administration </TITLE></HEAD>
<BODY BGCOLOR="#99CCCC" background="../graphics/web3.jpg"><CENTER>
<p><hr size=2><p>
<h1>MVD Administration</h1>
<H2>Only registered MVD members can use these functions</h2>
<font size=-1><a href=#Form> [ Jump to Form ] </a>&nbsp;&nbsp;<a href=#Files> [ Jump to Files ] </a>&nbsp;&nbsp;<a href="../"> [ Home ] </a></font><p>
<table border=0 width=550><td>
Make sure you read the instructions below so you don't inadvertantly change something you don't want to.</td>
</table>
<p>
<table border=0 width=500><td>
<small>
Below you have six input boxes organized into four sections above five buttons which are organized into two groups of functions. How you fill in the input boxes depends on the
function you wish to carry out. Also the same button may have different effects depending
on how the input boxes are filled out.<p>Here is a description of how to use this form. Note
that all the functions require you to fill in your username (aka - member name) and your
password. This is to prove you are authorized to do what you are attempting.
<p>
<b>To change your username and/or password</b>. Fill in the "Other Username" and/or the
"Other Password" fields and press the "Change User" button. The entries in these fields will replace your current values on
the left. If you leave one of the fields on the right blank it will not be changed. For
example to change just your password leave the "Other Username" field blank and put your
new password in the "Other Password" field.
<p><b>To add a new user or delete an old one.</b> You need a level-1 security clearance to
do either of these functions so don't worry about it.
<p><b>To add or edit an entry.</b> Fill in either the "Entry as Title" or the
"Entry as File" field and press the "Add/Edit Entry" button. The entries in this dadabase can be retrieved either by the entries's
title or by the name of it's html file. You can supply both fields and if a file isn't
found by filename or title one will be opened for editing and initialized with those values for it's title and filename. You will then
be able to enter new values that define each entry. If a file is found
by it's filename or title it will be opened for editing to allow you to change it's values.
If you enter values in both fields the filename will be searched for first and if found
it will be loaded with it's proper title intact even if you have a different one specified
in the title field. If you are creating a new entry it is best to just include a title and
let the program choose an appropriate filename. You can also leave both fields blank and
supply a title later in the form you will be taken to when you press the
"Add/Edit Entry" button.
 Be careful to use unique names for new entries so
you don't overwrite existing files. Check
 the document list below to see if
the title or filename is already being used. 
 <p><b>To delete an entry.</b>
Again - level-1 security clearance required.    
 </small>
</td></table><p>

<FORM METHOD=POST ACTION="mvladmin.cgi">
<p>
<a name=Form>
<table border=2 width=534 cellpadding=10 BGCOLOR="#FFFF99">
<tr valign=middle><td align=center valign=middle>Your Username<br><INPUT TYPE=TEXT SIZE=23 NAME="uname"><p>Your Password<br><INPUT TYPE=password SIZE=23 NAME="pword"><p></td><td align=center valign=middle>Other Username<br><INPUT TYPE=TEXT SIZE=23 NAME="ouname"><p>Other Password<br><INPUT TYPE=password SIZE=23 NAME="opword"><p></td></tr>
<tr valign=middle><td align=center valign=middle>Entry as Title<br><INPUT TYPE=TEXT SIZE=23 NAME="title"><p></td><td align=center valign=middle>Entry as File<br><INPUT TYPE=TEXT SIZE=23 NAME="file"><p></td></tr>
</table>
<table border=2 width=534 cellpadding=10 BGCOLOR="#0099CC">
<tr valign=middle><td align=center valign=middle>Membership Functions<br><INPUT TYPE=SUBMIT NAME="Action" VALUE="Change User">&nbsp;&nbsp;<INPUT TYPE=SUBMIT NAME="Action" VALUE="Add User">&nbsp;&nbsp;<INPUT TYPE=SUBMIT NAME="Action" VALUE="Delete User"><p></td></tr>
<tr valign=middle><td align=center valign=middle BGCOLOR="#33CCCC">Entry Functions<br>&nbsp;&nbsp;<INPUT TYPE=SUBMIT NAME="Action" VALUE="Add/Edit Entry">&nbsp;&nbsp;<INPUT TYPE=SUBMIT NAME="Action" VALUE="Delete Entry"><p></td></tr>
<tr valign=middle><td align=center valign=middle BGCOLOR="#FFFF99"><INPUT TYPE=RESET VALUE=" Reset All Input Boxes "><p></td></tr>
</table><p>
EOF

$FileNumb = $FileNum;
  print "<a name=Files>There are currently $FileNumb documents.<br><font size=2>Click on the <i>Title</i> to view that document. Click on the <i>Filename</i> to edit.</font><p>\n";
  print "<table border=2 cellpadding=5>\n";
  $c1=1;
  for($c=0;$c<$FileNumb;$c++){
    #print "<tr valign=middle><td valign=middle>$c1: <A HREF=\"mvl.cgi\?NextName=$ValidFiles[$c]\">$ValidNames[$c]</a></td><td align=right valign=middle> $ValidFiles[$c] <font size=1><INPUT TYPE=BUTTON NAME=\"Action\" VALUE=\"EDIT\" onclick=\"forms[0].title.value='$ValidNames[$c]'\;forms[0].file.value='$ValidFiles[$c]'\;\"></font></td></tr>";
    print "<tr valign=middle><td valign=middle><font size=-1>$c1: <A HREF=\"mvl.cgi\?shonav=1&NextName=$ValidFiles[$c]\">$ValidNames[$c]</a></font></td><td align=right valign=middle><font size=-1><A HREF=\"mvladmin.cgi\?Action=Add\/Edit%20Entry&file=$ValidFiles[$c]\"> $ValidFiles[$c] </a></font></td></tr>";
    $c1++;
  }
  print "</table></form><p><hr>\n";

print <<EOFF;
<a href="http://www.global-dialog.org" target=_top> [ Global Dialog Home ] </a>&nbsp;&nbsp;<a href="http://www.global-dialog.org/mvd/"> [ MVD Home ] </a>&nbsp;&nbsp;<a href="mvl.cgi?NextName=List"> [ List ]  </a><hr><p></CENTER></BODY></HTML>
EOFF
exit;
}


print "Content-type: text/html\n\n";
print <<EOF;
<HTML><HEAD>
<TITLE>Search MVD</TITLE>
</HEAD><BODY BGCOLOR="#99CCCC" background="../graphics/web3.jpg">
<center>
<p><hr size=2><p>
<font size=3>
<table width=700 cellpadding=0 border=0><td>
<FORM>
<center>
<a name=top>
<H2>Search MVD</H2>
<INPUT TYPE=TEXT SIZE=55 MAXLENGTH=255 NAME="Query" VALUE="$Query"><br>
Regular Expressions:&nbsp;
<INPUT TYPE=CHECKBOX NAME=RegExp    VALUE=CHECKED $RegExp>&nbsp;&nbsp;
Match Case:
<INPUT TYPE=CHECKBOX NAME=MatchCase VALUE=CHECKED $MatchCase><br>
<INPUT TYPE=SUBMIT  VALUE=Submit>
<INPUT TYPE=RESET   VALUE=Reset><BR>
</FORM><BR></center>
<P>This simple search engine searches the Dadabase for one string. A string is one
or more words. If more than one word is included in the query they will be treated
as a phrase and a match will occur only when those words are found together in the
way they were input. You can use regular expressions to do more sophisticated
searches. The output will include links to any matching entries, as well as the
matching lines and their contexts within the files.
<center><p><a href="regex.html"><font size=-1><i>How to use regular expressions.</i></font></a>
</center>
</td></table>
</center>
<HR><p>
EOF

if ($Query) { # Called with at least one argument; search for it.

    unless ($RegExp) { $Query =~ s/([\$()*+.?\[\\\]^{|}])/\\$1/g; }
    if ($WholeWord)  { $Query =  "\\b$Query\\b"; }
    $matchOptions = $MatchCase ? 'o' : 'oi';
    $len          = $Context*2 + 1;
    $foundLines   = 0;
    $foundFiles   = 0;
    $skipfile = 0;

    # The following regular expression matches whole tags within
    # a line or partial tags that are broken by line endings.
    # In tags that straddle more the two lines, the middle lines
    # won't match this expression. (That's a feature, not a bug! ;-)
    $tags = '<[^>]*?(?:>|$)|(^|\G)[^<>]*?>'; # matches (partial) tags

    #chdir($txtdir);       # cd to the directory to keep it simple...
    opendir(DIR, ".");    # opendir is most portable on current dir (.)
    @txtFiles = grep( -T && !/\.(cgi|log|txt|pl|htaccess|htpasswd|dat|php3|bak)$/i && !/(index.html|form.html|insert.html|regex.html)/, readdir(DIR));
    closedir(DIR);

    print "<center><b>Search Results - Alphabetical by
Title</b><br> <font size=-1>Click on the title to view that document.";    
print " <a href=#totals> [ Goto Totals ] </a></font></center><p>";

    foreach $file (@txtFiles) {

  if(!$Files2Names{$file}) {$skip[$skipfile++] = $file; next;}
	open(FILE, $file) || do
            { print "Couldn't open file $file: $!\n"; next; };

        undef @keep;       # Re-initializing @keep is essential!
        for $j (0 .. $Context) {
            $keep[$Context - $j] = ''; # Add blank line before.
            $_ = <FILE>;               # Get next line from FILE.
            s/$tags//go if $StripHTML; # Remove whole and partial tags.
            $keep[$Context + $j] = $_ if $_; # Add next line after.
        }

       $StripHTML = 0 unless $StripHTML;
        eval <<ENDLOOP;                 # eval all code up to ENDLOOP.
        \$found = 0;
        while ( \$keep[$Context]) {
            if (\$keep[$Context] =~ /$Query/$matchOptions) {
                \$beg = \$. - $len;
                print "<A HREF=\\"mvl.cgi?NextName=$file\\"><B>$Files2Names{$file}</B></A>";
                \$found++;
                 
                print ":\n";
                foreach \$line (\@keep) {
                    if (\$line) {
                        unless ($StripHTML) {   # Can escape tags in
                          \$line =~ s/</&lt;/g; # output only, but must
                          \$line =~ s/>/&gt;/g; # handle < & > separately.
                        }
                        print \$line;
                    }
                }
                print "<p>\n";
            }
            if (\$_) {
                \$_ =  <FILE>;         # Must strip all input or none:
                \$_ =~ s/$tags//go if ($StripHTML);
                 
                # s/<([^>]|\\n)*>//go; # doesn't work on single lines.
            }
            shift(\@keep);             # out with the oldest line
            push( \@keep, \$_);        # in with the new
        }
ENDLOOP
        die("$0: $@") if $@;            # $@ catches errors from eval.
        close(FILE);

	if ($found) {
            $foundLines += $found;
            $foundFiles++;
        }
    }
    print "</PRE><a name=totals><center><B>Totals: $foundLines matches in $foundFiles files, ";
    print "out of ", 0 + @txtFiles - $skipfile, " files searched.</B><a href=#top><font size=-1> [ Goto Top ] </a></font></center><p>\n"; }

print "</FORM><center><hr><a href=\"http:\/\/www.global-dialog.org\" target=_top> [ Global Dialog Home ] </a><hr>\n";
print "<p></font></center></BODY></HTML>\n";
exit;
