#!/usr/bin/perl
# --------------------------------------------------------  PerlInterpreter
# Wiki code by Rich DeVaul, based on original code 
# Copyright (c) 1995, Cunningham & Cunningham, Inc.
# --------------------------------------------------------  InitialComments
use DB_File;
$SCRIPT_NAME = $ENV{SCRIPT_NAME};
$SERVER_NAME = $ENV{SERVER_NAME};

$CDB = "/home/web/httpd/wiki/uberconfig";

## Do uberwiki config based on CDB
$FieldSeparator = "\263";

tie (%cdb,"DB_File",$CDB) || &AbortScript("can't open $CDB");
$configName= $SERVER_NAME;
$configName =~ s/\./dot/g;

$newConfigName = $SCRIPT_NAME;
$newConfigName =~ s/\/[^\/]+$//;
$newConfigName =~ s/\//slash/g;
$newConfigName = $configName . $newConfigName;

$configName=havendotorg ; 
$newConfigName=havendotorg ; 

sub SelectConfig {
    local ($name,$depth) = @_;
    local (%cfg);
    if ($depth > 10) {
	return %cfg;
    }
    $name =~ s/\./dot/g;
    $name =~ s/\//slash/g;
    %cfg = split($FieldSeparator, $cdb{$name});
    if ($cfg{symlink} ne "") {
	return SelectConfig($cfg{symlink},$depth+1);
    }
    $configName = $name;
    return %cfg;
}

%config = SelectConfig($newConfigName,1);

$DefaultTitle=$config{DefaultTitle} || "FrontPage";
$RecentChanges=$config{RecentChanges} || "RecentChanges";
$DefaultTemplate=$config{DefaultTemplate} || "\#\#1 $SERVER_NAME \#\#\n(([Title]))\n";
$ScriptName=$config{ScriptName} || $SCRIPT_NAME;
$ScriptUrl=$config{ScriptUrl} ||  "https://$SERVER_NAME/";
$defaultTextColor=$config{defaultTextColor} || "#000000";
$voiceFont[1]= $config{voiceFont1} || "color=\"#D0FFFF\"";
$voiceFont[2]= $config{voiceFont2} || "color=\"#FFA0C0\"";
$voiceFont[3]= $config{voiceFont3} || "color=\"#A0FFD8\"";
$voiceFont[4]= $config{voiceFont4} || "color=\"#10A0F0\"";
$templateName=$config{templateName} || "DefaultTemplate";
$thanksText=$config{thanksText}; ## "thank you" wiki text
$abortText=$config{abortText}; ## "abort" wiki text
$BodyTag=$config{BodyTag} || "<BODY>";
$HeaderAddInfo=$config{HeaderAddInfo}; ## extra header info
$Rss=$config{RSS} || "/tmp/$SERVER_NAME";
$UploadDirectory=$config{UploadDirectory} || "/tmp/$SERVER_NAME" . "_upload";
untie(%cdb);

# --------------------------------------------------------  defaultTextmColor
$textcolor = $defaultTextColor;
$cookedcolor = "";
$defaultOptions = "";

# --------------------------------------------------------  ScriptName
$DataBase = "/home/web/httpd/wiki/pages/$ScriptName"; 
# --------------------------------------------------------  MasterPasswords
open(PASSLIST, "/home/wiki/passwords") || warn "Can't open /home/wiki/passwords: $!\n";
while(<PASSLIST>) {
    if ($_ =~ /^$ScriptName Edit (\S+)$/) {$MasterEditPass=$1;}
    if ($_ =~ /^$ScriptName View (\S+)$/) {$MasterViewPass=$1;}
 }
if (!$MasterEditPass) {$MasterEditPass = "Shells";}
if (!$MasterViewPass) {$MasterViewPass = "nemo";}

# --------------------------------------------------------  DataBase
sub AbortScript {
local ($msg) = @_;
print <<EOF ;
<h3>The Wiki Wiki Server Can't Process Your Request</h3>
$msg<p>
This information has been logged.<br>
We are sorry for any inconvenince.
EOF
die $msg;
}
# --------------------------------------------------------  AbortScript
# --------------------------------------------------------  DefaultTitle
$linkWord = "[A-Z][a-z]+";
$LinkPattern = "(?<!!!)($linkWord){2,}";
$metaVarPattern = "(?<!!!)([A-Za-z][a-z]*)?($linkWord)+";
$EscapedPattern = "!!(($linkWord){2,})";

sub BodyTag {
    local ($bt);
    $bt = "\n</HEAD>\n" . $BodyTag;
    $bt =~ s/\$($metaVarPattern)/$$1/go;
    return $bt;
}


# --------------------------------------------------------  LinkPattern
$DefaultRequest = "browse";
# --------------------------------------------------------  DefaultRequest
if ($ENV{REQUEST_METHOD} eq GET){
$RawInput = $ENV{QUERY_STRING} || $DefaultTitle;
$RawInput =~ s/^($LinkPattern)/$DefaultRequest=$1/; 
} 
if ($ENV{REQUEST_METHOD} eq POST){
read(STDIN, $RawRawInput, $ENV{CONTENT_LENGTH});
$RawInput=$RawRawInput;
} 
# --------------------------------------------------------  RawInput
$RawInput =~ s/\+/ /g;
foreach $_ (split(/&/, $RawInput)) {
s/\%(..)/pack(C, hex($1))/ge;
s/$FieldSeparator//go;
($_, $CookedInput) = split (/=/, $_, 2);
$CookedInput{$_} = $CookedInput;
}
# --------------------------------------------------------  CookedInput
# --------------------------------------------------------  LogoUrl

sub SetDefaultTextColor {
    local($tc) = @_;
    $defaultTextColor=$tc;
    return "";
}

sub ProcessVoice {
    local ($vn, $font) = @_;
    $voiceFont[$vn] = $font;
    return "";
}

sub ProcessMeta {
    $meta = $meta . "<META " . pop(@_) . ">\n";
    return "";
}

sub ProcessMetaLink {
    $meta = $meta . "<LINK " . pop(@_) . ">\n";
    return "";
}

# -------------------------------------------------------- ProcessVoice

