&InitImportantStuff;

sub InitImportantStuff {

	# Remember, altering the powered-by notice is a
	# violation of the UBB license agreement, and a fairly
	# easy to spot one at that.

	$version        = "6.1.0 Public Beta 1.4";
	$version_number = "6R1R0";
	$release_j      = "2452139";
	$trademark      = qq(<font style='font-size: 8px' size='1'><sup><b>TM</b></sup></font>);
	$trade          = "™";
	if ($vars_display{showcopytype} eq 'image') {
		$InfopopCopyright = qq!!;
	} else {
		$InfopopCopyright = qq!Powered by ???!;
	}

	$InfopopCopyright .= qq% %;

	$masterCharset = $vars_display{masterCharset};
	$masterCharset = "ISO-8859-1" unless $masterCharset;

	# weights: used for member ratings
	%weights = (
		0 => "0.15",
		1 => "0.05",
		2 => "0.08",
		3 => "0.12",
		4 => "0.25",
		5 => "0.35"
	);
}    #endsub

sub list_check {

	# $_[0]: user number of member you are checking

	# used to see if particular member
	# is on ignore or buddy list
	$_[0] = &Do8Digit($_[0]);
	local ($list_add);

	if (-e "$vars_config{MembersPath}/pm_ignore/$user_number.cgi") {
		&RequireVars("$vars_config{MembersPath}/pm_ignore/$user_number.cgi");
	}

	if (-e "$vars_config{MembersPath}/pm_buddy/$user_number.cgi") {
		&RequireVars("$vars_config{MembersPath}/pm_buddy/$user_number.cgi");
	}

	unless (exists($pm_ignore{$_[0]})) {
		$list_add = qq~<a href="javascript:ignore();">$vars_wordlets{ignore_user}</a>~;

	}
	else {
		$list_add = "$vars_wordlets{user_on_ignore}";
	}

	unless (exists($pm_buddy{$_[0]})) {
		if ($list_add ne '') { $list_add .= ' | '; }
		$list_add .= qq~<a href="javascript:buddy();">$vars_wordlets{make_buddy}</a>~;
	}
	else {
		if ($list_add ne '') { $list_add .= ' | '; }
		$list_add .= "$vars_wordlets{user_on_buddy}";
	}

	return ($list_add);
}    # end list check

sub get_public_name {
	my @this_user = &OpenProfile($_[0]);
	chomp($this_user[15]);
	chomp($this_user[0]);
	my $this_public_name = $this_user[15];
	if ($this_public_name eq '') { $this_public_name = $this_user[0]; }
	return ($this_public_name);
}

sub get_rating {

	# %votes, %total, %avg, %weighted_avg should be prevously declared
	local ($the_rating);
	my $this_member = &Do8Digit($_[0]);
	undef(%weighted_avg);
	undef(%votes);

	if ((-s "$vars_config{MembersPath}/user_ratings/$this_member.cgi") && ($this_member ne '')) {
		do "$vars_config{MembersPath}/user_ratings/$this_member.cgi";
		$the_rating = $weighted_avg{total};
		$the_rating = &round_up($the_rating);
	} else {
		$the_rating = '';
	}
	return ($the_rating, $votes{total});
}    # end get_rating

sub round_up {
	my ($whole, $dec) = split (/\./, $_[0]);
	if ($dec > 49) { $whole++; }
	return ($whole);
}

sub Do2Decimal {
	$_[0] = sprintf("%3.2f", $_[0]);
	return ($_[0]);
}

sub user_access {
	local ($f, @profile, $this_user_access, $j, $perms, @permitted);
	($f, @profile) = @_;

	($j, $perms) = split (/&/, $profile[4]);
	chomp($perms);
	@permitted = split (/\,/, $perms);

	foreach (@permitted) {
		if ($_ eq "$f") {
			$this_user_access = 'true';
			last;
		} else {
			$this_user_access = 'false';
		}
	}

	if (!$this_user_access) {    #if the poor sap STILL isn't in...

		# check to see if forumpw cookie set:
		my $forumpw = cookie("forumpw$vars_config{Cookie_Number}");
		my %pwhash  = split (/\|\^\|/, $forumpw);

		my @foruminfo = GetForumRecord($f);

		# pw hash check
		if ((exists($pwhash{$f})) && ($pwhash{$f} eq $foruminfo[12])) {
			$this_user_access = "true";
		} else {
			$this_user_access = "false";
		}    #endunless
	}    #endif


	return ($this_user_access);
}    # end user_access

sub is_admin_or_mod {
	local ($f, @profile, $Moderator, @mods, $mod_name, $mod_num, $mod_match, $is_one, @mod_profile);
	($f, @profile) = @_;
	chomp($profile[8]);
	chomp($profile[0]);

	if ($profile[8] eq 'Administrator') {
		$is_one = 'true';
	} elsif ($profile[8] eq 'Moderator') {

		if ($f ne 'ALL') {

			# check to see if user is moderator of particular forum

			# check if moderator
			&RequireVars("$vars_config{VariablesPath}/vars_mods.cgi");

			$Moderator = ("Forum" . "$f" . "Moderator");
			$Moderator = $$Moderator;

			#split up Mod var
			@mods = split (/\|\|\^\|\|/, $Moderator);

			@mod_profile = ();
			foreach (@mods) {
				chomp($_);
				if (-s "$vars_config{MembersPath}/$_.cgi") {
					@mod_profile = &OpenProfile($_);
					chomp($mod_profile[0]);

					if ($mod_profile[0] eq $profile[0]) {
						$mod_match = 'true';
					}
				}
			}

			if ($mod_match ne 'true') {
				$is_one = 'false';
			} else {
				$is_one = 'true';
			}

		} else {

			# this is just to see if user is a mod of any forum
			$is_one = 'true';

		}

	} else {

		$is_one = 'false';
	}

	return ($is_one);
}    # is_admin_or_mod


sub Smilies {
	if (exists $vars_graemlins->{'graems'}) {
		$_[0] = &CustomGraemlins($_[0]);
	} else {
		&RequireVars("$vars_config{VariablesPath}/vars_graemlins.cgi");
		$_[0] = &CustomGraemlins($_[0]);
	}

	return ($_[0]);
}


