# FILE: src-board-subs-104
#-------------------------------------------------------------------------------
# DISCUS VERSION 3.10 COPYRIGHT NOTICE
#
# Discus 3.10 is copyright (c) 2000 by DiscusWare, LLC, all rights reserved.
# The use of Discus is governed by the Discus License Agreement which is
# available from the Discus WWW site at:
#    http://www.discusware.com/discus/license
#
# Pursuant to the Discus License Agreement, this copyright notice may not be
# removed or altered in any way.
#-------------------------------------------------------------------------------
#
# --------------------------------------------------------------------------------
# ATTENTION!  THIS FILE IS PART OF THE DISCUS PRO DISTRIBUTION AND IS COMMERCIAL
# SOFTWARE.  REDISTRIBUTION OF THIS FILE IS STRICTLY PROHIBITED AND WILL RESULT IN
# PROSECUTION TO THE MAXIMUM EXTENT OF THE LAW.  YOU ARE NOT PERMITTED TO REMOVE
# THIS NOTICE UNDER ANY CIRCUMSTANCES.
# --------------------------------------------------------------------------------

#---SEPARATOR---#

sub archive_mgr {
	if (!-w "$admin_dir/archive.txt") {
		&error_message("Archive Manager Error", "The file 'archive.txt' in your administration files directory does not exist or is not world writable.  Check that permissions are 0777 (rwxrwxrwx) on this file.", 0, 1);
	}
	&header;
	print "<HTML><HEAD><TITLE>Archive/Prune Manager</TITLE>\n";
	print "</HEAD>\n";
	print "<BODY BGCOLOR=#ffffff TEXT=#000000 LINK=#0000FF VLINK=#0000FF onLoad=\"window.defaultStatus = 'Archive Manager'\">\n";
	print "$fs<FONT SIZE=3><CENTER><B>Archive/Prune Manager</B></CENTER></FONT>\n";
	print "<HR>\n";
	print "<H3>Automatic Archiving/Pruning</H3>\n";
	print "<FORM ACTION=$cgiurl METHOD=POST>\n";
	print "<TABLE BGCOLOR=#ffffcc BORDER=1 WIDTH=100%><TR><TD>\n";
	print "$fs", "Choose which topics you wish to archive (move messages) or prune (delete\n";
	print "messages) automatically.  Also specify how many messages must be in the\n";
	print "conversation in order to invoke archiving/pruning and how many messages to leave\n";
	print "in the conversation upon archiving/pruning.<P>\n";
	print "<TABLE><TR><TD>$fs<B>Arch.</B></FONT></TD><TD>$fs<B>Prune</B></FONT></TD><TD>&nbsp;</TD><TD>$fs<B>Invoke</B></FONT></TD><TD>$fs<B>Leave</B></FONT></TD><TD>&nbsp;</TD><TD>$fs<B>Topic</B></FONT></TR>\n";
	open (ARCHIVE_CFG, "$admin_dir/archive.txt");
	@archive = <ARCHIVE_CFG>;
	close (ARCHIVE_CFG);
	foreach $l (@archive) {
		if ($l =~ m|^(\w+)=(\d+)|) {
			$archive{$1} = $2;
		}
	}
	open (TOPICS, "$message_dir/$board_topics_file");
	@topics = <TOPICS>;
	close (TOPICS);
	@t = grep(/^<!-Top:/, @topics);
	foreach $t (@t) {
		$t =~ m|<!-Top: (\d+)-!>|;
		$d = $1;
		&extract("//$d/$d.$ext");
		print "<TR>";
		print "<TD ALIGN=CENTER><INPUT TYPE=CHECKBOX NAME=archive_$d VALUE=1";
		print " CHECKED" if $archive{"archive_$d"} == 1;
		print " onClick=\"document.forms[0].pruning_$d.checked = false\"></TD>";
		print "<TD ALIGN=CENTER><INPUT TYPE=CHECKBOX NAME=pruning_$d VALUE=1";
		print " CHECKED" if $archive{"prune_$d"} == 1;
		print " onClick=\"document.forms[0].archive_$d.checked = false\"></TD>";
		print "<TD>&nbsp;</TD>";
		print "<TD ALIGN=CENTER><INPUT TYPE=TEXT SIZE=3 NAME=archive_msgs_$d VALUE=";
		if ($archive{"msgs_$d"} != 0) {
			print $archive{"msgs_$d"};
		} else {
			print "0";
		}
		print "></TD>";
		print "<TD ALIGN=CENTER><INPUT TYPE=TEXT SIZE=3 NAME=archive_leave_$d VALUE=";
		if ($archive{"leave_$d"} != 0) {
			print $archive{"leave_$d"};
		} else {
			print "0";
		}
		print "></TD>";
		print "<TD>&nbsp;</TD>\n";
		print "<TD>$fs$topic_name</FONT></TD></TR>\n";
	}
	print "</TABLE>\n";
	print "<P><INPUT TYPE=SUBMIT VALUE=\"Save Options\">\n";
	print "</TD></TR></TABLE>\n";
	print "<INPUT TYPE=HIDDEN NAME=username VALUE=$superuser>\n";
	print "<INPUT TYPE=HIDDEN NAME=action VALUE=archive_options>\n";
	print "</FORM><HR>\n";
	print "<H3>Manual Archiving/Pruning</H3>\n";
	print "<FORM ACTION=$cgiurl METHOD=POST  onSubmit=\"return confirm('Are you sure you want to archive/prune the selected topic?')\">\n";
	print "<TABLE BGCOLOR=#ffffcc BORDER=1 WIDTH=100%><TR><TD>\n";
	print "<TABLE><TR><TD>$fs<B>Topic:</B></FONT></TD><TD><SELECT NAME=topic SIZE=1>\n";
	foreach $t (@t) {
		$t =~ m|<!-Top: (\d+)-!>|;
		$d = $1;
		&extract("//$d/$d.$ext");
		print "<OPTION VALUE=$d> $topic_name\n";
	}
	print "</SELECT></TD></TR>\n";
	print "<TR><TD>$fs<B>Operation:</B></FONT></TD><TD>";
	print "<SELECT NAME=dowhat SIZE=1>\n";
	print "<OPTION VALUE=archive SELECTED>Archive (move)\n";
	print "<OPTION VALUE=prune>Prune (delete)\n";
	print "</SELECT>\n";
	print "</TD></TR>\n";
	print "<TR><TD>$fs<B>Threshold:</B></FONT></TD><TD>";
	print "<INPUT TYPE=TEXT	NAME=prune_days VALUE=30 SIZE=5>$fs days</TD></TR></TABLE><P>\n";
	print "<INPUT TYPE=SUBMIT VALUE='Archive/Prune Messages'>\n";
	print "</TD></TR></TABLE>\n";
	print "<INPUT TYPE=HIDDEN NAME=username VALUE=$superuser>\n";
	print "<INPUT TYPE=HIDDEN NAME=action VALUE=prune_board>\n";
	print "</FORM></FONT></BODY></HTML>\n";
	exit(0);
}

