###############################################################################
# Admin.pl                                                                    #
###############################################################################
# YaBB: Yet another Bulletin Board                                            #
# Open-Source Community Software for Webmasters                               #
# Version:        YaBB 2.2.1                                                  #
# Packaged:       March 5, 2008                                               #
# Distributed by: http://www.yabbforum.com                                    #
# =========================================================================== #
# Copyright (c) 2000-2008 YaBB (www.yabbforum.com) - All Rights Reserved.     #
# Software by:  The YaBB Development Team                                     #
#               with assistance from the YaBB community.                      #
# Sponsored by: Xnull Internet Media, Inc. - http://www.ximinc.com            #
#               Your source for web hosting, web design, and domains.         #
###############################################################################

$YaBBversion = 'YaBB 2.2.1';
$adminplver  = 'YaBB 2.2.1 $Revision: 1.80.2.13 $';

sub Admin {
	&is_admin_or_gmod;
	$yymain .= qq~
 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg" colspan="2">
		 <b>$admintxt{'1'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2">
		<img alt="Admin Centre Logo" src="$defaultimagesdir/aarea.jpg" />
	   </td>
       <td align="left" class="windowbg2">
		 $admintxt{'2'}
	   </td>
     </tr>
   </table>
 </div>

<br />

<div style="float: left; width: 49%; text-align: left;">

 <div class="bordercolor" style="padding: 0px; width: 95%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
		 <b>$admintxt{'6'}</b>
	   </td>
     </tr>
     <tr align="center" valign="middle">
       <td align="left" class="catbg"><span class="small">YaBB 2</span>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
Ron Hartendorp, Andrew Aitken, Carsten Dalgaard, Ryan Farrington, Zoltan Kovacs, Tim Ceuppens, Shoeb Omar, Torsten Mrotz, Brian Schaefer, Juvenall Wilson, Corey Chapman, Christer Jenson, Adrian Kreher, Steve Brereton, Jeffrey Man, Boris Tjuvanov, $yabbBeta<br /><br />
	   </td>
     </tr>
     <tr align="center" valign="middle">
       <td align="left" class="catbg"><span class="small">$yabbThanks</span>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
Dave Baughman, Bjoern Berg, Corey Chapman, Peter Crouch, ejdmoo, Dave G, Christian Land, Jeff Lewis, Gunther Meyer, Darya Misse, Parham Mofidi, AstroPilot, Torsten Mrotz, Carey P, Popeye, Michael Prager, Matt Siegman, Jay Silverman, StarSaber, Marco van Veelen, Myhailo Danylenko, $yabb2Credits<br /><br />
$noBytesHarmed<br /><br />
	   </td>
     </tr>
   </table>
 </div>

<br />

 <div class="bordercolor" style="padding: 0px; width: 95%; margin-left: 0px; margin-right: auto;">
  <script language="JavaScript" type="text/javascript">
  <!-- //hide from dinosaurs
	var STABLE;
  // -->
  </script>
  <script language="javascript" src="http://www.yabbforum.com/update/versioncheck.js" type="text/javascript"></script>
  <script language="JavaScript" type="text/javascript">
  <!-- //hide from dinosaurs
	document.write('<table width="100%" cellspacing="1" cellpadding="4">');		
	document.write('<tr><td colspan="2" class="titlebg"><b>$admintxt{'3'}</b></td></tr>');
	document.write('<tr><td class="windowbg2">$versiontxt{'4'}</td><td class="windowbg2"><b>$YaBBversion</b></td></tr>');
	if (!STABLE) {
		document.write('<tr><td colspan="2" class="titlebg">$rna</b></td></tr>');
	} else {
		document.write('<tr><td class="windowbg2">$versiontxt{'5'}</td><td class="windowbg2"><b>'+STABLE+'</b></td></tr>');
		document.write('<tr><td class="windowbg2">$versiontxt{'7'}</td><td class="windowbg2"><b>'+BETA+'</b></td></tr>');
		document.write('<tr><td class="windowbg2">$versiontxt{'8'}</td><td class="windowbg2"><b>'+ALPHA+'</b></td></tr>');
		if (STABLE == "$YaBBversion") {
			document.write('<tr><td colspan="2" valign="middle" class="windowbg2"><br />$versiontxt{'6'}<br /><br /></td></tr>');
		} else {
			document.write('<tr><td colspan="2" valign="middle" class="windowbg2"><br />$versiontxt{'2'}'+STABLE+'$versiontxt{'3'}<br /><br /></td></tr>');
		}
	}
	document.write('</table>');
  // -->
  </script>
  <noscript>$versiontxt{'1'}</noscript>
 </div>

</div>
<div style="float: left; width: 50%; text-align: right;">

 <div class="bordercolor" style="padding: 0px; width: 100%; margin-left: auto; margin-right: 0px;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
		 <b>$admintxt{'4'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2">
		 <iframe src="http://www.yabbforum.com/update/" frameborder="0" width="100%" height="293">$iFrameSupport
		 </iframe>
	   </td>
     </tr>
   </table>
 </div>

<br />

 <div class="bordercolor" style="padding: 0px; width: 100%; margin-left: auto; margin-right: 0px;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
		 <b>$admintxt{'5'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2">~;
	&GetLastLogins;
	$yymain .= qq~
	   </td>
     </tr>
   </table>
 </div>
~;

	if (-d "./Convert") {

		$yymain .= qq~
<br />
<div class="bordercolor" style="padding: 0px; width: 100%; margin-left: auto; margin-right: 0px;">
<form name="backdelete" action="$adminurl?action=convdelete" method="post">
<table width="100%" cellspacing="1" cellpadding="4">
	<tr valign="middle">
	<td align="left" class="titlebg">
		<b>$admintxt{'7'}</b>
	</td>
	</tr>
	<tr valign="middle">
	<td align="left" class="windowbg2"><br />
		$admintxt{'8'}<br /><br />
	</td>
	</tr>
	<tr valign="middle">
	<td align="center" class="catbg">
		<input type="submit" value="$admintxt{'9'}" class="button" />
	</td>
	</tr>
</table>
</form>
</div>
~;

	}

	$yymain .= qq~
<div style="height: 130px;">&nbsp;</div>
</div>
~;

	$yytitle = "$admin_txt{'208'}";
	&AdminTemplate;
}

sub DeleteConverterFiles {

	my @convertdir = qw~Boards Members Messages Variables~;

	foreach $cnvdir (@convertdir) {
		$convdir = "./Convert/$cnvdir";
		if (-d "$convdir") {
			opendir("CNVDIR", $convdir) || &admin_fatal_error("cannot_open_dir","$convdir");
			@convlist = readdir("CNVDIR");
			closedir("CNVDIR");
			foreach $file (@convlist) {
				unlink "$convdir/$file" || &admin_fatal_error("cannot_open_dir","$convdir/$file");
			}
			rmdir("$convdir");
		}
	}
	$convdir = "./Convert";
	if (-d "$convdir") {
		opendir("CNVDIR", $convdir) || &admin_fatal_error("cannot_open_dir","$convdir");
		@convlist = readdir("CNVDIR");
		closedir("CNVDIR");
		foreach $file (@convlist) {
			unlink "$convdir/$file";
		}
		rmdir("$convdir");
	}
	if (-e "./Setup.pl") { unlink("./Setup.pl"); }

	$yymain .= qq~<b>$admintxt{'10'}</b>~;
	$yytitle = "$admintxt{'10'}";
	&AdminTemplate;
	exit;
}

sub GetLastLogins {
	fopen(ADMINLOG, "$vardir/adminlog.txt");
	@adminlog = <ADMINLOG>;
	fclose(ADMINLOG);

	foreach $line (@adminlog) {
		chomp $line;
		@element = split(/\|/, $line);
		if (!${$uid.$element[0]}{'realname'}) { &LoadUser($element[0]); }    # If user is not in memory, s/he must be loaded.
		$element[2] = &timeformat($element[2]);
		$yymain .= qq~
		<a href="$scripturl?action=viewprofile;username=$useraccount{$element[0]}">${$uid.$element[0]}{'realname'}</a> <span class="small">($element[1]) - $element[2]</span><br />
		~;
	}
}

sub FullStats {
	&is_admin_or_gmod;
	my ($numcats, $numboards, $threadcount, $messagecount, $maxdays, $totalt, $totalm, $avgt, $avgm);
	my ($memcount, $latestmember) = &MembershipGet;
	&LoadUser($latestmember);
	$thelatestmember = qq~<a href="$scripturl?action=viewprofile;username=$useraccount{$latestmember}">${$uid.$latestmember}{'realname'}</a>~;
	$memcount ||= 1;

	$numcats = 0;

	unless ($mloaded == 1) { require "$boardsdir/forum.master"; }
	foreach $catid (@categoryorder) {
		$boardlist = $cat{$catid};
		$numcats++;
		(@bdlist) = split(/\,/, $boardlist);
		($catname, $catperms, $catallowcol) = split(/\|/, $catinfo{"$catid"});

		foreach $curboard (@bdlist) {
			chomp $curboard;
			$numboards++;
			push(@loadboards, $curboard);

		}
	}

	&BoardTotals("load", @loadboards);
	foreach $curboard (@loadboards) {

		$totalm += ${$uid.$curboard}{'messagecount'};
		$totalt += ${$uid.$curboard}{'threadcount'};

	}

	$avgm = int($totalm / $memcount);
	&LoadAdmins;

	if ($enableclicklog) {
		my (@log);
		fopen(LOG, "$vardir/clicklog.txt");
		@log = <LOG>;
		fclose(LOG);
		$yyclicks    = @log;
		$yyclicktext = $admin_txt{'692'};
		$yyclicklink = qq~$yyclicks&nbsp;(<a href="$adminurl?action=showclicks">$admin_txt{'693'}</a>)~;

	} else {
		$yyclicktext = $admin_txt{'692a'};
		$yyclicklink = "";
	}
	my (@elog);
	fopen(ELOG, "$vardir/errorlog.txt");
	@elog = <ELOG>;
	fclose(ELOG);
	$errorslog = @elog;

	$yymain .= qq~

 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
<img src="$imagesdir/info.gif" alt="" border="0" /> <b>$admintxt{'28'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="catbg">
		 <i>$admin_txt{'94'}</i>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'488'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$memcount</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'490'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$totalt</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'489'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$totalm</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admintxt{'39'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$avgm</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'658'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$numcats</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'665'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$numboards</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$errorlog{'3'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$errorslog</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'691'}&nbsp;<span class="small">($yyclicktext)</span></div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$yyclicklink</div>
		<br />&nbsp;<br />
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="catbg">
		 <i>$admin_txt{'657'}</i>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'656'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$thelatestmember</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'659'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">
~;

	# Sorts the threads to find the most recent post
	# No need to check for board access here because only admins have access to this page
	unless ($mloaded == 1) { require "$boardsdir/forum.master"; }
	foreach $catid (@categoryorder) {
		$boardlist = $cat{$catid};
		(@bdlist) = split(/\,/, $boardlist);
		foreach $curboard (@bdlist) {
			push(@goodboards, $curboard);
		}
	}

	&BoardTotals("load", @goodboards);
	&getlog(@goodboards);
	foreach $curboard (@goodboards) {
		chomp $curboard;
		$lastposttime = ${$uid.$curboard}{'lastposttime'};
		$lastposttime{$curboard} = &timeformat(${$uid.$curboard}{'lastposttime'});
		${$uid.$curboard}{'lastposttime'} = ${$uid.$curboard}{'lastposttime'} eq 'N/A' || !${$uid.$curboard}{'lastposttime'} ? $boardindex_txt{'470'} : ${$uid.$curboard}{'lastposttime'};
		$lastpostrealtime{$curboard} = ${$uid.$curboard}{'lastposttime'} eq 'N/A' || !${$uid.$curboard}{'lastposttime'} ? '' : ${$uid.$curboard}{'lastposttime'};
		if (${$uid.$curboard}{'lastposter'} =~ m~\AGuest-(.*)~) {
			${$uid.$curboard}{'lastposter'} = $1;
			$lastposterguest{$curboard} = 1;
		}
		${$uid.$curboard}{'lastposter'} = ${$uid.$curboard}{'lastposter'} eq 'N/A' || !${$uid.$curboard}{'lastposter'} ? $boardindex_txt{'470'} : ${$uid.$curboard}{'lastposter'};
		${$uid.$curboard}{'messagecount'} = ${$uid.$curboard}{'messagecount'} || 0;
		${$uid.$curboard}{'threadcount'} = ${$uid.$curboard}{'threadcount'} || 0;
		$totalm += ${$uid.$curboard}{'messagecount'};
		$totalt += ${$uid.$curboard}{'threadcount'};

		# determine the true last post on all the boards a user has access to
		if ($lastposttime > $lastthreadtime) {
			$lsdatetime = &timeformat($lastposttime);
			$lsposter = ${$uid.$curboard}{'lastposter'};
			$lssub = ${$uid.$curboard}{'lastsubject'};
			$lspostid = ${$uid.$curboard}{'lastpostid'};
			$lsreply = ${$uid.$curboard}{'lastreply'};
			$lastthreadtime = $lastposttime;
		}
	}
	$lssub =~ s/\A\[m.*?\]/$maintxt{'758'}/;
	&ToChars($lssub);
	$yymain .= qq~<a href="$scripturl?num=$lspostid/$lsreply#$lsreply">$lssub</a> ($lsdatetime)</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'684'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$administrators</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'684a'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$gmods</div>
		<br />
		 <div style="float: left; clear: left; width: 35%; text-align: left; padding-top: 2px; padding-bottom: 2px;">$admin_txt{'425'}</div>
		 <div style="float: left; width: 65%; text-align: left; padding-top: 2px; padding-bottom: 2px;">
		 <script language="javascript" src="http://www.yabbforum.com/update/versioncheck.js" type="text/javascript"></script>
		<script language="JavaScript" type="text/javascript">  
			<!-- //hide from dinosaurs  
				document.write("$versiontxt{'4'} <b>$YaBBversion</b> - $versiontxt{'5'} <b>"+STABLE+"</b> <p>");  
			// -->
		</script>
		<noscript>$versiontxt{'1'} <img src="http://www.yabbforum.com/images/version/versioncheck.gif" alt="" /></noscript> 
		 </div>
		<br />&nbsp;<br />
	   </td>
     </tr>
   </table>
 </div>
~;
	$yytitle = $admintxt{'28'};
	$action_area = "stats";
	&AdminTemplate;
	exit;
}

sub LoadAdmins {
	&is_admin_or_gmod;
	my (@members, $curentry, $memdata);
	$administrators = "";
	$gmods          = "";
	&ManageMemberinfo("load");
	while (($membername, $value) = each(%memberinf)) {
		($memberrealname, undef, $memposition, $memposts) = split(/\|/, $value);
		if($do_scramble_id){$membernameCloaked = &cloak($membername); } else { $membernameCloaked = $membername; }
		if ($memposition eq "Administrator") {
			$administrators .= qq~ <a href="$scripturl?action=viewprofile;username=$membernameCloaked">$memberrealname</a><span class="small">,</span> \n~;
		}
		if ($memposition eq "Global Moderator") {
			$gmods .= qq~ <a href="$scripturl?action=viewprofile;username=$membernameCloaked">$memberrealname</a><span class="small">,</span> \n~;
		}
	}
	$administrators =~ s~<span class="small">,</span> \n\Z~~;
	$gmods          =~ s~<span class="small">,</span> \n\Z~~;
	if ($gmods eq "") { $gmods = qq~&nbsp;~; }
	undef %memberinf;
}

sub ShowClickLog {
	&is_admin_or_gmod;

	if ($enableclicklog) { $logtimetext = $admin_txt{'698'}; }
	else { $logtimetext = $admin_txt{'698a'}; }

	my ($totalip, $totalclick, $totalbrow, $totalos, @log, @iplist, $date, @to, @from, @info, @os, @browser, @newiplist, @newbrowser, @newoslist, @newtolist, @newfromlist, $i, $curentry);
	fopen(LOG, "$vardir/clicklog.txt");
	@log = <LOG>;
	fclose(LOG);

	$i = 0;
	foreach $curentry (@log) {
		($iplist[$i], $date, $to[$i], $from[$i], $info[$i]) = split(/\|/, $curentry);
		$i++;
	}
	$i = 0;
	foreach $curentry (@info) {
		if ($curentry !~ /\s\(Win/i || $curentry !~ /\s\(mac/) { $curentry =~ s/\s\((compatible;\s)*/ - /ig; }
		else { $curentry =~ s/(\S)*\(/; /g; }
		if ($curentry =~ /\s-\sWin/i) { $curentry =~ s/\s-\sWin/; win/ig; }
		if ($curentry =~ /\s-\sMac/i) { $curentry =~ s/\s-\sMac/; mac/ig; }
		($browser[$i], $os[$i]) = split(/\;\s/, $curentry);
		if ($os[$i] =~ /\)\s\S/) { ($os[$i], $browser[$i]) = split(/\)\s/, $os[$i]); }
		$os[$i] =~ s/\)//g;
		$i++;
	}

	for ($i = 0; $i < @iplist; $i++) { $iplist{ $iplist[$i] }++; }
	$i = 0;
	while (($key, $val) = each(%iplist)) {
		$newiplist[$i] = [$key, $val];
		$i++;
	}
	$totalclick = @iplist;
	$totalip    = @newiplist;
	for ($i = 0; $i < @newiplist; $i++) {

		if ($newiplist[$i]->[0] =~ /\S+/ && $newiplist[$i]->[0] =~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) {
			$guestiplist .= qq~$newiplist[$i]->[0]&nbsp;<span style="color: #FF0000;">(<i>$newiplist[$i]->[1]</i>)</span><br />~;
		} else {
			&LoadUser($newiplist[$i]->[0]);
			if($do_scramble_id){$cloakedUserName = &cloak($newiplist[$i]->[0]); } else {$cloakedUserName = $newiplist[$i]->[0]; }
			my $displayUserName = $newiplist[$i]->[0];
			if(${$uid.$displayUserName}{'realname'} && (${$uid.$displayUserName}{'realname'} ne $newiplist[$i]->[0])) 	{
				$displayUserName = ${$uid.$displayUserName}{'realname'};}
			$useriplist .= qq~<a href="$scripturl?action=viewprofile;username=$cloakedUserName">$displayUserName</a>&nbsp;<span style="color: #FF0000;">(<i>$newiplist[$i]->[1]</i>)</span><br />~;
		}
	}

	for ($i = 0; $i < @browser; $i++) { $browser{ $browser[$i] }++; }
	$i = 0;
	while (($key, $val) = each(%browser)) {
		$newbrowser[$i] = [$key, $val];
		$i++;
	}
	$totalbrow = @newbrowser;
	for ($i = 0; $i < @newbrowser; $i++) {
		if ($newbrowser[$i]->[0] =~ /\S+/) {
			$browserlist .= qq~$newbrowser[$i]->[0] &nbsp;<span style="color: #FF0000;">(<i>$newbrowser[$i]->[1]</i>)</span><br />~;
		}
	}

	for ($i = 0; $i < @os; $i++) { $os{ $os[$i] }++; }
	$i = 0;
	while (($key, $val) = each(%os)) {
		$newoslist[$i] = [$key, $val];
		$i++;
	}
	$totalos = @newoslist;
	for ($i = 0; $i < @newoslist; $i++) {
		if ($newoslist[$i]->[0] =~ /\S+/) {
			$oslist .= qq~$newoslist[$i]->[0] &nbsp;<span style="color: #FF0000;">(<i>$newoslist[$i]->[1]</i>)</span><br />~;
		}
	}

	for ($i = 0; $i < @to; $i++) { $to{ $to[$i] }++; }
	$i = 0;
	while (($key, $val) = each(%to)) {
		$newtolist[$i] = [$key, $val];
		$i++;
	}
	for ($i = 0; $i < @newtolist; $i++) {
		if ($newtolist[$i]->[0] =~ /\S+/) {
			$scriptcalls .= qq~<a href="$newtolist[$i]->[0]" target="_blank">$newtolist[$i]->[0]</a>&nbsp;<span style="color: #FF0000;">(<i>$newtolist[$i]->[1]</i>)</span><br />~;
		}
	}

	for ($i = 0; $i < @from; $i++) { $from{ $from[$i] }++; }
	$i = 0;
	while (($key, $val) = each(%from)) {
		$newfromlist[$i] = [$key, $val];
		$i++;
	}
	for ($i = 0; $i < @newfromlist; $i++) {
		if ($newfromlist[$i]->[0] =~ /\S+/ && $newfromlist[$i]->[0] !~ m~$boardurl~i) {
			$message = $newfromlist[$i]->[0];
			&wrap;
			if (!$yyYaBBCloaded) { require "$sourcedir/YaBBC.pl"; }
			&DoUBBC;
			&wrap2;
			$referlist .= qq~<a href="$newfromlist[$i]->[0]" target="_blank">$message</a>&nbsp;<span style="color: #FF0000;">(<i>$newfromlist[$i]->[1]</i>)</span><br />~;
		}
	}

	$yymain .= qq~

 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
<img src="$imagesdir/info.gif" alt="" border="0" /> <b>$admin_txt{'693'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
		 $admin_txt{'697'}$logtimetext<br /><br />
	   </td>
     </tr>
   </table>
 </div>

~;
	if ($enableclicklog) {
		$yymain .= qq~

<br />

 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg" colspan="2">
<img src="$imagesdir/cat.gif" alt="" border="0" /> <b>$admin_txt{'694'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2" colspan="2"><br />
		 $admin_txt{'691'}: $totalclick<br />
		 $admin_txt{'743'}: $totalip<br /><br />
	   </td>
     </tr>
     <tr valign="middle">
       <td align="center" class="catbg" width="50%">
		 <b>$clicklog_txt{'users'}</b>
	   </td>
       <td align="center" class="catbg" width="50%">
		 <b>$clicklog_txt{'guests'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2" valign="top" width="50%"><br />
		 $useriplist<br />
	   </td>
       <td align="left" class="windowbg2" valign="top" width="50%"><br />
		 $guestiplist<br />
	   </td>
     </tr>
   </table>
 </div>

<br />

 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
<img src="$imagesdir/cat.gif" alt="" border="0" /> <b>$admin_txt{'695'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="catbg">
		 <i>$admin_txt{'744'}: $totalbrow</i>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
		 $browserlist<br />
	   </td>
     </tr>
   </table>
 </div>

<br />

 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
<img src="$imagesdir/cat.gif" alt="" border="0" /> <b>$admin_txt{'696'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="catbg">
		 <i>$admin_txt{'745'}: $totalos</i>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
		 $oslist<br />
	   </td>
     </tr>
   </table>
 </div>

<br />

 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
<img src="$imagesdir/cat.gif" alt="" border="0" /> <b>$admin_txt{'696a'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
		 $scriptcalls<br />
	   </td>
     </tr>
   </table>
 </div>

<br />

 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
<img src="$imagesdir/cat.gif" alt="" border="0" /> <b>$admin_txt{'838'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
		 $referlist<br />
	   </td>
     </tr>
   </table>
 </div>
~;
	}
	$yytitle     = $admin_txt{'693'};
	$action_area = "showclicks";
	&AdminTemplate;
	exit;
}

sub AdminMembershipRecount {
	&is_admin_or_gmod;
	&MembershipCountTotal;
	$yymain .= qq~<b>$admin_txt{'505'}</b>~;
	$yytitle     = $admin_txt{'504'};
	$action_area = "membershiprecount";
	&AdminTemplate;
	exit;
}

sub AdminBoardRecount {

	&is_admin_or_gmod();
	&automaintenance('on');

	$action_area = 'boardrecount';
	$yytitle = $admin_txt{'502'};

	# Set up the multi-step action
	$maxtime = 20; # Time in seconds to spend
	$begin_time = CORE::time;
	$topicnum = $INFO{'topicnum'} || 0;

	if (!$INFO{'tnext'}) {

		# Get the thread list
		opendir(TXT, $datadir);
		@topiclist = grep { /^\d{1,10}\.txt$/ } readdir(TXT);
		closedir(TXT);
		@topiclist = sort @topiclist;

		for ($i = $topicnum; $i < scalar @topiclist; $i++) {
			($filename, $fileext) = split(/\./, $topiclist[$i]);
			fopen(MSG, "$datadir/$filename.txt");
			@messages = <MSG>;
			fclose(MSG);
			@lastmessage = split(/\|/, $messages[$#messages]);
			&MessageTotals('load', $filename);
			${$filename}{'replies'} = $#messages;
			if ($lastmessage[0] =~ /^\[m\]:/) { ${$filename}{'lastposter'} = $lastmessage[11]; }
			else { ${$filename}{'lastposter'} = $lastmessage[4] eq 'Guest' ? qq~Guest-$lastmessage[1]~ : $lastmessage[4]; }
			&MessageTotals('update', $filename);
			$topicnum++;
			if (time > $begin_time + $maxtime) {
				$topicnum = $i;
				last;
			}
		}

		# Prepare to continue...
		$numleft = scalar @topiclist - $topicnum;
		if ($numleft == 0) {
			$yySetLocation = qq~$adminurl?action=boardrecount;tnext=1~;
			&redirectexit;
		}

		# Continue
		$sumtopic = @topiclist;
		$resttopic = $sumtopic - $topicnum;

		$yymain .= qq~
		<br />
		$rebuild_txt{'1'}
		<br />
		$rebuild_txt{'5'} $maxtime $rebuild_txt{'6'}
		<br /><br />
		$rebuild_txt{'13'} $sumtopic
		<br />
		$rebuild_txt{'14'} $resttopic
		<br />
		<br />
		<br />
		<div id="boardrecountcontinued">
		<br />
		$rebuild_txt{'1'}<br />
		$rebuild_txt{'2'} <a href="$adminurl?action=boardrecount;topicnum=$topicnum" onclick="rebRecount();">$rebuild_txt{'3'}</a>
		</div>
		<script type="text/javascript" language="JavaScript">
		<!--
		var convtext = "$rebuild_txt{'4'}";
		function rebRecount() {
			document.getElementById("boardrecountcontinued").innerHTML = convtext;
		}

		function recounttick() {
			rebRecount();
			location.href="$adminurl?action=boardrecount;topicnum=$topicnum";
		}

		setTimeout("recounttick()",3000)
		// -->
		</script>
		~;
		&AdminTemplate();
	}

	# Get the board list from the forum.master file
	require "$boardsdir/forum.master";
	foreach (keys %board) {
		&BoardCountTotals($_);
	}
	$yymain .= qq~<b>$admin_txt{'503'}</b>~;
	&automaintenance('off');
	&AdminTemplate;
	exit;

}


sub RebuildMessageIndex {
	&is_admin_or_gmod();
	&automaintenance('on');

	opendir(CTB, $datadir);
	@threadlist = grep { /^\d{1,10}\.txt$/ } readdir(CTB);
	closedir(CTB);
	
	# storing status of threads, and board of thread - from boards
	require "$boardsdir/forum.master";
	foreach $oldboard (keys %board) {
		fopen(OLDBOARD, "$boardsdir/$oldboard.txt") || &admin_fatal_error('cannot_open', "$boardsdir/$oldboard.txt", 1);
		while ($oldThreadLine = <OLDBOARD>) {
			chomp $oldThreadLine;
			($mnum, undef, undef, undef, undef, undef, undef, undef, $mstate) = split(/\|/, $oldThreadLine);
			$thread_status{$mnum} = $mstate;
			$thread_boards{$mnum} = $oldboard;
		}
		fclose(OLDBOARD);
	}
	
 	threadcheck: foreach $thread (@threadlist) {
		chomp $thread;
		$thread =~ s/\.txt$//;
		
		if ($thread eq '' || !-e "$datadir/$thread.txt" || -s "$datadir/$thread.txt" < 35) {
			unlink("$datadir/$thread.txt");
			unlink("$datadir/$thread.ctb");
			unlink("$datadir/$thread.mail");
			unlink("$datadir/$thread.poll");
			unlink("$datadir/$thread.polled");
			next threadcheck;
		}
		
		if (!-e "$datadir/$thread.ctb") {
			${$thread}{'board'} = '';
			${$thread}{'replies'} = '';
			${$thread}{'views'} = '';
			${$thread}{'lastposter'} = '';
			${$thread}{'lastpostdate'} = '';
			${$thread}{'threadstatus'} = '';
			${$thread}{'repliers'} = '';
			&MessageTotals('update', $thread);
		}
		
		&MessageTotals('load', $thread);

		# set correct board
		$theboard = exists $thread_boards{$thread} ? $thread_boards{$thread} : ${$thread}{'board'};
		# if boardname is wrong - > put to recycle
		if (!exists $board{$theboard} ) { $theboard = $binboard; }; 
		$thestatus = exists $thread_status{$thread} ? $thread_status{$thread} : '';

		fopen(FILETXT, "$datadir/$thread.txt") || &admin_fatal_error('cannot_open', "$datadir/$thread.txt", 1);
		@threaddata = <FILETXT>;
		fclose(FILETXT);
		(@firstinfo) = split(/\|/, $threaddata[0]);
		(@lastinfo) = split(/\|/, $threaddata[$#threaddata]);
		$thelastinfo = sprintf("%010d", $lastinfo[3]);

		if (${$thread}{'board'} ne $theboard) {
			# rewrite/create a correct thread.ctb
			$lastposter = $lastinfo[4] eq 'Guest' ? qq~Guest-$lastinfo[1]~ : $lastinfo[4];
			${$thread}{'board'} = $theboard;
			${$thread}{'replies'} = $#threaddata;
			${$thread}{'views'} = ${$thread}{'views'} || 0;
			${$thread}{'lastposter'} = $lastposter;
			${$thread}{'lastpostdate'} = $thelastinfo;
			${$thread}{'threadstatus'} = $thestatus;
			${$thread}{'repliers'} = '';
			&MessageTotals('update', $thread);
		} else {
			$theboard = ${$thread}{'board'};
			$thestatus = ${$thread}{'threadstatus'};
		}

		$threadinfo = qq~$theboard|$thelastinfo|$thread|$firstinfo[0]|$firstinfo[1]|$firstinfo[2]|$lastinfo[3]|$#threaddata|$firstinfo[4]|$firstinfo[5]|$thestatus\n~;
		push(@$theboard, $threadinfo);
	}
	
	foreach $newboard (keys %board) {
		my @SortBoards = ();
		@SortBoards = sort { lc($b) cmp lc($a) } (@$newboard);
		fopen(NEWBOARD, ">$boardsdir/$newboard.txt") || &admin_fatal_error('cannot_open', "$boardsdir/$newboard.txt", 1);
		truncate NEWBOARD, 0;
		seek NEWBOARD, 0, 0;
		for ($i = 0; $i < @SortBoards; $i++) {
			my @thisthread = ();
			(@thisthread) = split(/\|/, $SortBoards[$i]);
			print NEWBOARD qq~$thisthread[2]|$thisthread[3]|$thisthread[4]|$thisthread[5]|$thisthread[6]|$thisthread[7]|$thisthread[8]|$thisthread[9]|$thisthread[10]~;
		}
		fclose(NEWBOARD);
	}
	
	foreach (keys %board) {
		&BoardCountTotals($_);
	}

	&automaintenance('off');
	$yymain .= qq~<b>$admin_txt{'507'}</b>~;
	$yytitle = $admin_txt{'506'};
	$action_area = 'rebuildmesindex';
	&AdminTemplate;
	exit;
}

sub case_insensitive {
	uc($::a) cmp uc($::b);
}

sub DeleteOldMessages {
	&is_admin_or_gmod;
	fopen(DELETEOLDMESSAGE, "$vardir/oldestmes.txt");
	$maxdays = <DELETEOLDMESSAGE>;
	fclose(DELETEOLDMESSAGE);
	$yytitle = "$aduptxt{'04'}";
	$yymain .= qq~
<form action="$adminurl?action=removeoldthreads" method="post">
 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
<img src="$imagesdir/ban.gif" alt="" border="0" /> <b>$aduptxt{'04'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
		 $aduptxt{'05'}<br /><br />
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2"><br />
		 $admin_txt{'4'}: <input type="checkbox" name="keep_them" value="1" /><br />
		 $admin_txt{'124'} <input type=text name="maxdays" size="2" value="$maxdays" /> $admin_txt{'579'} $admin_txt{'2'}:<br /><br />
		 <div align="left" style="margin-left: 25px; margin-right: auto;">
~;

	unless ($mloaded == 1) { require "$boardsdir/forum.master"; }

	foreach $catid (@categoryorder) {
		$boardlist = $cat{$catid};
		(@bdlist) = split(/\,/, $boardlist);
		($catname, $catperms) = split(/\|/, $catinfo{"$catid"});

		foreach $curboard (@bdlist) {
			($boardname, $boardperms, $boardview) = split(/\|/, $board{"$curboard"});

			$selectname = $curboard . 'check';
			$yymain .= qq~
		   <input type="checkbox" name="$selectname" value="1" />&nbsp;$boardname<br />
~;
		}
	}
	$yymain .= qq~
		 </div><br />
	   </td>
     </tr>
     <tr valign="middle">
       <td align="center" class="catbg">
		 <input type="submit" value="$admin_txt{'31'}" class="button" />
	   </td>
     </tr>
   </table>
 </div>
</form>
~;
	$action_area = "deleteoldthreads";
	&AdminTemplate;
	exit;
}

# refresh the IM system, or update it, or rebuld it . Whichever!
sub RebuildIMs	{
	&automaintenance("on");
	&is_admin_or_gmod;
	$yytitle = "$admin_txt{'600'}";
	$yymain .= "<b>$admin_txt{'601'}</b>";
	# grep a list of members from vars file
	opendir("MEMBSDIR", $memberdir);
	my @imslist = grep { /\.vars$/ } readdir(MEMBSDIR);
	closedir("MEMBSDIR");	
	#new ims
	#0	$mnum = 3;
	#1	$imnewcount = 0;
	#2	$moutnum = 17;
	#3	$storenum = 0;
	#4	@incurrent = qw/ /;  # list of messages in .msg
	#5	@inunread = qw/ /; # unread in msg
	#6	@inreplied = qw/ /; # replied to
	#7	@inforward = qw/ /; # forwarded
	#8	@outcurrent = qw/ /; # list of messages in .outbox
	#9	@outunread = qw/ /; # outbox, not opened by receiver
	#10	@storecurrentin = qw/ /; # list of messages in .imstore msg
	#11	@storecurrentout = qw/ /; # list of messages in .imstore outbox
	
	foreach my $member (@imslist)	{
		chomp $member;
		my $memlen = length($member);
		my($member,$undef) = substr($member,0, $memlen-5); 
		&buildIMS($member);
	}	
	&automaintenance("off");
	$action_area = "updateinstantmessages";
	&AdminTemplate;
	exit;
}

sub RebuildMemHistory {
	my (@contents,$begin_time,$maxtime,$start_time,$timeleft,$hour,$min,$sec,$sumtopic,$resttopic);

	# Security
	&is_admin_or_gmod;
	&automaintenance("on");

	# Set up the multi-step action
	$maxtime = 30; # Time in seconds to spend
	$begin_time = CORE::time;

	if (-e "$datadir/topicrest.txt.rebuild" ) {
		fopen(TOPICREST, "$datadir/topicrest.txt.rebuild") || &fatal_error('cannot_open', "$datadir/topicrest.txt.rebuild", 1);
		@contents = <TOPICREST>;
		fclose(TOPICREST);
		chomp @contents;

		fopen(TOPICCALC, "$datadir/topiccalc.txt.rebuild") || &fatal_error('cannot_open', "$datadir/topiccalc.txt.rebuild", 1);
		$start_time = <TOPICCALC>;
		$sumtopic = <TOPICCALC>;
		fclose(TOPICCALC);
		chomp ($begin_time,$sumtopic);
	}

	if (! @contents) {
		# Delete all rlog
		opendir(MEMBERS, $memberdir) || die "$txt{'230'} ($memberdir) :: $!";
		@contents = grep { /\.rlog$/ } readdir(MEMBERS);
		closedir(MEMBERS);
		foreach $recfile (@contents) {
			chomp $recfile;
			unlink "$memberdir/$recfile";
		}

		# Get the thread list
		opendir(TXT, $datadir);
		@contents = grep { /^\d{1,10}\.txt$/ } readdir(TXT);
		closedir(TXT);

		fopen(TOPICREST, ">$datadir/topicrest.txt.rebuild") || &fatal_error('cannot_open', "$datadir/topicrest.txt.rebuild", 1);
		foreach my $topic (@contents) {
			chomp $topic;
			$topic =~ s/\.txt$//;
			print TOPIC "$topic\n" if $topic;
		}		
		fclose(TOPICREST);

		$sumtopic = @contents;
		$start_time = $begin_time;
		fopen(TOPICCALC, ">$datadir/topiccalc.txt.rebuild") || &fatal_error('cannot_open', "$datadir/topiccalc.txt.rebuild", 1);
		print TOPICCALC "$start_time\n";
		print TOPICCALC "$sumtopic\n";
		fclose(TOPICCALC);

		$begin_time = +$maxtime; # only first step
	}

	# Loop through each -rest- topic
	while (@contents) {
		$topic = pop @contents;
		chomp $topic;

		my %curtopic=();

		fopen(TOPIC, "$datadir/$topic.txt");
		my @topic = <TOPIC>;
		fclose(TOPIC);

		foreach my $line (@topic) {
			my $user;
			(undef, undef, undef, undef, $user, undef) = split(/\|/, $line, 6);
			if($user ne 'Guest') {
				$curtopic{$user} ||= 0;
				$curtopic{$user}++;
			}	
		}

		foreach my $user (keys %curtopic ) {
			if ( -e "$memberdir/$user.vars") { 
				fopen(HIST, ">>$memberdir/$user.rlog");
				print HIST "$topic\t$curtopic{$user}\n";
				fclose(HIST);
			}
		}

		last if time > $begin_time + $maxtime;
	}

	fopen(TOPICREST, ">$datadir/topicrest.txt.rebuild") || &fatal_error('cannot_open', "$datadir/topicrest.txt.rebuild", 1);
	foreach (@contents) {print TOPICREST "$_\n"};
	fclose(TOPICREST);

	# See if we're completely done
	if(! @contents) {
		unlink("$datadir/topicrest.txt.rebuild");
		unlink("$datadir/topiccalc.txt.rebuild");

		$yymain .= qq~<b>$admin_txt{'598'}</b>~;
		$action_area = "rebuildmemhist";
		&automaintenance("off");
		&AdminTemplate();
	}
	# Or prepare to continue looping
	else {
		$resttopic = @contents;

		$run_time = int(time-$start_time);
		$run_time = 1 if !$run_time;
		$time_left = int($resttopic/(($sumtopic-$resttopic)/$run_time));

		$hour= int($run_time/3600);
		$min = int(($run_time-$hour*3600)/60);
		$sec = $run_time - $hour*3600 - $min*60;
		$hour = "0$hour" if $hour<10; $min = "0$min" if $min<10; $sec = "0$sec" if $sec<10;

		$run_time = "$hour:$min:$sec";

		$hour= int($time_left/3600);
		$min = int(($time_left-$hour*3600)/60);
		$sec = $time_left - $hour*3600 - $min*60;
		$hour = "0$hour" if $hour<10; $min = "0$min" if $min<10; $sec = "0$sec" if $sec<10;

		$time_left = "$hour:$min:$sec";

		$yymain .= qq~
<br />
$rebuild_txt{'1'}
<br />
$rebuild_txt{'5'} $maxtime $rebuild_txt{'6'}
<br /><br />
$rebuild_txt{'13'} $sumtopic
<br />
$rebuild_txt{'14'} $resttopic
<br />
<br />
$rebuild_txt{'7'} $run_time
<br />
$rebuild_txt{'8'} $time_left
<br />
<br />
<div id="memcontinued">
$rebuild_txt{'2'} <a href="$adminurl?action=rebuildmemhist" onclick="clearMeminfo();">$rebuild_txt{'3'}</a>
</div>
<script type="text/javascript" language="JavaScript">
<!--
	var convtext = "$rebuild_txt{'4'}";
	function clearMeminfo() {
		document.getElementById("memcontinued").innerHTML = convtext;
	}

	function membtick() {
		clearMeminfo();
		location.href="$adminurl?action=rebuildmemhist";
	}

setTimeout("membtick()", 1000)
// -->
</script>
~;
	&AdminTemplate();
	}
}

sub RebuildMemList {
	my (@contents, $begin_time, $maxtime, $start_time, $timeleft, $hour, $min, $sec, $sumuser, $grpdel, $grpexist, $regtime);

	# Security
	&automaintenance("on");
	&is_admin_or_gmod;

	# Set up the multi-step action
	$maxtime = 30; # Time in seconds to spend
	$begin_time = CORE::time;
	
	if (-e "$memberdir/memberrest.txt.rebuild" ) {
		fopen(MEMBERREST, "$memberdir/memberrest.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberrest.txt.rebuild", 1);
		@contents = <MEMBERREST>;
		fclose(MEMBERREST);
		chomp @contents;

		fopen(MEMBERCALC, "$memberdir/membercalc.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/membercalc.txt.rebuild", 1);
		$start_time = <MEMBERCALC>;
		$sumuser = <MEMBERCALC>;
		fclose(MEMBERCALC);
		chomp ($start_time, $sumuser);
	}
	if (! @contents) {
		# Get the list
		opendir(MEMBERS, $memberdir) || die "$txt{'230'} ($memberdir) :: $!";
		@contents = grep { /\.vars$/ } readdir(MEMBERS);
		closedir(MEMBERS);

		fopen(MEMBERREST, ">$memberdir/memberrest.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberrest.txt.rebuild", 1);
		foreach my $member (@contents) {
			chomp $member;
			$member =~ s/\.vars$//;
			print MEMBERREST "$member\n" if $member;
		}
		fclose(MEMBERREST);

		$sumuser = @contents;
		$start_time = $begin_time;
		fopen(MEMBERCALC, ">$memberdir/membercalc.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/membercalc.txt.rebuild", 1);
		print MEMBERCALC "$start_time\n";
		print MEMBERCALC "$sumuser\n";
		fclose(MEMBERCALC);

		$begin_time = $maxtime; # only first step
	} else {
		# Loop through each -rest- member
		while (@contents) {
			$member = pop @contents;
			chomp $member;
			$grpdel   = 0;
			$grpexist = '';
	
			# Load the user's info
			&UserCheck($member, "realname+email+regdate+position+addgroups+postcount");
			(@addigroups) = split(/\,/, $usercheck{'addgroups'});
			foreach $addigrp (@addigroups) {
				if (!exists $NoPost{$addigrp}) { $grpdel = 1; }
				else { $grpexist .= qq~$addigrp,~; }
			}
			$actposition = $usercheck{'position'};
			if (!exists $Group{$actposition} && !exists $NoPost{$actposition}) {
				$usercheck{'position'} = "";
				$grpdel = 1;
			}
			if ($grpdel) {
				if (!${$uid.$member}{'password'}) { &LoadUser($member); }
				$grpexist =~ s/,\Z//;
				${$uid.$member}{'addgroups'} = qq~$grpexist~;
				${$uid.$member}{'position'}  = $usercheck{'position'};
				&UserAccount($member, "update");
			}
			if (!$usercheck{'position'}) { $usercheck{'position'} = &MemberPostGroup($usercheck{'postcount'}); }
			$regtime = &stringtotime($usercheck{'regdate'});
			$memberlist{$member} = $regtime ? sprintf("%010d", $regtime) : &stringtotime($forumstart);
			$memberinf{$member}  = qq~$usercheck{'realname'}\|$usercheck{'email'}\|$usercheck{'position'}\|$usercheck{'postcount'}\|${$uid.$member}{'addgroups'}~;
	
			undef %{$uid.$member} if ($username ne $member);
			last if time > $begin_time + $maxtime;
		}
	}
	
	# Save what we've rebuilt so far
	fopen(MEMBERLIST, ">>$memberdir/memberlist.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberlist.txt.rebuild", 1);
	foreach (keys %memberlist) {print MEMBERLIST "$_\t$memberlist{$_}\n"};
	fclose(MEMBERLIST);

	fopen(MEMBERINFO, ">>$memberdir/memberinfo.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberinfo.txt.rebuild", 1);
	foreach (keys %memberinf) {print MEMBERINFO "$_\t$memberinf{$_}\n"};
	fclose(MEMBERINFO);

	fopen(MEMBERREST, ">$memberdir/memberrest.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberrest.txt.rebuild", 1);
	foreach (@contents) {print MEMBERREST "$_\n"};
	fclose(MEMBERREST);


	# See if we're completely done
	if(! @contents) {
	%memberlist=();
		# Sort memberlist.txt
		fopen(MEMBERLIST, "$memberdir/memberlist.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberlist.txt", 1);
		my %memberlist = map {split(/\t/, $_)} <MEMBERLIST>;
		fclose(MEMBERLIST);
		fopen(MEMBERLIST, ">$memberdir/memberlist.txt.rebuild") || &fatal_error('cannot_open', "$memberdir/memberlist.txt", 1);
#		print MEMBERLIST map {"$_\t$memberlist{$_}"} sort {$memberlist{$a} <=> $memberlist{$b}} keys %memberlist;
		foreach (sort {$memberlist{$a} <=> $memberlist{$b}} keys %memberlist) {print MEMBERLIST "$_\t$memberlist{$_}"};
		fclose(MEMBERLIST);

		# Move the updated copy back
		rename("$memberdir/memberlist.txt.rebuild", "$memberdir/memberlist.txt");
		rename("$memberdir/memberinfo.txt.rebuild", "$memberdir/memberinfo.txt");
		unlink("$memberdir/memberrest.txt.rebuild");
		unlink("$memberdir/membercalc.txt.rebuild");

		$regcounter = &MembershipCountTotal();
		$yymain .= qq~<b>$admin_txt{'594'} $regcounter $admin_txt{'594a'}</b>~;
		$yytitle     = "$admin_txt{'593'}";
		$action_area = "rebuildmemlist";
		&automaintenance("off");
		&AdminTemplate();
	}
	# Or prepare to continue looping
	else {
		$restuser = scalar @contents;
		$run_time = int(time-$start_time);
		$run_time ||= 1;
		$time_left = int($restuser/(($sumuser-$restuser+1)/$run_time));

		$hour= int($run_time/3600);
		$min = int(($run_time-$hour*3600)/60);
		$sec = $run_time - $hour*3600 - $min*60;
		$hour = "0$hour" if $hour<10; $min = "0$min" if $min<10; $sec = "0$sec" if $sec<10;

		$run_time = "$hour:$min:$sec";

		$hour= int($time_left/3600);
		$min = int(($time_left-$hour*3600)/60);
		$sec = $time_left - $hour*3600 - $min*60;
		$hour = "0$hour" if $hour<10; $min = "0$min" if $min<10; $sec = "0$sec" if $sec<10;

		$time_left = "$hour:$min:$sec";

		$yymain .= qq~
<br />
$rebuild_txt{'1'}
<br />
$rebuild_txt{'5'} $maxtime $rebuild_txt{'6'}
<br /><br />
$rebuild_txt{'10'} $sumuser
<br />
$rebuild_txt{'10a'} $restuser
<br />
<br />
$rebuild_txt{'7'} $run_time
<br />
$rebuild_txt{'8'} $time_left
<br />
<br />
<div id="memcontinued">
$rebuild_txt{'2'} <a href="$adminurl?action=rebuildmemlist" onclick="clearMeminfo();">$rebuild_txt{'3'}</a>
</div>
<script type="text/javascript" language="JavaScript">
<!--
	var convtext = "$rebuild_txt{'4'}";
	function clearMeminfo() {
		document.getElementById("memcontinued").innerHTML = convtext;
	}

	function membtick() {
		clearMeminfo();
		location.href="$adminurl?action=rebuildmemlist";
	}

setTimeout("membtick()", 1000)
// -->
</script>
~;
	&AdminTemplate();
	}
}

sub DeleteMultiMembers {
	&is_admin_or_gmod;
	my ($count, $currentmem, $start, $sortmode, $sortorder, $deadusers, @userslist);
	chomp $FORM{'button'};
	chomp $FORM{'emailsubject'};
	chomp $FORM{'emailtext'};
	$tmpemailsubject = $FORM{'emailsubject'};
	$tmpemailtext = $FORM{'emailtext'};
	if ($FORM{'button'} != 1 && $FORM{'button'} != 2) { &admin_fatal_error('no_access'); }
	
	if ($FORM{'del_mail'} || $FORM{'emailtext'} ne '') { require "$sourcedir/Mailer.pl"; }

	fopen(FILE, "$memberdir/memberlist.txt");
	@memnum = <FILE>;
	fclose(FILE);
	$count = 0;
	
	if ($FORM{'button'} == 1 && $FORM{'emailtext'} ne "") {
		$FORM{'emailsubject'} =~ s~\|~&#124~g;
		$FORM{'emailtext'}    =~ s~\|~&#124~g;
		$FORM{'emailtext'} =~ s/\r(?=\n*)//g;
		$mailline = qq~$date|$FORM{'emailsubject'}|$FORM{'emailtext'}|$username~;
		&MailList($mailline);
	}
	
	my $templanguage = $language;
	&getMailFiles;
	
	while (@memnum >= $count) {
		$currentmem = $FORM{"member$count"};
		if (exists $FORM{"member$count"}) {
			if (-e "$memberdir/$currentmem.vars") { # Bypass dead entries.
				&UserCheck($currentmem, "realname+email+language");
				if ($FORM{'emailtext'} ne '') {
					$emailsubject = $FORM{'emailsubject'};
					$emailtext = $FORM{'emailtext'};
					$emailsubject =~ s~\[name\]~$usercheck{'realname'}~ig;
					$emailsubject =~ s~\[username\]~$currentmem~ig;
					$emailtext =~ s~\[name\]~$usercheck{'realname'}~ig;
					$emailtext =~ s~\[username\]~$currentmem~ig;
					&sendmail($usercheck{'email'}, $emailsubject, $emailtext);
				} elsif ($FORM{'del_mail'}) {
					$language = $usercheck{'language'};
					&LoadLanguage('Email');
					my $message = &template_email($deleteduseremail, {'displayname' => $usercheck{'realname'}});
					&sendmail($usercheck{'email'}, "$deletedusersybject $mbname", $message, '', $emailcharset);
				}
			}
			if ($FORM{'button'} == 2) {
				unlink("$memberdir/$currentmem.dat");
				unlink("$memberdir/$currentmem.vars");
				unlink("$memberdir/$currentmem.ims");
				unlink("$memberdir/$currentmem.msg");
				unlink("$memberdir/$currentmem.log");
				unlink("$memberdir/$currentmem.rlog");
				unlink("$memberdir/$currentmem.outbox");
				unlink("$memberdir/$currentmem.imstore");
				unlink("$memberdir/$currentmem.imdraft");
				# save name up
				push (@userslist, $currentmem);
				#&MemberIndex("remove", $currentmem);
				# For security, remove username from mod position
				&KillModerator($currentmem);
			}
		}
		$count++;
	}
	if(@userslist)	{
		$deadusers = join(',', @userslist);
		&MemberIndex("remove", $deadusers);	
	}
	$language = $templanguage;
	if ($INFO{'start'} ne '') { $startmode = $INFO{'start'}; }
	if ($INFO{'sort'}  ne '') { $sortmode  = ";sort=" . $INFO{'sort'}; }
	if ($INFO{'order'}) { $sortorder = ";reversed=" . $INFO{'order'}; }

	if ($FORM{'button'} == 1) {
		$yySetLocation = qq~$adminurl?action=mailing;$sortmode~;
	} else {
		$yySetLocation = qq~$adminurl?action=viewmembers;start=$startmode$sortmode$sortorder~;
	}
	&redirectexit;
}

sub ml {
	&is_admin_or_gmod;
	require "$sourcedir/Mailer.pl";
	$FORM{'emails'} = "; " . $FORM{'emails'};
	$FORM{'emails'} =~ s/[\n\r]//g;
	@emails = split(/;\s*/, $FORM{'emails'});
	foreach $curmem (@emails) {
		&sendmail($curmem, "$mbname: $FORM{'subject'}", "$FORM{'message'}\n\n$admin_txt{'130'}\n\n$scripturl");
	}
	$yySetLocation = qq~$adminurl~;
	&redirectexit;
}

sub clean_log {
	&is_admin_or_gmod;

	# Overwrite with a blank file
	fopen(FILE, ">$vardir/log.txt");
	print FILE '';
	fclose(FILE);
	$yymain .= qq~<b>$admin_txt{'596'}</b>~;
	$yytitle     = "$admin_txt{'595'}";
	$action_area = "clean_log";
	&AdminTemplate;
	exit;
}

sub ipban {
	&is_admin_or_gmod;
	my (@banlist, $line, $tmp, @ipban, @emailban, @userban, $bantype, $eban, $iban, $uban);
	
	if (!-e "$vardir/ban.txt") {
		fopen(BANFILE, ">$vardir/ban.txt") || &admin_fatal_error('cannot_open', "$vardir/ban.txt", 1);
		print BANFILE "E|\n";
		print BANFILE "I|\n";
		print BANFILE "U|\n";
		fclose(BANFILE);
	}

	fopen(FILE, "$vardir/ban.txt") || &admin_fatal_error('cannot_open', "$vardir/ban.txt", 1);
	@banlist = <FILE>;
	fclose(FILE);
	foreach $line (@banlist) {
		chomp $line;
		($bantype, $tmp) = split(/\|/, $line);
		if ($bantype eq 'I') { $iban = $tmp; }
		if ($bantype eq 'E') { $eban = $tmp; }
		if ($bantype eq 'U') { $uban = $tmp; }
	}
	$iban =~ s/\,/\n/g;
	$eban =~ s/\,/\n/g;
	$uban =~ s/\,/\n/g;
	$yymain .= qq~
<form action="$adminurl?action=ipban2" method="post">
 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg">
		<img src="$imagesdir/ban.gif" alt="" border="0" /><b>$admin_txt{'340'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="catbg"><span class="small">
			$admin_txt{'724'}
		 </span>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="center" class="windowbg2"><br />
		<textarea cols="60" rows="10" name="ban" style="width: 95%">$iban</textarea><br /><br />
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="catbg"><span class="small">
			$admin_txt{'725'}
		 </span>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="center" class="windowbg2"><br />
		<textarea cols="60" rows="10" name="ban_email" style="width: 95%">$eban</textarea><br /><br />
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="catbg"><span class="small">
			$admin_txt{'725a'}
		 </span>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="center" class="windowbg2"><br />
		<textarea cols="60" rows="10" name="ban_memname" style="width: 95%">$uban</textarea><br /><br />
	   </td>
     </tr>
     <tr valign="middle">
       <td align="center" class="catbg">
		 <input type="submit" value="$admin_txt{'10'}" class="button" />
	   </td>
     </tr>
   </table>
 </div>
</form>
~;
	$yytitle     = "$admin_txt{'340'}";
	$action_area = "ipban";
	&AdminTemplate;
	exit;
}

sub ipban2 {
	&is_admin_or_gmod;
	$FORM{'ban'} =~ tr/\r//d;
	$FORM{'ban'} =~ s/ //g;
	$FORM{'ban'} =~ s~\A[\s\n]+~~;
	$FORM{'ban'} =~ s~[\s\n]+\Z~~;
	$FORM{'ban'} =~ s~\n\s*\n~\n~g;
	$FORM{'ban'} =~ s/\n/\,/g;
	$FORM{'ban_email'} =~ s/ //g;
	$FORM{'ban_email'} =~ tr/\r//d;
	$FORM{'ban_email'} =~ s~\A[\s\n]+~~;
	$FORM{'ban_email'} =~ s~[\s\n]+\Z~~;
	$FORM{'ban_email'} =~ s~\n\s*\n~\n~g;
	$FORM{'ban_email'} =~ s/\n/\,/g;
	$FORM{'ban_memname'} =~ s/ //g;
	$FORM{'ban_memname'} =~ tr/\r//d;
	$FORM{'ban_memname'} =~ s~\A[\s\n]+~~;
	$FORM{'ban_memname'} =~ s~[\s\n]+\Z~~;
	$FORM{'ban_memname'} =~ s~\n\s*\n~\n~g;
	$FORM{'ban_memname'} =~ s/\n/\,/g;

	fopen(BANFILE, ">$vardir/ban.txt", 1);
	print BANFILE "E|$FORM{'ban_email'}\n";
	print BANFILE "I|$FORM{'ban'}\n";
	print BANFILE "U|$FORM{'ban_memname'}\n";
	fclose(BANFILE);

	$yySetLocation = qq~$adminurl~;
	&redirectexit;
}

sub ipban_update {
	# This is for quick updating for banning + unbanning
	&is_admin_or_gmod;
	
	if (!-e "$vardir/ban.txt") {
		fopen(BANFILE, ">$vardir/ban.txt") || &admin_fatal_error('cannot_open', "$vardir/ban.txt", 1);
		print BANFILE "E|\n";
		print BANFILE "I|\n";
		print BANFILE "U|\n";
		fclose(BANFILE);
	}
	
	if ($INFO{'ban'}) { $ban_details = $INFO{'ban'}; $ban_t = 'I'; }
	if ($INFO{'ban_email'}) { $ban_details = $INFO{'ban_email'}; $ban_t = 'E'; }
	if ($INFO{'ban_memname'}) {
		if ($do_scramble_id){ $name = &decloak($INFO{'ban_memname'}); } else { $name = $INFO{'ban_memname'}; }
		$ban_details = $name; $ban_t = 'U';
	}

	if ($INFO{'unban'} eq 1) {
		# Make sure there are no dupes before writing, sort for neatness too
		fopen(BANFILE, "+<$vardir/ban.txt", 1) || &admin_fatal_error('cannot_open', "$vardir/ban.txt", 1);
		@allbans = <BANFILE>;
		foreach $line (@allbans) {
			my @banned = ();
			chomp $line;
			my ($bantype, $bannedlst) = split(/\|/, $line);
			my $newlinne = qq~$bantype|~;
			@banned = split(/\,/, $bannedlst);
			foreach my $banned (@banned) {
				chomp $banned;
				if ($banned ne $ban_details) { $newlinne .= qq~$banned,~; }
			}
			$newlinne =~ s/,\Z//;
			push (@newallbans, "$newlinne\n");
		}
		seek BANFILE, 0, 0;
		truncate BANFILE, 0;
		print BANFILE @newallbans;
		fclose(BANFILE);
	} else {
		# Make sure there are no dupes before writing, sort for neatness too
		fopen(BANFILE, "+<$vardir/ban.txt", 1) || &admin_fatal_error('cannot_open', "$vardir/ban.txt", 1);
		@allbans = <BANFILE>;
		foreach $line (@allbans) {
			my @banned = ();
			chomp $line;
			my ($bantype, $bannedlst) = split(/\|/, $line);
			my (@bannedlst) = split(/\,/, $bannedlst);
			$newlinne = qq~$bantype|~;
			if ($bantype eq $ban_t) {
				push (@bannedlst, $ban_details);
				$newbannedlst = join (',', @bannedlst);
				$newlinne .= $newbannedlst;
				push (@newallbans, "$newlinne\n");
			} else {
				push (@newallbans, "$line\n");
			}
		}
		seek BANFILE, 0, 0;
		truncate BANFILE, 0;
		print BANFILE @newallbans;
		fclose(BANFILE);
	}
	$yySetLocation = qq~$scripturl?action=viewprofile;username=$INFO{'username'}~;
	&redirectexit;
}



sub ver_detail {
	&is_admin_or_gmod;

	require "$boarddir/YaBB.$yyext";
	$YaBBplver =~ s/\$Revision\: (.*?) \$/Build $1/ig;
	
	$yymain .= qq~
	<div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
	<table width="100%" cellspacing="1" cellpadding="4">
	<tr valign="middle">
			<td align="left" class="titlebg" colspan="3"><img src="$imagesdir/info.gif" alt="" border="0" /><b>$admin_txt{'429'}</b></td>
     </tr>
	<tr valign="middle">
		<td align="left" class="windowbg2" colspan="3">
		<script language="javascript" src="http://www.yabbforum.com/update/versioncheck.js" type="text/javascript"></script>
		$versiontxt{'4'} <b>$YaBBversion</b><br />
		<script language="JavaScript" type="text/javascript">  
		<!-- //hide from dinosaurs  
			document.write("$versiontxt{'5'} <b>"+STABLE+"</b><br />$versiontxt{'7'} <b>"+BETA+"</b>");  
		// -->
		</script>
		<noscript>$versiontxt{'1'} <img src="http://www.yabbforum.com/images/version/versioncheck.gif" alt="" /></noscript> 
	</td>
	</tr>
	<tr valign="middle">
		<td align="center" class="catbg" width="40%"><b>$admin_txt{'495'}</b><br /></td>
		<td align="center" class="catbg" width="60%"><b>$admin_txt{'494'}</b><br /></td>
	</tr>
	<tr>
		<td class="windowbg2" align="left">$admin_txt{'496'}</td>
		<td class="windowbg2" align="left"><i>$YaBBversion</i></td>
	</tr><tr>
		<td class="windowbg2" align="left">YaBB.$yyext</td>
		<td class="windowbg2" align="left"><i>$YaBBplver</i></td>
	</tr><tr>
		<td class="windowbg2" align="left">AdminIndex.pl</td>
		<td class="windowbg2" align="left"><i>$adminindexplver</i></td>
	</tr>
~;

	opendir(LNGDIR, $langdir);
	my @lfilesanddirs = readdir(LNGDIR);
	close(LNGDIR);
	foreach $fld (@lfilesanddirs) {
		if (-d "$langdir/$fld" && $fld =~ m^\A[0-9a-zA-Z_\#\%\-\:\+\?\$\&\~\,\@/]+\Z^ && -e "$langdir/$fld/Main.lng") {
			fopen(FILE, "$langdir/$fld/version.txt");
			my @ver = <FILE>;
			fclose(FILE);
			$yymain .= qq~
			<tr>
				<td width="30%" class="windowbg2" align="left">$fld Language Pack</td>
				<td width="35%" class="windowbg2" align="left"><i>$ver[0]</i></td>
			</tr>
			~;
		}
	}
	$yymain .= qq~
	<tr valign="middle">
			<td align="left" class="titlebg" colspan="3"><b>$admin_txt{'430'}</b></td>
     </tr>
	~;	
	opendir(DIR, $admindir);
	my @adminDIR = readdir(DIR);
	close(DIR);
	@adminDIR = sort (@adminDIR);
	foreach my $fileinDIR (@adminDIR) {
		chomp $fileinDIR;
		if ($fileinDIR =~ m/\.pl\Z/) {
			require "$admindir/$fileinDIR";
			my $txtrevision = lc $fileinDIR;
			$txtrevision =~ s/\.pl/plver/ig;
			$$txtrevision =~ s/\$Revision\: (.*?) \$/Build $1/ig;
			$yymain .= qq~
			<tr>
				<td class="windowbg2" align="left">$fileinDIR</td>
				<td class="windowbg2" align="left"><i>$$txtrevision</i></td>
			</tr>
			~;
		}
	}
	$yymain .= qq~
	<tr valign="middle">
			<td align="left" class="titlebg" colspan="3"><b>$admin_txt{'431'}</b></td>
     </tr>
	~;	
	opendir(DIR, $sourcedir);
	my @sourceDIR = readdir(DIR);
	close(DIR);
	@sourceDIR = sort (@sourceDIR);
	foreach my $fileinDIR (@sourceDIR) {
		chomp $fileinDIR;
		if ($fileinDIR =~ m/\.pl\Z/) {
			require "$sourcedir/$fileinDIR";
			my $txtrevision = lc $fileinDIR;
			$txtrevision =~ s/\.pl/plver/ig;
			$$txtrevision =~ s/\$Revision\: (.*?) \$/Build $1/ig;
			$yymain .= qq~
			<tr>
				<td class="windowbg2" align="left">$fileinDIR</td>
				<td class="windowbg2" align="left"><i>$$txtrevision</i></td>
			</tr>
			~;
		}
	}

	$yymain .= qq~
   </table>
 </div>
~;
	$yytitle = $admin_txt{'429'};
	$action_area = "detailedversion";
	&AdminTemplate;
	exit;
}

sub Refcontrol {
	&is_admin_or_gmod;
	&LoadLanguage('RefControl');
	fopen(FILE, "$sourcedir/SubList.pl");
	@scriptlines = <FILE>;
	fclose(FILE);
	fopen(FILE, "$vardir/allowed.txt");
	@allowed = <FILE>;
	fclose(FILE);
	$startread = 0;
	$counter   = 0;

	foreach $scriptline (@scriptlines) {
		chomp $scriptline;
		if (substr($scriptline, 0, 1) eq "'") {
			$scriptline =~ /\'(.*?)\'/;
			$actionfound = $1;
			push(@actfound, $actionfound);
			$counter++;
		}
	}
	$column  = int($counter / 3);
	$counter = 0;
	foreach $actfound (@actfound) {
		$selected = "";
		foreach $allow (@allowed) {
			chomp $allow;
			if ($actfound eq $allow) { $selected = ' checked="checked"'; last; }
		}
		$refexpl_txt{$actfound} =~ s/"/'/g; # XHTML Validation
		$dismenu .= qq~<input type="checkbox" name="$actfound"$selected />&nbsp;<img src="$imagesdir/question.gif" align="middle" alt="$reftxt{'1a'} $refexpl_txt{$actfound}" title="$reftxt{'1a'} $refexpl_txt{$actfound}" border="0" /> $actfound<br />\n~;
		$counter++;
		if ($counter > $column + 1) {
			$dismenu .= qq~</td><td align="left" class="windowbg2" valign="top" width="33%">~;
			$counter = 0;
		}
	}
	$yymain  .= qq~
<form action="$adminurl?action=referer_control2" method="post">
 <div class="bordercolor" style="padding: 0px; width: 99%; margin-left: 0px; margin-right: auto;">
   <table width="100%" cellspacing="1" cellpadding="4">
     <tr valign="middle">
       <td align="left" class="titlebg" colspan="3">
<img src="$imagesdir/preferences.gif" alt="" border="0" /><b>$reftxt{'1'}</b>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2" colspan="3"><br />
		$reftxt{'2'}<br />
	  <span class="small">
		<i>$reftxt{'3'}</i><br /><br />
	  </span>
	   </td>
     </tr>
     <tr valign="middle">
       <td align="left" class="windowbg2" valign="top" width="33%">
		$dismenu
	   </td>
     </tr>
     <tr valign="middle">
       <td align="center" class="catbg" colspan="3">
		<input type="submit" value="$reftxt{'4'}" class="button" />
	   </td>
     </tr>
   </table>
 </div>
</form>
~;
	$yytitle     = "$reftxt{'1'}";
	$action_area = "referer_control";
	&AdminTemplate;
	exit;
}

sub Refcontrol2 {
	&is_admin_or_gmod;
	fopen(FILE, "$sourcedir/SubList.pl");
	@scriptlines = <FILE>;
	fclose(FILE);
	$startread = 0;
	$counter   = 0;
	foreach $scriptline (@scriptlines) {
		chomp $scriptline;
		if (substr($scriptline, 0, 1) eq "'") {
			$scriptline =~ /\'(.*?)\'/;
			$actionfound = $1;
			push(@actfound, $actionfound);
			$counter++;
		}
	}
	foreach $actfound (@actfound) {
		if ($FORM{$actfound}) { push(@outfile, "$actfound\n"); }
	}

	fopen(FILE, ">$vardir/allowed.txt");
	print FILE @outfile;
	fclose(FILE);
	$yySetLocation = qq~$adminurl~;
	&redirectexit;
}

sub AddMember {
	&is_admin_or_gmod;
	&LoadLanguage('Register');
	if ($regcheck) {
		require "$sourcedir/Decoder.pl";
		&validation_code;
	}
	$yymain .= qq~
<form action="$adminurl?action=addmember2" method="post" name="creator"> 
<table align="center" border="0" cellspacing="1" cellpadding="3" class="bordercolor">
  <tr>
	<td colspan="2" width="100%" valign="middle" class="titlebg">
	<img src="$imagesdir/register.gif" alt="" border="0" style="vertical-align: middle;" /><b> $admintxt{'17a'}</b>
	</td>
  </tr><tr>
	<td width="30%" class="windowbg"><b>$register_txt{'98'}:</b></td>
	<td width="70%" class="windowbg"><input type="text" name="regusername" size="30" maxlength="18" /><input type="hidden" name="_session_id_" id="_session_id_" value="$sessionid" /><input type="hidden" name="regdate" id="regdate" value="$regdate" /></td>
  </tr><tr>
	<td width="30%" class="windowbg"><b>$register_txt{'98a'}:</b></td>
	<td width="70%" class="windowbg"><input type="text" name="regrealname" size="30" maxlength="18" /></td>
  </tr><tr>
	<td width="30%" class="windowbg"><b>$register_txt{'69'}:</b></td>
	<td width="70%" class="windowbg"><input type="text" maxlength="40" name="email" size="50" /></td>
  </tr>~;
	if ($allow_hide_email == 1) {
		$yymain .= qq~
  <tr>
	<td width="30%" class="windowbg"><b>$register_txt{'721'}</b></td>
	<td width="70%" class="windowbg"><input type="checkbox" name="hideemail" value="checked" /></td>
  </tr>
~;
	}
	$yymain .= qq~
~;
	unless ($emailpassword) {
		$yymain .= qq~
	<tr>
		<td width="30%" class="windowbg"><b>$register_txt{'81'}:</b></td>
		<td width="70%" class="windowbg"><input type="password" maxlength="30" name="passwrd1" size="30" /></td>
	</tr><tr>
		<td width="30%" class="windowbg"><b>$register_txt{'82'}:</b></td>
		<td width="70%" class="windowbg"><input type="password" maxlength="30" name="passwrd2" size="30" /></td>
	</tr>
~;
	}

	if ($regcheck) {
		$yymain .= qq~
	<tr>
		<td width="30%" class="windowbg"><b>$floodtxt{'1'}:</b></td>
		<td width="70%" class="windowbg">$showcheck<br /><span class="small">$floodtxt{'casewarning'}</span></td>
	</tr><tr>
		<td width="30%" class="windowbg"><b>$floodtxt{'3'}:</b></td>
		<td width="70%" class="windowbg"><input type="text" maxlength="30" name="verification" id="verification" size="30" /></td>
	</tr>
~;
	}

	$yymain .= qq~
  <tr>
	<td colspan="2" align="center" class="catbg">
		<input type="submit" value="$register_txt{'97'}" class="button" />
	</td>
</tr>
</table>
</form>
~;

	$yymain .= qq~


<script type="text/javascript" language="JavaScript"> <!--
	document.creator.regusername.focus();
	//function 
//--> </script>
~;
	$yytitle     = "$register_txt{'97'}";
	$action_area = "addmember";
	&AdminTemplate;
	exit;
}

sub AddMember2 {
	&is_admin_or_gmod;
	&LoadLanguage('Register');
	&LoadLanguage('Main');
	my %member;
	while (($key, $value) = each(%FORM)) {
		$value =~ s~\A\s+~~;
		$value =~ s~\s+\Z~~;
		$value =~ s~[\n\r]~~g;
		$member{$key} = $value;
	}
	$member{'username'} =~ s/\s/_/g;

	# check if there is a system hash named like this by checking existence through size
	my $hsize = keys(%{ $member{'regusername'} });
	if ($hsize > 0) { &admin_fatal_error("system_prohibited_id"); }
	if (length($member{'regusername'}) > 25) { $member{'regusername'} = substr($member{'regusername'}, 0, 25); }
	&admin_fatal_error("no_username","($member{'regusername'})") if ($member{'regusername'} eq '');
	&admin_fatal_error("id_alfa_only","($member{'regusername'})") if ($member{'regusername'} eq '_' || $member{'regusername'} eq '|');
	&admin_fatal_error("id_reserved","($member{'regusername'})") if ($member{'regusername'} =~ /guest/i);
	&admin_fatal_error("invalid_character","$register_txt{'35'} $register_txt{'241'}") if ($member{'regusername'} !~ /\A[0-9A-Za-z#%+-\.@^_]+\Z/);
	&admin_fatal_error("invalid_character","$register_txt{'35'} $register_txt{'241'}") if ($member{'regusername'} =~ /,/);
	&admin_fatal_error("no_email","($member{'regusername'})")                          if ($member{'email'} eq "");
	&admin_fatal_error("id_taken","($member{'regusername'})")                          if (-e ("$memberdir/$member{'regusername'}.vars"));
	&admin_fatal_error("password_is_userid")                                           if ($member{'regusername'} eq $member{'passwrd1'});

	if ($regcheck) {
		require "$sourcedir/Decoder.pl";
		&validation_check($FORM{'verification'});
	}

	if ($emailpassword) {
		srand();
		$member{'passwrd1'} = int(rand(100));
		$member{'passwrd1'} =~ tr/0123456789/ymifxupbck/;
		$_ = int(rand(77));
		$_ =~ tr/0123456789/q8dv7w4jm3/;
		$member{'passwrd1'} .= $_;
		$_ = int(rand(89));
		$_ =~ tr/0123456789/y6uivpkcxw/;
		$member{'passwrd1'} .= $_;
		$_ = int(rand(188));
		$_ =~ tr/0123456789/poiuytrewq/;
		$member{'passwrd1'} .= $_;
		$_ = int(rand(65));
		$_ =~ tr/0123456789/lkjhgfdaut/;
		$member{'passwrd1'} .= $_;
	} else {
		&admin_fatal_error("password_mismatch","($member{'regusername'})") if ($member{'passwrd1'} ne $member{'passwrd2'});
		&admin_fatal_error("no_password","($member{'regusername'})") if ($member{'passwrd1'} eq '');
		&admin_fatal_error("invalid_character","$register_txt{'36'} $register_txt{'241'}") if ($member{'passwrd1'} !~ /\A[\s0-9A-Za-z!@#$%\^&*\(\)_\+|`~\-=\\:;'",\.\/?\[\]\{\}]+\Z/);
	}
	&admin_fatal_error("invalid_character","$register_txt{'69'} $register_txt{'241'}") if ($member{'email'} !~ /[\w\-\.\+]+\@[\w\-\.\+]+\.(\w{2,4}$)/);
	&admin_fatal_error("invalid_email") if (($member{'email'} =~ /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)|(\.$)/) || ($member{'email'} !~ /\A.+@\[?(\w|[-.])+\.[a-zA-Z]{2,4}|[0-9]{1,4}\]?\Z/));
	fopen(FILE, "$vardir/ban_email.txt");
	@banned = <FILE>;
	fclose(FILE);
	foreach $curban (@banned) {
		if ($member{'email'} eq "$curban") { &admin_fatal_error("banned","$register_txt{'678'}$register_txt{'430'}!"); }
	}

	if (lc $member{'regusername'} eq lc &MemberIndex("check_exist", $member{'regusername'})) { &admin_fatal_error("id_taken","($member{'regusername'})"); }
	if (lc $member{'email'} eq lc &MemberIndex("check_exist", $member{'email'})) { &admin_fatal_error("email_taken","($member{'email'})"); }
	if (lc $member{'regrealname'} eq lc &MemberIndex("check_exist", $member{'regrealname'})) { &admin_fatal_error("name_taken","($member{'regrealname'})"); }

	if ($name_cannot_be_userid && lc $member{'regusername'} eq lc $member{'regrealname'}) { &admin_fatal_error("name_is_userid"); }

	&ToHTML($member{'email'});

	fopen(RESERVE, "$vardir/reserve.txt") || &admin_fatal_error("cannot_open","$vardir/reserve.txt", 1);
	@reserve = <RESERVE>;
	fclose(RESERVE);
	fopen(RESERVECFG, "$vardir/reservecfg.txt") || &admin_fatal_error("cannot_open","$vardir/reservecfg.txt", 1);
	@reservecfg = <RESERVECFG>;
	fclose(RESERVECFG);
	for ($a = 0; $a < @reservecfg; $a++) {
		chomp $reservecfg[$a];
	}
	$matchword = $reservecfg[0] eq 'checked';
	$matchcase = $reservecfg[1] eq 'checked';
	$matchuser = $reservecfg[2] eq 'checked';
	$matchname = $reservecfg[3] eq 'checked';
	$namecheck = $matchcase eq 'checked' ? $member{'regusername'} : lc $member{'regusername'};
	$realnamecheck = $matchcase eq 'checked' ? $member{'regrealname'} : lc $member{'regrealname'};

	foreach $reserved (@reserve) {
		chomp $reserved;
		$reservecheck = $matchcase ? $reserved : lc $reserved;
		if ($matchuser) {
			if ($matchword) {
				if ($namecheck eq $reservecheck) { &admin_fatal_error('id_reserved',"$reserved"); }
			} else {
				if ($namecheck =~ $reservecheck) { &admin_fatal_error('id_reserved',"$reserved"); }
			}
		}
		if ($matchname) {
			if ($matchword) {
				if ($realnamecheck eq $reservecheck) { &admin_fatal_error('name_reserved',"$reserved"); }
			} else {
				if ($realnamecheck =~ $reservecheck) { &admin_fatal_error('name_reserved',"$reserved"); }
			}
		}
	}

	&admin_fatal_error("id_taken") if (-e ("$memberdir/$member{'username'}.vars"));

	if ($send_welcomeim == 1) {
		# new format msg file:
		# messageid|(from)user|(touser(s))|(ccuser(s))|(bccuser(s))|subject|date|message|(parentmid)|reply#|ip|messagestatus|flags|storefolder|attachment
		$messageid = $^T . $$;
		fopen(IM, ">$memberdir/$member{'regusername'}.msg", 1);
		print IM "$messageid|$sendname|$member{'regusername'}|||$imsubject|$date|$imtext|$messageid|0|$ENV{'REMOTE_ADDR'}|s|u||\n";
		fclose(IM);
	}
	$encryptopass = &encode_password($member{'passwrd1'});
	$reguser      = $member{'regusername'};
	$registerdate = timetostring($date);

	if ($default_template) { $new_template = $default_template; }
	else { $new_template = "default"; }

	${$uid.$reguser}{'password'}      = $encryptopass;
	${$uid.$reguser}{'realname'}      = $member{'regrealname'};
	${$uid.$reguser}{'email'}         = lc($member{'email'});
	${$uid.$reguser}{'postcount'}     = 0;
	${$uid.$reguser}{'usertext'}      = $defaultusertxt;
	${$uid.$reguser}{'userpic'}       = "blank.gif";
	${$uid.$reguser}{'regdate'}       = $registerdate;
	${$uid.$reguser}{'regtime'}       = int(time);
	${$uid.$reguser}{'timeselect'}    = $timeselected;
	${$uid.$reguser}{'timeoffset'}    = $timeoffset;
	${$uid.$reguser}{'dsttimeoffset'} = $dstoffset;
	${$uid.$reguser}{'hidemail'}      = $FORM{'hideemail'};
	${$uid.$reguser}{'timeformat'}    = qq~MM D+ YYYY @ HH:mm:ss*~;
	${$uid.$reguser}{'template'}      = $new_template;
	${$uid.$reguser}{'language'}      = $language;
	${$uid.$reguser}{'pageindex'}     = qq~1|1|1~;

	&UserAccount($reguser, "register") & MemberIndex("add", $reguser) & FormatUserName($reguser);

	if ($emailpassword) {
		require "$sourcedir/Mailer.pl";
		&sendmail($member{'email'}, "$register_txt{'700'} $mbname", "$register_txt{'248'} $member{'regusername'}!\n\n$register_txt{'719'} $member{'regusername'}, $register_txt{'492'} $member{'passwrd1'}\n\n$register_txt{'701'}\n$scripturl?action=profile;username=$useraccount{$member{'regusername'}}\n\n$register_txt{'130'}");
	} else {
		if ($emailwelcome) {
			require "$sourcedir/Mailer.pl";
			&sendmail($member{'email'}, "$register_txt{'700'} $mbname", "$register_txt{'248'} $member{'regusername'}!\n\n$register_txt{'719'} $member{'regusername'}, $register_txt{'492'} $member{'passwrd1'}\n\n$register_txt{'701'}\n$scripturl?action=profile;username=$useraccount{$member{'regusername'}}\n\n$register_txt{'130'}");
		}

	}

	$yytitle       = "$register_txt{'245'}";
	$yymain        = "$register_txt{'245'}";
	$yySetLocation = qq~$adminurl?action=viewmembers;sort=regdate;reversed=on;start=0~;
	&redirectexit;
	$action_area = "addmember";
	&AdminTemplate;
}

sub startTraceFile	{
	&is_admin_or_gmod;
	
	fopen("TRACEFILE", "+>$vardir/tracefile.txt");	
	print TRACEFILE "###############################################################################";
	print TRACEFILE "Tracefile for $mbname, started ";
	print TRACEFILE "###############################################################################";
	fclose("TRACEFILE");	
}

1;