sub check_html {
	if ($_[0] =~ /\/\s*SCRIPT\s*>/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag}: SCRIPT");
		exit(0);
	}

	if ($_[0] =~ /<\s*EMBED\s*?>/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} EMBED");
		exit(0);
	}
	if ($_[0] =~ /<\s*OBJECT\s*?>/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} OBJECT");
		exit(0);
	}

	if ($_[0] =~ /<\s*IFRAME\s*?>/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} IFRAME");
		exit(0);
	}

	if ($_[0] =~ /<\s*FORM\s*?>/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} FORM");
		exit(0);
	}

	if ($_[0] =~ /<\s*XMP\s*?>/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} XMP");
		exit(0);
	}

	if ($_[0] =~ /<\s*APPLET\s*?>/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} APPLET");
		exit(0);
	}
	if ($_[0] =~ /<\s*BODY\s*?>/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} BODY");
		exit(0);
	}

	if ($_[0] =~ /<\s*HEAD\s*?>/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} HEAD");
		exit(0);
	}
	if ($_[0] =~ /<\s*HTML\s*?>/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} HTML");
		exit(0);
	}

	if ($_[0] =~ /ONLOAD\s*=/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} ONLOAD");
		exit(0);
	}
	if ($_[0] =~ /ONCLICK\s*=/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} ONCLICK");
		exit(0);
	}
	if ($_[0] =~ /MOUSEOVER\s*=/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} MOUSEOVER");
		exit(0);
	}

	if ($_[0] =~ /ONERROR\s*=/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} ONERROR");
		exit(0);
	}
	if ($_[0] =~ /\.cookie/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} COOKIE");
		exit(0);
	}

	if ($_[0] =~ /getcookie/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} GETCOOKIE");
		exit(0);
	}
	if ($_[0] =~ /(<)([^>]*?)(\()/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} Parenthesis in HTML tag");
		exit(0);
	}

	if ($_[0] =~ /eval\s*\(/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} EVAL");
		exit(0);
	}

}    # end check for script

sub Truncate {
	$vars_misc{stringLengthLimit} = 180 unless $vars_misc{stringLengthLimit};
	$_[0] =~ s/(\S{$vars_misc{stringLengthLimit}})/$1 /isg;
	return ($_[0]);
}

sub PipeCleaner {
	$_[0] =~ s/\|\|/&#0124;&#0124;/sg;
	return ($_[0]);
}

sub GetPubName {
	local (@user_p);
	@user_p = &OpenProfile($_[0]);
	chomp($user_p[15]);
	chomp($user_p[0]);
	if ($user_p[15] eq '') { $user_p[15] = $user_p[0]; }
	return ($user_p[15]);
}    # get pub name


sub GetUserNumber {
	local ($MatchName, $ThisProfileNumber);

	# $_[0] : Member Login Name

	my $GetNameClean = quotemeta($_[0]);

	# Note: %ProfileNumber hash declared in use vars (ultimatebb.cgi)
	# memberlist_array declaed in use vars too
	# memlistopen also use vars

	if (exists $ProfileNumber{$GetNameClean}) {    # check if it's already found
		return $ProfileNumber{$GetNameClean};
	} else {
		unless ($memlistopen) {    # only open once
			%ProfileNumber = %{&OpenFileAsHash("$vars_config{MembersPath}/memberslist.cgi", "|!!|")};
			$memlistopen++;
		}

		return ($ProfileNumber{$_[0]});
	}    # end else

}    #end GetUserNumber


sub PostHackDetails {

	my $called = "(called by " . (caller)[1] . ", " . (caller)[2] . ")";

	my $hackstring = "";

	$hackstring .= "\nHACK ATTEMPT DATE: $GotTime{LastLoginDT}\n$_[1]\nAttempt Details:\nEnvironment:\n";
	foreach (sort keys %ENV) {
		$hackstring .= "$_ \t $ENV{$_}\n";
	}

	$hackstring .= "\nPassed to script:\n";

	foreach (sort keys %in) {
		$hackstring .= "$_ \t $in{$_}\n";
	}

	$hackstring .= "-=- " x 20;

	&AppendFileAsString("$vars_config{NonCGIPath}/hacklog.cgi", $hackstring);

	&StandardHTML("$_[0] $called");
}

sub CheckBadChars {    # check for | , ;, .. or >< character hack attempts
	my $checkthis = shift;
	if ($checkthis =~ /\||\;|<|>|\.\.|\*/) {    #
		&PostHackDetails("$vars_wordlets_err{hack_attempt_bad_char}");
	}
	return 1;
}    # end SR

sub name_clean {
	$_[0] = &strip_lead_trail_space($_[0]);
	$_[0] =~ s/\s{2,}/ /g;
	$_[0] =~ s/</&lt;/g;
	$_[0] =~ s/>/&gt;/g;
	return ($_[0]);
}

sub CleanVar2 {
	$_[0] =~ s/!/\\!/g;
	return ($_[0]);
}

sub SmallClean {
	$_[0] =~ s/~/\\~/g;
	return ($_[0]);
}

sub SmallClean2 {    #like SmallClean only doesn't double-escape
	$_[0] = &SmallClean($_[0]);
	$_[0] =~ s/\\\\~/\\~/g;
	if ($_[0] =~ m/\\$/) { $_[0] .= ' '; }
	return $_[0];
}

sub ConvertReturns {
	$_[0] = &strip_lead_trail_space($_[0]);
	$_[0] =~ s/\n\r\n/<p>/ig;
	$_[0] =~ s/\n/<br \/>/ig;
	$_[0] =~ s/\r//g;
	$_[0] =~ s/(<p>){2,}/<p>/ig;
	$_[0] =~ s/(<br \/><br \/>){2,}/<br \/>/ig;
	$_[0] =~ s/<!/< !/ig;
	$_[0] =~ s/(<ul.*?>)(<br \/>)/$1/ig;
	return ($_[0]);
}

sub LimitReturns {
	$_[0] =~ s/\s+$//;
	$_[0] =~ s/\n{2,}/\n/ig;
	$_[0] =~ s/(\n\r\n){2,}/\n\r\n/ig;
	$_[0] =~ s/\r{2,}/\r/g;
	return ($_[0]);
}

sub EliminateReturns {
	$_[0] =~ s/\s{2,}/ /g;
	$_[0] =~ s/\n\r\n//g;
	$_[0] =~ s/\n//g;
	$_[0] =~ s/\r//g;
	return ($_[0]);
}

sub OpenForumsFile {
	unless ($alltheforums[0]) {
		@alltheforums = &OpenFileAsArray("$vars_config{VariablesPath}/vars_forums.cgi");
	}
	my @forumsfile = grep(/\|\^\|/, @alltheforums);
	return (@forumsfile);
}

sub Do2Digit {
	return(sprintf ("%.2d", $_[0]));
}


sub Do6Digit {
	return(sprintf ("%.6d", $_[0]));
}


sub Do8Digit {
	return(sprintf ("%.8d", $_[0]));
}

