#!/usr/local/bin/perl
require "/home/roger/lib/weblib.lib";
#use DB_File;
use HTML::Parser;
use URI::URL;
@ISA=("HTML::Parser");
$|=1;
# Identify the web site desired
dbmopen(%DIR,"/home/todd/db/homepage.db",0);
@program=split(m#/#,$ENV{PATH_INFO});
$program=$program[1];
dbmopen(%INFO,$DIR{$program}."db",0644);
dbmclose(%DIR);
# Load button names and associated text
@buttons=split(/,/,$INFO{"%%BUTTONS"});
@buttondescription=split(/:/,$INFO{"%%BUTTONDESCRIPTION"});
$bno=0;
foreach $button(@buttons){
	($button,$buttontext)=split(/:/,$button);
	$buttontext{$button}=$buttontext?$buttontext:$button;
	$button{$button}=++$bno;
}
# Determine source of call, either CGI or shell
if($ENV{GATEWAY_INTERFACE}){
	print "Content-type: text/html\n\n";
}
# Initialize header elements, colors, base tag, body tag
$bgcolor=$INFO{"%%BGCOLOR"}?$INFO{"%%BGCOLOR"}:"#ffffff";
$bgtext=$INFO{"%%BGTEXT"}?$INFO{"%%BGTEXT"}:"#000000";
$bglink=$INFO{"%%BGLINK"}?$INFO{"%%BGLINK"}:"#0000ff";
$bgvlink=$INFO{"%%BGVLINK"}?$INFO{"%%BGVLINK"}:"#996600";
$bgalink=$INFO{"%%BGALINK"}?$INFO{"%%BGALINK"}:"#ff0000";
$background=$INFO{"%%BACKGROUND"};
$background=qq{background="$background" } if $background;
$defbody="<body ${background}bgcolor=$bgcolor text=$bgtext link=$bglink ".
	"vlink=$bgvlink alink=$bgalink>\n";
# Create opening wrapper
$masthead=$INFO{"%%MASTHEADGRAPHIC"};
if($masthead){
	@masthead=split(/:/,$masthead);
	$masthead=qq{<IMG SRC="$masthead[0]" width=$masthead[1] height=$masthead[2]};
	$masthead.=qq{ alt=" [$masthead[3]]"} if $masthead[3];
	$masthead.=">";
}
print "<html><head><title>".$INFO{"%%HOMEPAGENAME"}.
	" - Site Map</title></head>";
print $defbody;
$wrapopen="<center>$masthead<br>\n<table><tr>";
foreach $button(@buttons){
	$wrapopen.= "<td align=left><a".buttoninfo($button)."</td>\n";
}
$wrapopen.= "</tr>\n";
print $wrapopen;
# Get button children info
# Set up navigation graphics
@blank=split(/:/,$INFO{"%%SPACER"});
$blank=qq{<img src="$blank[0]"};
$blank.=" width=$blank[1]" if $blank[1];
$blank.=" height=$blank[2]" if $blank[2];
$blank.=qq{ alt="$blank[3]"} if $blank[3];
$blank.=" border=0>";
# Open the appropriate file, and wrap it depending on the mode
foreach $button(@buttons){
	%Child=%Parent=%Succ=%Title=%URL=();
	&followLinks($button);
	$bgcolor=$INFO{"%%SIDEBARCOLOR"}?$INFO{"%%SIDEBARCOLOR"}:"white";
	print "<td valign=top bgcolor=$bgcolor>",&makeLinks($Child{$button}),"</td>\n";
}
print "</tr>\n";
print "</table></center>";
dbmclose(%INFO);
sub makeLinks{
my $link=shift;
my ($title,$nonlink,$descriptivetext)=split(/[%^]/,$Title{$link});
my $returnvalue;
if(!$NCND{$link}||$Child{$link}){
$nonlink=" $nonlink" if $nonlink ne ""&& $title ne "";
$htmllink=$URL{$link}?$URL{$link}:$INFO{"%%HOMEPAGEPROGRAM"}."/$link";
if($descriptivetext){
  $htmllink.=qq{ onMouseOver="window.status='$descriptivetext';return true"};}
else{$htmllink.=qq{ onMouseOver="window.status='$title';return true"};}
if($currentlevel == 0){
	$font=0,$returnvalue.="</font>\n" if $font==-1;
	$returnvalue.= "<h3>";
	$returnvalue.="<a href=$htmllink>$title</a>" if $title ne "";
	$returnvalue.="$nonlink</h3>\n";
	$font=-1;
	$returnvalue.= "<font size=-1>\n" if $Child{$link};
}
elsif($currentlevel == 1){
	$returnvalue.= ${blank};
	$returnvalue.= "<a href=$htmllink>$title</a>" if $title ne "";
	$returnvalue.=$nonlink; 
# this is the line that causes problems in IE
	$returnvalue.="<br>" if $nonlink!~/<h\d/i;
	$returnvalue.="<br>" if $Child{$link}||!$Succ{$link};
	$returnvalue.="\n";
}
elsif($currentlevel > 1){
	$returnvalue.= ${blank}x($currentlevel-1);
	$returnvalue.= $blank if $title ne "";	# It's not a label
	$returnvalue.= "<a href=$htmllink>$title</a>" if $title ne "";
	$returnvalue.=$nonlink;
	$returnvalue.="<br>" if $nonlink!~/<h\d/i;
	$returnvalue.="<br>" if $Child{$link}||!$Succ{$link};
	$returnvalue.="\n";
}
}
if($Child{$link}){
	$currentlevel++;
	$returnvalue.=makeLinks($Child{$link});
	$currentlevel--;
}
$returnvalue.=makeLinks($Succ{$link}) if $Succ{$link};
return $returnvalue;
}
sub buttoninfo{
	local $buttonname=shift;
	local($buttoninfo,$here,$there);
	local($DIR)=split(/%%/,$INFO{$buttonname});
	$buttoninfo=' href="';
	if($DIR =~ m#http://#){
		$buttoninfo.=$DIR;
		$buttoninfo.='"';
	}
	else{
		$buttoninfo.=$INFO{"%%HOMEPAGEPROGRAM"};
		$buttoninfo.="/$buttonname" if $buttonname ne $buttons[0];
		$buttoninfo.='/index.html"';
	}
	($here,$there)=split(/;/,$buttondescription[$button{$buttonname}-1]);
	$buttoninfo.=qq{ onMouseOver="window.status='$here';return true"};
	$buttoninfo.=">";
	$buttoninfo.='<IMG SRC="'.$INFO{"%%IMAGEPATH"}.'/';
	$buttoninfo.=$currentbutton eq $buttonname?${buttonname}.$INFO{"%%ONSUFFIX"}
		:${buttonname}.$INFO{"%%OFFSUFFIX"};
	$buttoninfo.='" border=0 height=25 width=102 alt=" [';
	$buttoninfo.=$buttontext{$buttonname};
	$buttoninfo.=']"></a>';
}
sub followLinks{
	my $link=shift;
	my($parent,$child,$succ,@restrict);
	my(%DENY,%ALLOW,$addr,@IP,$IP);
	my $allow;
	print "Following $link<br>" if $debug;
	#$count++;
	local($URL,$linkage,$title,$restrict)=split(/%%/,$INFO{$link});
	%restrict=split(/[:;]/,$restrict);
	$allow=1;
	if($restrict{IP}){
		$allow=0;
		$addr=pack('C4',split(/\./,$ENV{REMOTE_ADDR}));
		@IP=split(/,/,$restrict{IP});
		foreach $IP(@IP){
			my $deny=$IP=~s/^-//;
			if($IP=~/^[\d.]+$/){$IP=pack("C*",split(/\./,$IP));}
			else{$IP=gethostbyname($IP);}
			if($deny){$DENY{$IP}=1;}
			else{$ALLOW{$IP}=1;};
		}
		foreach $IP(keys %ALLOW){
			last if $allow||=(substr($addr,0,length($IP)) eq $IP);
		}
		if($allow){
			foreach $IP(keys %DENY){
				last unless $allow=(substr($addr,0,length($IP)) ne $IP);
			}
		}
	}
	if($restrict{From} || $restrict{To}){
		my @time=(localtime(time))[0..5];
		$time[4]++;
		$time[5]+=1900;
		my $now=sprintf("%4d%02d%02d%02d%02d%02d",reverse(@time));
		$allow&&= $restrict{From} le $now if $restrict{From};
		@time=(localtime(time))[0..5];
		$time[4]++;
		$time[5]+=1900;
		$now=sprintf("%4d%02d%02d%02d%02d%02d",reverse(@time));
		$allow&&= $restrict{To}."235959" gt $now if $restrict{To};
	}
	($parent,$child,$succ)=split(/;/,$linkage);
	if($allow){
		$URL{$link}=$URL;
		$Title{$link}=$title;
		$Child{$link}=$child;
		$Succ{$link}=$succ;
		$Parent{$link}=$parent;
		$NCND{$link}=1 if $restrict{NCND};  # check for No Child, No Display mode
		return unless $link eq $button || $parent;
		push(@predecessor,$link);
		print "Pushed: $link<br>"if $debug;
		print "<tr><td>$Title{$link}</td><td>$link</td><td>$parent</td>",
			"<td>$Child{$link}</td><td>$Succ{$link}</td></tr>\n" if $debug;
		followLinks($child) if $child;
		followLinks($Succ{$link}) if $Succ{$link};
	}
	else{
		# Relink predecessor or parent as appropriate
		if($Child{$parent} eq $link){
			print "Relinking ${link}'s parent ($parent) to have child of $succ<br>"
				if $debug;
			$Child{$parent}=$succ;
			followLinks($succ) if $succ;
			return;
		}
		else{
			print "Relinking $predecessor[$#predecessor] to be succeeded by ",
				"$succ<br>" if $debug;
			$link=$predecessor[$#predecessor];
			$Succ{$link}=$succ;
			print "<tr><td>$Title{$link}</td><td>$link</td><td>$parent</td>",
				"<td>$Child{$link}</td><td>$Succ{$link}</td></tr>\n" if $debug;
			followLinks($succ) if $succ;
		}
	}
	if($allow){
		$temp=pop(@predecessor);
		print "Popped: $temp->$Succ{$temp}<br>" if $debug;
	}
}
