# FILE: src-board-subs-6
# Template Manager and skins
#-------------------------------------------------------------------------------
# DISCUS VERSION 3.10 COPYRIGHT NOTICE
#
# Discus 3.10 is copyright (c) 2000 by DiscusWare, LLC, all rights reserved.
# The use of Discus is governed by the Discus License Agreement which is
# available from the Discus WWW site at:
#    http://www.discusware.com/discus/license
#
# Pursuant to the Discus License Agreement, this copyright notice may not be
# removed or altered in any way.
#-------------------------------------------------------------------------------

#---SEPARATOR---#

sub skinmaker {
	&header;
	if ($FORM{'submit'} ne "") {
		print "<HTML><HEAD><TITLE>Submit Skin to DiscusWare</TITLE></HEAD>\n";
		print "<BODY BGCOLOR=#ffffff TEXT=#000000>\n";
		print "$fs<CENTER><FONT SIZE=3><B>Submit Skin to DiscusWare</B></FONT></CENTER><HR><P>\n";
		print "You have chosen to submit the skin you created to DiscusWare.  If you proceed with\n";
		print "this submission, you are granting DiscusWare, LLC the right to distribute, without limitation\n";
		print "or royalties, the submitted\n";
		print "file from DiscusWare's web site.  All submissions become the property of DiscusWare, LLC\n";
		print "upon submission.  If you agree to these terms, please click the &quot;I Agree&quot; button\n";
		print "below.  If you do not agree, please use your browser's &quot;Back&quot; button to return to\n";
		print "the previous screen.  We appreciate your contribution to the collection of Discus skins.<P>\n";
		print "<FORM ACTION=http://www.discusware.com/cgi-bin/utils/skins.cgi METHOD=POST>\n";
		print "<INPUT TYPE=HIDDEN NAME=skinname VALUE=\"", &escape($FORM{'skinname'}), "\">\n";
		print "<INPUT TYPE=HIDDEN NAME=yourname VALUE=\"", &escape($FORM{'yourname'}), "\">\n";
		print "<INPUT TYPE=HIDDEN NAME=copyright VALUE=\"", &escape($FORM{'copyright'}), "\">\n";
		print "<INPUT TYPE=HIDDEN NAME=descript VALUE=\"", &escape($FORM{'descript'}), "\">\n";
		print "<INPUT TYPE=HIDDEN NAME=username VALUE=$superuser>\n";
		print "<INPUT TYPE=HIDDEN NAME=cgiurlm VALUE=\"$cgiurlm\">\n";
		print "<TABLE><TR><TD>$fs<B>Please enter your e-mail address</B>. This is for our records but is\n";
		print "not distributed with the skin.</FONT></TD><TD VALIGN=TOP><INPUT TYPE=TEXT NAME=email SIZE=40></TD></TR>\n";
		print "</TABLE><P>\n";
	} else {
		print "# <plaintext>";
		print "# Skin generator: Discus $release_version.$free_revision ";
		print "Pro" if $pro;
		print "\n";
		print "#\n";
		print "# To save your skin, use your browser's \"Save As...\" feature to save this\n";
		print "# text file to your local drive.\n#\n";
	}
	undef $var;
	foreach $key (keys(%FORM)) {
		$FORM{$key} =~ s/\n/ /g;
	}
	if ($FORM{'colors'}) {
		($bgcolor,$text,$link,$vlink,$alink,$face,$size,$background) = &extract_colorsonly;
		$var .=  "<#SkinBG#> $bgcolor\n";
		$var .=  "<#SkinText#> $text\n";
		$var .=  "<#SkinLink#> $link\n";
		$var .=  "<#SkinVlink#> $vlink\n";
		$var .=  "<#SkinAlink#> $alink\n";
		$var .=  "<#SkinFace#> $face\n";
		$var .=  "<#SkinSize#> $size\n";
	}
	if ($FORM{'altcol'}) {
		for ($i = 1; $i <= 10; $i++) {
			$var .=  "<#SkinALT_$i#> " . $GLOBAL_OPTIONS{"alt_color_$i"} . "\n";
		}
	}
	$sc = 0;
	if ($GLOBAL_OPTIONS{'skinchoice'} ne "" && $GLOBAL_OPTIONS{'skinchoice'} ne "-none-" && -e "$admin_dir/$GLOBAL_OPTIONS{'skinchoice'}.skin") {
		open (FILE, "$admin_dir/$GLOBAL_OPTIONS{'skinchoice'}.skin");
		@file = <FILE>;
		close (FILE);
		@file = grep(!/^#/, @file);
		@file = grep(/\S/, @file);
		@file = grep(!/^<#(\w+)#>/, @file);
		$var = join("", @file);
		$sc = 1;
	} else {
		foreach $file ("newpage", "topics", "subtopics", "messages", "addmessage-private", "addmessage-public") {
			open (FILE, "$admin_dir/$file.conf");
			@file = <FILE>;
			close (FILE);
			@file = grep(!/^#/, @file);
			@file = grep(/\S/, @file);
			$var .=  "\n<#include $file.conf#>\n";
			$var .=  join("", @file);
			$var .=  "\n<#end $file.conf#>\n";
		}
	}
	$var =~ s/$message_url/\/$message_url/g;
	$var =~ s/$html_url/\$html_url/g;
	$var =~ s/$script_url/\/$script_url/g;
	$var .= "<#SkinURL#>	$html_url\n";
	$var .= "<#SkinName#>	$FORM{'skinname'}\n";
	$var .= "<#SkinAuthor#>	$FORM{'yourname'}\n";
	$var .= "<#SkinCopyright#>	$FORM{'copyright'}\n";
	$var .= "<#SkinDescr#>	$FORM{'descript'}\n";
	if ($FORM{'submit'} ne "") {
		print "<INPUT TYPE=HIDDEN NAME=text VALUE=\"", &escape($var), "\">\n";
		print "<CENTER><INPUT TYPE=SUBMIT VALUE=\"I Agree\"></CENTER></FORM><P>\n";
		print "<FONT COLOR=#0000aa><I>We appreciate your contribution!</FONT><P>\n";
		print "</BODY></HTML>\n";
		exit(0);
	} else {
		print "# Note: this file is saved as $GLOBAL_OPTIONS{'skinchoice'}.skin in your\n" if $sc;
		print "# administration files directory.\n#\n" if $sc;
		print $var;
		exit(0);
	}
}

#---SEPARATOR---#

sub skinsaver {
	my ($choice) = @_;
	&lock("skinsaver", "$admin_dir/options.txt");
	open (OPTIONS, "$admin_dir/options.txt");
	@options = <OPTIONS>;
	close (OPTIONS);
	@options = grep(!/^skinchoice=/, @options);
	if ($choice =~ m|[^\w\-]| || $choice eq "") {
		push (@options, "skinchoice=-none-\n"); $choice = "-none-";
	} else {
		push (@options, "skinchoice=$choice\n");
	}
	open (OPTIONS, ">$admin_dir/options.txt");
	print OPTIONS sort(@options);
	close (OPTIONS);
	&unlock("skinsaver", "$admin_dir/options.txt");
	$GLOBAL_OPTIONS{'skinchoice'} = $choice;
}

#---SEPARATOR---#

sub permform {
	my ($skinname, $operation) = @_;
	if ($skinname =~ m|[^\w\-]| || $skinname eq "") {
		&error_message("Invalid Skin Name", "Skin name not valid for this subroutine");
	}
	if (!-e "$admin_dir/$skinname.skin") {
		&error_message("Invalid Skin Name", "Skin file does not exist");
	}
	open (SKIN, "$admin_dir/$skinname.skin");
	@file = <SKIN>;
	close (SKIN);
	&header;
	print "<HTML><HEAD><TITLE>Skin Installer</TITLE></HEAD>\n";
	print "<BODY BGCOLOR=#ffffff TEXT=#000000 LINK=#0000ff VLINK=#800080>\n";
	print "$fs<CENTER><FONT SIZE=3><B>Skin Installer</B></FONT></CENTER>\n";
	print "<HR>\n";
	print <<End_Disclaimer;
<A NAME=disclaimer></A>
<FONT COLOR=#0000ff><B>Important -- Please Read Carefully</B></FONT>
<P>
Applying this skin to your board will entirely change your board appearance as defined in the skin.  Additionally,
you should be aware that if a skin is improperly written, either intentionally or accidentally, that serious negative
consequences could result.  In particular, you could experience <FONT COLOR=#ff0000>permanent data loss</FONT> or
give an intruder <FONT COLOR=#ff0000>unauthorized access</FONT> to your server.  Please read the administration
instructions for the <A HREF="#disclaimer" onClick="window.open('$html_url/board-admin-instr-19.html#a', 'help', 'resizable,status,menubar,scrollbars,width=650,height=495');">Template Manager</A> if you have not already done
so.
<P>
It is recommended that you install skins only from trusted sources.  The author field of a skin may also
be forged.  In particular, the only skins distributed by DiscusWare are given in the Discus Template Gallery or
that are distributed with Discus.  DiscusWare recommends installing <FONT COLOR=#ff0000>only</FONT> skins obtained
from these location.  DiscusWare accepts public submissions of skins and verifies their integrity before posting
them.
<P>
<A HREF="http://www.discusware.com/support/resources/templates/gallery" TARGET=_blank>Click here</A> to go to
the Discus Template Gallery.<BR>
<A HREF="#disclaimer" onClick="window.open('$html_url/board-admin-instr-19.html#safe', 'help', 'resizable,status,menubar,scrollbars,width=650,height=495');">Click Here</A> for information about templates
distributed with Discus.<BR>

End_Disclaimer
	print "<HR SIZE=0>\n";
	print "<FONT COLOR=#0000ff><B>Basic Information About Skin</B></FONT><P>\n";
	@v = grep(/^<#(\w+)#>/, @file);
	foreach $line (@v) {
		$line =~ m|^<#(\w+)#>|; $o = $1; $TV{$1} = $'; $TV{$o} =~ s/^\s+//; $TV{$o} =~ s/\s+$//; $TV{$o} = &remove_html($TV{$o}); $TV{$o} =~ s/<//g; $TV{$o} =~ s/>//g;
	}
	print "<U>Skin Name:</U> $TV{'SkinName'}<BR>\n";
	print "<U>Skin Author:</U> $TV{'SkinAuthor'}<BR>\n";
	print "<U>Skin Copyright:</U> $TV{'SkinCopyright'}<BR>\n";
	print "<U>Skin Description:</U> $TV{'SkinDescr'}<P>\n";
	print "<FORM ACTION=$cgiurl METHOD=POST>\n";
	print "\n";
	if ($TV{'SkinBG'} || $TV{'SkinText'} || $TV{'SkinLink'} || $TV{'SkinVlink'} || $TV{'SkinAlink'}) {
		print "<HR SIZE=0><INPUT TYPE=checkbox NAME=grantcolor VALUE=1> <B><FONT COLOR=#0000ff>Grant Appearance Change Request</FONT></B><P>\n";
		print "The skin you have selected wants to change the color scheme of your board.  Shown here is the\n";
		print "color scheme that is being proposed.  If you will allow this skin to change your color scheme,\n";
		print "check the box above.<P>\n";
		print "<UL><TABLE BORDER=1><TR><TD><TABLE>\n";
		print "<TR><TD>$fs", "<B>Background</B></FONT></TD><TD BGCOLOR=\"$TV{'SkinBG'}\">", "&nbsp;" x 4, "</TD></TR>\n";
		print "<TR><TD>$fs", "<B>Text</B></FONT></TD><TD BGCOLOR=\"$TV{'SkinText'}\">", "&nbsp;" x 4, "</TD></TR>\n";
		print "<TR><TD>$fs", "<B>Link</B></FONT></TD><TD BGCOLOR=\"$TV{'SkinLink'}\">", "&nbsp;" x 4, "</TD></TR>\n";
		print "<TR><TD>$fs", "<B>Visited Link</B></FONT></TD><TD BGCOLOR=\"$TV{'SkinVlink'}\">", "&nbsp;" x 4, "</TD></TR>\n";
		print "<TR><TD>$fs", "<B>Active Link</B></FONT></TD><TD BGCOLOR=\"$TV{'SkinAlink'}\">", "&nbsp;" x 4, "</TD></TR>\n";
		print "</TABLE></TD></TR></TABLE></UL><P>\n";
	}
	if ($TV{'SkinFace'} || $TV{'SkinSize'}) {
		print "<HR SIZE=0><INPUT TYPE=checkbox NAME=grantfont VALUE=1> <B><FONT COLOR=#0000ff>Grant Font Change Request</FONT></B><P>\n";
		print "The skin you have selected wants to change the font scheme of your board.  Shown here is the\n";
		print "font scheme that is being proposed.  If you will allow this skin to change your font scheme,\n";
		print "check the box above.<P>\n";
		print "<UL><TABLE BORDER=1><TR><TD><TABLE>\n";
		print "<TR><TD>$fs", "<B>Font Name</B></FONT></TD><TD>$fs$TV{'SkinFace'}</FONT></TD></TR>\n";
		print "<TR><TD>$fs", "<B>Font Size</B></FONT></TD><TD>$fs$TV{'SkinSize'}</FONT></TD></TR>\n";
		print "<TR><TD>$fs", "<B>Example</B></FONT></TD><TD><FONT FACE=\"$TV{'SkinFace'}\" SIZE=\"$TV{'SkinSize'}\">The quick brown fox jumps over the lazy dog</FONT></TD></TR>\n";
		print "</TABLE></TD></TR></TABLE></UL><P>\n";
	}
	if (grep(/^SkinALT_(\d+)$/, keys(%TV))) {
		print "<HR SIZE=0><INPUT TYPE=checkbox NAME=grantalt VALUE=1> <B><FONT COLOR=#0000ff>Grant Alternating Color Change Request</FONT></B><P>\n";
		print "The skin you have selected wants to change the alternating colors of your board.  Shown here is the\n";
		print "set of alternating colors that is being proposed.  If you will allow this skin to change your alternating colors,\n";
		print "check the box above.<P>\n";
		print "<UL><TABLE BORDER=1><TR><TD><TABLE>\n";
		for ($i = 1; $i <= 5; $i++) {
			print "<TR><TD>$fs<B>$i</B></FONT></TD><TD BGCOLOR=", $TV{"SkinALT_$i"}, ">&nbsp;&nbsp;&nbsp;</TD>";
			$x = $i+5;
			print "<TD>&nbsp;&nbsp;&nbsp;</TD><TD>$fs<B>$x</B></FONT></TD><TD BGCOLOR=", $TV{"SkinALT_$x"}, ">&nbsp;&nbsp;&nbsp;</TD>";
			print "</TR>\n";
		}
		print "</TABLE></TD></TR></TABLE></UL><P>\n";
	}
	print "<HR SIZE=0>\n";
	print "<FONT COLOR=#0000ff><B>Potential problems found with this skin:</B></FONT><P>\n";
	undef %FC;
	$flag = "";
	foreach $line (@file) {
		if ($line =~ m|<#include (\w+)\.conf#>|) {
			$flag = $1;
		} elsif ($line =~ m|<#end (\w+)\.conf#>|) {
			$flag = "";
		} elsif ($flag ne "") {
			$line =~ s/\r\n/\n/g;
			$line =~ s/\r/\n/g;
			$FC{$flag} .= $line;
		}
	}
	if ($flag ne "") {
		print "<FONT COLOR=#ff0000><B>Fatal Error</B></FONT>: Skin is corrupt (read file '$flag.conf' not closed)\n";
		print "</FONT></BODY></HTML>\n";
		exit(0);
	}
	if ($FC{'newpage'} =~ m|<!--Start-->\n|) {
		$FC{'newpage'} = $';
	} else {
		print "newpage.conf in this skin is corrupt (missing start tag).\n";
		print "</FONT></BODY></HTML>\n";
		exit(0);
	}
	if ($FC{'topics'} !~ m|\[General\]\n|) {
		print "topics.conf in this skin is corrupt (missing [General] section).\n";
		print "</FONT></BODY></HTML>\n";
		exit(0);
	}
	if ($FC{'topics'} !~ m|\[Topic\]\n|) {
		print "topics.conf in this skin is corrupt (missing [Topic] section).\n";
		print "</FONT></BODY></HTML>\n";
		exit(0);
	}
	if ($FC{'messages'} !~ m|<!-Text-!>| || $FC{'messages'} !~ m|<!-/Text-!>|) {
		print "messages.conf in this skin is corrupt (missing text identifier tags).\n";
		print "</FONT></BODY></HTML>\n";
		exit(0);
	}
	if ($FC{'messages'} !~ m|<!-Email-!>| || $FC{'messages'} !~ m|<!-/Email-!>|) {
		print "messages.conf in this skin is corrupt (missing profile link tags).\n";
		print "</FONT></BODY></HTML>\n";
		exit(0);
	}
	if ($FC{'messages'} !~ m|<!-Name-!>| || $FC{'messages'} !~ m|<!-/Name-!>|) {
		print "messages.conf in this skin is corrupt (missing poster identification tags).\n";
		print "</FONT></BODY></HTML>\n";
		exit(0);
	}
	if ($FC{'messages'} !~ m|<!-Name-!>| || $FC{'messages'} !~ m|<!-/Name-!>|) {
		print "messages.conf in this skin is corrupt (missing poster identification tags).\n";
		print "</FONT></BODY></HTML>\n";
		exit(0);
	}
	foreach $file ("messages", "topics", "newpage", "subtopics") {
		if ($FC{$file} =~ m|\$admin_dir| || $FC{$file} =~ m|\$pro_license| || $FC{$file} =~ m|\$pro_fileid|) {
			print "$file.conf in this skin contains restricted information ($&) that could be used to compromise the security of your site.\n";
			print "</FONT></BODY></HTML>\n";
			exit(0);
		}
	}
	$highrisk = 0;
	@req_var = ('subtopic_variable', 'about_variable', 'about_source_variable', 'announcement_source_variable', 'message_variable', 'about_source_variable', 'head', 'announcement_variable');
	foreach $line (@req_var) {
		if ($FC{'newpage'} !~ m|\$$line|) {
			print "<FONT COLOR=#ff0000><B>High Risk:</B></FONT> newpage.conf missing variable <B>\$$line</B><BR><UL>This will lead to data loss on your board</UL><P>\n";
			$highrisk = 1;
		}
	}
	@req_var = ('TOPIC_NAME', 'URL');
	foreach $line (@req_var) {
		if ($FC{'topics'} !~ m|\$$line|) {
			print "<FONT COLOR=#ff0000><B>High Risk:</B></FONT> topics.conf missing variable <B>\$$line</B><BR><UL>This will lead to data loss on your board</UL><P>\n";
			$highrisk = 1;
		}
	}
	@req_var = ('SUBTOPIC_NAME', 'URL');
	foreach $line (@req_var) {
		if ($FC{'subtopics'} !~ m|\$$line|) {
			print "<FONT COLOR=#ff0000><B>High Risk:</B></FONT> subtopics.conf missing variable <B>\$$line</B><BR><UL>This will lead to data loss on your board</UL><P>\n";
			$highrisk = 1;
		}
	}
	@req_var = ('POSTER_NAME', 'MESSAGE_TEXT');
	foreach $line (@req_var) {
		if ($FC{'messages'} !~ m|\$$line|) {
			print "<FONT COLOR=#ff0000><B>High Risk:</B></FONT> messages.conf missing variable <B>\$$line</B><BR><UL>This will lead to data loss on your board</UL><P>\n";
			$highrisk = 1;
		}
	}
	if ($FC{'messages'} !~ m|<!-Text-!>([.\n]*)\$MESSAGE_TEXT([.\n]*)<!-/Text-!>|) {
		print "<FONT COLOR=#ff0000><B>High Risk:</B></FONT> messages.conf does not seem to handle message text properly<BR><UL>If this is the case, the text of all messages posted on your board will be lost if you apply this skin</UL><P>\n";
		$highrisk = 1;
	}
	if ($FC{'messages'} !~ m|<!-Email-!>([.\n]*)\$PROFILE_LINK([.\n]*)<!-/Email-!>|) {
		print "<FONT COLOR=#ff0000><B>High Risk:</B></FONT> messages.conf does not seem to handle profile links properly<BR><UL>If this is the case, the poster links (to e-mail address or profiles) on your board will be lost if you apply this skin</UL><P>\n";
		$highrisk = 1;
	}
	if ($FC{'messages'} !~ m|<!-Name-!>([.\n]*)\$POSTER_NAME([.\n]*)<!-/Name-!>|) {
		print "<FONT COLOR=#ff0000><B>High Risk:</B></FONT> messages.conf does not seem to handle names properly<BR><UL>If this is the case, the poster names on your board will be lost if you apply this skin</UL><P>\n";
		$highrisk = 1;
	}
	foreach $file ("messages", "topics", "newpage", "subtopics") {
		while ($FC{$file} =~ m|<!--#(.*?)-->|g) {
			print "<FONT COLOR=#ff0000><B>Security Risk:</B></FONT> $file.conf seems to have a server side include<BR><UL>Potential SSI found: &lt;!--#$1--&gt;<P>Mischevious SSI calls can run commands on your server or display restricted files.  If you do not know exactly what this line does, you should not apply this skin!</UL>\n";
			$highrisk = 1;
		}
	}
	foreach $file ("messages", "topics", "newpage", "subtopics") {
		while ($FC{$file} =~ m|<\?(.*?)\?>|g) {
			print "<FONT COLOR=#ff0000><B>Security Risk:</B></FONT> $file.conf seems to have PHP-style commands<BR><UL>Potential command found: &lt;?$1?&gt;<P>Mischevious PHP calls can run commands on your server or display restricted files.  If you do not know exactly what this line does, you should not apply this skin!</UL>\n";
			$highrisk = 1;
		}
	}
	foreach $file ("messages", "topics", "newpage", "subtopics") {
		while ($FC{$file} =~ m|<\%(.*?)\%>|g) {
			print "<FONT COLOR=#ff0000><B>Security Risk:</B></FONT> $file.conf seems to have PHP-style commands<BR><UL>Potential SSI found: &lt;%$1%&gt;<P>Mischevious PHP calls can run commands on your server or display restricted files.  If you do not know exactly what this line does, you should not apply this skin!</UL>\n";
			$highrisk = 1;
		}
	}
	foreach $file ("messages", "topics", "newpage", "subtopics") {
		if ($FC{$file} =~ m|<\s*script|i) {
			print "<FONT COLOR=#888800><B>Moderate Risk:</B></FONT> $file.conf contains one or more scripts.<BR><UL>Malicious JavaScript put onto a page could have undesirable effects, like setting and reading cookies or opening windows.  However, JavaScript is used effectively in many Discus template files for the support of features on a page.  You should study the skin to see what the script does before installing.</UL>\n";
		}
	}
	foreach $file ("messages", "topics", "newpage", "subtopics") {
		if ($FC{$file} =~ m|<\s*meta|i) {
			print "<FONT COLOR=#888800><B>Low Risk:</B></FONT> $file.conf contains one or META tags.<BR><UL>META tags are used to communicate with browsers and search engine scripts.  However, malicious META tags can be used to &quot;hijaak&quot; your page (make other pages on other sites come up in your window).  You should study the skin to see what the META tag does before installing.</UL>\n";
		}
	}
	print "The analysis in the section above is <U>not</U> a complete analysis of the skin.  You should\n";
	print "exercise due diligence and look over the actual code of the skin before installing it on your\n";
	print "system.<P><HR SIZE=0><P>\n";
	print "<INPUT TYPE=HIDDEN NAME=username VALUE=$superuser>\n";
	print "<INPUT TYPE=HIDDEN NAME=action VALUE=apply>\n";
	print "<INPUT TYPE=HIDDEN NAME=submit VALUE=\"$FORM{'submit'}\">\n";
	print "<INPUT TYPE=HIDDEN NAME=skin VALUE=$skinname>\n";
	print "<TABLE WIDTH=100% BGCOLOR=#ffffcc BORDER=1><TR><TD ALIGN=CENTER>\n";
	print "<INPUT TYPE=SUBMIT VALUE=\"$FORM{'submit'}\">\n";
	print "<INPUT TYPE=BUTTON onClick=\"history.back()\" VALUE=\"Cancel\">\n";
	print "</TD></TR></TABLE>\n";
	print "</FORM>\n";
	print "<P><HR SIZE=0><B>Here is the text of the skin:</B><P><PLAINTEXT>\n";
	print @file;
	exit(0);
}

#---SEPARATOR---#
#REQ:change_board_colors
#REQ:show_gauge
#REQ:regenerate_board
#REQ:skinsaver

sub skin_install {
	my ($skinname, $operation) = @_;
	if ($skinname =~ m|[^\w\-]| || $skinname eq "") {
		&error_message("Invalid Skin Name", "Skin name not valid for this subroutine");
	}
	if (!-e "$admin_dir/$skinname.skin") {
		&error_message("Invalid Skin Name", "Skin file does not exist");
	}
	open (SKIN, "$admin_dir/$skinname.skin");
	@file = <SKIN>;
	close (SKIN);
	@v = grep(/^<#(\w+)#>/, @file);
	foreach $line (@v) {
		$line =~ m|^<#(\w+)#>|; $o = $1; $TV{$1} = $'; $TV{$o} =~ s/^\s+//; $TV{$o} =~ s/\s+$//; $TV{$o} = &remove_html($TV{$o}); $TV{$o} =~ s/<//g; $TV{$o} =~ s/>//g;
	}
	if ($FORM{'grantcolor'}) {
		undef @CACHED_COLOR_RESULT;
		undef $GLOBAL_OPTIONS{'COLOR_bgcolor'};
		($bgcolor,$text,$link,$vlink,$alink,$face,$size,$background) = &extract_colorsonly;
		&change_board_colors($TV{'SkinBG'}, $TV{'SkinText'}, $TV{'SkinLink'}, $TV{'SkinVlink'}, $TV{'SkinAlink'}, $face, $size, $background);
	}
	if ($FORM{'grantfont'}) {
		undef @CACHED_COLOR_RESULT;
		undef $GLOBAL_OPTIONS{'COLOR_bgcolor'};
		($bgcolor,$text,$link,$vlink,$alink,$face,$size,$background) = &extract_colorsonly;
		&change_board_colors($bgcolor,$text,$link,$vlink,$alink,$TV{'SkinFace'},$TV{'SkinSize'},$background);
	}
	if ($FORM{'grantalt'}) {
		&lock("skin_install", "$admin_dir/options.txt");
		open (OPTIONS, "$admin_dir/options.txt");
		@options = <OPTIONS>;
		close (OPTIONS);
		@options = grep(!/^alt_color_(\d+)/, @options);
		for ($i = 1; $i <= 10; $i++) {
			push (@options, "alt_color_$i=" . $TV{"SkinALT_$i"} . "\n");
			$GLOBAL_OPTIONS{"alt_color_$i"} = $TV{"SkinALT_$i"};
		}
		open (OPTIONS, ">$admin_dir/options.txt");
		print OPTIONS sort(@options);
		close (OPTIONS);
		&unlock("skin_install", "$admin_dir/options.txt");
	}
	&skinsaver($skinname);
	if ($operation eq "Save and Apply") {
		undef $TOPIC_FORMAT_STRING;
		undef %FC;
		undef $TEMPL_FOUND{"topics"};
		&change_board_colors("*");
		($bgcolor,$text,$link,$vlink,$alink,$face,$size,$background) = &extract_colorsonly;
		$COLOR_CHANGER = join("\t", $bgcolor, $text, $link, $vlink, $alink, $face, $size, $background);
		&regenerate_board('Installing New Skin (Regenerating Board)', "$cgiurl2?username=$superuser&action=templates&rrrrr=222", "$cgiurlm?username=$superuser&cmd=template_mgr");
	}
}

#---SEPARATOR---#

sub template_mgr_1 {
	&header;
	print "<HTML><HEAD><TITLE>Template Manager</TITLE>\n";
	print "<SCRIPT LANGUAGE=\"JavaScript\">\n";
	print "<!-- \n";
	print "function newwin (d) {\n";
	$rows = 20;
	$rows = $GLOBAL_OPTIONS{'templ_box_rows'} if $GLOBAL_OPTIONS{'templ_box_rows'};
	$cols = 75;
	$cols = $GLOBAL_OPTIONS{'templ_box_cols'} if $GLOBAL_OPTIONS{'templ_box_cols'};
	$width = int((600/75)*$cols) + 50;
	$height = int(16*$rows) + 175;
	print "  var it = window.open(\"$cgiurl2?username=$superuser&action=template&file=\" + d, \"editor\", \"resizable,status,menubar,scrollbars,width=$width,height=$height\");\n";
	print "}\n";
	print "// -->\n";
	print "</SCRIPT></HEAD>\n";
	print '<BODY BGCOLOR="ffffff" TEXT="000000" LINK="0000FF" VLINK="0000FF" ';
	print "onLoad=\"window.defaultStatus = 'Template Manager'\">$fs\n";
	print "<FONT SIZE=3><CENTER><B>Template Manager</B></CENTER></FONT>\n";
	print "<HR>\n";
	print "<H3>Discus Appearance &quot;Skins&quot;</H3>\n";
	print "<P>\n";
	print "This section allows you to select an appearance skin for your discussion board.\n";
	print "If you want to use individual template files, choose &quot;No Skin&quot; from\n";
	print "this list.<P>\n";
	print "<FORM ACTION=$cgiurl METHOD=POST onSubmit=\"if (document.forms[0].previewed.value == 1) { return true; } else { return confirm('You have not previewed this skin.  Are you sure you want to continue?'); }\">\n";
	print "<INPUT TYPE=HIDDEN NAME=action VALUE=skin>\n";
	print "<INPUT TYPE=HIDDEN NAME=username VALUE=$superuser>\n";
	print "<TABLE BGCOLOR=#ffffcc BORDER=1><TR><TD>\n";
	print "<TABLE BORDER=0 CELLPADDING=2><TR><TD>$fs<B>Choose</B></FONT></TD>\n";
	print "<TD>$fs<B>Name</B></FONT></TD>\n";
	print "<TD>$fs<B>Author</B></FONT></TD>\n";
	print "<TD>$fs<B>Copyright</B></FONT></TD>\n";
	print "<TD>$fs<B>Description</B></FONT></TD>\n";
	print "</TR>\n";
	print "<TR BGCOLOR=#ccffcc><TD ALIGN=CENTER VALIGN=TOP><INPUT TYPE=RADIO NAME=choice VALUE='-none-'";
	print " CHECKED" if ($GLOBAL_OPTIONS{'skinchoice'} eq "-none-" || $GLOBAL_OPTIONS{'skinchoice'} eq "" || $GLOBAL_OPTIONS{'skinchoice'} eq "0");
	print " onClick=\"document.forms[0].myskin.value = '';\"></TD><TD VALIGN=TOP>$fs", "None</FONT></TD><TD VALIGN=TOP>$fs", "N/A</FONT></TD>";
	print "<TD>&nbsp;</TD><TD VALIGN=TOP>$fs<FONT SIZE=1>Use individual template files to control board appearance</FONT></TD></TR>\n";
	$bg = "#D0D0D0";
	opendir(DIR, "$admin_dir");
	while ($dir = readdir(DIR)) {
		next if $dir !~ m|^([\w\-]+)\.skin$|;
		$tfile = $1;
		open (FILE, "$admin_dir/$dir");
		@file = <FILE>;
		close (FILE);
		undef %TV;
		@v = grep(/^<#(\w+)#>/, @file);
		foreach $line (@v) {
			$line =~ m|^<#(\w+)#>|; $o = $1; $TV{$1} = $'; $TV{$o} =~ s/^\s+//; $TV{$o} =~ s/\s+$//; $TV{$o} = &remove_html($TV{$o}); $TV{$o} =~ s/<//g; $TV{$o} =~ s/>//g;
		}
		foreach $x ("SkinName", "SkinAuthor", "SkinCopyright", "SkinDescr", "SkinURL") {
			$TV{$x} = "None Given" if $TV{$x} eq "";
		}
		if ($bg eq "#E3E3E3") {
			$bg = "#D0D0D0";
		} else {
			$bg = "#E3E3E3";
		}
		print "<TR BGCOLOR=$bg><TD ALIGN=CENTER VALIGN=TOP><INPUT TYPE=RADIO NAME=choice VALUE='$tfile'";
		print " CHECKED" if $GLOBAL_OPTIONS{'skinchoice'} eq $tfile;
		print " onClick=\"document.forms[0].myskin.value = '$tfile';\"></TD><TD VALIGN=TOP>$fs<FONT SIZE=1><B>$tfile</B><BR>$TV{SkinName}</FONT></FONT></TD><TD VALIGN=TOP>$fs<FONT SIZE=1>";
		print "<A HREF=\"$TV{'SkinURL'}\" TARGET=_blank>" if $TV{'SkinURL'} =~ m|^https?://|;
		print $TV{'SkinAuthor'};
		print "</A>" if $TV{'SkinURL'} =~ m|^https?://|;
		if ($tfile eq "classic" || $tfile eq "updatedclassic" || $tfile eq "tables" || $tfile eq "supportforum") {
			print "<P><FONT COLOR=#00aa00 SIZE=1><B>*Safe*</B></FONT> (<A HREF=$html_url/board-admin-instr-19.html#safe TARGET=_blank>Info</A>)\n";
		}
		print "</FONT></FONT></TD><TD VALIGN=TOP>$fs<FONT SIZE=1>$TV{'SkinCopyright'}</FONT></FONT></TD><TD VALIGN=TOP>$fs";
		print "<FONT SIZE=1>$TV{'SkinDescr'}</FONT></FONT></TD></TR>\n";
	}
	closedir(DIR);
	print "</TABLE><P>\n";
	print "<CENTER>\n";
	print "<INPUT TYPE=hidden NAME=myskin VALUE=\"\">\n";
	print "<INPUT TYPE=hidden NAME=previewed VALUE=0>\n";
	print "<INPUT TYPE=button VALUE=\"Preview\" onClick=\"";
	print "document.forms[0].previewed.value = 1; var newwin = window.open('$cgiurl?action=prevskin&username=$superuser&template=' + document.forms[0].myskin.value, 'previewer', 'resizable,status,menubar,scrollbars,width=650,height=495');\">\n";
	print "<INPUT TYPE=submit NAME=submit VALUE=\"Save and Apply\">\n";
	print "<INPUT TYPE=submit NAME=submit VALUE=\"Save Only\"></CENTER>\n";
	print "</TD></TR></TABLE><P></FORM>\n";
	print "<HR><H3>Skin Creator</H3>\n";
	print "This section allows you to take your current template files and make them into a skin to share with\n";
	print "other Discus users.<p>\n";
	print "<FORM ACTION=$cgiurl METHOD=POST NAME=sc>\n";
	print "<INPUT TYPE=HIDDEN NAME=action VALUE=skincreate>\n";
	print "<INPUT TYPE=HIDDEN NAME=username VALUE=$superuser>\n";
	print "<TABLE BGCOLOR=#ffffcc BORDER=1><TR><TD>\n";
	print "$fs", "Please enter the following information about your skin.  (This information will be saved in the\n";
	print "skin file itself.)<P>\n";
	print "<TABLE><TR><TD>$fs", "Name&nbsp;of&nbsp;Skin:</FONT></TD><TD><INPUT TYPE=TEXT NAME=skinname SIZE=41></TD></TR>\n";
	print "<TR><TD>$fs", "Your&nbsp;Name:</FONT></TD><TD><INPUT TYPE=TEXT NAME=yourname SIZE=41></TD></TR>\n";
	print "<TR><TD>$fs", "Copyright&nbsp;Info:</FONT></TD><TD><INPUT TYPE=TEXT NAME=copyright SIZE=41></TD></TR>\n";
	print "<TR><TD valign=top>$fs", "Description:</FONT></TD><TD><textarea rows=5 cols=40 wrap=virtual name=descript></textarea></TD></TR>\n";
	print "</TABLE>\n";
	print "<INPUT TYPE=CHECKBOX NAME=colors VALUE=1 CHECKED> Write my board's color scheme with this skin<BR>\n";
	print "<INPUT TYPE=CHECKBOX NAME=altcol VALUE=1 CHECKED> Write my board's alternating color settings with this skin<BR>\n";
	print "<P><CENTER><INPUT TYPE=SUBMIT VALUE=\"Save to Your Computer\">\n";
	print "<INPUT TYPE=SUBMIT VALUE=\"Submit to DiscusWare\" name=submit>\n";
	print "</CENTER>\n";
	print "</TD></TR></TABLE>\n";
	print "</FORM>\n";
	print "<HR><H3>Template Editors</H3>\n";
	print "This section allows you to edit templates that are associated with the Discus\n";
	print "program.  You can control the operation of your board and the formatting of\n";
	print "pages, topics, subtopics, messages, and &quot;Add a Message&quot; boxes by\n";
	print "editing the templates.<P>\n";
	print "<FONT COLOR=#ff0000><B>WARNING!</B>  No verification of your changes is\n";
	print "performed.  You can break or corrupt your board by editing templates\n";
	print "improperly.  It is <I>strongly</I> suggested that you make backup copies\n";
	print "of all templates before editing them in any way.  <B>DiscusWare, LLC does\n";
	print "<U>not</U> provide support for difficulties encountered as a result of editing\n";
	print "templates.</FONT>\n";
	print "<HR>\n";
	print "<TABLE BORDER=0 WIDTH=100% CELLPADDING=2 CELLSPACING=0>\n";
	print "<TR BGCOLOR=#c0c0c0>\n";
	print "<TD>$fs", "Template</FONT></TD>\n";
	print "<TD>$fs", "Description</FONT></TD>\n";
	print "<TD>$fs", "Status</FONT></TD></TR>\n";
	undef %desc;
	$desc{'addmessage-private'} = "&quot;Add a Message&quot; boxes in private posting areas";
	$desc{'addmessage-public'} = "&quot;Add a Message&quot; boxes in public posting areas";
	$desc{'discus'} = "Configuration of Discus program";
	$desc{'messages'} = "Format of messages on a page";
	$desc{'newpage'} = "Page structure";
	$desc{'subtopics'} = "Format of subtopics on a page";
	$desc{'topics'} = "Format of topics on the first page";
	$desc{'webtags'} = "Create or modify formatting tags";
	$desc{'language'} = "Text displayed in dynamic forms";
	$desc{'language_pro'} = "Text displayed in dynamic forms" if $pro;
	$desc{'stopwords'} = "Words not to index for searching";
	$desc{'attachments'} = "Attachment MIME type information" if $pro;
	$desc{'newprofile'} = "Default for new user profile" if $pro;
	$desc{'charconvert'} = "Character conversion configuration";
	undef %skin;
	opendir(DIR, "$admin_dir");
	while ($dir = readdir(DIR)) {
		next if $dir !~ m|\.skin$|;
		$skin{$`} = "Skin File";
	}
	closedir(DIR);
	foreach $key (sort keys(%desc)) {
		print "<TR BGCOLOR=#ffffcc><TD VALIGN=TOP>$fs<FONT SIZE=1><A HREF=javascript:newwin(\"$key\")>$key.conf</A></FONT></FONT></TD>\n";
		print "<TD VALIGN=TOP>$fs<FONT SIZE=1>$desc{$key}</FONT></FONT></TD>";
		if (-r "$admin_dir/$key.conf" && !-w "$admin_dir/$key.conf") {
			print "<TD VALIGN=TOP>$fs<FONT SIZE=1>Read Only</FONT></FONT></TD>";
		} elsif (-r "$admin_dir/$key.conf" && -w "$admin_dir/$key.conf") {
			print "<TD VALIGN=TOP>$fs<FONT SIZE=1>Read/Write</FONT></FONT></TD>\n";
		} elsif (!-e "$admin_dir/$key.conf") {
			print "<TD VALIGN=TOP>$fs<FONT SIZE=1>Does Not Exist</FONT></TD>\n";
		} else {
			print "<TD VALIGN=TOP>$fs<FONT SIZE=1>N/A</FONT></FONT></TD>\n";
		}
		print "</TR>\n";
	}
	foreach $key (sort keys(%skin)) {
		print "<TR BGCOLOR=#ffffcc><TD VALIGN=TOP>$fs<FONT SIZE=1><A HREF=javascript:newwin(\"*", "$key\")>$key.skin</A></FONT></FONT></TD>\n";
		print "<TD VALIGN=TOP>$fs<FONT SIZE=1>$skin{$key}</FONT></FONT></TD>";
		if (-r "$admin_dir/$key.skin" && !-w "$admin_dir/$key.skin") {
			print "<TD VALIGN=TOP>$fs<FONT SIZE=1>Read Only</FONT></FONT></TD>";
		} elsif (-r "$admin_dir/$key.skin" && -w "$admin_dir/$key.skin") {
			print "<TD VALIGN=TOP>$fs<FONT SIZE=1>Read/Write</FONT></FONT></TD>\n";
		} elsif (!-e "$admin_dir/$key.skin") {
			print "<TD VALIGN=TOP>$fs<FONT SIZE=1>Does Not Exist</FONT></TD>\n";
		} else {
			print "<TD VALIGN=TOP>$fs<FONT SIZE=1>N/A</FONT></FONT></TD>\n";
		}
		print "</TR>\n";
	}
	print "</TABLE>\n";
	print "</BODY></HTML>\n";
	exit(0);

}

#---SEPARATOR---#

sub template_editor {
	my ($template, $saved) = @_;
	my ($readonly);
	$readonly = 0;
	if ($template =~ m|\.|) {
		$template = $`;
		$template = join("", "*", $template) if $' eq "skin";
	}
	if ($template =~ m|^\*(.*)|) {
		$template = $1; $template =~ s/[^\w\-\.]//g; $file = "$template.skin";
	} else {
		$template =~ s/[^\w\-\.]//g; $file = "$template.conf";
	}
	&header;
	print "<HTML><HEAD><TITLE>Template Editor</TITLE>\n";
	print '<BODY BGCOLOR="ffffff" TEXT="000000" LINK="0000FF" VLINK="0000FF" ';
	print "onLoad=\"window.defaultStatus = 'Template Editor'\">$fs\n";
	print "<FONT SIZE=3><CENTER><B>Template&nbsp;Editor&nbsp;($file)</B></CENTER></FONT>\n";
	print "<HR>\n";
	if ($saved) {
		print "<CENTER><TABLE BGCOLOR=#ccccff WIDTH=500><TR><TD ALIGN=CENTER>";
		print "$fs<FONT SIZE=3 COLOR=#ff0000><B>Changes&nbsp;Saved!</B></FONT></FONT>";
		print "</TD></TR></TABLE></CENTER><P>\n";
	}
	if (open(FILE, "$admin_dir/$file")) {
		@file = <FILE>;
		close (FILE);
	} else {
		print "<P><FONT COLOR=#ff0000 SIZE=3><B>File Not Found</B></FONT><P>\n";
		print "The requested file, <B>$template.conf</B>, could not be opened.\n";
		print "The system says: <B>$!</B>.<P>\n";
		print "</BODY></HTML>\n";
		exit(0);
	}
	if (!-w "$admin_dir/$file") {
		$readonly = 1;
	}
	print "</FONT><P>\n";
	if ($readonly == 0) {
		print "<FORM ACTION=$cgiurl2 METHOD=POST>\n";
		print "<INPUT TYPE=HIDDEN NAME=username VALUE=$superuser>\n";
		print "<INPUT TYPE=HIDDEN NAME=action VALUE=template2>\n";
		print "<INPUT TYPE=HIDDEN NAME=file VALUE=\"$file\">\n";
		print "<INPUT TYPE=HIDDEN NAME=x VALUE=1>\n";
		$rows = 20;
		$rows = $GLOBAL_OPTIONS{'templ_box_rows'} if $GLOBAL_OPTIONS{'templ_box_rows'};
		$cols = 75;
		$cols = $GLOBAL_OPTIONS{'templ_box_cols'} if $GLOBAL_OPTIONS{'templ_box_cols'};
		print "<TABLE><TR><TD><TEXTAREA ROWS=$rows COLS=$cols NAME=text WRAP=off onChange=\"document.forms[0].x.value = 0\">";
		foreach $line (@file) {
			$line =~ s/&/&amp;/g;
			$line =~ s/"/&quot;/g;
			$line =~ s/</&lt;/g;
			$line =~ s/>/&gt;/g;
			$line =~ s/\t/   /g;
			print $line;
		}
		print "</TEXTAREA></TD></TR></TABLE>\n";
		print "<INPUT TYPE=SUBMIT NAME=submit VALUE=\"Save Changes\">&nbsp;&nbsp;";
		print "<INPUT TYPE=BUTTON VALUE=\"Close\" onClick=\"if (document.forms[0].x.value == 1) { self.close(); } else { var m = confirm('Your changes are not saved.  If you continue, all of your changes since your last save will be lost!  Continue anyway?'); if (m == true) { self.close(); }}\">";
		print "</FORM>\n";
	} else {
		print "<PRE><B>$template.conf is read-only</B>\n\n";
		foreach $line (@file) {
			$line =~ s/&/&amp;/g;
			$line =~ s/"/&quot;/g;
			$line =~ s/</&lt;/g;
			$line =~ s/>/&gt;/g;
			$line =~ s/\t/   /g;
			print $line;
		}
		print "</PRE><P>\n";
		print "<FORM>\n";
		print "<INPUT TYPE=BUTTON VALUE=\"Close\" onClick=\"self.close()\">";
		print "</FORM>\n";
	}
	print "</BODY></HTML>\n";
	exit(0);
}


#---SEPARATOR---#
#REQ:printuntil
#REQ:topic_format
#REQ:regenerate_subtopic_list
#REQ:regenerate_message

sub preview_skin {
	my ($skinname) = @_;
	$skinname =~ s/[^\w\-]//g;
	$GLOBAL_OPTIONS{'skinchoice'} = $skinname;
	undef %FC;
	if (open (FILEx, "$admin_dir/$GLOBAL_OPTIONS{'skinchoice'}.skin")) {
		@file = <FILEx>;
		close (FILEx);
		$flag = "";
		foreach $line (@file) {
			if ($line =~ m|<#include ([\w\-]+)\.conf#>|) {
				$flag = $1;
			} elsif ($line =~ m|<#end ([\w\-]+)\.conf#>|) {
				$flag = "";
			} elsif ($flag ne "") {
				$line =~ s/\r\n/\n/g;
				$line =~ s/\r/\n/g;
				$FC{$flag} .= $line;
			}
		}
	} else {
		foreach $file ("newpage", "messages", "subtopics", "topics", "addmessage-private", "addmessage-public") {
			open (FILE, "$admin_dir/$file.conf");
			@file = <FILE>;
			close (FILE);
			$FC{$file} = join("", @file);
		}
	}
	@PrintUntil_FILE = split(/\n/, $FC{'newpage'});
	@PFSave = @PrintUntil_FILE; undef %TV;
	if (open (FILE, "$admin_dir/$skinname.skin")) {
		@file = <FILE>;
		close (FILE);
		@v = grep(/^<#(\w+)#>/, @file);
		foreach $line (@v) {
			$line =~ m|^<#(\w+)#>|; $o = $1; $TV{$1} = $'; $TV{$o} =~ s/^\s+//; $TV{$o} =~ s/\s+$//; $TV{$o} = &remove_html($TV{$o}); $TV{$o} =~ s/<//g; $TV{$o} =~ s/>//g;
		}
	}
	($bgcolor, $text, $link, $vlink, $alink, $face, $size, $image) = &extract_colorsonly;
	$bgcolor = $TV{'SkinBG'} if $TV{'SkinBG'};
	$text = $TV{'SkinText'} if $TV{'SkinText'};
	$link = $TV{'SkinLink'} if $TV{'SkinLink'};
	$vlink = $TV{'SkinVlink'} if $TV{'SkinVlink'};
	$alink = $TV{'SkinAlink'} if $TV{'SkinAlink'};
	$face = $TV{'SkinFace'} if $TV{'SkinFace'};
	$size = $TV{'SkinSize'} if $TV{'SkinSize'};
	$FONT_STRING = "<FONT FACE=\"$face\" SIZE=\"$size\" COLOR=\"$text\">";
	for ($i = 1; $i <= 10; $i++) {
		$GLOBAL_OPTIONS{"alt_color_$i"} = $TV{"SkinALT_$i"} if $TV{"SkinALT_$i"};
	}
	foreach $line (@PrintUntil_FILE) {
		$line .= "\n";
		$line = &eval_subst($line);
		$cs = $GLOBAL_OPTIONS{'charset'}; $cs = "" if $cs eq "0";
		if ($line =~ m|</HEAD>|i && $cs ne "") {
			$line = "<!-ShowMeta-!><META http-equiv=\"Content-Type\" content=\"text/html; charset=$cs\">\n$`</HEAD>$'\n";
		}
	}
	&header;
	&printuntil(1, 1, 0, "Preview Skin", 0, 1, 0);
	print "<FONT SIZE=3><B><CENTER>Preview of Skin</CENTER></B></FONT><HR>\n";
	print "<CENTER>\n";
	if ($FORM{'prevtype'} eq "") {
		print "[<B>Topics List</B>] [<A HREF=$cgiurl?action=prevskin&prevtype=s&username=$superuser&template=$skinname>Subtopics List</A>] [<A HREF=$cgiurl?action=prevskin&prevtype=m&username=$superuser&template=$skinname>Messages List</A>]";
	} elsif ($FORM{'prevtype'} eq "s") {
		print "[<A HREF=$cgiurl?action=prevskin&username=$superuser&template=$skinname>Topics List</A>] [<B>Subtopics List</B>] [<A HREF=$cgiurl?action=prevskin&prevtype=m&username=$superuser&template=$skinname>Messages List</A>]";
	} else {
		print "[<A HREF=$cgiurl?action=prevskin&username=$superuser&template=$skinname>Topics List</A>] [<A HREF=$cgiurl?action=prevskin&prevtype=s&username=$superuser&template=$skinname>Subtopics List</A>] [<B>Messages List</B>]";
	}
	print "\n[<A HREF=# onClick=\"self.close()\">Close Window</A>]\n";
	print "</CENTER><HR>\n";
	print "<I>Please note: Links defined in standard ways from this skin have been disabled in this preview to prevent accidental navigation into the board.</I><P>\n";
	&printuntil(3, 3, 0, "Preview Skin", 0, 1, 0);
	&printuntil(5, 5, 0, "Preview Skin", 0, 1, 0);
	open (TREE, "$admin_dir/tree.txt");
	@TREE_STRUCTURE_FILE = <TREE>;
	close (TREE);
	undef %TLL;
	foreach $line (@TREE_STRUCTURE_FILE) {
		@c = split(/\t/, $line);
		$TLL{$c[1]} = $line if $c[1] > 0;
	}
	open (TOP, "$message_dir/$board_topics_file");
	@topfile = <TOP>;
	close (TOP);
	if ($FORM{'prevtype'} eq "") {
		@tf = split(/\n/, $FC{'topics'});
		foreach $line (@tf) {
			$line .= "\n";
		}
		@tf = grep(/\S/, @tf);
		@tf = grep(!/^#/, @tf);
		$TS = ""; $TOPIC_FORMAT_STRING = "";
		$flag3 = 0;
		foreach $linex (@tf) {
			if ($linex =~ m|^\[General\]|) {
				$flag3 = 1;
			} elsif ($linex =~ m|^\[Topic\]|) {
				$flag3 = 2;
			} elsif ($flag3 == 1) {
				$TS .= $linex;
			} elsif ($flag3 == 2) {
				chomp $linex;
				$TOPIC_FORMAT_STRING .= $linex;
			}
		}
		$TS = &common_discus_variables($TS);
		$TOPIC_FORMAT_STRING = &common_discus_variables($TOPIC_FORMAT_STRING);
		foreach $line (@topfile) {
			if ($line =~ m|<!-Top: (\d+)-!>|) {
				push (@topics, $line);
			} elsif ($line =~ m|^<!-Description: (\d+)-!>|) {
				$description_seen{$1} = $line;
			}
		}
		if (scalar(@topics)) {
			$lastchance = $topics[scalar(@topics)-1];
			$lastchance =~ m|<!-Top: (\d+)-!>|; $lc = $1;
		} else {
			print "NOTE: You have no topics on your board.  No preview can be shown.";
		}
		$flagd = 0;
		foreach $tl (@topics) {
			undef %DPr;
			$tl =~ m|<!-Top: (\d+)-!>|;
			$tn = $1;
			$x = $TLL{$tn};
			@c = split(/\t/, $x);
			if ($c[8] ne "") {
				@x = split(/;/, $c[8]);
				foreach $x (@x) {
					($par, $val) = split(/=/, $x);
					$DPr{$par} = &unescape($val);
				}
			}
			$xctr += 1 if $DPr{'hidden'} != 1;
			if ($x eq "") {
				&extract("$message_dir/$tn/$tn.$ext") if -e "$message_dir/$tn";
				&extract("$secdir/$tn/$tn.$ext") if -e "$secdir/$tn";
				$count = 0;
				open (LOG, "$admin_dir/msg_index/$tn-log.txt");
				while (<LOG>) {
					$count += 1;
					$ll = $_;
				}
				close (LOG);
				$lmd = (split(/;/, $ll))[2];
				$group = "\u$owner";
			} else {
				@c = split(/\t/, $x);
				$topic_name = &unescape($c[4]);
				$count = $c[7];
				$group = "\u$c[6]";
				$lmd = $c[9];
			}
			if ($description_seen{$tn} ne "") {
				if ($description_seen{$tn} =~ m|<P class="desc">(.*)</P>|) {
					$descr = $1; $flagd = 1;
				} else {
					$descr = "";
				}
			} elsif ($tl =~ m|<!-Descr-!>(.*)<!-/Descr-!>|) {
				$descr = $1; $flagd = 1;
			} else {
				$descr = "";
			}
			$url = "#";
			$ttlcount += $count; $ttl_count_disp += $count if !$DPr{'hidden'};
			if ($flagd == 0 && $tn == $lc) {
				$descr = "This is a sample topic description for the last topic ($topic_name).  If you choose to use topic descriptions in the future, they will be displayed like this.";
			}
			if ($DPr{'hidden'}) {
				$tl = "";
			} else {
				$tl = &topic_format($tn, $topic_name, $url, $lmd, $group, $descr, $count, $xctr, $DPr{'icons'}, $DPr{'hidden'});
				$TOPICS .= $tl;
			}
		}
		$TS =~ s%\$TOPICS%$TOPICS%g;
		$TS =~ s%\$FONT_STRING%<FONT FACE="$face" SIZE="$size">%g;
		$TS =~ s%\$TOTAL_DISPLAYED%$ttl_count_disp%g;
		$TS =~ s%\$TOTAL_MESSAGES%$ttlcount%g;
		if ($TS =~ m|\$TOTAL_USERS|) {
			if ($USER_COUNTER ne "") {
				$TS =~ s%\$TOTAL_USERS%$USER_COUNTER%g;
			} else {
				undef %uc; $count = 0;
				open (USERS, "$admin_dir/users.txt");
				while (<USERS>) {
					($uname, $rest) = split(/:/, $_, 2);
					$count += 1 if $uc{$uname} != 1;
					$uc{$uname} = 1;
				}
				close (USERS);
				$TS =~ s%\$TOTAL_USERS%$count%g;
			}
		}
		if ($TS =~ m|\$DISCUS_VERSION|) {
			$version_string = "Discus $release_version";
			$version_string .= $free_revision if !$pro;
			$version_string .= $pro_revision if $pro;
			$version_string .= " Pro" if $pro;
			$TS =~ s%\$DISCUS_VERSION%$version_string%g;
		}
		print $TS;
		&printuntil(7, 17, 0, "", 0, 1);
	} else {
		undef $t; undef $p; $cdelta = 1000000;
		@topics = grep(/^<!-Top: (\d+)-!>/, @topfile);
		@topics = sort lm @topics;
O:		foreach $line (@topics) {
			$line =~ m|<!-Top: (\d+)-!>|;
			$tn = $1;
			open (TREE, "$admin_dir/msg_index/$tn-tree.txt");
			@TREE = <TREE>;
			close (TREE);
I:			foreach $line2 (@TREE) {
				@c = split(/\t/, $line2);
				$ttry = $c[1]; $ptry = $c[2];
				if ($c[5] =~ m|Sublist| && $FORM{'prevtype'} eq "s") {
					$y = scalar(grep(/^(\d+)\t$ttry\t(\d+)\t$ptry\t/, @TREE));
					next if $y < 3;
					$delta = ($y - 15) if $y > 15;
					$delta = (8 - $y) if $y < 8;
					next if $delta > $cdelta;
					$cdelta = $delta;
					$t = $tn; $p = $c[2];
					last O if ($y >= 8 && $y <= 15);
				} elsif ($c[5] =~ m|Messages| && $FORM{'prevtype'} eq "m") {
					$y = scalar(split(/,/, $c[11]));
					next if $y < 3;
					$delta = ($y - 15) if $y > 15;
					$delta = (4 - $y) if $y < 8;
					next if $delta > $cdelta;
					$cdelta = $delta;
					$t = $tn; $p = $c[2];
					last O if ($y >= 4 && $y <= 15);
				}
			}
		}
		if ($t == 0) {
			print "(Could not generate preview.  None of your pages have a suitable number of ";
			print "subtopics" if $FORM{'prevtype'} eq "s";
			print "messages" if $FORM{'prevtype'} eq "m";
			print " on them!)\n";
			&printuntil(7, 17, 0, "", 0, 1);
			exit(0);
		}
		($head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src) = &get_page($t, $p);
		$LAST_TOPIC_FORMAT_STRING = $t;
		print "Note: This is a preview of topic/page <A HREF=";
		print "$script_url/board-auth.$cgi_extension?file=/$t/$p.$ext TARGET=_blank>" if !-e "$message_dir/$t";
		print "$message_url/$t/$p.$ext TARGET=_blank>" if -e "$message_dir/$t";
		print "$t/$p</A>.  Click the link to see the page displayed with the currently selected skin.<P>\n";
		if ($FORM{'prevtype'} eq "s") {
		 	$subtopic_variable = &regenerate_subtopic_list($t, $p, $sublist, 0, 1);
			$flag = 0;
			foreach $line (@PFSave) {
				if ($line =~ m|^<!--Sublist-->|) {
					print $line; $flag = 1;
				} elsif ($line =~ m|^<!--/Sublist-->|) {
					print $line; $flag = 0;
				} elsif ($flag == 1) {
					$line = &eval_subst($line);
					print $line;
				}
			}
			&printuntil(7, 17, 0, "", 0, 1);
			exit(0);
		} else {
			&determine_templates($t, "", "", 1);
			$TEMPL_FOUND{"messages_$t"} =~ s%$script_url/([\w\-]+)\.$cgi_extension%#%g;
			$message_variable = &regenerate_message($t, $p, $message, 0, 1);
			&printuntil(7, 11, 0, "", 0, 1);
			$flag = 0;
			foreach $line (@PFSave) {
				if ($line =~ m|^<!--Messages-->|) {
					print $line; $flag = 1;
				} elsif ($line =~ m|^<!--/Messages-->|) {
					print $line; $flag = 0;
				} elsif ($flag == 1) {
					$line = &eval_subst($line);
					print $line;
				}
			}
			&printuntil(13, 13, 0, "", 0, 1);
			foreach $line (@PFSave) {
				if ($line =~ m|^<!--Add-->|) {
					print $line; $flag = 1;
				} elsif ($line =~ m|^<!--/Add-->|) {
					print $line; $flag = 0;
				} elsif ($line =~ m|\[Read addmessage\.txt\]|) {
					$x = $TEMPL_FOUND{"addmessage_$t"};
					$x =~ s/TYPE="?SUBMIT"?/TYPE=BUTTON/gi;
					$x =~ s%$script_url/board-post\.$cgi_extension%%g;
					$x =~ s%$script_url%%g;
					print $x;
				} elsif ($flag == 1) {
					$line = &eval_subst($line);
					print $line;
				}
			}
			&printuntil(15, 17, 0, "", 0, 1);
			exit(0);
		}
	}
	exit(0);
}

sub lm {
	$a =~ m|<!-Top: (\d+)-!>|; $an = $1;
	$b =~ m|<!-Top: (\d+)-!>|; $bn = $1;
	if ($lm{$an} eq "") {
		($al) = grep(/^(\d+)\t$an\t/, @TREE_STRUCTURE_FILE);
		@c = split(/\t/, $al); $lm{$an} = $c[9];
	}
	if ($lm{$bn} eq "") {
		($bl) = grep(/^(\d+)\t$bn\t/, @TREE_STRUCTURE_FILE);
		@c = split(/\t/, $bl); $lm{$bn} = $c[9];
	}
	return -1 if $lm{$an} > $lm{$bn};
	return 1 if $lm{$an} < $lm{$bn};
	return 0;
}

#---SEPARATOR---#

sub template_save {
	my ($template, $text) = @_;
	$skin = 0;
	if ($template =~ m|\.skin$|) {
		$template = $`; $skin = 1;
	} elsif ($template =~ m|\.conf$|) {
		$template = $`;
	}
	$template =~ s/[^\w\-]//g;
	$file = "$template.conf" if $skin == 0;
	$file = "$template.skin" if $skin == 1;
	$exten = "conf" if $skin == 0;
	$exten = "skin" if $skin == 1;
	if (!-e "$admin_dir/$template.$exten") {
		&error_message("Template Save Error", "The indicated template, $file, does not already exist.");
	}
	$nextbu = 0;
	if (opendir(DIR, "$admin_dir/backups")) {
		while ($dir = readdir(DIR)) {
			if ($dir =~ m|^$template-(\d+)\.$exten$|) {
				$nextbu = (1+$1) if (1+$1) > $nextbu;
			}
		}
		closedir(DIR);
	}
	$nextbu = "00$nextbu" if $nextbu < 10;
	$nextbu = "0$nextbu" if $nextbu >= 10 && $nextbu < 100;
	if (open(BAK, ">$admin_dir/backups/$template-$nextbu.$exten")) {
		open (SRC, "$admin_dir/$template.$exten");
		while (<SRC>) {
			print BAK;
		}
		close (SRC);
		close (BAK);
	} else {
		&error_message("Template Save Error", "Cannot make a backup copy of this template.  Make sure the directory &quot;backups&quot; under your administration directory exists and is world-writable.  Then try to save again.");
	}
	if (open(SRC, ">$admin_dir/$template.$exten")) {
		print SRC $text;
		close (SRC);
	} else {
		&error_message("Template Save Error", "Cannot write to template file $template.$exten.");
	}
}

# END - FILE IS CORRECTLY UPLOADED #