#---SEPARATOR---#
#REQ:regenerate_message
#REQ:add_page
#REQ:get_number
#REQ:new_file
#REQ:change_board_colors
#REQ:incremental
#REQ:show_gauge

sub prune_messages {
	my ($topic, $tempfile, $dowhat, $prune_days, $place) = @_;
	my ($head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src);
	if ($FORM{'place'} eq "") {
		($fileref, $counter, $tempfiler) = &incremental("PRUNE", 1, "", $topic);
		&show_gauge("\U$FORM{'dowhat'}\E Operation", "Estimating time to \U$FORM{'dowhat'}\E this topic", 0, "$cgiurl?username=$superuser&action=prune_board&counter=$counter&tempfiler=$tempfiler&place=1&prune_days=$FORM{'prune_days'}&topic=$topic&dowhat=$FORM{'dowhat'}");
	}
	if ($FORM{'place'} eq "1") {
		&lock("prune_messages", "*");
		($fileref) = &incremental($FORM{'tempfiler'}, 2, "", "");
		@TEMPFILER = @{$fileref};
		$starttime = time;
		$returned = "";
		$sec_due_to_factor = int($GLOBAL_OPTIONS{'reindex_factor'} / 30);
		open (TREE, "$admin_dir/msg_index/$topic-tree.txt");
		@TREE_STRUCTURE_FILE = <TREE>;
		close (TREE);
		undef %ddd;
		$cutoff = time - (24 * 60 * 60 * $FORM{'prune_days'});
		$topic_is_running = $topic;
		$ft = time;
		$total_messages_touched = 0;
O:		while (time <= ($starttime + 2 + $sec_due_to_factor)) {
			$file = shift(@TEMPFILER);
			last if $file eq "";
			$file =~ m|(\d+)/(\d+)\.$ext|; $page = $2; $topic = $1;
			$i_used_topic = $topic if $topic > 0;
			($head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src) = &get_page($topic, $page);
			@sublist = split(/\n/, $sublist);
I:			foreach $st (@sublist) {
				if ($st =~ m|<!-Top: (\d+)-!>|) {
					$x = $1;
					if (grep(/^$topic\/$x\.$ext/, @TEMPFILER)) {
						push (@TEMPFILER, $file);
						redo O;
					}
				}
			}
			$FORM{'done'} += 1;
			$file =~ m|(\d+)/(\d+)\.$ext|; $page = $2; $topic = $1;
			if ($topic_is_running != $topic && $topic_is_running > 0) {
				unshift(@TEMPFILER, $file);
				last;
			}
			undef @newmsg; $flag = 0;
			($head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src) = &get_page($topic, $page);
			next if ($head =~ m|<!--Param: (\w*)Archive(\w*)-->| && $FORM{'dowhat'} eq "archive");
			next if ($head =~ m|<!--Param: (\w*)Notouch(\w*)-->|);
			@msg = split(/\n/, $message); $lastpost = 0;
MX:			foreach $line (@msg) {
				if ($line =~ m|<!-Post: (\d+)-!>(.*)<!-Time: (\d+)-!>|) {
					($post, $time) = ($1, $3);
					next MX if $time > $cutoff;
					$lastpost = $time if $time > $lastpost;
					$flag = 1;
					$total_messages_touched += 1;
					push (@newmsg, $line);
					$line = "";
				} elsif ($line =~ m|<!-Post: (\d+)-!>|) {
					$post = $1;
					$flag = 1;
					$total_messages_touched += 1;
					push (@newmsg, $line);
					$line = "";
				} elsif ($line =~ m|<!-/Post: (\d+)-!>|) {
					if ($flag == 1) {
						$flag = 0;
						push (@newmsg, $line);
						$line = "";
					}
				} elsif ($flag == 1) {
					push (@newmsg, $line);
					$line = "";
				}
			}
			next if scalar(@newmsg) == 0;
			@msg = grep(/\S/, @msg);
			$message = join("\n", @msg);
			$message = &regenerate_message($topic, $page, $message);
			($txl) = grep(/^(\d+)\t$topic\t$page\t/, @TREE_STRUCTURE_FILE);
			chomp $txl;
			@c = split(/\t/, $txl); @x = split(/,/, $c[11]); undef @y;
			foreach $line (@newmsg) {
				if ($line =~ m|<!-Post: (\d+)-!>|) {
					$p = $1;
					@x = grep(!/^$p$/, @x);
					push (@y, $p);
				}
			}
			$c[11] = join(",", @x);
			$txl = join("\t", @c);
			$txl .= "\n";

#########################################
### ARCHIVING ACTION

			if ($dowhat eq "archive") {
				next if scalar(@msg) == 0;
				$num = &get_number(12345);
				$new_page = $L{'ARCHIVE_SUBTOPIC_NAME'};
				$lastpost = time if $lastpost <= 0;
				($dt) = &get_date_time('dateonly', $lastpost);
				$new_page =~ s/\%date/$dt/g;
				$ct = 0; $lastnum = $page;
				foreach $line (@TREE_STRUCTURE_FILE) {
					@c = split(/\t/, $line);
					if ($c[3] == $page) {
						$lastnum = $c[2];
					} elsif ($c[2] == $page) {
						$line = $txl;
					}
				}
TSFL:			foreach $line (@TREE_STRUCTURE_FILE) {
					@c = split(/\t/, $line);
					$ct++;
					if ($c[1] == $topic && $c[2] == $lastnum) {
						$poster_name = "-";
						$newline = join("\t", ($c[0]+1), $c[1], $num, $page, &escape($new_page), "ArchiveMessages", $owner, scalar(@y), $lastpost, $lastpost, "-", join(",", @y));
						$newline .= "\n";
						if ($c[5] !~ m|Sublist|) {
							$c[5] .= "Sublist";
							$line = join("\t", @c);
						}
						splice(@TREE_STRUCTURE_FILE, $ct, 0, $newline);
						last TSFL;
					}
				}
				foreach $xx (@y) {
					$ddd{$xx} = $num;
				}
				@sublist = split(/\n/, $sublist);
				$url = "$message_url/$topic/$num.$ext";
				$url .= "?$lasttime" if !$noqm;
				$st = &get_date_time("shorter", $lasttime);
				push (@sublist, "<!-Top: $num-!>" . &format_subtopics($url, $new_page, $st, "-", 0));
				$sublist = join("\n", @sublist);
				if ($head =~ m|<!--Param: (\w+)-->|) {
					$p = $1; $b = $`; $a = $';
					if ($p !~ m|Sublist|) {
						$head = join("", $b, "<!--Param: Sublist$p-->", $a);
					}
				}
				$head =~ m|<!--Owner: (\w+)-->|; $owner = $1;
				&set_page($topic, $page, $head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src);
				&new_file ($topic, $num, $page, $owner, $new_page, "ArchiveMessages", $lasttime, "", 12345);
				($head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src) = &get_page($topic, $num);
				$message = join("\n", @newmsg);
				$message = &regenerate_message($topic, $num, $message);
				&set_page($topic, $num, $head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src);
				open (SRC, "$admin_dir/msg_index/$topic/$page-src.txt");
				@src = <SRC>;
				close (SRC);
				open (SRCNEW, ">$admin_dir/msg_index/$topic/$num-src.txt");
				foreach $l (@src) {
					($s, $src) = split(/\s/, $l);
					if (grep(/^$s$/, @src)) {
						print SRCNEW $l;
						$l = "";
					}
				}
				@src = grep(/\S/, @src);
				open (SRC, ">$admin_dir/msg_index/$topic/$page-src.txt");
				print SRC @src;
				close (SRC);
			} else {
#########################################
### PRUNING ACTION
				$pg_gone = 0; undef %thisddd;
				if (!grep(/^<!-Post: (\d+)-!>/, @msg)) {
					$head =~ m|<!--Param: (\w+)-->|;
					$p = $1;
					$p =~ s/Messages//;
					$p =~ s/Add//;
					$p =~ s/Archive//;
					$p =~ s/Create//;
					if ($sublist !~ m|<!-Top: (\d+)-!>| && $p =~ m|Sublist|) {
						$p =~ s/Sublist//;
					}
					$pg_gone = 1 if $p eq "";
				}
				foreach $line (@newmsg) {
					if ($line =~ m|<!-Post: (\d+)-!>|) {
						($post, $time) = ($1, $2);
						$ddd{$post} = -1; $thisddd{$post} = 1;
					}
				}
				if ($pg_gone == 1) {
					unlink("$message_dir/$topic/$page.$ext") if -e "$message_dir/$topic";
					unlink("$secdir/$topic/$page.$ext") if -e "$secdir/$topic";
					$head =~ m|<!--Parent: (\d+)--|; $hold_my_parent = $1;
				} else {
					@msg = grep(/\S/, @msg); $message = join("\n", @msg);
					$message = &regenerate_message($topic, $page, $message);
					&set_page($topic, $page, $head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src);
				}
				undef %updates; $found  = 0;
				foreach $linet (reverse(@TREE_STRUCTURE_FILE)) {
					@c = split(/\t/, $linet);
					if ($c[1] == $topic && $c[2] == $page) {
						chomp $linet;
						@c = split(/\t/, $linet);
						if ($pg_gone == 0) {
							@x = split(/,/, $c[11]);
							foreach $x (@x) {
								if ($thisddd{$x} == 1) {
									$x = "";
								}
							}
						}
						$found = 1;
						$c[7] -= scalar(keys(%thisddd));
						$c[11] = join(",", @x);
						$linet = join("\t", @c);
						$linet .= "\n";
						$updates{$c[3]} = 1;
						$linet = "" if $pg_gone == 1;
					} elsif ($updates{$c[2]} == 1) {
						$updates{$c[3]} = 1;
						$c[7] -= scalar(keys(%thisddd));
						$linet = join("\t", @c);
						$linet .= "\n" if $linet !~ m|\n$|;
					}
				}
				$x = scalar(@TREE_STRUCTURE_FILE);
				&log_error("src-board-subs-104", "prune_messages", "Did not find tree entry for $topic/$page among $x entries in current tree file") if $found == 0;
				if ($pg_gone == 1) {
					@TREE_STRUCTURE_FILE = grep(/\S/, @TREE_STRUCTURE_FILE);
					($head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src) = &get_page($topic, $hold_my_parent);
					@sl = split(/\n/, $sublist);
					@sl = grep(!/<!-Top: $page-!>/, @sl);
					$sublist = join("\n", @sl);
					&set_page($topic, $hold_my_parent, $head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src);
					unlink("$admin_dir/msg_index/$topic/$page-src.txt");
				} else {
					open (SRC, "$admin_dir/msg_index/$topic/$page-src.txt");
					@src = <SRC>;
					close (SRC);
					foreach $l (@src) {
						($s, $src) = split(/\s/, $l);
						$l = "" if $ddd{$s};
					}
					@src = grep(/\S/, @src);
					open (SRC, ">$admin_dir/msg_index/$topic/$page-src.txt");
					print SRC @src;
					close (SRC);
				}
			}
		}
		$ref = \@TREE_STRUCTURE_FILE;
		&safe_write("$admin_dir/msg_index/$topic-tree.txt", $ref);
		if ($total_messages_touched && $dowhat ne "archive") {
			open (TREE, "$admin_dir/tree.txt");
			@TREE_STRUCTURE_FILE = <TREE>;
			close (TREE);
			foreach $line (@TREE_STRUCTURE_FILE) {
				@c = split(/\t/, $line);
				if ($c[1] == $topic) {
					$c[7] -= $total_messages_touched;
					$line = join("\t", @c);
					last;
				}
			}
			$ref = \@TREE_STRUCTURE_FILE;
			&safe_write("$admin_dir/tree.txt", $ref);
		}
		open (LOG, "$admin_dir/msg_index/$topic-log.txt");
		open (LOGNEW, ">$admin_dir/msg_index/$topic-log.txt.NEW");
		while (<LOG>) {
			@c = split(/;/, $_);
			if ($ddd{$c[0]} != 0) {
				if ($ddd{$c[0]} == -1) {
					next;
				} else {
					($tpc, $pg) = split(/\//, $c[3]);
					$c[3] = join("/", $tpc, $ddd{$c[0]});
					$line = join(";", @c);
					$line .= "\n";
					$msgsize += length($line);
					print LOGNEW $line;
				}
			} else {
				print LOGNEW $_;
				$msgsize += length($_);
			}
		}
		close (LOG);
		close (LOGNEW);
		&rename_file("$admin_dir/msg_index/$topic-log.txt", $msgsize);
		if ($FORM{'dowhat'} eq "prune" && scalar(keys(%ddd))) {
			open (ATTACH, "$admin_dir/msg_index/attach-mgr.txt");
			while (<ATTACH>) {
				($num, $stuff) = split(/\s+/, $_);
				if ($ddd{$num} != -1) {
					push (@attach, $_);
				} else {
					chomp $stuff;
					unlink("$message_dir/$topic/$stuff");
					unlink("$secdir/$topic/$stuff");
				}
			}
			close (ATTACH);
			open (ATTACH, ">$admin_dir/msg_index/attach-mgr.txt");
			print ATTACH @attach;
			close (ATTACH);
		}
		open (SEARCH, "$admin_dir/msg_index/$topic-search.txt");
		open (SEARCHNEW, ">$admin_dir/msg_index/$topic-search.txt.NEW");
		$searchsize = 0;
		while (<SEARCH>) {
			chomp;
			($post, $topic, $page, $stuff) = split(/\s+/, $_, 4);
			if ($ddd{$post} != 0) {
				$_ = "" if $ddd{$post} == -1;
				$_ = join(" ", $post, $topic, $ddd{$post}, $stuff) if $ddd{$post} > 0;
				$_ .= "\n" if $ddd{$post} > 0;
				$searchsize += length($_);
				print SEARCHNEW $_;
			} else {
				print SEARCHNEW $_;
				$searchnew += length($_);
			}
		}
		close (SEARCH);
		close (SEARCHNEW);
		&rename_file("$admin_dir/msg_index/$topic-search.txt", $searchsize);
		$fileref = \@TEMPFILER;
		($status, $foo, $tempfiler) = &incremental($FORM{'tempfiler'}, 3, $fileref);
		if ($status) {
			if ($FORM{'counter'} > 0) {
				$pct = $FORM{'done'} / $FORM{'counter'};
			} else {
				$pct = 0;
			}
			&unlock("prune_messages", "*");
			&show_gauge("\U$FORM{'dowhat'}\E Operation", "\U$FORM{'dowhat'}\E action - $FORM{'done'} of $FORM{'counter'} processed", $pct, "$cgiurl?username=$superuser&action=prune_board&tempfiler=$tempfiler&done=$FORM{'done'}&counter=$FORM{'counter'}&dowhat=$FORM{'dowhat'}&topic=$FORM{'topic'}&prune_days=$FORM{'prune_days'}&place=1");
		}
		&unlock("prune_messages", "*");
		undef @TREE_STRUCTURE_FILE;
		&change_board_colors("*");
		&show_gauge("\U$FORM{'dowhat'}\E Operation", "Preparing to regenerate topic to update information", 0, "$cgiurl2?username=$superuser&action=templates&rrrrr=2&sssss=1&tpclist=$i_used_topic");
	}
}

#---SEPARATOR---#

sub ip_ban_form {
	print "<B>IP Banning</B>\n";
	print "<BLOCKQUOTE>\n";
	print "You can ban users by IP address or number from all access to scripts.  This will prevent posting, searching, and\n";
	print "administration from any of the domains you specify.  You may use * as a\n";
	print " wildcard character.  Note that this banning overrides any settings from the Access Manager.  <FONT COLOR=#0000aa><B><U>Enter one address/pattern per box.</U></B></FONT><P>\n";
	if ($GLOBAL_OPTIONS{'ip_banned_list'}) {
		@ips = split(/,/, $GLOBAL_OPTIONS{'ip_banned_list'});
		foreach $ip (@ips) {
			print "<INPUT TYPE=CHECKBOX NAME=ip_banned_list VALUE=$ip CHECKED> ", $GLOBAL_OPTIONS{"ip_banned_$ip"}, "<BR>\n";
		}
	}
	print "<INPUT TYPE=CHECKBOX NAME=ip_banned_new VALUE=1></FONT> <INPUT NAME=ip_banned_NEW SIZE=20 TYPE=TEXT VALUE='' onChange=\"document.forms[0].ip_banned_new.checked = true\">\n";
	print "$fs<P></BLOCKQUOTE>\n";
}

#---SEPARATOR---#

sub check_ban_ip {
	if ($GLOBAL_OPTIONS{'ip_banned_list'} ne "") {
		my @ip = split(/,/, $GLOBAL_OPTIONS{'ip_banned_list'});
		foreach my $ipb (@ip) {
			my $RA = $ENV{'REMOTE_ADDR'};
			my $RH = $ENV{'REMOTE_HOST'};
			my $iph = $GLOBAL_OPTIONS{"ip_banned_$ipb"};
			$iph =~ s/\s//g;
			next if $iph eq "";
			my $ip = quotemeta($iph);
			$ip =~ s/\\\*/\(\.\+\)/g;
			my $a = 0;
			$a = 1 if $RA =~ m|^$ip$|i;
			$a = 1 if $RH =~ m|^$ip$|i;
			if ($a) {
				undef my $f;
				if ($0 =~ m|(.*)/|) {
					$f = $';
				} else {
					$f = $0;
				}
				&log_error("src-board-subs-104", "check_ban_ip", "Visitor $RH [$RA] banned under rule [$iph] for file $f");
				&error_message($L{IP_BANNED}, $L{IP_BANNED_MESSAGE}, 0, 1);
			}
		}
	}
}

#---SEPARATOR---#

sub save_archive_options {
	my (@outfile);
	foreach $key (keys(%FORM)) {
		$t = 0;
		if ($key =~ m|^archive_(\d+)|) {
			$t = $1;
			push (@outfile, "archive_$t=1\n");
		} elsif ($key =~ m|^pruning_(\d+)|) {
			$t = $1;
			push (@outfile, "prune_$t=1\n");
		}
		if ($t != 0) {
			$max = $FORM{"archive_msgs_$t"}; $leave = $FORM{"archive_leave_$t"};
			&error_message("Archive Specification Error", "Maximum messages in thread must be nonzero") if $max <= 0;
			&error_message("Archive Specification Error", "Messages to leave in thread must be nonnegative") if $leave < 0;
			&error_message("Archive Specification Error", "Maximum messages in thread must be greater than number of messages to leave in thread") if $max <= $leave;
			push (@outfile, "msgs_$t=$max\n");
			push (@outfile, "leave_$t=$leave\n");
			$t = 0;
		}
	}
	&lock("save_archive_options", "$admin_dir/archive.txt");
	open (FILE, ">$admin_dir/archive.txt") || &error_message("File Write Error", "Could not write to $admin_dir/archive.txt");
	print FILE @outfile;
	close (FILE);
	&unlock("save_archive_options", "$admin_dir/archive.txt");
}

#---SEPARATOR---#
#REQ:move_message
#REQ:remove_message

sub auto_prune {
	my ($topic_number, $page_number) = @_;
	open (ARCHIVE_CFG, "$admin_dir/archive.txt");
	@archive = <ARCHIVE_CFG>;
	close (ARCHIVE_CFG);
	undef %archive;
	foreach $line (@archive) {
		chomp $line;
		if ($line =~ m|^(\w+)=(\w+)|) {
			$archive{$1} = $2;
		}
	}
	if ($archive{"archive_$topic_number"} == 1 || $archive{"prune_$topic_number"} == 1) {
		my ($head, $color, $lm, $ann, $ann_src, $sublist, $about, $about_src, $message, $message_src, $description_src) = &get_page($topic_number, $page_number);
		@msg = split(/\n/, $message);
		$message_count = scalar(grep(/^<!-Post: (\d+)-!>/, @msg));
		$max = $archive{"msgs_$topic_number"};
		$leave = $archive{"leave_$topic_number"};
		$acton = ($message_count - $leave);
		return 1 if $message_count < $max;
		undef %posts;
		foreach $line (@msg) {
			if ($line =~ m|<!-Post: (\d+)-!><!-Time: (\d+)-!>|) {
				($post, $time) = ($1, $2);
				$posts{$post} = $time;
			}
		}
		@postbyorder = sort {$posts{$a} <=> $posts{$b};} keys(%posts);
		undef @actions;
		for ($ctr = 1; $ctr <= $acton; $ctr++) {
			$x = shift(@postbyorder);
			push (@actions, $x); $lastpost = $posts{$x};
		}
		$poststr = join(",", @actions);
		if ($archive{"prune_$topic_number"} == 1) {
			delete $TPC_TREE{$topic_number};
			&remove_message($topic_number, $page_number, $poststr);
		} elsif ($archive{"archive_$topic_number"} == 1) {
			$new_page = $L{'ARCHIVE_SUBTOPIC_NAME'};
			($dt) = &get_date_time('dateonly', $lastpost);
			$new_page =~ s/\%date/$dt/g;
			&move_message($topic_number, $page_number, $poststr, "Create", $new_page, 10402, 0, $lasttime, 1);
		}
	}
}

#---SEPARATOR---#
#REQ:queue_action
#REQ:show_gauge

sub queue_approver {
	my ($queued_messages, $tempfile, $username, $total, $mycounter, @tempfile) = @_;
	if (!$queued_messages && $tempfile eq "") {
		&error_message("Approve Message Action", "You did not select any messages to approve!", 0, 1);
	}
	if (!$tempfile) {
		$tempfile = join("", $$, time, "Q"); $tempfile =~ s/\W//g;
		open (TEMPFILE, ">$admin_dir/msg_index/$tempfile.TMP") || &error_message("Approve Message Action", "Could not approve queued messages due to temporary file writing error.");
		print TEMPFILE $queued_messages;
		close (TEMPFILE);
		@x = split(/,/, $queued_messages); $mcnt = scalar(@x); $plural_s = ""; $plural_s = "s" if $mcnt != 1;
		&show_gauge("Approving messages", "Estimating time needed to approve $mcnt queued message$plural_s", 0, "$cgiurl?action=queue_approver&username=$username&tempfile=$tempfile&total=$mcnt");
	} else {
		$tempfile =~ s/\W//g;
		open (TEMPFILE, "$admin_dir/msg_index/$tempfile.TMP") || &error_message("Approve Message Action", "Temporary file $tempfile cannot be read!");
		@tempfile = <TEMPFILE>;
		close (TEMPFILE);
		$timer_mark = time;
		$queued_messages = $tempfile[0]; chomp $queued_messages;
		my (@x);
		@x = split(/,/, $queued_messages);
		$timelimit = $GLOBAL_OPTIONS{'reindex_factor'} / 5;
		$timelimit = 3 if $timelimit < 1;
		while (scalar(@x) > 0) {
			$qmindex = pop(@x);
			&queue_action($username, $qmindex, "approve", 1, 1);
			$mycounter += 1;
			if (time >= ($timer_mark + $timelimit) && scalar(@x) > 0) {
				$str = join(",", @x);
				open (TEMPFILE, ">$admin_dir/msg_index/$tempfile.TMP") || &error_message("Approve Message Action", "Could not re-write temporary file!");
				print TEMPFILE $str;
				close (TEMPFILE);
				&show_gauge("Approving messages", "$mycounter of $total message(s) approved", $mycounter/$total, "$cgiurl?action=queue_approver&username=$username&tempfile=$tempfile&total=$total&mycounter=$mycounter");
			}
		}
		unlink("$admin_dir/msg_index/$tempfile.TMP");
		return 1;
	}
	&error_message("Queue_approver error message 1", "Fell through subroutine.  You should never see this message. Contact DiscusWare Support.", 0, 1);
}

#---SEPARATOR---#
#REQ:userapp_action
#REQ:show_gauge

sub userapp_approver {
	my ($username, $marked, $tempfile, $total, $mycounter) = @_;
	if (!$marked && !$tempfile) {
		&error_message("Approve Users Action", "You did not select any users to approve!", 0, 1);
	}
	if (!$tempfile) {
		$tempfile = join("", $$, time, "UQ"); $tempfile =~ s/\W//g;
		open (TEMPFILE, ">$admin_dir/msg_index/$tempfile.TMP") || &error_message("Approve Users Action", "Could not approve queued users due to temporary file writing error.");
		print TEMPFILE $marked;
		close (TEMPFILE);
		@x = split(/,/, $marked); $mcnt = scalar(@x); $plural_s = ""; $plural_s = "s" if $mcnt != 1;
		&show_gauge("Approving users", "Estimating time needed to approve $mcnt queued user$plural_s", 0, "$cgiurl3?action=userapp_approver&username=$username&tempfile=$tempfile&total=$mcnt");
	} else {
		$tempfile =~ s/\W//g;
		open (TEMPFILE, "$admin_dir/msg_index/$tempfile.TMP") || &error_message("Approve Users Action", "Temporary file $tempfile cannot be read!");
		@tempfile = <TEMPFILE>;
		close (TEMPFILE);
		$timer_mark = time;
		$queued_users = $tempfile[0]; chomp $queued_users;
		my (@x);
		@x = split(/,/, $queued_users);
		$timelimit = $GLOBAL_OPTIONS{'reindex_factor'} / 5;
		$timelimit = 3 if $timelimit < 1;
		while (scalar(@x) > 0) {
			$qmindex = pop(@x);
			&userapp_action($username, $qmindex, "approve");
			$mycounter += 1;
			if (time >= ($timer_mark + $timelimit) && scalar(@x) > 0) {
				$str = join(",", @x);
				open (TEMPFILE, ">$admin_dir/msg_index/$tempfile.TMP") || &error_message("Approve Users Action", "Could not re-write temporary file!");
				print TEMPFILE $str;
				close (TEMPFILE);
				&show_gauge("Approving users", "$mycounter of $total user(s) approved", $mycounter/$total, "$cgiurl3?action=userapp_approver&username=$username&tempfile=$tempfile&total=$total&mycounter=$mycounter");
			}
		}
		unlink("$admin_dir/msg_index/$tempfile.TMP");
		return 1;
	}
	&error_message("Queue_approver error message 2", "Fell through subroutine.  You should never see this message. Contact DiscusWare Support.", 0, 1);
}

# END - FILE IS CORRECTLY UPLOADED #