$LogoImage = "";
$LogoImage2 = "";
# --------------------------------------------------------  SubLogoImage2
##$ScriptUrl = "https://devaul.net/cgi-bin/$ScriptName";
# --------------------------------------------------------  ScriptUrl
sub RetrievePage {
local($title) = pop(@_);
split($FieldSeparator, $db{$title} || 
"text${FieldSeparator}Describe $title here.");
}
# --------------------------------------------------------  RetrievePage
sub EscapeMetaCharacters {
    $text = pop(@_);
    $text =~ s/&/&amp;/g;
    $text =~ s/</&lt;/g;
    $text =~ s/>/&gt;/g;
    return $text;
}
# --------------------------------------------------------  EscapeMetaCharacters
sub InPlaceUrl {
local($num) = (@_);
local($ref) = $InPlaceUrl[$num];
"<a href=\"$ref\">$ref</a>";
}
# --------------------------------------------------------  InPlaceUrl
$TranslationToken = $FieldSeparator;
$incToken= "<inc>";
# --------------------------------------------------------  TranslationToken
sub EmitCode {
($code, $depth) = @_;
while (@code > $depth) {
    local($_) = pop @code; 
    print "</$_>\n"}
while (@code < $depth) {
    push (@code, ($code)); 
    print "<$code>\n"}
if ($code[$#code] ne $code) {
    print "</$code[$#code]><$code>\n";
    $code[$#code] = $code;}
}
# --------------------------------------------------------  EmitCode
sub ProcessCode {
($code, $depth) = @_;
local($localfoo);
$localfoo="";
while (@code > $depth) {
    local($_) = pop @code; 
    $localfoo = "$localfoo</$_>\n"}
while (@code < $depth) {
    push (@code, ($code)); 
    $localfoo = "$localfoo<$code>\n"}
if ($code[$#code] ne $code) {
    $localfoo = "$localfoo</$code[$#code]><$code>\n";
    $code[$#code] = $code;}
return $localfoo;
}
# -------------------------------------------------------- ProcessCode
sub AsAnchor {
local($title) = pop(@_);
defined $db{$title}
? "<a href=\"$ScriptUrl\?$title$defaultOptions\">$title<\/a>"
: "$title<a href=\"$ScriptUrl\?edit=$title\">?<\/a>";
}
# --------------------------------------------------------  AsAnchor
sub AsNamedAnchor {
local($title, $titlename)=@_;
defined $db{$title}
? "<a href=\"$ScriptUrl\?$title$defaultOptions\">$titlename<\/a>"
: "$titlename<a href=\"$ScriptUrl\?edit=$title\">?<\/a>";
}
# --------------------------------------------------------  AsNamedAnchor
sub AsLink {
local($num, %current) = @_;
local($ref) = $current{"r$num"};
defined $ref
? ($ref =~ /\.jpg$/i ? "<img src=\"$ref\">" 
 : $ref =~ /\.gif$/i ? "<img src=\"$ref\">" 
 : $ref =~ /\.png$/i ? "<img src=\"$ref\">" 
 : "<a href=\"$ref\">[$num]<\/a>")
: "[$num]";
}
# --------------------------------------------------------  AsLink
$SearchForm = <<EOF ;
<form action="$ScriptUrl">
<input 
type="text" 
size="20" 
name="search" 
value="$CookedInput{value}">
<\/form>
EOF
# --------------------------------------------------------  SearchForm

sub FormOptions {
    local($options);
    $options = "<input type=\"hidden\" name=\"textcolor\" value=\"$textcolor\">\n";
    if ($CookedInput{back}) {
	$options = $options."<input type=\"hidden\" name=\"back\" value=\"$CookedInput{back}\">\n";
    }
    if ($CookedInput{vpwd}) {
	$options = $options."<input type=\"hidden\" name=\"vpwd\" value=\"$CookedInput{vpwd}\">\n";
    }
    if ($CookedInput{epwd}) {
	$options = $options."<input type=\"hidden\" name=\"epwd\" value=\"$CookedInput{epwd}\">\n";
    }
    return $options;
}

sub PasswordChangeForm {
    local ($title, %tc, $footext, $options, $yvcheck, $nvcheck, $ywcheck, $nwcheck, $back);
    $title = pop(@_);
    %tc = RetrievePage($title);
    $back = $CookedInput{back};
    &ExtractColor;
    $backtitle = $CookedInput{back} ? $CookedInput{back} : $title;

    $options=&FormOptions;

    if (!$tc{vpwd} || $tc{vpwd} eq "none") {
	$disview = "readonly";
    }

    if ($tc{worldview} eq "no") {
	$yvcheck="";
	$nvcheck="checked";
    }
    else {
	$yvcheck="checked";
	$nvcheck="";
    }

    if (!$tc{epwd} || $tc{epwd} eq "none") {
	$diswrite = "readonly";
    }

    if ($tc{worldwrite} eq "no") {
	$ywcheck="";
	$nwcheck="checked";
    }
    else {
	$ywcheck="checked";
	$nwcheck="";
    }

    $footext = <<EOF ;
    <TABLE width="100%" cellspacing="00" cellpadding="10">
	<TR>
	<TD colspan=2>
        <H3>Access Control for <A href="$ScriptUrl?$title$defaultOptions">$title</A></H3> 

	This form allows you to assign or change the viewing and
	editing passwords associated with $title, and to change the
	access control options for this page. Unless this wiki is
	served by an ssl-only server, restrictions imposed here will
	provide modest security at best. <P>The
	intended purpose for viewing access restriction is to
	discurage search engines from indexing specific wiki pages.
	The intended purpose for setting editing passwords is to
	provide weak security for journal authors in the upgraded
	journal mode.  <BLOCKQUOTE>

	WITHOUT SSL ENCRYPTION, ANYONE WITH A PACKET SNIFFER ON THE
	WIRE CAN TRIVIALLY INTERCEPT THESE PASSWORDS. YOU HAVE BEEN
	WARNED.

	</BLOCKQUOTE>
        </TD>
        </TR>
        <TR>
        <TD>
          <H2>Viewing Options</H2>

		Setting the vieweing password to a value other than
		"none" will require viewers to provide this password
		in order to view $title if the viewing status is
		"restricted" You must provide the current edit
		password in order to make changes.

	    <form method="POST" action="$ScriptUrl"> 
	        $options
		    <label for="oldvpwpd">Current view password
			</label><BR>
		<input type="password" id="epwd" name="oldvpwd" size="12"> <P>
		<label for="vpwd1">New view password</label><BR>
		<input type="password" id="vpwd1" name="vpwd1" size="12"> <P>
		<label for="vpwd2">Confirm new view password</label><BR>
		<input type="password" id="vpwd2" name="vpwd2" size="12"> <P>
                <label for="worldview">Access Control</label><BR>
		<INPUT $disview type="radio" name="worldview" value="yes" $yvcheck> 
		    world viewable<BR>
		<INPUT $disview type="radio" name="worldview" value="no" $nvcheck> 
		    password required<P>
                <input type="hidden" size=1 name="post" value="$title">
	        <input type="hidden" size=1 name="type" value="vpwd">
		<input type="submit" value=" Change ">
		<input type="reset" value=" Reset "> 
		</form>

        </TD>
        <TD>
	    <H2>Editing Options</H2>

		The edit password provides access control for viewing
		and editing $title. You may use this form to toggle
		the "world writable" status of the page.  You must
		provide the current edit password in order to make
		changes.

	    <form method="POST" action="$ScriptUrl"> 
		$options
		    <label for="oldepwd">Current edit password
			</label><BR>
		<input type="password" id="oldepwd" name="oldepwd" size="12"> <P>
		<label for="epwd1">New edit password</label><BR>
		<input type="password" id="epwd1" name="epwd1" size="12"> <P>
		<label for="epwd2">Confirm new edit password</label><BR>
		<input type="password" id="epwd2" name="epwd2" size="12"> <P>
                <label for="worldwrite">Access Control</label><BR>
		<INPUT type="radio" name="worldwrite" value="yes" $ywcheck $diswrite> 
		    world writable<BR>
		<INPUT type="radio" name="worldwrite" value="no" $nwcheck $diswrite> 
		    password required<P>
                <input type="hidden" size=1 name="post" value="$title">
                <input type="hidden" size=1 name="type" value="epwd">
                <input type="submit" value=" Change ">
                <input type="reset" value=" Reset "> 
            </form>
        </TD>
    </TR>
    </TABLE>

<CENTER>Return to <A href="$ScriptUrl?$backtitle$defaultOptions">$backtitle</A> (Quit without making changes).</CENTER>
EOF
    return $footext;
}
# ---------------------------------------------------- PasswordChangeForm

sub JournalForm {
    local ($title,%tc, $cookedJournal,$footext);
    $title = pop(@_);
    %tc = RetrievePage($title);
    $cookedJournal = $tc{journal_text};
    $cookedJournal = &EscapeMetaCharacters($cookedJournal);
    $cookedJournal = &ProcessBodyText($title,$cookedJournal,$rdepth+1, %current); 
    $options = &FormOptions;

    $footext = <<EOF ;
   
    <TABLE width="80%" cellspacing="0" cellpadding="10">
	<TR>
	<TD>
        <CENTER>
        <H3>$title Journal</H3> 
	<A href="$ScriptUrl?journal=$title$defaultOptions">Edit this journal</A> in its
	entirety. Modify
	    <A href="$ScriptUrl?access=$title$defaultOptions">page access control</A>.<P>
        </CENTER>
        </TD>
        </TR>
        <TR>
        <TD>
    <form method="POST" action="$ScriptUrl"> 
	$options
    <TEXTAREA NAME="new_journal_text" ROWS=10 COLS=60 wrap=virtual>##3 $DateToday - $TimeStamp ##

</TEXTAREA><BR>
    <input type="hidden" size=1 name="post" value="$title">
    <input type="hidden" size=1 name="type" value="journal">
    <input type="submit" value=" Save ">
    <input type="reset" value=" Reset ">
    </form>
	</TD>
        </TR>
        <TR>
        <TD >
        $cookedJournal
        </TD>
	</TR>
    </TABLE>
EOF
	return $footext;
}
# -------------------------------------------------------- JournalForm


sub HitCounter {
    local($title,%tc) = @_;
    %tc = RetrievePage($title);
    return $tc{hit_counter};
}
# --------------------------------------------------------  HitCounter
sub RecentHitCounter {
    local($title,%tc) = @_;
    %tc = RetrievePage($title);
    return $tc{recent_hit_counter};
}
# --------------------------------------------------------  RecentHitCounter
sub ColorSelectionForm {
    local($title) = pop(@_);
$theColorSelectionForm = <<EOF ;
   <form method="GET" action="$ScriptUrl\?browse=$title">
    <P>
     <tt><big><strong>Change&nbsp;text&nbsp;color:</strong></big></tt><P>

      This form allows you to change the default text foreground
      color.  Your color selection will "follow" you as you navigate
      the wiki.
     <br>
     <input type="hidden" name="browse" value="$title">
     <input type="radio" name="textcolor" 
      value="$defaultTextColor">
        <font color="$defaultTextColor"> default</font><br>
     <input type="radio" name="textcolor" 
      value="#D0C0C0"><font color="#D0C0C0"> reddish</font><br>
     <input type="radio" name="textcolor"
      value="#C0D0C0"><font color="#C0D0C0"> greenish</font><br>
     <input type="radio" name="textcolor"
      value="#C0C0D0"><font color="#C0C0D0"> blueish</font><br>
     <input type="radio" name="textcolor"
      value="#F0F0F0"><font color="#F0F0F0">&nbsp;"wiki&nbsp;classic"&nbsp;white</font><br>
     <input type="submit" value="Change">
      
   </FORM>
   <form method="GET" action="$ScriptUrl\?browse=$title">
    <P>

      You may also select a new default foreground color by typing its
      description (such as <tt><font
      color="#10F030">#10F030</font></tt> or <tt><font
      color="red">red</font></tt>) into the box below and hitting
      "Enter."  The default is the current text color.<br>

     <input type="hidden" name="browse" value="$title">
     <input type="text" size="8" name="textcolor"
      value="$textcolor"><br>
   </FORM>
EOF
    return $theColorSelectionForm;
}
# --------------------------------------------------------  ColorSelectionForm
sub RecursePage {
    local($title, $rdepth, $text);
    local(%old);
    ($title, $rdepth) = @_;
    $rdepth += 1;
#    print "Depth=$rdepth<p>";
    if ($rdepth > 10)
    { 
        $text= "<P><STRONG>RECURSIVE DEPTH LIMIT of 10 EXCEEDED</STRONG><P>";
    }
    else {
	%old = %current;
	%current = &RetrievePage($title);
	if ( $current{worldview} eq "no" && $current{vpwd} && $current{vpwd} ne "none" && $vpwd ne $MasterViewPass && $current{vpwd} ne $vpwd ) {
	    return "<P><STRONG>Correct viewing pasword required for $title<P>";
	}
	$text = $current{text};
	$text = &EscapeMetaCharacters($text);
	$text = &ProcessBodyText($title,$text,$rdepth,%current);
        %current = %old;
    }
    return $text
}
# --------------------------------------------------------  RecursePage

sub bob {
    local($_) = pop(@_);
#    local($left,$center,$right);
    local ($localInc);
    local ($text);
    ($_ eq "") && return "";
    if (/&lt;(.*?)&gt;/s) {
	my $left = $`;
        my $center = $&;
	my $right = $';
	$center =~ s/&amp;/&/;
	return(&bob($left) . $center . &bob($right));
    } else {
	while (s/\b((http)|(https)|(ftp)|(mailto)|(news)|(file)|(gopher)):[^\s\<\>\[\]"'\(\)]*[^\s\<\>\[\]"'\(\)\,\.\?]/$TranslationToken$InPlaceUrl$TranslationToken/)

              {
                  $InPlaceUrl[$InPlaceUrl++] = $&;
              }
        while (s/\(\(($LinkPattern)\)\)/$incToken$incCounter$incToken/) {
           print "<!-- start: rdepth $rdepth incCounter: $incCounter title: $1-->\n";
#           print "<!-- vpwd: $vpwd -->\n";
           $localInc= $incCounter++;
           $incArray[$localInc] = &RecursePage($1,$rdepth);


#            foreach (split(/\n/,$incArray[$localInc])) {
#               print "<!-- INC " . ($localInc) . ": $_ \n";
#            }
#            print "<!-- END INC " . ($localInc) . "-->\n";

           print "<!-- end: rdepth $rdepth  incCounter: $incCounter-->\n";
#              $incArray[$incCounter++] = "$1";
        }
        s/\b$LinkPattern\b/&AsAnchor($&)/geo;
        s/$EscapedPattern\b/$1/g;
        s/\[\[(<a [^>]+>)[^<]*(<\/a>)\s([^\]]+)\]\]/$1$3$2/gio;
        s/\[\[[^<]+(<a [^>]+>\?<\/a>)\s([^\]]+)\]\]/$2$1/gio;

        return($_);
    }
}
# -------------------------------------------------------  Bob

sub ProcessTemplateText {
    local($text) = @_;
    $oldtext = $_;
    $_= $text;

    # Truly frightening stuff

    s/\[eval (.*?) EVALEOF\]/eval $1/geo;
    $outtext=$_;

    $_ =$oldtext;
    return $outtext;
}

sub scalarIndirect {
    local($sn, $rdepth) = @_;
    local($text);
    $rdepth += 1;

    if ($rdepth > 10)
    { 
        $text= "<P><STRONG>RECURSIVE DEPTH LIMIT of 10 EXCEEDED</STRONG><P>";
    }
    else {
	%old = %current;
	$text = &EscapeMetaCharacters($$sn);
	$text = &ProcessBodyText($title,$text,$rdepth+1,%current);
        %current = %old;
    }
    return $text;
}

sub callIndirect {
    local($subname) = @_;
    local($result);

    if ($config{$subname}) {
	$result = eval $config{$subname};
	$result =~ s/text_area/textarea/ig;
    }
    else {
	$result = "&lt;&lt;UNKNOWN SYMBOL $subname &gt;&gt;";
    }
    return $result;
}

sub ProcessBodyText {
    local($title,$text,$rdepth,%current);
    ($title,$text,$rdepth,%current) = @_;
    local($oldtext,$outtext);
    $oldtext = $_;
    $_ = &bob($text);

    ## Convert the sequence ==> into one tab character for the
    ## purposes of other markup conventions ##
    s/==&gt;/\t/gs;
    s/\\\n/ /g;
    s/\\\\/<br>/gs;
    s/%%(.*?)%%/<center>$1<\/center>/gs;
    s/\${2}([1-4])(.*?)\${2}/<font $voiceFont[$1]>$2<\/font>/gs;

    # --- The <a></A> tag matching stuff was modified so that it would
    # --- not mistakenly match <abracadabra>foo</artichoke> as links.
    s/&lt;a( .*?)&gt;/<A $1>/sgio;
    s/&lt;\/a( *?)&gt;/<\/A>/sgio;
    s/&lt;(\/?)font(.*?)&gt;/<$1FONT $2>/sgi;
    s/&lt;img(.*?)&gt;/<IMG $1>/sgi;
    s/\{\{(.*?)\}\}/<tt>$1<\/tt>/gs;
    # ---------------------------------------- attempt to add blockquote
    s/&lt;(\/?)blockquote&gt;/<$1BLOCKQUOTE>/sgi;
    # ---------------------------------------- attempt to add spacing
    s/&amp;nbsp\;/\&nbsp\;/gs;
    # ---------------------------------------- attempt to add interesting marks
    s/&amp;dagger\;/\&dagger\;/gs;
    s/&amp;Dagger\;/\&Dagger\;/gs;
    # ---------------------------------------- attempt to add class support
    s/&lt;span(.*?)&gt;/<SPAN $1>/sgi;
    s/&lt;\/span( *?)&gt;/<\/SPAN>/sgi;
    s/&lt;div(.*?)&gt;/<DIV $1>/sgi;
    s/&lt;\/div( *?)&gt;/<\/DIV>/sgi;
    # ---------------------------------------- attempt to add form support
    s/&lt;(\/?)form(.*?)&gt;/<$1FORM $2>/sgi;
    s/&lt;(\/?)input(.*?)&gt;/<$1input $2>/sgi;
    s/&lt;(\/?)select(.*?)&gt;/<$1SELECT $2>/sgi;
    s/&lt;(\/?)option(.*?)&gt;/<$1OPTION $2>/sgi;
    s/&lt;(\/?)textarea(.*?)&gt;/<$1TEXTAREA $2>/sgi;
    # ---------------------------------------- attempt to add table support
    s/&lt;(\/?)table(.*?)&gt;/<$1TABLE $2>/sgi;

    # --- The <tr></tr> tag matching was modified so that it would not
    # --- mistakenly match <tractor-pull>bar</treason>
    s/&lt;tr(( .*?)?)&gt;/<TR $1>/sgi;
    s/&lt;\/tr( *?)&gt;/<\/TR>/sgi;
    s/&lt;(\/?)td(.*?)&gt;/<$1TD $2>/sgi;
    # ----- attempt to add support for IFRAME tag
    s/&lt;(\/?)iframe(.*?)&gt;/<$1IFRAME $2>/sgi;

    s/\"{2}(.*?)\"{2}/<big>$1<\/big>/gs;
    s/'{3}(.*?)'{3}/<strong>$1<\/strong>/gs;
    s/'{2}(.*?)'{2}/<em>$1<\/em>/gs;
## do some basic despaming... #
    s/@/&#64;<!-- no spam -->/g;


    foreach (split(/\n/, $_))
    {
	# --------------------------------- attempt to add anchor support
# ---------------------------------------- direct image inlining support

	$code = "";
s/^\s*$/<p>/                  && ($code = '...');             
s/^(\t+)(.+):\t/<dt>$2<dd>/   && ($outtext=$outtext.&ProcessCode(DL, length $1));
s/^(\t+)\*/<li>/              && ($outtext=$outtext.&ProcessCode(UL, length $1));
s/^(\t+)\d+\.?/<li>/          && ($outtext=$outtext.&ProcessCode(OL, length $1));
/^\s/                        && ($outtext=$outtext.&ProcessCode(PRE, 1));
$code                         || ($outtext=$outtext.&ProcessCode("", 0));
# s/'{3}(.*)'{3}/<strong>$1<\/strong>/g;
# s/'{2}(.*)'{2}/<em>$1<\/em>/g;
s/##([1-9])(.*?)##/<H$1>$2<\/H$1>/g;
# s/##1(.*?)##/<H1>$1<\/H1>/g;
# s/##2(.*?)##/<H2>$1<\/H2>/g;
# s/##3(.*?)##/<H3>$1<\/H3>/g;
# s/##4(.*?)##/<H4>$1<\/H4>/g;
# s/##5(.*?)##/<H5>$1<\/H5>/g;
# Attempt to add comment syntax
	s/^\/\/(.*?)\r/<!-- $1 -->/;

s/^-----*/<hr>/;

s/\[(\d+)\]/&AsLink($1,%current)/geo;
s/$TranslationToken(\d+)$TranslationToken/&InPlaceUrl($1)/geo;
	s/$incToken(\d+)$incToken/"<!-- inclusion: $1 -->\n$incArray[$1]"/geo;

# ---------------------------------------- attempt to add in-page edit link
s/\[Title\]/$title/ge;
s/\[edit\]/<a href=\"$ScriptUrl\?edit=$title$defaultOptions\">Edit $title<\/a>/go;
s/\[edit ($LinkPattern)\]/<a href=\"$ScriptUrl\?edit=$1$defaultOptions\">Edit $1<\/a>/go;

s/\[access\]/<a href=\"$ScriptUrl\?access=$title$defaultOptions\">Access Control for $title<\/a>/go;
s/\[Search\]/$SearchForm/;
# add scriptURL substitution for use in <A> tags.
s/\[Script Url\]/$ScriptUrl/ge;
s/\[Default Color\]/$cookedcolor/ge;
s/\[Default Options\]/$defaultOptions/ge;
s/\[Color Selection\]/&ColorSelectionForm($title)/e;
s/\[Hit Counter\]/&HitCounter($title)/e;
s/\[Hit Counter ($LinkPattern)\]/&HitCounter($1)/e;
s/\[Recent Hit Counter\]/&RecentHitCounter($title)/e;

# ------------------------------------------------------ Journal Support
s/\[Journal\]/&JournalForm($title)/e;
s/\[Password Change\]/&PasswordChangeForm($title)/e;
s/\[Password Change ($LinkPattern)\]/&PasswordChangeForm($1)/e;

# ------------ Deeply Frightening Subrotine and Scalar Evaluation Support
# This syntax does not do "wiki" text expansion:
s/\[scalar ($metaVarPattern)\]/$$1/go;
# ------------ Alternate syntax -- this _does_ do wiki text expansion
s/\$($metaVarPattern)/scalarIndirect($1)/geo;
s/\[callsub ($metaVarPattern)\]/callIndirect($1)/geo;

#print "$_\n";
	$outtext="$outtext$_\n";
}
    $outtext = $outtext.&ProcessCode("", 0);
    $_ = $oldtext;
    return $outtext;
}
# --------------------------------------------------------  ProcessBodyText

sub ExtractColor {
$textcolor = $CookedInput{textcolor};
if ($textcolor eq "") {
    $textcolor = $defaultTextColor;
}
$cookedcolor = $textcolor;
$cookedcolor =~ s/\#/\%23/g;
$defaultOptions = "&textcolor=$cookedcolor";
if ($title) {
    $defaultOptions = $defaultOptions."&back=$title";
}
if ($CookedInput{vpwd}) {
    $defaultOptions = $defaultOptions."&vpwd=$CookedInput{vpwd}";
}
if ($CookedInput{epwd}) {
    $defaultOptions = $defaultOptions."&epwd=$CookedInput{epwd}";
}
}
# --------------------------------------------------------  ExtractColor
sub HandleBrowse {
$title = $CookedInput{browse};
$vpwd = $CookedInput{vpwd};
$meta = <<EOF ;
<META http-equiv="Content-Style-Type" content="text/css">
EOF

&ExtractColor;

&RequestLock;
%old = &RetrievePage($title);
if ( $old{worldview} eq "no" && $old{vpwd} ne "none" && $vpwd ne $MasterViewPass && $old{vpwd} ne $vpwd ) {
    $options = &FormOptions;
print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>$title</title>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag;
print <<EOF ;

    <TABLE WIDTH="100%" cellspacing=20 cellpadding=20 BORDER=0>
	<TR><TD align=center>
	    <H1>Password Required</H1>
	    </TD></TR>
        <TR><TD align=center>
	    
	The page you are trying to access is password protected.<P>
	Please enter the appropriate password in the text area below<BR>
	to view the page.
	    </TD></TR>
        <TR><TD align=center>	    	
   <form method="GET" action="$ScriptUrl\?browse=$title">
    <P>
     $options
     <input type="hidden" name="browse" value="$title">
     <input type="password" size="12" name="vpwd"><P>
     <input type="submit" value=" Submit ">
   </FORM>
	    </TD></TR>
      </TABLE>
    </BODY>
    </HTML>
EOF
    untie(%db);
##    dbmclose(%db);
    &ReleaseLock;
    return;
}
## Increment the hit counters
$old{hit_counter} = $old{hit_counter}+1;
$old{recent_hit_counter} = $old{recent_hit_counter} +1;
&ReplacePage($title, *old);
&ReleaseLock;

$date=$old{date};
$templateName = $old{template} ? $old{template} : $templateName;

if ($templateName eq "default") {
    $templateName="DefaultTemplate";
}
if (%template = &RetrievePage($templateName)) {
    $rawTemplate = $template{text};
}
else {
    $rawTemplate = $DefaultTemplate;
    $template{text} = $rawTemplate;
}

$_ = $rawTemplate;

s/\[Script Url\]/$ScriptUrl/ge;
s/\[Title\]/$title/ge;
s/\[Edit Date\]/$date/ge;
# --- edit voice stuff
s/\[Voice ([1-9]) (.*?)\]/&ProcessVoice($1,$2)/ge;
s/<meta (.*?)>/&ProcessMeta($1)/ge;
s/<link (.*?)>/&ProcessMetaLink($1)/ge;

# --- set default text color
s/\[DefaultTextColor (.*?)\]/&SetDefaultTextColor($1)/ge;

$_ = &EscapeMetaCharacters($_);

    $InPlaceUrl = 0;
    $incCounter = 0;
$rdepth = 0;

# foreach (split(/\n/,$_)) {
#     print "<!-- PRE: $_ \n";
# }
# print "     END PRE -->\n";

print <<EOF ;
<HTML>
<head>
<title>$title</title>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag;
print &ProcessBodyText($title,$_,1,%old);
#print &RecursePage($title,0,$_);
#print &bob($_);

print "</body>\n</html>";

}
# --------------------------------------------------------  HandleBrowse
sub HandleAccess {
    $title = $CookedInput{access};
    $title =~ /^$LinkPattern$/ || &AbortScript("access: improper name: $title");
    &ExtractColor;
    %old = &RetrievePage($title);
    print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>Access: $title</title>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag;
print <<EOF ;
<CENTER><H1>Access Control for $title</H1></CENTER>
EOF

    print &PasswordChangeForm($title);
    print "</body>\n</html>";
}
# -------------------------------------------------------- HandleAccess

sub HandleEdit {
    $title = $CookedInput{edit} || $CookedInput{copy};
    $title =~ /^$LinkPattern$/ || &AbortScript("edit: improper name: $title");
    $backtitle = $CookedInput{back} ? $CookedInput{back} : $title;
    &ExtractColor;
    %old = &RetrievePage($title);
				# extract edit password
    $epwd = $CookedInput{epwd};
				# figure optional parameters for
				# hidden form input, less edit
				# password (in case the edit password
				# is wrong and needs to be provided by
				# the user in the next block of code).

    $options = &FormOptions;

    if ( $old{worldwrite} eq "no" && $old{epwd} && $old{epwd} ne "none" 
	&& $epwd ne $MasterEditPass && $old{epwd} ne $epwd ) {
	print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>Edit password required</title>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag;
print <<EOF ;
    <TABLE WIDTH="100%" cellspacing=20 cellpadding=20 BORDER=0>
	<TR><TD align=center>
	    <H1>Edit Password Required</H1>
	    </TD></TR>
        <TR><TD align=center>
	    
	The page you are trying to access is password protected.<P>
	Please enter the appropriate password in the text area below<BR>
	to edit the page.
	    </TD></TR>
        <TR><TD align=center>	    	
	    <form method="GET" action="$ScriptUrl\?">
            <P>
            <input type="hidden" name="edit" value="$title">
            $options
            <input type="password" size="12" name="epwd"><br>
            </FORM>
        </TD></TR>
     </TABLE>
</BODY>
</HTML>
EOF
    untie(%db);
##        dbmclose(%db);
	&ReleaseLock;
	return;
    }


# -------------------- extract template
    $template = $old{template} ? $old{template} : "$templateName";

    $_ = $CookedInput{copy} ? $old{copy} : $old{text};
    $note = 'Copy of ' if $CookedInput{copy};

				# deal with CR/LF 
    s/\r\n/\n/g;
				# escape stuff
    $_ = &EscapeMetaCharacters($_);
				# default tab conversion?
    $convert = "checked" if $ENV{HTTP_USER_AGENT} =~ /WebExplorer/;  
				# print the edit form
    print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>Edit $note$title</title>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag;
print <<EOF ;
<form method="POST" action="$ScriptUrl">
  $options
  <input type="hidden" name="type" value="edit">
  <h1>$note$title 
    <font color="#000000">
      <input type="submit" value=" Save ">
      <input type="reset" value=" Reset ">
    </font>
  </h1>
  Back to <a href="$ScriptUrl?$backtitle$defaultOptions">$backtitle</a> (quit without changes)
  <P>
  <TEXTAREA NAME="text" ROWS=20 COLS=80 wrap=virtual>$_</TEXTAREA><br>
  <input type="checkbox" name="convert" value="tabs" $convert>

  I can't type tabs. 
  Please <a href="$ScriptUrl?ConvertSpacesToTabs$defaultOptions">ConvertSpacesToTabs</a>
  for me when I save.<p>

  <a href="$ScriptUrl?GoodStyle$defaultOptions">GoodStyle</a> tips for editing.<br>
  <a href="$ScriptUrl?links=$title$defaultOptions">EditLinks</a> to other web servers.<br>
EOF
				# Optional "copy" block
    print <<EOF if $old{copy} && !$CookedInput{copy};
    <a href="$ScriptUrl?copy=$title">EditCopy</a> from previous author.<br>
EOF
				# Continue main form body
print <<EOF ;
  <input type="hidden" size=1 name="post" value="$title">
</form>

<form method="POST" action="$ScriptUrl">
  Select the 
  <A href="$ScriptUrl\?browse=PageTemplate$defaultOptions">PageTemplate</A>
  for this page:

  $options

  <input type="text" size="20" name="template"
   value="$template"><br>
  <input type="hidden" size=1 name="post" value="$title">
  <input type="hidden" name="type" value="template">
</form>
</body>
EOF
				# end of form and routine.
}
# --------------------------------------------------------  HandleEdit

sub HandleJournalEdit {
    $title = $CookedInput{journal} ;
    $title =~ /^$LinkPattern$/ || &AbortScript("edit: improper name: $title");
    &ExtractColor;
    %old = &RetrievePage($title);
				# extract edit password
    $epwd = $CookedInput{epwd};
				# figure optional parameters for
				# hidden form input, less edit
				# password (in case the edit password
				# is wrong and needs to be provided by
				# the user in the next block of code).

    $options = "<input type=\"hidden\" name=\"textcolor\" value=\"$textcolor\">\n";
    if ($CookedInput{vpwd}) {
	$options = $options."<input type=\"hidden\" name=\"vpwd\" value=\"$CookedInput{vpwd}\">\n";
    }
    if ($CookedInput{epwd}) {
	$options = $options."<input type=\"hidden\" name=\"epwd\" value=\"$CookedInput{epwd}\">\n";
    }


    if ( $old{worldwrite} eq "no" && $old{epwd} && $old{epwd} ne "none" 
	&& $epwd ne $MasterEditPass && $old{epwd} ne $epwd ) {
	print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>Edit password required</title>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag ;
print <<EOF ;
    <TABLE WIDTH="100%" cellspacing=20 cellpadding=20 BORDER=0>
	<TR><TD align=center>
	    <H1>Edit Password Required</H1>
	    </TD></TR>
        <TR><TD align=center>
	    
	The page you are trying to access is password protected.<P>
	Please enter the appropriate password in the text area below<BR>
	to edit the page.
	    </TD></TR>
        <TR><TD align=center>	    	
	    <form method="GET" action="$ScriptUrl\?">
            <P>
            <input type="hidden" name="journal" value="$title">
            $options
            <input type="password" size="12" name="epwd"><br>
            </FORM>
        </TD></TR>
     </TABLE>
</BODY>
</HTML>
EOF
    untie(%db);
##        dbmclose(%db);
	&ReleaseLock;
	return;
    }

				# Extend options with edit password
    if ($CookedInput{epwd}) {
	$options = $options."<input type=\"hidden\" name=\"epwd\" value=\"$CookedInput{epwd}\">\n";
    }

# -------------------- extract template
    $template = $old{template} ? $old{template} : "$templateName";

    $_ = $old{journal_text};

				# deal with CR/LF 
    s/\r\n/\n/g;
				# escape stuff
    $_ = &EscapeMetaCharacters($_);
				# default tab conversion?
    $convert = "checked" if $ENV{HTTP_USER_AGENT} =~ /WebExplorer/;  
				# print the edit form
    print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>Edit $note$title</title>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag ;
print <<EOF ;
<form method="POST" action="$ScriptUrl">
  $options
  <input type="hidden" name="type" value="edit">
  <h1>$note$title 
    <font color="#000000">
      <input type="submit" value=" Save ">
      <input type="reset" value=" Reset ">
    </font>
  </h1>
  Back to <a href="$ScriptUrl?$title$defaultOptions">$title</a> (quit without changes)
  <P>
  <TEXTAREA NAME="journal_text" ROWS=20 COLS=80 wrap=virtual>$_</TEXTAREA><br>
  <input type="checkbox" name="convert" value="tabs" $convert>

  I can't type tabs. 
  Please <a href="$ScriptUrl?ConvertSpacesToTabs$defaultOptions">ConvertSpacesToTabs</a>
  for me when I save.<p>

  <a href="$ScriptUrl?GoodStyle$defaultOptions">GoodStyle</a> tips for editing.<br>
  <a href="$ScriptUrl?links=$title$defaultOptions">EditLinks</a> to other web servers.<br>
EOF
				# Optional "copy" block
    print <<EOF if $old{copy} && !$CookedInput{copy};
    <a href="$ScriptUrl?copy=$title">EditCopy</a> from previous author.<br>
EOF
				# Continue main form body
    print <<EOF ;
  <input type="hidden" size=1 name="post" value="$title">
</form>

<form method="POST" action="$ScriptUrl">
  Select the 
  <A href="$ScriptUrl\?browse=PageTemplate$defaultOptions">PageTemplate</A>
  for this page:

  $options

  <input type="text" size="20" name="template"
   value="$template"><br>
  <input type="hidden" size=1 name="post" value="$title">
  <input type="hidden" name="type" value="template">
</form>
</body>
EOF
				# end of form and routine.
}
# --------------------------------------------------------  HandleJournalEdit


sub HandleLinks {
$title = $CookedInput{links};
$title =~ /^$LinkPattern$/ || &AbortScript("link: improper name: $title");
&ExtractColor;
%old = &RetrievePage($title);
print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>$title Links</title>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag ;
print <<EOF ;
<form method="POST" action="$ScriptUrl">
<h1>$title Links 
<font color="#000000">
<input type="submit" value=" Save ">
<input type="reset" value=" Reset "></font></h1>
[1] <input type="text" size=55 name="r1" value="$old{r1}"><br>
[2] <input type="text" size=55 name="r2" value="$old{r2}"><br>
[3] <input type="text" size=55 name="r3" value="$old{r3}"><br>
[4] <input type="text" size=55 name="r4" value="$old{r4}"><br>
[5] <input type="text" size=55 name="r5" value="$old{r5}"><br>
[6] <input type="text" size=55 name="r6" value="$old{r6}"><br>
[7] <input type="text" size=55 name="r7" value="$old{r7}"><br>
[8] <input type="text" size=55 name="r8" value="$old{r8}"><p>
Type the full URL (http:// ...) for each reference cited in the text.<p>
<input type="hidden" size=1 name="post" value="$title">
<input type="hidden" name="type" value="references">
</form>
EOF
}
# --------------------------------------------------------  HandleLinks
sub HandleSearch  {
local($m, $n, @rec);
$pat = $CookedInput{search};
$pat =~ s/[+?.*()[\]{}|\\]/\\$&/g;
$results = Results;
$results = "for $&" if $pat =~ /\W+/;
print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>Search $results</title></head>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag;
print "<CENTER><H1>Search $results</H1></CENTER>";
while (($key, $value) = each %db){
    $n++;
    %rec = split($FieldSeparator, $value);
    if ($key =~/\b\w*($pat)\w*\b/i ||
	$rec{text} =~ /\b\w*($pat)\w*\b/i){
	$m++;
	print "<a href=\"$ScriptUrl\?$key\">$key<\/a> . . . . . .  $&<br>\n";
    }
}
$m = $m || No;
print "<hr>$m pages found out of $n pages searched.</body></HTML>";
}
# --------------------------------------------------------  HandleSearch
sub CookSpaces {
$CookedInput{text} =~ s/ {3,8}/\t/g
if $CookedInput{convert};
}
# --------------------------------------------------------  CookSpaces
$LockDirectory = "/tmp/$ScriptName"; 
# --------------------------------------------------------  LockDirectory
sub RequestLock {
local ($n) = 0;
while (mkdir($LockDirectory, 0555) == 0) {
$! == 17 || &AbortScript("can't make $LockDirectory: $!\n");  # EEXIST == 17 is OK, try later.
$n++ < 30 || &AbortScript("timed out waiting for $LockDirectory\n");
sleep(1);
}
}
# --------------------------------------------------------  RequestLock
sub BackupCopy {
$old{copy} = $old{text} 
if $old{host} && $old{host} ne $ENV{REMOTE_HOST};
}
# --------------------------------------------------------  BackupCopy
($sec, $min, $hour, $mday, $mon, $year) = localtime($^T);
$DateToday = (January, February, March, April, May, June, July, 
August, September, October, November, December)[$mon]
. " " . $mday . ", " . ($year+1900);
if ($min < 10) {
    $TimeStamp = $hour . ":0" . $min;
}
else {
    $TimeStamp = $hour . ":" . $min;
}

# --------------------------------------------------------  DateToday
sub ReplacePage {
local($title, *page) = @_;
local($value, @value);
$page{date} = $DateToday;
$page{host} = $ENV{REMOTE_HOST};
$page{agent} = $ENV{HTTP_USER_AGENT};
$page{rev}++;
@value = %page;
$value = join($FieldSeparator, @value);
open (WDB, ">$DataBase.wdb/$title");
print WDB $value;
close WDB;
$db{$title} = $value;
}
# --------------------------------------------------------  ReplacePage
sub ReleaseLock {
rmdir($LockDirectory);
}
# --------------------------------------------------------  ReleaseLock
#$SignatureUrl = "https://borglab.com/signature.jpg";
# --------------------------------------------------------  SignatureUrl
sub HandlePost {
$title = $CookedInput{post};
$back = $CookedInput{back};
&ExtractColor;
if ($back) {
  $backstring="<P>Back to <a href=\"$ScriptUrl?$back$defaultOptions\">$back</a>";
  }

&CookSpaces;
&RequestLock;
use DB_File;

tie(%db,"DB_File",$DataBase) || &AbortScript("can't open $DataBase for update\n");
## dbmopen(%db, $DataBase , 0666) || &AbortScript("can't open $DataBase for update\n");
%old = &RetrievePage($title);
$old{recent_hit_counter}=0;
&BackupCopy;
				# Handle request for setting page edit password
if ( $CookedInput{type} eq "epwd" ) {
    print("<!-- type: $CookedInput{type} -->\n");
    print("<!-- epwd1: $CookedInput{epwd1}  epwd2: $CookedInput{epwd2} -->\n");
				# $MasterEditPass is the default password for all pages
    if (!$old{epwd}) { $old{epwd}=$MasterEditPass; }
				# "none" means no password, $MasterEditPass
				# is the master password.
    if ($old{epwd} ne "none" && 
    $CookedInput{oldepwd} ne $old{epwd} && $CookedInput{oldepwd} ne $MasterEditPass) {
	print("<!-- abort: old password does not match -->\n");
	print("<!-- abort: provided: $CookedInput{oldepwd} -->\n");
	untie(%db);
#	dbmclose(%db);
	&ReleaseLock;
	&AbortScript("Old password does not match");
    }
				# Check to see if we are setting the password
    if ( $CookedInput{epwd1} ne "" && $CookedInput{epwd2} ne "" ) {
				# It appears that we are attempting to set a password
				# new passwords must agree
	if ( $CookedInput{epwd1} ne $CookedInput{epwd2} ) {
	    print("<!-- abort: new passwords do not agree -->\n");
	    untie(%db);
##	    dbmclose(%db);
	    &ReleaseLock;
	    &AbortScript("New passwords are not the same");
	}
				# assigning new edit password
	print("<!-- Assigning new edit password $CookedInput{epwd1} -->\n");
	$old{epwd} = $CookedInput{epwd1};
    }
				# Assign viewing status
    $old{worldwrite}= $CookedInput{worldwrite}
}
				# Handle request for setting page view options
elsif ( $CookedInput{type} eq "vpwd" ) {
    print("<!-- type: $CookedInput{type} -->\n");
    print("<!-- old: $old{vpwd}  vpwd1: $CookedInput{vpwd1}  vpwd2: $CookedInput{vpwd2} -->\n");
				# $MasterViewPass is the default password for all pages
    if (!$old{vpwd}) { $old{vpwd}=$MasterViewPass; }
				# "none" means no password, $MasterViewPass
				# is the master password.
    if ($old{vpwd} ne "none" && 
    $CookedInput{oldvpwd} ne $old{vpwd} && $CookedInput{oldvpwd} ne $MasterViewPass) {
	print("<!-- abort: old password does not match -->\n");
	print("<!-- abort: old: $old{vpwd} provided: $CookedInput{oldvpwd} -->\n");
	untie(%db);
#	dbmclose(%db);
	&ReleaseLock;
	&AbortScript("Old password does not match");
    }
				# Check to see if we are setting the password

    if ( $CookedInput{vpwd1} ne "" && $CookedInput{vpwd2} ne "" ) {
				# It appears that we are attempting to set a password
	if ( $CookedInput{vpwd1} ne $CookedInput{vpwd2} ) {
	    print("<!-- abort: new passwords do not agree -->\n");
	    untie(%db);
##	    dbmclose(%db);
	    &ReleaseLock;
	    &AbortScript("New passwords are not the same");
	}
	print("<!-- Assigning new view password $CookedInput{vpwd1} -->\n");
	$old{vpwd} = $CookedInput{vpwd1};
    }
				# Assign viewing status
    $old{worldview}= $CookedInput{worldview}
}
else {
    for (keys(%CookedInput)) {
	next if /post/ || /form/ || /title/;
	if ( $CookedInput{$_} && ! ($CookedInput{$_} =~ /^[ \n\r]*$/s )) {
	    $old{$_} = $CookedInput{$_};
	}
    }
    if ( $CookedInput{new_journal_text} && ! ($CookedInput{new_journal_text} =~ /^[ \n\r]*$/s )) {
	$old{journal_text} = $CookedInput{new_journal_text} . "\n\n" .  $old{journal_text};
    }
}

&ReplacePage($title, *old);

%rc = &RetrievePage($RecentChanges);
if ( $rc{text} eq "" ) {
    $rc{text} = "##1Recent Changes## \n";
}

$rc{text} =~ s/\t\* $title .*\n//;
$rc{text} =~ s/$DateToday .*\n//;
$rc{text} =~ s/(##1Recent Changes##.*?\n)/$1\n$DateToday \n\t* $title {{([Hit Counter !!$title] hits)}} . . . . . . $TimeStamp EDT/s;
&ReplacePage($RecentChanges, *rc);
$anchor = &AsAnchor($title);
		untie(%db);
##dbmclose(%db);
&ReleaseLock;

## Attempt to add support for RSS feed

if ( open (RSS, "<$Rss.xml") != 0 ) {
    read(RSS,$rssdata,10000);
    close RSS;
}
else {
    $rssdata= <<EOF ;
<?xml version="1.0" ?>
<rss version="2.0">

<channel>

<title>$SERVER_NAME Wiki RSS Syndication -- Recent Changes<\/title>
<description>Page edits for $SERVER_NAME result in new items. <\/description>
<link>$ScriptUrl<\/link>

<!-- next item marker -->

<\/channel>

<\/rss>
EOF
}
open (RSS, ">$Rss.xml");

## Delete previous occurances of item
$rssdata=~ s/\n<item>\n<title>$title<\/title>.*?<\/item>\n//gsx;

## Insert new occurance at marker
$rssdata=~ s/<!-- next item marker -->/<!-- next item marker -->\n<item>\n<title>$title<\/title>\n<guid isPermaLink=\"false\">$title:$DateToday:$TimeStamp<\/guid>\n<description>$title edited on $DateToday at $TimeStamp<\/description>\n<link>$ScriptUrl?$title<\/link>\n<\/item>\n/;

print RSS $rssdata;
close RSS;

print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>Thanks for $title Edits</title></head>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag;
print <<EOF ;
Thank you for editing $anchor.
<P>
$thanksText
<P>
$backstring
<P>
p.s. Be sure to <em>Reload</em> your old pages.<br>
</body>
</html>
EOF
}
# --------------------------------------------------------  HandlePost
sub HandleSpecial {
    $action= $CookedInput{special};
    $title = $CookedInput{$action};
    &ExtractColor;
    print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>$action: $title</title>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag;
    if ( exists $config{"SPECIAL$action"} ) {
	print "<!-- Evaluating SPECIAL$action -->\n";
	eval $config{"SPECIAL$action"};
	print "<!-- Done evaluating SPECIAL$action -->\n";
    }
    else {
	print "&lt;&lt;UNKNOWN SYMBOL SPECIAL$action&gt;&gt;";
    }
    print <<EOF ;
    </BODY>
</HTML>
EOF

}
# --------------------------------------------------------  HandleSpecial

sub DumpBinding {
local(*dict) = @_;
print "<hr><dl>\n";
for (keys(%dict)){print "<dt>$_<dd>$dict{$_}\n";}
print "</dl><hr>\n";
}
# --------------------------------------------------------  DumpBinding

# InitialComments
print "Content-type: text/html\n\n";
print "<!-- SCRIPT_NAME: $SCRIPT_NAME -->\n";
print "<!-- SERVER_NAME: $SERVER_NAME -->\n";
print "<!-- configName: $configName -->\n";
print "<!-- newConfigName: $newConfigName -->\n";
print "<!-- ScriptUrl: $ScriptUrl -->\n";
use DB_File;
tie(%db,"DB_File",$DataBase) || &AbortScript("can't open $DataBase for update\n");
##dbmopen(%db, $DataBase , 0666) || &AbortScript("can't open $DataBase");
if ($ENV{REQUEST_METHOD} eq GET){
  SWITCHONE: {
      $CookedInput{browse}  && do { &HandleBrowse; last SWITCHONE; };
      $CookedInput{edit}    && do { &HandleEdit; last SWITCHONE; };
      $CookedInput{journal} && do { &HandleJournalEdit; last SWITCHONE; };
      $CookedInput{copy}    && do { &HandleEdit; last SWITCHONE; };
      $CookedInput{links}   && do { &HandleLinks; last SWITCHONE; };
      $CookedInput{search}  && do { &HandleSearch; last SWITCHONE; };
      $CookedInput{access}  && do { &HandleAccess; last SWITCHONE; };
      $CookedInput{special} && do { &HandleSpecial; last SWITCHONE; };
      &AbortScript("Unknown operation or request:\n$RawInput");
  }
    untie(%db);
}
##dbmclose (%db);
if ($ENV{REQUEST_METHOD} eq POST) {
  SWITCHTWO: {
      if ($CookedInput{post}) { &HandlePost; last SWITCHTWO; }
      if ($CookedInput{special}) { &HandleSpecial; last SWITCHTWO; }
      use MIME::Parser;
      ### Create parser, and set some parsing options:
      my $parser = new MIME::Parser;
      $parser->output_under($UploadDirectory);

      ### Parse input:
      $entity = $parser->parse_data($RawRawInput) or &AbortScript("parse failed");

      ### Take a look at the top-level entity (and any parts it has):
print <<EOF ;
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<HTML>
<head>
<title>Upload Results</title>
EOF
print $meta;
print $HeaderAddInfo;
print &BodyTag;
print <<EOF ;
<H1>File Upload Results</H1>
The results returned by your file upload are below.  Please note that the file name is randomly generated and the file type is likely to be set to "text."  However, your file data should be preserved.<P>
Please copy the file name for future reference.  In general, you probably want to notify Rich about the upload so that he can restore the proper file name and type and move the file to somewhere more appropriate.  However, you can now download your file from its present location as a subdirectory of <a href="https://borglab.com/uploads/">https://borglab.com/uploads/</A>.
<P>
Use the "back" button on your browser to return to the borglab wiki.
<H2>Upload Status Information</H2>
<PRE>
EOF

      $entity->dump_skeleton;
      print <<EOF ;
</PRE></BODY></HTML>
EOF
    }
}
# &DumpBinding(*CookedInput);
# &DumpBinding(*old);
# &DumpBinding(*ENV);
# --------------------------------------------------------  WikiInHyperPerl