sub MainButtonOptions {
	local ($MyProfileLink, $RegisterLink, $SearchLink, $MainButtons, $this_forum, $ifmyreg, $ifregsearch, $ifsearchrest);
	if (exists $in{'f'}) {
		$this_forum = "&search_forum=$in{f}";
	} else {
		$this_forum = "";
	}

	if ($vars_registration{DisplayRegistration} ne 'NO') {
		$MyProfileLink = qq(<a href="$vars_config{CGIURL}/ultimatebb.cgi?ubb=my_profile"><acronym title="$vars_wordlets{profile_acronym}">$vars_wordlets{profile_link}</acronym></a>);
		$ifmyreg       = "|";
		$ifregsearch   = "|" unless $vars_registration{SuspendRegister} eq "true";
		$RegisterLink  = qq(<a href="$vars_config{CGIURL}/ultimatebb.cgi?ubb=agree"><acronym title="$vars_wordlets{register_acronym}">$vars_wordlets{register_link}</acronym></a>) unless $vars_registration{SuspendRegister} eq "true";
	}

	if ($vars_search{AllowSearch} ne 'FALSE') {
		$ifsearchrest = "|";
		$SearchLink   = qq(<a href="$vars_config{CGIURL}/ultimatebb.cgi?ubb=search$this_forum"><acronym title="$vars_wordlets{search}">$vars_wordlets{search_link}</acronym></a>);
	}

	$MainButtons = qq!
$MyProfileLink $ifmyreg $RegisterLink $ifregsearch $SearchLink $ifsearchrest <a href="$vars_config{CGIURL}/ultimatebb.cgi?ubb=faq"><acronym title="$vars_wordlets{faq_acronym}">$vars_wordlets{faq_link}</acronym></a> | <a href="$vars_config{CGIURL}/ultimatebb.cgi"><acronym title="$vars_wordlets{forum_acronym}">$vars_wordlets{forum_home_link}</acronym></a>
!;


	return ($MainButtons);
}    # end mainbuttonoptions

sub GetCatName {

	# $_[0] : category number
	local ($j, $CName, $CNum, $one, $ThisCatName);
	my @catlist = &GetCategoriesFile;

	FINDIT: foreach $one (@catlist) {
		($j, $CName, $CNum) = split (/\|\^\|/, $one);
		chomp($CNum);
		if ($CNum == $_[0]) { $ThisCatName = "$CName"; last FINDIT; }
	}
	return ($ThisCatName);
}

sub Validate {
	local ($each);
	local (@splitter);
	local ($Redo);
	local ($BadLine);
	my $Redo = '';
	$BadLine = "";

	foreach $each (@_) {
		chomp($each);

		if ($each !~ /\|/) {
			if ($in{$each} eq '') {
				$Redo = 'true';
				if ($each =~ /custom/) {
					if ($each eq 'customfield1') { $each = $vars_registration{customfield1}; }
					if ($each eq 'customfield2') { $each = $vars_registration{customfield2}; }
					if ($each eq 'customfield3') { $each = $vars_registration{customfield3}; }
					if ($each eq 'customfield4') { $each = $vars_registration{customfield4}; }
				}
				$BadLine .= "$vars_wordlets_err{did_not_complete} $each<br />";
			}

		} else {

			# this is an AND list
			@splitter = split (/\|/, $each);
			$ok = 'false';
			foreach $one (@splitter) {
				chomp($one);
				if ($in{$one}) { $ok = 'true'; }
			}

			if ($ok eq 'false') {
				$Redo = 'true';
				$BadLine .= "$vars_wordlets{missing_input_line} $each<br />";
			}

		}    #end single/OR
	}
	if ($Redo eq 'true') {
		if (($in{ubb} eq 'submit_registration') || ($in{ubb} eq 'edit_profile')) {

			#print qq%Content-type: text/html\n\n%;
			print header(
				-charset => "$masterCharset",
				-type    => "text/html",
			);

		}
		&StandardHTML("$vars_wordlets_err{missing_fields_intro}<p>$BadLine</p>");
	}
}    #end validate sr

sub GetForumRecord {

	# $_[0] : forum number
	local ($one, @for, @check, $goodline, @got_it);
	my @for = &OpenForumsFile;
	CHECK: foreach $one (@for) {
		@check = split (/\|\^\|/, $one);
		if ($check[8] eq $_[0]) {
			$goodline = $one;
			last CHECK;
		}
	}
	chomp($goodline);
	@got_it = split (/\|\^\|/, $goodline);
	return (@got_it);
}

sub GetMemberListArray {
	local ($thisline, @profiles, @members);
	my @themembers = &OpenFileAsArray("$vars_config{MembersPath}/memberslist.cgi");

	foreach $thisline (@themembers) {
		@profiles = split (/\|\!\!\|/, $thisline);
		chomp($profiles[1]);
		push (@members, $profiles[0]);
	}

	return (@members);
}    # end Get Member List Array sr

sub GetEmails {
	local ($dos, $EmailHere, $MemNum, $EmailLine, @EmailList);
	my @theemails = &OpenFileAsArray("$vars_config{MembersPath}/emailfile.cgi");

	foreach $dos (@theemails) {
		($EmailHere, $MemNum) = split (/\|\|/, $dos);
		chomp($MemNum);
		$EmailLine = "$EmailHere??$MemNum";
		push (@EmailList, $EmailLine);
	}
	return (@EmailList);
}

# thanks to Cal for this patch, even if it DOES use map :)
sub GeneratePassword {
	return &GeneratePasswordCore(6);
}

sub GeneratePassword2 {
	return &GeneratePasswordCore(8);
}

sub GeneratePasswordCore {
	my @digit = ('A'..'Z',1..9);
	srand(time);
	return join '',map{$digit[rand(@digit)]}(1..$_[0]);
}

sub hit_me {
	local (*FILE);

	unless (-d "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/counter") {
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie");
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files");
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/counter", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/counter");
	}

	unless (-e "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/counter/$GotTime{JSYear}-$GotTime{mon}.cgi") {
		&WriteFileAsString("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/counter/$GotTime{JSYear}-$GotTime{mon}.cgi", "0");
	}

	open(FILE, "+<$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/counter/$GotTime{JSYear}-$GotTime{mon}.cgi") or die "Can't open counter: $!";
	&lock;
	my $hits = <FILE>;
	chomp($hits);
	$hits++;
	seek(FILE, 0, 0); truncate(FILE, 0);
	print FILE $hits;
	&unlock;
	close(FILE);
	chmod(0666, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/counter/$GotTime{JSYear}-$GotTime{mon}.cgi");

}    # end hit_me

sub auto_url {
	local ($check);
	$check = shift;
	$check =~ s/(^|\s)(http:\/\/\S+)(\.?|,?)/$1<a href="$2" target="_blank">$2<\/a>$3/isg;
	$check =~ s/(^|\s)(https:\/\/\S+)(\.?|,?)/$1<a href="$2" target="_blank">$2<\/a>$3/isg;
	$check =~ s/(^|\s)(ftp:\/\/\S+)(\.?|,?)/$1<a href="$2" target="_blank">$2<\/a>$3/isg;
	$check =~ s/(^|\s)(www\.\S+)(\.?|,?)/$1<a href="http:\/\/$2" target="_blank">$2<\/a>$3/isg;

	return ($check);
}    # end auto_url

