#!/bin/perl

$dir="/export/home/bob/data/gothbase";

if($ENV{'PATH_INFO'}) {
    $ENV{'QUERY_STRING'}=~tr/A-Z/a-z/;
    @look=&desafe($ENV{'QUERY_STRING'});
    $bestfile=0;
    if($ENV{'PATH_INFO'} eq '/name') {
	while($file=<$dir/*>){
	    if($file=~/\.(html|css)$/i) {next}
	    open(GB,$file);
	    while(<GB>){
		if(s/^\s*(Net|Real)? ?name:\s*//i){
		    tr/A-Z/a-z/;
		    foreach(split(/\s*,\s*/)){
			$count=&namecount($_,@look);
			if($count>$bestfile){$bestfile=$count;$best=$file;}
		    }
		}
	    }
	    close(BG);
	}
    } elsif($ENV{'PATH_INFO'} eq '/realname') {
	while($file=<$dir/*>){
	    if($file=~/\.(html|css)$/i) {next}
	    open(GB,$file);
	    while(<GB>){
		if(s/^\s*Real ?name:\s*//i){
		    tr/A-Z/a-z/;
		    $count=&namecount($_,@look);
		    if($count>$bestfile){$bestfile=$count;$best=$file;}
		}
	    }
	    close(BG);
	}
    } elsif($ENV{'PATH_INFO'} eq '/netname') {
	while($file=<$dir/*>){
	    if($file=~/\.(html|css)$/i) {next}
	    open(GB,$file);
	    while(<GB>){
		if(s/^\s*(Net)?name:\s*//i){
		    tr/A-Z/a-z/;
		    foreach(split(/\s*,\s*/)){
			$count=&namecount($_,@look);
			if($count>$bestfile){$bestfile=$count;$best=$file;}
		    }
		}
	    }
	    close(BG);
	}
    } elsif($ENV{'PATH_INFO'} eq '/email') {
	$look=join('',@look);
	while($file=<$dir/*>){
	    if($file=~/\.(html|css)$/i) {next}
	    open(GB,$file);
	    while(<GB>){
		chop;
		if(s/^\s*E-?mail:\s*//i){
		    tr/A-Z/a-z/;
		    foreach(split(/\s*,\s*/)){
			$count=&emailcount($_,$look);
			if($count>$bestfile){$bestfile=$count;$best=$file;}
		    }
		}
	    }
	    close(BG);
	}
    } else {&fail()}
    if($bestfile==0){&fail("$ENV{'QUERY_STRING'} not found in database","404 Not found")}
    print "Content-type: text/html\n\n";
    open(FILE,"<$best");
    &parse(<FILE>);
    close(FILE);
    exit;
} elsif($ENV{'QUERY_STRING'}=~/\//){&fail()}
elsif(-f "$dir/$ENV{'QUERY_STRING'}") {
    @perm=stat("$dir/$ENV{'QUERY_STRING'}");
    if(!($perm[2] & 4)){&fail("File does not exist","404 Not found")}
    print "Content-type: text/html\n\n";
    open(FILE,"<$dir/$ENV{'QUERY_STRING'}");
    &parse(<FILE>);
    close(FILE);
    exit;
} else {
    print "Content-type: text/html\n\n";
    print "<html><head><title>Gothbase</title>\n",
    '<LINK REL=STYLESHEET TYPE="text/css" href="/~bob/goth.css"></head><body>',"\n",
    "<h1>net.goth Database</h1><UL>\n";
    while($file=<$dir/*>){
	if($file=~/\.(html|css)$/i) {next}
	open(GB,$file);
	$real=$net=$email='';
	while(<GB>){
	    chop;
	    s/&/&amp;/g;
	    s/>/&gt;/g;
	    s/</&lt;/g;
	    if(s/^\s*Real ?name:\s*//i){$real=$_}
	    if(s/^\s*(Net)?name:\s*//i){$net=$_}
	    if(s/^\s*E-?mail:\s*//i){$email=$_}
	}
	close(BG);
	$file=~s/^.*\///;
	print "<LI><a href=\"gothbase.cgi?$file\">";
	$nom=$net||$real||"<i>none</i>";
	$nom=~s/\(.*\)//;
	print "$nom</a>";
	if($email){$email=~s/[, \/].*$//;&protect($email);print " <tt class=\"prot\">&lt;$email&gt;</tt>\n"}
    }
    print "</ul></body></html>\n";
}

sub protect {
    $_[0]=~tr/n-za-mN-ZA-M@0-45-9/a-mn-zA-MN-Z+5-90-4/;
}



sub parse{
    $name=$ENV{'QUERY_STRING'};
    print "<html><head>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"goth.css\" />\n<title>";
    $text="<table>";
    foreach(@_){
	$c="";
	if(/^- (Version.*)-/){
	    $name=~s/,.*$//;
	    print "Gothbase entry for $name</title>\n</head><body>\n<h1>$name</h1>$text</table>\n<hr>$1\n</body><html>";
	    last;
	}
	if(s/^ ?(\S[^:]*)://){
	    $a=$1;$a=~tr/_/ /;
	    if($a=~/e-?mail|address|phone/i) {$c=' class="prot"';&protect($_);}
	    $text.="\n<tr valign=\"top\"><th align=\"left\">$a</th><td$c>$_";
	    if($a eq 'Netname' && $_ ne ""){$name=$_}
	    if($name eq "" && $a eq 'Realname' && $_ ne ""){$name=$_}
	}
	else {$text.=$_}
    }
}

sub fail {
    print "Content-type: text/html\n";
    if ($_[1] ne "") {
        print "Status: $_[1]\n\n";
    } else {
        print "Status: 400 Bad request\n\n";
    }
    print "<html><head><title>Error!</title></head><body>\n";
    print "<h1>Error</h1>\n<p class=error>$_[0]</p>\n";
    print "</body></html>\n";
    exit;
}


sub desafe
{
    @all=();
    @lines=split(/[?+]/,$_[0]);
    foreach(@lines){
        @line=split(/[%]/);
        $text=shift(@line);
        foreach(@line){
            $text=$text.pack("C",hex(substr($_,0,2)));
        }
        @all=(@all,split(/ /,$text));
    }
    @all;
}

sub namecount {
    local($word,@look)=@_;
    if($word=~/^\s*$/){return 0}
    local(@words)=split(/\s+/,$word);
    $c=$ws=0;
    if($#words==$#look){return ($words[0] eq $look[0])}
    for($j=0;$j<=$#look;$j++){
	for($i=$ws;$i<=$#words;$i++){
	    if($look[$j] eq $words[$i]){
		$c++;
		$ws=$i+1; 
	    }
	}
    }
    return $c;
}

sub emailcount {
    local($word,$look)=@_;
    if($word=~/^\s*$/){return 0}
    $look=~s/@(.*)$//;
    local(@lhost)=split(/\./,$1);
    $word=~s/@(.*)$//;
    local(@whost)=split(/\./,$1);
    if($look ne $word){return 0}
    $c=1;
    for($i=0;i<=$#whost;$i++){
	if($lhost[$#lhost-$i] eq $whost[$#whost-$i]){$c++} else{last}}
    return $c;
}