sub UBBCode {
	$_[0] =~ s/(\[URL|(^|\s)http:\/\/|(^|\s)www\.)(\S*?)([".]+?)(\]|\[\/URL\]|\s|$)/$1$4$5$6/isg;
	$_[0] =~ s/(\[URL|(^|\s)ftp:\/\/|(^|\s)ftp\.)(\S*?)([".]+?)(\]|\[\/URL\]|\s|$)/$1$4$5$6/isg;
	$_[0] =~ s/(\[URL|(^|\s)https:\/\/|(^|\s)www\.)(\S*?)([".]+?)(\]|\[\/URL\]|\s|$)/$1$4$5$6/isg;


	$_[0] = &auto_url($_[0]);

	unless ($_[0] =~ /\[\/.+]/) {
		return ($_[0]);
	}    # only process if there are ubbcode tags

	if ($_[0] =~ /\.cookie/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} COOKIE");
		exit(0);
	}
	if ($_[0] =~ /ONERROR\s*=/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} ONERROR");
		exit(0);
	}

	if ($_[0] =~ /getcookie/i) {
		&StandardHTML("$vars_wordlets_err{illegal_html_tag} GETCOOKIE");
		exit(0);
	}

	$_[0] =~ s/(\[URL\])(http|https|ftp)(:\/\/\S+?)(\[\/URL\])/ <a href="$2$3" target="_blank">$2$3<\/A> /isg;
	$_[0] =~ s/(\[URL\])(\S+?)(\[\/URL\])/ <a href="http:\/\/$2" target="_blank">$2<\/a> /isg;
	$_[0] =~ s/(\[URL=)(http|https|ftp)(:\/\/\S+?)(\])(.+?)(\[\/URL\])/<a href="$2$3" target="_blank">$5<\/a>/isg;
	$_[0] =~ s/(\[URL=)(\S+?)(\])(.+?)(\[\/URL\])/<a href="http:\/\/$2" target="_blank">$4<\/a>/isg;
	$_[0] =~ s/(\[EMAIL\])(\S+\@\S+?)(\[\/EMAIL\])/ <a href="mailto:$2">$2<\/a> /isg;
	$_[0] =~ s,(\[code\])(.+?)(\[/code\]),<blockquote><font size="1" face="$vars_style{FontFace}">$vars_wordlets{ubbcode_code}:<\/font><hr><pre>$2</pre><hr><\/blockquote>,isg;

	if ($_[1] eq 'ON') {
		$_[0] =~ s/(\[IMG\])(\S+?)(\[\/IMG\])/&imageize($2)/eisg;
	}

	$_[0] =~ s/(\[QUOTE\])(.+?)(\[\/QUOTE\])/ <blockquote><font size="1" face="$vars_style{FontFace}">$vars_wordlets{ubbcode_quote}:<\/font><hr>$2<hr><\/blockquote>/isg;
	$_[0] =~ s/(\[i\])(.+?)(\[\/i\])/<i>$2<\/i>/isg;
	$_[0] =~ s/(\[b\])(.+?)(\[\/b\])/<b>$2<\/b>/isg;
	$_[0] =~ s/(\[qb\])(.+?)(\[\/qb\])/<strong>$2<\/strong>/isg;
	$_[0] =~ s/(\[list\])\n?\r?(.+?)(\[\/list\])/<ul type="square">$2<\/ul>/isg;
	$_[0] =~ s/(\[list=)(A|1)(\])\n?\r?(.+?)(\[\/list\])/<ol type="$2">$4<\/ol>/isg;
	$_[0] =~ s/\n?\r?(\[\*\])/<li>/isg;
	return ($_[0]);
}


sub imageize {
	# Prevents baddies from creating images that make UBB do stuff :)
	my $string = shift;
	my $returner;
	my $string2 = UBBCGI::unescape($string);
	my $string3 = UBBCGI::unescapeHTML($string);
	if (($string !~ m/(ultimatebb|cp)\.cgi/i) && ($string2 !~ m/(ultimatebb|cp)\.cgi/i) && ($string3 !~ m/(ultimatebb|cp)\.cgi/i)) {
		$returner = qq~ <img src="$string"> ~;
	} else {
		$returner = q! [img]! . $string . q![/img] !;
	}    #endif
	return ($returner);
}    #endsub

sub ImageChecker {
	# Another routine to prevent baddies from creating images that make UBB do stuff :)
	my $string = shift;
	my $returner;
	my $string2 = UBBCGI::unescape($string);
	my $string3 = UBBCGI::unescapeHTML($string);
	if (($string !~ m/(ultimatebb|cp)\.cgi/i) && ($string2 !~ m/(ultimatebb|cp)\.cgi/i) && ($string3 !~ m/(ultimatebb|cp)\.cgi/i)) {
		$returner = $string;
	} else {
		$returner = "";
	}    #endif
	return ($returner);
}    #endsub

sub CensorCheck {
	local ($ThisWord, $wordlength, $replaceword, $WordCheck);
	my $WordCheck = shift;
	my @censored = split (/ /, $vars_misc{censorwords});
	if ($vars_misc{Censor} eq 'ON') {
		for (@censored) {

			if (m/({)(.*)(})/) {
				$ThisWord    = ("$2");
				$wordlength  = length($ThisWord);
				$replaceword = '*' x $wordlength . " ";
				$WordCheck =~ s/\b$ThisWord\b/$replaceword/isg;
			} else {
				$wordlength  = length($_);
				$replaceword = "*" x $wordlength;
				$WordCheck =~ s/$_/$replaceword/isg;
			}
		}
	}
	return ($WordCheck);
}    # end CensorCheck


sub ClearUserPostHistories {
	use File::Path;
	rmtree("$vars_config{MembersPath}/user_posts");
	mkdir("$vars_config{MembersPath}/user_posts", 0777);
	chmod(0777, "$vars_config{MembersPath}/user_posts");
}

sub ClearSummaryCache {
	opendir(FILE, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/summary");
	my @summs = readdir(FILE);
	closedir(FILE);

	foreach (@summs) {
		unlink("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/summary/$_");
	}

	unless (-d "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files") {
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files");
	}
	unless (-d "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/summary") {
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/summary", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/summary");
	}
}

sub ClearMiscCache {
	opendir(FILE, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/misc");
	my @summs = readdir(FILE);
	closedir(FILE);

	foreach (@summs) {
		unlink("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/misc/$_");
	}

	unless (-d "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files") {
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files");
	}
	unless (-d "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/misc") {
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/misc", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/misc");
	}
}

sub ClearForumPageCache {
	use File::Path;
	rmtree("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forum_page");

	unless (-d "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files") {
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files");
	}
	mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forum_page", 0777);
	chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forum_page");
}

sub ClearSingleForumPageCache {

	# $_[0] : $the path for the forum page to be removed from cache
	# $_[1] : forum number

	use File::Path;
	rmtree("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forum_page/$_[0]");


	unless (-d "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files") {
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files");
	}

	unless (-d "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forum_page/$_[0]") {
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forum_page/$_[0]", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forum_page/$_[0]");
	}
}

sub ClearForumTopicsCache {
	use File::Path;
	rmtree("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forums");

	unless (-d "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files") {
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files");
	}

	mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forums", 0777);
	chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forums");
}

sub ClearSingleForumTopicsCache {
	use File::Path;

	# $_[0] : $the path for the forum for which topics are to be removed from cache
	rmtree("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forums/$_[0]");

	unless (-d "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files") {
		mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files", 0777);
		chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files");
	}
	mkdir("$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forums/$_[0]", 0777);
	chmod(0777, "$vars_config{NonCGIPath}/cache-$cache_cookie/ubb_files/forums/$_[0]");
}

sub GetModLine {
	local (@mod_profile);

	&RequireVars("$vars_config{VariablesPath}/vars_mods.cgi");

	local ($Moderator, @mods, @mod_links, $mod_name, $mod_num, $mod_line);

	$Moderator = ("Forum" . "$_[0]" . "Moderator");
	$Moderator = $$Moderator;

	if ($Moderator) {

		#split up Mod var
		@mods = split (/\|\|\^\|\|/, $Moderator);

		@mod_links = ();
		foreach (@mods) {
			chomp($_);

			if ((-e "$vars_config{MembersPath}/$_.cgi") && ($_ ne '')) {
				@mod_profile = &OpenProfile($_);
				chomp($mod_profile[15]);
				chomp($mod_profile[0]);
				if ($mod_profile[15] eq '') {
					$mod_profile[15] = "$mod_profile[0]";
				}

				$mod_line = qq!<a href="$vars_config{CGIURL}/ultimatebb.cgi?ubb=get_profile&u=$_">$mod_profile[15]</a>!;
				push (@mod_links, $mod_line);
			}
		}    # if member exists!

		$Moderator = join (", ", @mod_links);
	} else {
		$Moderator = "$vars_wordlets{no_mods}";
	}
	return ($Moderator);
}    # end get mod line


sub illegal_name_check {

	# thanks to ajmanlover for inspiring the high bit character regexes
	if (
	($_[0] =~ m/^[\s\#\!\|]/) ||
	($_[0] =~ m/[!"`\;~><]/) ||
	($_[0] =~ m/\|+/) ||
	($_[0] =~ m/\&(nbsp|amp|gt|lt)/) ||
	($_[0] =~ m/[\s\|]$/) ||
	($_[0] =~ m/\s{2,}/) ||
	($_[0] =~ m/__\w+__/)
	) {

		if (($in{ubb} eq 'submit_registration') || ($in{ubb} eq 'edit_profile')) {

			#print qq%Content-type: text/html\n\n%;
			print header(
				-charset => "$masterCharset",
				-type    => "text/html",
			);

		}
		&StandardHTML("$vars_wordlets_err{bad_reg_chars}");
	}    # end name tripwire

	#the high-bit regexes are a little tricky, and require refinement....
	if (
	(($_[0] =~ m/[\x80-\xFF]/) && ($vars_registration{allowHighBit} ne "YES")) ||
	(($_[0] !~ m/^[a-zA-Z0-9\!\?\#\$\@\*\&\^\+\-\:\[\]\']/) && ($vars_registration{allowHighBit} ne "YES")) ||
	(($_[0] !~ m/[a-zA-Z0-9\!\?\#\$\@\*\&\^\+\-\:\[\]\'\.]$/) && ($vars_registration{allowHighBit} ne "YES")) ||
	($_[0] =~ m/[\x00-\x1f]/)
	) {

		if (($in{ubb} eq 'submit_registration') || ($in{ubb} eq 'edit_profile')) {

			#print qq%Content-type: text/html\n\n%;
			print header(
				-charset => "$masterCharset",
				-type    => "text/html",
			);

		}
		&StandardHTML("$vars_wordlets_err{bad_reg_chars}");

	}
}

sub verify_id_num {

	# used for verifying all cookie user info
	my $un       = shift;
	my $pw       = shift;
	my $user_num = shift;
	chomp($user_num);
	local ($lcpw, $lc_un, $lc_pw_in, $lc_un_in);

	#do we have a user number?
	if (($user_num eq '') || ($user_num !~ /^\d{8}$/)) {
		&StandardHTML("$vars_wordlets_err{invalid_username}");
	}

	my @profile = &OpenProfile("$user_num");
	chomp($profile[0]);
	chomp($profile[1]);

	#lowercase everything
	$lcpw     = lc($profile[1]);
	$lc_un    = lc($profile[0]);
	chomp($lc_pw_in = lc($pw));	# jic
	chomp($lc_un_in = lc($un));

	# check password
	if ($lcpw ne "$lc_pw_in") {
		&StandardHTML("$vars_wordlets_err{invalid_password}");
	}

	# check username
	if ($lc_un ne "$lc_un_in") {
		&StandardHTML("$vars_wordlets_err{invalid_username}");
	}
	return (@profile);
}    #end verify_id_num


sub verify_id_num_2 {

	# verify_id_num_2 is the same as verify_id_num,
	# except that we need to print the header here if there
	# is a problem!

	# used for verifying all cookie user info
	my $un       = shift;
	my $pw       = shift;
	my $user_num = shift;
	chomp($user_num);
	local ($lcpw, $lc_un, $lc_pw_in, $lc_un_in);

	#do we have a user number?
	if (($user_num eq '') || ($user_num !~ /^\d{8}$/)) {

		#print qq%Content-type: text/html\n\n%;
		print header(
			-charset => "$masterCharset",
			-type    => "text/html",
		);

		&StandardHTML("$vars_wordlets_err{invalid_username}");
	}

	my @profile = &OpenProfile("$user_num");
	chomp($profile[0]);
	chomp($profile[1]);

	#lowercase everything
	$lcpw     = lc($profile[1]);
	$lc_un    = lc($profile[0]);
	chomp($lc_pw_in = lc($pw));	# jic
	chomp($lc_un_in = lc($un));

	# check password
	if ($lcpw ne "$lc_pw_in") {

		#print qq%Content-type: text/html\n\n%;
		print header(
			-charset => "$masterCharset",
			-type    => "text/html",
		);

		&StandardHTML("$vars_wordlets_err{invalid_password}");
	}

	# check username
	if ($lc_un ne "$lc_un_in") {

		#print qq%Content-type: text/html\n\n%;
		print header(
			-charset => "$masterCharset",
			-type    => "text/html",
		);

		&StandardHTML("$vars_wordlets_err{invalid_username}");
	}
	return (@profile);
}    #end verify_id_num_2


sub hop_to_list {
	local (%forum_order_list, %forum_name_list, %cat_list, @all_forums, @sorted_forums, @sortrow, $j, @checkit, $ok, $uno, $key, $cat_type, $ThisCatNam, $ThisCatNumb, @catgroup, $cat_name, $select_list);

	@all_forums = &OpenForumsFile;

	undef(%forum_order_list);
	undef(%forum_name_list);
	undef(%cat_list);
	undef(@sortcat);
	undef(@cats);

	# make sure only open forums are listed
	foreach $j (@all_forums) {
		chomp($j);
		@checkit = split (/\|\^\|/, $j);
		if ($checkit[3] eq 'On') {
			$forum_order_list{$checkit[8]} = "$checkit[14]";
			$forum_name_list{$checkit[8]}  = "$checkit[1]";

			# create cat list:
			if (($checkit[0]) && ($checkit[0] > 0)) {
				$cat_list{$checkit[8]} = "$checkit[0]";
			}

		}
	}

	# sort forum list:
	@sorted_forums = sort { $forum_order_list{$a} <=> $forum_order_list{$b} } keys %forum_order_list;

	$select_list = qq~
<option value=''>$vars_wordlets{select_a_forum}</option>
<option value=''></option>
~;

	if ($vars_display{CategoryView} ne 'yes') {

		foreach (@sorted_forums) {

			if ($in{f} eq "$_") {

				$select_list .= qq~<option value="$_" selected="selected">$forum_name_list{$_}</option>\n~;

			} else {

				$select_list .= qq~<option value="$_">$forum_name_list{$_}</option>\n~;

			}
		}

	} else {

		my @cats    = &GetCategoriesFile;
		my @sortcat = sort(@cats);

		CATLOOP: foreach $cat_type (@sortcat) {

			$ok = '';
			($j, $ThisCatNam, $ThisCatNumb) = split (/\|\^\|/, $cat_type);
			chomp($ThisCatNumb);

			# grab cat name:
			$cat_name = &GetCatName($ThisCatNumb);

			# make sure there are forums in this category:
			foreach $key (keys %cat_list) {
				if ($cat_list{$key} eq "$ThisCatNumb") { $ok = 'y'; }
			}
			unless ($ok eq 'y') { next CATLOOP; }

			# print cat name in select list:
			$select_list .= qq~
<option value=""></option>
<option value="CAT:$ThisCatNumb">$vars_wordlets{category_header_hopto} $cat_name</option>
<option value="">--------------------</option>
~;

			# get all forums in category, sorted:
			foreach $key (@sorted_forums) {

				if (exists($cat_list{$key})) {
					if ($cat_list{$key} eq "$ThisCatNumb") {

						if (($in{f} eq "$key") && ($_[0] ne "nosel")) {	#so much for warning clean...
							$select_list .= qq~<option value="$key" selected="selected">$forum_name_list{$key}</option>\n~;

						} else {
							$select_list .= qq~<option value="$key">$forum_name_list{$key}</option>\n~;
						}    # end if/else f = key

					}    # if cat list key exists
				}    # end if cat list check

			}    # end foreach forum order list
		}    # end foreach sortcat

	}    # end if/else cat view

	return ($select_list);
}    ## end hop_to_list


sub check_email_bans {

	# parameter:
	# $_[0] : email

	local (@banlist, $banword, $banword2);

	if (-e "$vars_config{NonCGIPath}/BanLists/EmailBan.cgi") {
		@banlist = &OpenFileAsArray("$vars_config{NonCGIPath}/BanLists/EmailBan.cgi");
	} else {
		return;
	}

	if ($banlist[0]) {

		my $check = 0;
		CHECKBANLIST: foreach $word (@banlist) {
			chomp $word;
			$banword = quotemeta $word;
			if ($_[0] =~ m/$banword/i) {
				$check++;
				last CHECKBANLIST;
			}
		}    #endforeach

		$vars_misc{'ReverseEmailBans'} = "NO" unless $vars_misc{'ReverseEmailBans'};

		if (($check > 0) && ($vars_misc{'ReverseEmailBans'} ne "YES")) {
			if (($in{ubb} eq 'submit_registration') || ($in{ubb} eq 'edit_profile') || ($in{ubb} eq 'do_)lgin')) {

				#print qq%Content-type: text/html\n\n%;
				print header(
					-charset => "$masterCharset",
					-type    => "text/html",
				);
			}
			&StandardHTML("$vars_wordlets_err{banned_email}");
		} elsif (($check < 1) && ($vars_misc{'ReverseEmailBans'} eq "YES")) {

			if (($in{ubb} eq 'submit_registration') || ($in{ubb} eq 'edit_profile') || ($in{ubb} eq 'do_login')) {

				#print qq%Content-type: text/html\n\n%;
				print header(
					-charset => "$masterCharset",
					-type    => "text/html",
				);
			}
			&StandardHTML("$vars_wordlets_err{banned_email}");
		} else {
			return;    #ovbiously not banned
		}    #endif


	}    #if EmailBan list is not empty
}    # end check_email_bans


sub check_ip_bans {

	local (@ip_ban_list, $ip_number, $banword, $banword2);
	$ip_number = $ENV{'REMOTE_ADDR'};

	# Check IP Ban List--
	if (-e "$vars_config{NonCGIPath}/BanLists/IPBan.cgi") {
		@ip_ban_list = &OpenFileAsArray("$vars_config{NonCGIPath}/BanLists/IPBan.cgi");
	} else {
		return;
	}

	if ($ip_ban_list[0]) {

		my $check = 0;
		CHECKBANLIST: foreach $word (@ip_ban_list) {
			chomp $word;
			$banword = quotemeta $word;
			if ($ip_number =~ m/^$banword/i) {

				#print "Banned!";
				$check++;
				last CHECKBANLIST;
			} else {

				#print "NOT banned! (";
			}
		}    #endforeach

		$vars_misc{'ReverseIPBans'} = "NO" unless $vars_misc{'ReverseIPBans'};

		if (($check > 0) && ($vars_misc{'ReverseIPBans'} ne "YES")) {
			if (($in{ubb} eq 'submit_registration') || ($in{ubb} eq 'edit_profile') || ($in{ubb} eq 'do_login')) {

				#print qq%Content-type: text/html\n\n%;
				print header(
					-charset => "$masterCharset",
					-type    => "text/html",
				);
			}
			&StandardHTML("$vars_wordlets_err{ip_banned} $ip_number");

		} elsif (($check < 1) && ($vars_misc{'ReverseIPBans'} eq "YES")) {
			if (($in{ubb} eq 'submit_registration') || ($in{ubb} eq 'edit_profile') || ($in{ubb} eq 'do_login')) {

				#print qq%Content-type: text/html\n\n%;
				print header(
					-charset => "$masterCharset",
					-type    => "text/html",
				);
			}
			&StandardHTML("$vars_wordlets_err{ip_banned} $ip_number");
		} else {
			return;
		}    #endif


	}    #if ip_ban_list is not empty
}    # end ip ban check


# another Cal patch
sub make_random_number {
	my @digit = (1..9);
	srand(time);
	return join '', map{$digit[rand(@digit)]}(1..6);
}


sub check_private_access {
	local (@profile, $Moderator);
	&RequireVars("$vars_config{VariablesPath}/vars_mods.cgi");

	# since forum is private, user must be logged in

	# $_[0]: forum number
	# $_[1]: forum password (blank, if none)

	if ($username eq '') {
		&StandardHTML(qq!$vars_wordlets_err{not_logged_in}<p> <a href="$vars_config{CGIURL}/ultimatebb.cgi?ubb=login">$vars_wordlets{login_now}</a></p>!);
	}

	# user is logged in, so get profile
	@profile = &verify_id_num($username, $password, $user_number);
	chomp($user_number);
	chomp($profile[8]);
	chomp($profile[4]);



	unless ($profile[8] eq 'Administrator') {

		if ($profile[8] eq 'Moderator') {

			$Moderator = ("Forum" . "$_[0]" . "Moderator");
			$Moderator = $$Moderator;

			$user_number = &Do8Digit($user_number);

			unless ($Moderator =~ /$user_number/) {

				# user is not moderator, so check for explicit permission
				#print "$Moderator ne $user_number";
				&check_explicit($profile[4], $_[0], $_[1]);
			}

		} else {
			&check_explicit($profile[4], $_[0], $_[1]);

		}
	}    # if not an admin

}    # end check private access


sub check_explicit {
	local ($j, $perms, @explicit, $access_rights, $forum_name, %pwhash, $forumpw);

	# one argument:
	# $_[0] : user permissions (from profile[4])
	# $_[1] : forum number
	# $_[2] : forum password (blank, if none)

	($j, $perms) = split (/&/, $_[0]);
	@explicit = split (/,/, $perms);

	foreach (@explicit) {
		chomp($_);
		if ($_[1] == $_) { $access_rights = 'true'; }
	}

	unless ($access_rights eq 'true') {

		if ($_[2] ne '') {

			# check to see if forumpw cookie set:
			$forumpw = cookie("forumpw$vars_config{Cookie_Number}");
			%pwhash  = split (/\|\^\|/, $forumpw);

			# pw hash check
			unless ((exists($pwhash{$_[1]})) && ($pwhash{$_[1]} eq "$_[2]")) {

				my @forum_line = &GetForumRecord($_[1]);
				$forum_name = $forum_line[1];
				&set_page_elements;
				&LoadTemplate("public_query_forum_pw");
				exit(0);

			}

		} else {
			&StandardHTML("$vars_wordlets_err{no_access}");
		}    # end if forum pw exists

	}    # end access right ne true



}    # end check_explicit sr


sub Y2K {
	local ($check_length, $year);
	$check_length = length($_[0]);
	if ($check_length < 4) {
		if ($check_length == 2) {
			$year = ("19" . "$_[0]");
		} else {
			$year = $_[0] - 100;
			$year = sprintf("%2d", $year);
			$year =~ tr/ /0/;
			$year = ("20" . "$year");
		}
	} else {
		$year = $_[0];
	}
	return ($year);
}    # end Y2K sr


sub TimeFormat {
	local ($time_formatted, @timearray, $get_hour, $get_minute);

	if ($vars_time{TimeFormat} eq '24HR') {
		@timearray = split (/ /, $_[0]);
		chomp($timearray[1]);
		($get_hour, $get_minute) = split (/:/, $timearray[0]);
		chomp($get_minute);

		if ($timearray[1] eq 'PM') {
			if ($get_hour < 12) { $get_hour = ($get_hour + 12); }
		} else {
			if ($get_hour == 12) { $get_hour = '0'; }
		}
		$get_hour       = &Do2Digit($get_hour);
		$get_minute     = &Do2Digit($get_minute);
		$time_formatted = "$get_hour:$get_minute";
	} else {
		$time_formatted = "$_[0]";
	}
	return ($time_formatted);
}    # end TimeFormat

sub strip_lead_trail_space {
	$_[0] =~ s/^\s+//;
	$_[0] =~ s/\s+$//;
	return ($_[0]);
}

sub CustomTitle {
	my $title = shift;
	my $custom_title;
	chomp($title);

	if ($title eq "Administrator") {
		$custom_title = "$vars_misc{AdminTitle}";
	} elsif ($title eq "Moderator") {
		$custom_title = "$vars_misc{ModeratorTitle}";
	} elsif ($title eq "Member") {
		$custom_title = "$vars_misc{MemberTitle}";
	} elsif ($title eq "Junior Member") {
		$custom_title = "$vars_misc{JrMemberTitle}";
	}

	return ($custom_title);
}    # end customer title sr

sub email_test {
	local ($t);
	if (($_[0] =~ m/\s/) ||
	($_[0] !~ /\S+\@\S+\.\S+/) ||
	($_[0] =~ /^\./) ||
	($_[0] =~ /\.{2,}/) ||
	($_[0] =~ /\.$/) ||
	($_[0] =~ /\.\@/) ||
	($_[0] =~ /\@\./) ||
	($_[0] =~ /;/)) {
		$t = 'n';
	} else {
		$t = 'y';
	}
	return ($t);
}


sub build_mod_emails {
	&RequireVars("$vars_config{VariablesPath}/vars_mods.cgi");
	local ($Moderators, $mod_emails, @mods, @mod_profile, @mod_email);

	# $_[0] : forum number

	$Moderators = ("Forum" . "$_[0]" . "Moderator");
	$Moderators = $$Moderators;

	#split up Mod var
	@mods = split (/\|\|\^\|\|/, $Moderators);

	foreach (@mods) {
		if (-s "$vars_config{MembersPath}/$_.cgi") {
			@mod_profile = &OpenProfile($_);
			chomp($mod_profile[2]);
			push (@mod_email, $mod_profile[2]);
		}
	}

	# combine emails
	$Moderators = join (", ", @mod_email);

	return ($Moderators);

}


sub CheckCachedFile {
	return if $in{ubb} =~ m/prune/;    #if we're pruning, ignore the missing file
	my $file      = shift;
	my $called    = shift;                                 #caller() string
	my $cachepath = $vars_config{NonCGIPath} . "/cache";
	my $forumpath = $vars_config{NonCGIPath} . "/Forum";
	if ($file =~ m/^$cachepath/) {

		unless (-d "$vars_config{NonCGIPath}/cache-$vars_config{cache_pw}") {
			mkdir("$vars_config{NonCGIPath}/cache-$vars_config{cache_pw}", 0777);
			chmod(0777, "$vars_config{NonCGIPath}/cache-$vars_config{cache_pw}");
		}    # cache pw without directory == screwy setup, so create

		unless (-d "$vars_config{NonCGIPath}/cache-$vars_config{cache_pw}") {
			&StandardHTML($vars_wordlets_err{cache_broken});
		}    # If it still didn't get created, our noncgi directory is screwy, so have user fix

	} elsif ($file =~ m!^$forumpath(\d+).*/(\d\d\d\d\d\d)\.cgi$!) {    #also check to see if this is a thread file
		&StandardHTML("Forum $1, Thread $2 was not found $called");
	}    #endif

	return;
}    #end


sub CheckForExistingNames {
	my $input_name  = shift;    #lower case username
	my $printheader = shift;

	# make sure publicly displayed name is unique
	# and check login name against pub names
	if (-s "$vars_config{MembersPath}/public_names.cgi") {
		my @pubs = &OpenFileAsArray("$vars_config{MembersPath}/public_names.cgi");

		foreach my $duper (@pubs) {
			chomp($duper);
			my $lc_it = lc($duper);

			if ($input_name eq $lc_it) {
				print header(
					-charset => "$masterCharset",
					-type    => "text/html",
				    )
				    if $printheader;
				&StandardHTML("$vars_wordlets_err{dupe_name}");
			}

		}
	}    # if pub names file exists and has size


	foreach my $item (&GetMemberListArray) {
		chomp($item);
		$item2 = lc($item);
		if ($input_name eq $item2) {
			print header(
				-charset => "$masterCharset",
				-type    => "text/html",
			    )
			    if $printheader;
			&StandardHTML("$vars_wordlets_err{dupe_name}");
		}
	}

	return;
}    #endsub



sub CheckLength {

	#checks %in for bad lengths, truncates where nessecary
	my ($invalue, $formlength) = @_;
	return unless exists $in{$invalue};
	$in{$invalue} =~ s/[\x00-\x1f]//gsi;
	if (length($in{$invalue}) > $formlength) {
		$in{$invalue} = substr($in{$invalue}, 0, $formlength);
	}
}    #endsub


sub CheckLength2 {

	#checks a passed value for bad lengths, truncates where nessecary - doesn't filter lowbits
	my ($invalue, $formlength) = @_;
	if (length($invalue) > $formlength) {
		$invalue = substr($invalue, 0, $formlength);
	}

	return $invalue;
}    #endsub

sub CheckLengthOrDie {

	#checks %in for bad lengths, then dies if it's unexpected
	my ($invalue, $formlength) = @_;
	$formlenth++;
	$in{$invalue} =~ s/[\x00-\x1f]//g;
	if (length($in{$invalue}) > $formlength) {
		my $errorstring = "(Form value $invalue is " . length($in{$invalue}) . " characters. Must be under $formlength!)";
		&StandardHTML("$vars_wordlets_err{bad_input} <br />$errorstring");
		exit(0);
	}
}    #endsub


sub NeutralizeHTMLEntities {
	return UBBCGI::escapeHTML($_[0]);
}    #endsub

sub NeutralizeBackHTMLEntities {
	return UBBCGI::unescapeHTML($_[0]);
}    #endsub


sub CustomGraemlins {
	my $string = shift;
	foreach my $item (keys %{$vars_graemlins->{'graems'}}) {
		my $short = %$vars_graemlins->{'graems'}->{$item};
		#$short->{'trigger'} = quotemeta $short->{'trigger'};
		$string =~ s/:\Q$short->{'trigger'}\E\:/ <img src="graemlins\/$short->{'image'}" border="0" alt="[$short->{'text'}]" \/> /gi;
	}    #endforeach

	foreach my $item (keys %{$vars_graemlins->{'origs'}}) {
		my $short = %$vars_graemlins->{'origs'}->{$item};
		#$short->{'trigger'} = quotemeta $short->{'trigger'};
		$string =~ s/\Q$short->{'trigger'}\E/ <img src="$short->{'image'}" border="0"> /gi;
	}    #endforeach
	return $string;
}    #endsub


sub GoodNiceTruncate {
	my ($string, $slength) = @_;
	my ($spacecount, $sspacecount);

	$string = &NeutralizeBackHTMLEntities($string);

	return $string if (length($string) <= $slength);

	my $shortstring = substr($string, 0, $slength);

	while ($shortstring =~ m/\s/g) {
		$spacecount++;
	}
	while ($string =~ m/\s/g) {
		$sspacecount++;
	}

	if (($spacecount > 1) && ($sspacecount >= $spacecount) && ($shortstring ne $string)) {

		$shortstring =~ s/\s(\S+)$//gi;
		$shortstring =~ s/\s*$//gi;
	}    #endif

	$shortstring = &NeutralizeHTMLEntities($shortstring);

	return "$shortstring...";
}    #end sub NiceTruncate


sub GetOrPost {
	my $expected = shift;
	die "What is '$ENV{REQUEST_METHOD}'?" unless $ENV{REQUEST_METHOD} =~ m/^(GET|POST|HEAD)$/;
	&StandardHTML($vars_wordlets_err{invalid_input}) unless $ENV{REQUEST_METHOD} eq $expected;
	return;
}    #endsub


sub Exit {
	exit(0);
}

sub DoThatClearCacheThing {

	my ($thispath, $thread) = @_;

	if (-d $thispath) {
		opendir(DIR, "$thispath") or die $!;
		my @removeus = grep(/^$thread/, readdir(DIR));
		closedir(DIR);
		foreach my $thisfile (@removeus) {
			unlink("$thispath/$thisfile");
		}    #endforeach
	}    #endif

	return;

}    #endsub

sub SetExactPath {
	my $forum      = shift;
	return $exact_path if(($exact_path) && ($exact_path =~ m/Forum$forum[$-\D]/));
	my @forumfacts = &GetForumRecord($forum);
	$exact_path = "Forum$forum";
	if ($forumfacts[6] eq 'private') {
		$exact_path .= "/private-$forumfacts[7]";
	}
	return $exact_path;
}    #endsub

sub GetCategoriesFile {
	return @allthecategories if @allthecategories;
	@allthecategories = &OpenFileAsArray("$vars_config{NonCGIPath}/categories.file");
	return @allthecategories;
}

sub LoadTemplate {
	#why not do() directly?  Centralized error checking, that's why!  :)
	my $fn = shift;

	my $called = "\n(called by " . (caller)[1] . ", " . (caller)[2] . ")\n";

	my $file = "$vars_config{NonCGIPath}/Templates/$fn.pl";

	if(-e $file) {
		do $file; die "$fn: $@ $called" if $@;
	} else {
		die "$fn: template not found $called";
	}
	return;
} #endsub

sub RequireCode {	# fakes a require()
	my $called = "\n(called by " . (caller)[1] . ", " . (caller)[2] . ")\n";
	do $_[0]; die "$_[0]: $@ $called" if $@;
} #endsub

sub RequireVars {	# fakes a require and locks the file
	my $called = "\n(called by " . (caller)[1] . ", " . (caller)[2] . ")\n";
	my $token = &OpenAndLock($_[0]);
	do $_[0]; die "$_[0]: $@ $called" if $@;
	&CloseAndUnlock($token);
} #endsub

sub LoadStyleTemplate {
	my $number = shift;

	local(%vars_style);	# use our own copy rather than the global one

	if($number !~ m/^\d+$/) {
		$number = 1;
	}

	if($vars_style_reference{$number}) {
		return %{$vars_style_reference{$number}};
	}

	&RequireVars("$vars_config{NonCGIPath}/styles/vars_style_$number.cgi");

	$vars_style_reference{$number} = \%vars_style;

	return %vars_style;
}

sub ServeFromCache {

	# if the cache is off and we have NOT generated a new page, return
	return if(($vars_misc{use_cache} eq "no") && (!$ThisHTML));

	# if we've generated a new page, print it and return
	if($ThisHTML) { print $ThisHTML; return; }

	my $called = "\n(called by " . (caller)[1] . ", " . (caller)[2] . ")\n";

	my $filename = "$vars_config{NonCGIPath}/cache-$vars_config{cache_pw}/$_[0]";

	if((-e $filename) && (-s $filename)) {	#if it's there and it has a size
		&OpenFileToSTDOUT($filename);
		exit(0);
	} elsif((-e $filename) && (-z $filename)) {	#if it's there but blank
		unlink($filename) or die "$! unlinking cache/$_[0] $called";
		return;
	} elsif(!-e $filename) {	#not there at all
		return;
	} else {	#can't be done - file can not both exist and not exist
		die "This routine has confused my poor little brain! $called";
	}

} #endsub

# do not remove:
1;
