Initial population
authorDan
Wed, 11 Jul 2007 21:01:48 -0400
changeset 0 f9ffdbd96607
child 1 8f6143115bf5
Initial population
plugins/PunBB.php
punbb/COPYING
punbb/admin_bans.php
punbb/admin_categories.php
punbb/admin_censoring.php
punbb/admin_forums.php
punbb/admin_groups.php
punbb/admin_index.php
punbb/admin_loader.php
punbb/admin_maintenance.php
punbb/admin_options.php
punbb/admin_permissions.php
punbb/admin_prune.php
punbb/admin_ranks.php
punbb/admin_reports.php
punbb/admin_users.php
punbb/cache/.htaccess
punbb/cache/index.html
punbb/delete.php
punbb/edit.php
punbb/extern.php
punbb/footer.php
punbb/header.php
punbb/help.php
punbb/img/avatars/index.html
punbb/img/index.html
punbb/img/smilies/big_smile.png
punbb/img/smilies/cool.png
punbb/img/smilies/hmm.png
punbb/img/smilies/index.html
punbb/img/smilies/lol.png
punbb/img/smilies/mad.png
punbb/img/smilies/neutral.png
punbb/img/smilies/roll.png
punbb/img/smilies/sad.png
punbb/img/smilies/smile.png
punbb/img/smilies/tongue.png
punbb/img/smilies/wink.png
punbb/img/smilies/yikes.png
punbb/include/cache.php
punbb/include/common.php
punbb/include/common_admin.php
punbb/include/dblayer/common_db.php
punbb/include/dblayer/index.html
punbb/include/dblayer/mysql.php
punbb/include/dblayer/mysqli.php
punbb/include/dblayer/pgsql.php
punbb/include/dblayer/sqlite.php
punbb/include/email.php
punbb/include/functions.php
punbb/include/parser.php
punbb/include/search_idx.php
punbb/include/template/admin.tpl
punbb/include/template/help.tpl
punbb/include/template/index.html
punbb/include/template/main.tpl
punbb/include/template/maintenance.tpl
punbb/include/template/redirect.tpl
punbb/index.php
punbb/install.php
punbb/lang/English/common.php
punbb/lang/English/delete.php
punbb/lang/English/forum.php
punbb/lang/English/help.php
punbb/lang/English/index.html
punbb/lang/English/index.php
punbb/lang/English/login.php
punbb/lang/English/mail_templates/activate_email.tpl
punbb/lang/English/mail_templates/activate_password.tpl
punbb/lang/English/mail_templates/form_email.tpl
punbb/lang/English/mail_templates/index.html
punbb/lang/English/mail_templates/new_reply.tpl
punbb/lang/English/mail_templates/new_reply_full.tpl
punbb/lang/English/mail_templates/welcome.tpl
punbb/lang/English/misc.php
punbb/lang/English/post.php
punbb/lang/English/prof_reg.php
punbb/lang/English/profile.php
punbb/lang/English/register.php
punbb/lang/English/search.php
punbb/lang/English/stopwords.txt
punbb/lang/English/topic.php
punbb/lang/English/userlist.php
punbb/lang/index.html
punbb/login.php
punbb/misc.php
punbb/moderate.php
punbb/plugins/AMP_Example.php
punbb/plugins/index.html
punbb/post.php
punbb/profile.php
punbb/register.php
punbb/search.php
punbb/style/Cobalt.css
punbb/style/Lithium.css
punbb/style/Mercury.css
punbb/style/Oxygen.css
punbb/style/Radium.css
punbb/style/Sulfur.css
punbb/style/imports/Cobalt_cs.css
punbb/style/imports/Lithium_cs.css
punbb/style/imports/Mercury_cs.css
punbb/style/imports/Oxygen_cs.css
punbb/style/imports/Radium_cs.css
punbb/style/imports/Sulfur_cs.css
punbb/style/imports/base.css
punbb/style/imports/base_admin.css
punbb/style/imports/index.html
punbb/style/imports/minmax.js
punbb/style/index.html
punbb/userlist.php
punbb/viewforum.php
punbb/viewtopic.php
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/PunBB.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,1 @@
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/COPYING	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_bans.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,362 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_MOD || ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_ban_users'] == '0'))
+	message($lang_common['No permission']);
+
+
+// Add/edit a ban (stage 1)
+if (isset($_REQUEST['add_ban']) || isset($_GET['edit_ban']))
+{
+	if (isset($_GET['add_ban']) || isset($_POST['add_ban']))
+	{
+		// If the id of the user to ban was provided through GET (a link from profile.php)
+		if (isset($_GET['add_ban']))
+		{
+			$add_ban = intval($_GET['add_ban']);
+			if ($add_ban < 2)
+				message($lang_common['Bad request']);
+
+			$user_id = $add_ban;
+
+			$result = $db->query('SELECT group_id, username, email FROM '.$db->prefix.'users WHERE id='.$user_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+			if ($db->num_rows($result))
+				list($group_id, $ban_user, $ban_email) = $db->fetch_row($result);
+			else
+				message('No user by that ID registered.');
+		}
+		else	// Otherwise the username is in POST
+		{
+			$ban_user = trim($_POST['new_ban_user']);
+
+			if ($ban_user != '')
+			{
+				$result = $db->query('SELECT id, group_id, username, email FROM '.$db->prefix.'users WHERE username=\''.$db->escape($ban_user).'\' AND id>1') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+				if ($db->num_rows($result))
+					list($user_id, $group_id, $ban_user, $ban_email) = $db->fetch_row($result);
+				else
+					message('No user by that username registered. If you want to add a ban not tied to a specific username just leave the username blank.');
+			}
+		}
+
+		// Make sure we're not banning an admin
+		if (isset($group_id) && $group_id == PUN_ADMIN)
+			message('The user '.pun_htmlspecialchars($ban_user).' is an administrator and can\'t be banned. If you want to ban an administrator, you must first demote him/her to moderator or user.');
+
+		// If we have a $user_id, we can try to find the last known IP of that user
+		if (isset($user_id))
+		{
+			$result = $db->query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE poster_id='.$user_id.' ORDER BY posted DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+			$ban_ip = ($db->num_rows($result)) ? $db->result($result) : '';
+		}
+
+		$mode = 'add';
+	}
+	else	// We are editing a ban
+	{
+		$ban_id = intval($_GET['edit_ban']);
+		if ($ban_id < 1)
+			message($lang_common['Bad request']);
+
+		$result = $db->query('SELECT username, ip, email, message, expire FROM '.$db->prefix.'bans WHERE id='.$ban_id) or error('Unable to fetch ban info', __FILE__, __LINE__, $db->error());
+		if ($db->num_rows($result))
+			list($ban_user, $ban_ip, $ban_email, $ban_message, $ban_expire) = $db->fetch_row($result);
+		else
+			message($lang_common['Bad request']);
+
+		$ban_expire = ($ban_expire != '') ? date('Y-m-d', $ban_expire) : '';
+
+		$mode = 'edit';
+	}
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Bans';
+	$focus_element = array('bans2', 'ban_user');
+	require PUN_ROOT.'header.php';
+
+	generate_admin_menu('bans');
+
+
+?>
+	<div class="blockform">
+		<h2><span>Ban advanced settings</span></h2>
+		<div class="box">
+			<form id="bans2" method="post" action="admin_bans.php">
+				<div class="inform">
+				<input type="hidden" name="mode" value="<?php echo $mode ?>" />
+<?php if ($mode == 'edit'): ?>				<input type="hidden" name="ban_id" value="<?php echo $ban_id ?>" />
+<?php endif; ?>				<fieldset>
+						<legend>Supplement ban with IP and e-mail</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Username</th>
+									<td>
+										<input type="text" name="ban_user" size="25" maxlength="25" value="<?php if (isset($ban_user)) echo pun_htmlspecialchars($ban_user); ?>" tabindex="1" />
+										<span>The username to ban.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">IP-adresses</th>
+									<td>
+										<input type="text" name="ban_ip" size="45" maxlength="255" value="<?php if (isset($ban_ip)) echo $ban_ip; ?>" tabindex="2" />
+										<span>The IP or IP-ranges you wish to ban (e.g. 150.11.110.1 or 150.11.110). Separate addresses with spaces. If an IP is entered already it is the last known IP of this user in the database.<?php if ($ban_user != '' && isset($user_id)) echo ' Click <a href="admin_users.php?ip_stats='.$user_id.'">here</a> to see IP statistics for this user.' ?></span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">E-mail/domain</th>
+									<td>
+										<input type="text" name="ban_email" size="40" maxlength="50" value="<?php if (isset($ban_email)) echo strtolower($ban_email); ?>" tabindex="3" />
+										<span>The e-mail or e-mail domain you wish to ban (e.g. someone@somewhere.com or somewhere.com). See "Allow banned e-mail addresses" in Options for more info.</span>
+									</td>
+								</tr>
+							</table>
+							<p class="topspace"><strong class="warntext">You should be very careful when banning an IP-range because of the possibility of multiple users matching the same partial IP.</strong></p>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Ban message and expiry</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Ban message</th>
+									<td>
+										<input type="text" name="ban_message" size="50" maxlength="255" value="<?php if (isset($ban_message)) echo pun_htmlspecialchars($ban_message); ?>" tabindex="4" />
+										<span>A message that will be displayed to the banned user when he/she visits the forums.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Expire date</th>
+									<td>
+										<input type="text" name="ban_expire" size="17" maxlength="10" value="<?php if (isset($ban_expire)) echo $ban_expire; ?>" tabindex="5" />
+										<span>The date when this ban should be automatically removed (format: YYYY-MM-DD). Leave blank to remove manually.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<p class="submitend"><input type="submit" name="add_edit_ban" value=" Save " tabindex="6" /></p>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+// Add/edit a ban (stage 2)
+else if (isset($_POST['add_edit_ban']))
+{
+	confirm_referrer('admin_bans.php');
+
+	$ban_user = trim($_POST['ban_user']);
+	$ban_ip = trim($_POST['ban_ip']);
+	$ban_email = strtolower(trim($_POST['ban_email']));
+	$ban_message = trim($_POST['ban_message']);
+	$ban_expire = trim($_POST['ban_expire']);
+
+	if ($ban_user == '' && $ban_ip == '' && $ban_email == '')
+		message('You must enter either a username, an IP address or an e-mail address (at least).');
+	else if (strtolower($ban_user) == 'guest')
+		message('The guest user cannot be banned.');
+
+	// Validate IP/IP range (it's overkill, I know)
+	if ($ban_ip != '')
+	{
+		$ban_ip = preg_replace('/[\s]{2,}/', ' ', $ban_ip);
+		$addresses = explode(' ', $ban_ip);
+		$addresses = array_map('trim', $addresses);
+
+		for ($i = 0; $i < count($addresses); ++$i)
+		{
+			$octets = explode('.', $addresses[$i]);
+
+			for ($c = 0; $c < count($octets); ++$c)
+			{
+				$octets[$c] = (strlen($octets[$c]) > 1) ? ltrim($octets[$c], "0") : $octets[$c];
+
+				if ($c > 3 || preg_match('/[^0-9]/', $octets[$c]) || intval($octets[$c]) > 255)
+					message('You entered an invalid IP/IP-range.');
+			}
+
+			$cur_address = implode('.', $octets);
+			$addresses[$i] = $cur_address;
+		}
+
+		$ban_ip = implode(' ', $addresses);
+	}
+
+	require PUN_ROOT.'include/email.php';
+	if ($ban_email != '' && !is_valid_email($ban_email))
+	{
+		if (!preg_match('/^[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$/', $ban_email))
+			message('The e-mail address (e.g. user@domain.com) or partial e-mail address domain (e.g. domain.com) you entered is invalid.');
+	}
+
+	if ($ban_expire != '' && $ban_expire != 'Never')
+	{
+		$ban_expire = strtotime($ban_expire);
+
+		if ($ban_expire == -1 || $ban_expire <= time())
+			message('You entered an invalid expire date. The format should be YYYY-MM-DD and the date must be at least one day in the future.');
+	}
+	else
+		$ban_expire = 'NULL';
+
+	$ban_user = ($ban_user != '') ? '\''.$db->escape($ban_user).'\'' : 'NULL';
+	$ban_ip = ($ban_ip != '') ? '\''.$db->escape($ban_ip).'\'' : 'NULL';
+	$ban_email = ($ban_email != '') ? '\''.$db->escape($ban_email).'\'' : 'NULL';
+	$ban_message = ($ban_message != '') ? '\''.$db->escape($ban_message).'\'' : 'NULL';
+
+	if ($_POST['mode'] == 'add')
+		$db->query('INSERT INTO '.$db->prefix.'bans (username, ip, email, message, expire) VALUES('.$ban_user.', '.$ban_ip.', '.$ban_email.', '.$ban_message.', '.$ban_expire.')') or error('Unable to add ban', __FILE__, __LINE__, $db->error());
+	else
+		$db->query('UPDATE '.$db->prefix.'bans SET username='.$ban_user.', ip='.$ban_ip.', email='.$ban_email.', message='.$ban_message.', expire='.$ban_expire.' WHERE id='.intval($_POST['ban_id'])) or error('Unable to update ban', __FILE__, __LINE__, $db->error());
+
+	// Regenerate the bans cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_bans_cache();
+
+	redirect('admin_bans.php', 'Ban '.(($_POST['mode'] == 'edit') ? 'edited' : 'added').'. Redirecting &hellip;');
+}
+
+
+// Remove a ban
+else if (isset($_GET['del_ban']))
+{
+	confirm_referrer('admin_bans.php');
+
+	$ban_id = intval($_GET['del_ban']);
+	if ($ban_id < 1)
+		message($lang_common['Bad request']);
+
+	$db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$ban_id) or error('Unable to delete ban', __FILE__, __LINE__, $db->error());
+
+	// Regenerate the bans cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_bans_cache();
+
+	redirect('admin_bans.php', 'Ban removed. Redirecting &hellip;');
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Bans';
+$focus_element = array('bans', 'new_ban_user');
+require PUN_ROOT.'header.php';
+
+generate_admin_menu('bans');
+
+?>
+	<div class="blockform">
+		<h2><span>New ban</span></h2>
+		<div class="box">
+			<form id="bans" method="post" action="admin_bans.php?action=more">
+				<div class="inform">
+					<fieldset>
+						<legend>Add ban</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Username<div><input type="submit" name="add_ban" value=" Add " tabindex="2" /></div></th>
+									<td>
+										<input type="text" name="new_ban_user" size="25" maxlength="25" tabindex="1" />
+										<span>The username to ban (case insensitive). The next page will let you enter a custom IP and e-mail. If you just want to ban a specific IP/IP-range or e-mail just leave it blank.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+			</form>
+		</div>
+
+		<h2 class="block2"><span>Existing bans</span></h2>
+		<div class="box">
+			<div class="fakeform">
+<?php
+
+$result = $db->query('SELECT id, username, ip, email, message, expire FROM '.$db->prefix.'bans ORDER BY id') or error('Unable to fetch ban list', __FILE__, __LINE__, $db->error());
+if ($db->num_rows($result))
+{
+	while ($cur_ban = $db->fetch_assoc($result))
+	{
+		$expire = format_time($cur_ban['expire'], true);
+
+?>
+				<div class="inform">
+					<fieldset>
+						<legend>Ban expires: <?php echo $expire ?></legend>
+						<div class="infldset">
+							<table cellspacing="0">
+<?php if ($cur_ban['username'] != ''): ?>								<tr>
+									<th>Username</th>
+									<td><?php echo pun_htmlspecialchars($cur_ban['username']) ?></td>
+								</tr>
+<?php endif; ?><?php if ($cur_ban['email'] != ''): ?>								<tr>
+									<th>E-mail</th>
+									<td><?php echo $cur_ban['email'] ?></td>
+								</tr>
+<?php endif; ?><?php if ($cur_ban['ip'] != ''): ?>								<tr>
+									<th>IP/IP-ranges</th>
+									<td><?php echo $cur_ban['ip'] ?></td>
+								</tr>
+<?php endif; ?><?php if ($cur_ban['message'] != ''): ?>								<tr>
+									<th>Reason</th>
+									<td><?php echo pun_htmlspecialchars($cur_ban['message']) ?></td>
+								</tr>
+<?php endif; ?>							</table>
+							<p class="linkactions"><a href="admin_bans.php?edit_ban=<?php echo $cur_ban['id'] ?>">Edit</a> - <a href="admin_bans.php?del_ban=<?php echo $cur_ban['id'] ?>">Remove</a></p>
+						</div>
+					</fieldset>
+				</div>
+<?php
+
+	}
+}
+else
+	echo "\t\t\t\t".'<p>No bans in list.</p>'."\n";
+
+?>
+			</div>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_categories.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,258 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_ADMIN)
+	message($lang_common['No permission']);
+
+
+// Add a new category
+if (isset($_POST['add_cat']))
+{
+	confirm_referrer('admin_categories.php');
+
+	$new_cat_name = trim($_POST['new_cat_name']);
+	if ($new_cat_name == '')
+		message('You must enter a name for the category.');
+
+	$db->query('INSERT INTO '.$db->prefix.'categories (cat_name) VALUES(\''.$db->escape($new_cat_name).'\')') or error('Unable to create category', __FILE__, __LINE__, $db->error());
+
+	redirect('admin_categories.php', 'Category added. Redirecting &hellip;');
+}
+
+
+// Delete a category
+else if (isset($_POST['del_cat']) || isset($_POST['del_cat_comply']))
+{
+	confirm_referrer('admin_categories.php');
+
+	$cat_to_delete = intval($_POST['cat_to_delete']);
+	if ($cat_to_delete < 1)
+		message($lang_common['Bad request']);
+
+	if (isset($_POST['del_cat_comply']))	// Delete a category with all forums and posts
+	{
+		@set_time_limit(0);
+
+		$result = $db->query('SELECT id FROM '.$db->prefix.'forums WHERE cat_id='.$cat_to_delete) or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
+		$num_forums = $db->num_rows($result);
+
+		for ($i = 0; $i < $num_forums; ++$i)
+		{
+			$cur_forum = $db->result($result, $i);
+
+			// Prune all posts and topics
+			prune($cur_forum, 1, -1);
+
+			// Delete the forum
+			$db->query('DELETE FROM '.$db->prefix.'forums WHERE id='.$cur_forum) or error('Unable to delete forum', __FILE__, __LINE__, $db->error());
+		}
+
+		// Locate any "orphaned redirect topics" and delete them
+		$result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT JOIN '.$db->prefix.'topics AS t2 ON t1.moved_to=t2.id WHERE t2.id IS NULL AND t1.moved_to IS NOT NULL') or error('Unable to fetch redirect topics', __FILE__, __LINE__, $db->error());
+		$num_orphans = $db->num_rows($result);
+
+		if ($num_orphans)
+		{
+			for ($i = 0; $i < $num_orphans; ++$i)
+				$orphans[] = $db->result($result, $i);
+
+			$db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $orphans).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error());
+		}
+
+		// Delete the category
+		$db->query('DELETE FROM '.$db->prefix.'categories WHERE id='.$cat_to_delete) or error('Unable to delete category', __FILE__, __LINE__, $db->error());
+
+		// Regenerate the quickjump cache
+		require_once PUN_ROOT.'include/cache.php';
+		generate_quickjump_cache();
+
+		redirect('admin_categories.php', 'Category deleted. Redirecting &hellip;');
+	}
+	else	// If the user hasn't comfirmed the delete
+	{
+		$result = $db->query('SELECT cat_name FROM '.$db->prefix.'categories WHERE id='.$cat_to_delete) or error('Unable to fetch category info', __FILE__, __LINE__, $db->error());
+		$cat_name = $db->result($result);
+
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Categories';
+		require PUN_ROOT.'header.php';
+
+		generate_admin_menu('categories');
+
+?>
+	<div class="blockform">
+		<h2><span>Category delete</span></h2>
+		<div class="box">
+			<form method="post" action="admin_categories.php">
+				<div class="inform">
+				<input type="hidden" name="cat_to_delete" value="<?php echo $cat_to_delete ?>" />
+					<fieldset>
+						<legend>Confirm delete category</legend>
+						<div class="infldset">
+							<p>Are you sure that you want to delete the category "<?php echo pun_htmlspecialchars($cat_name) ?>"?</p>
+							<p>WARNING! Deleting a category will delete all forums and posts (if any) in that category!</p>
+						</div>
+					</fieldset>
+				</div>
+				<p><input type="submit" name="del_cat_comply" value="Delete" /><a href="javascript:history.go(-1)">Go back</a></p>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+		require PUN_ROOT.'footer.php';
+	}
+}
+
+
+else if (isset($_POST['update']))	// Change position and name of the categories
+{
+	confirm_referrer('admin_categories.php');
+
+	$cat_order = $_POST['cat_order'];
+	$cat_name = $_POST['cat_name'];
+
+	$result = $db->query('SELECT id, disp_position FROM '.$db->prefix.'categories ORDER BY disp_position') or error('Unable to fetch category list', __FILE__, __LINE__, $db->error());
+	$num_cats = $db->num_rows($result);
+
+	for ($i = 0; $i < $num_cats; ++$i)
+	{
+		if ($cat_name[$i] == '')
+			message('You must enter a category name.');
+
+		if (!@preg_match('#^\d+$#', $cat_order[$i]))
+			message('Position must be an integer value.');
+
+		list($cat_id, $position) = $db->fetch_row($result);
+
+		$db->query('UPDATE '.$db->prefix.'categories SET cat_name=\''.$db->escape($cat_name[$i]).'\', disp_position='.$cat_order[$i].' WHERE id='.$cat_id) or error('Unable to update category', __FILE__, __LINE__, $db->error());
+	}
+
+	// Regenerate the quickjump cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_quickjump_cache();
+
+	redirect('admin_categories.php', 'Categories updated. Redirecting &hellip;');
+}
+
+
+// Generate an array with all categories
+$result = $db->query('SELECT id, cat_name, disp_position FROM '.$db->prefix.'categories ORDER BY disp_position') or error('Unable to fetch category list', __FILE__, __LINE__, $db->error());
+$num_cats = $db->num_rows($result);
+
+for ($i = 0; $i < $num_cats; ++$i)
+	$cat_list[] = $db->fetch_row($result);
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Categories';
+require PUN_ROOT.'header.php';
+
+generate_admin_menu('categories');
+
+?>
+	<div class="blockform">
+		<h2><span>Add/remove/edit categories</span></h2>
+		<div class="box">
+		<form method="post" action="admin_categories.php?action=foo">
+			<div class="inform">
+				<fieldset>
+					<legend>Add/delete categories</legend>
+					<div class="infldset">
+						<table class="aligntop" cellspacing="0">
+							<tr>
+								<th scope="row">Add a new category<div><input type="submit" name="add_cat" value="Add New" tabindex="2" /></div></th>
+								<td>
+									<input type="text" name="new_cat_name" size="35" maxlength="80" tabindex="1" />
+									<span>The name of the new category you want to add. You can edit the name of the category later (see below).Go to <a href="admin_forums.php">Forums</a> to add forums to your new category.</span>
+								</td>
+							</tr>
+<?php if ($num_cats): ?>							<tr>
+								<th scope="row">Delete a category<div><input type="submit" name="del_cat" value="Delete" tabindex="4" /></div></th>
+								<td>
+									<select name="cat_to_delete" tabindex="3">
+<?php
+
+	while (list(, list($cat_id, $cat_name, ,)) = @each($cat_list))
+		echo "\t\t\t\t\t\t\t\t\t\t".'<option value="'.$cat_id.'">'.pun_htmlspecialchars($cat_name).'</option>'."\n";
+
+?>
+									</select>
+									<span>Select the name of the category you want to delete. You will be asked to confirm your choice of category for deletion before it is deleted.</span>
+								</td>
+							</tr>
+<?php endif; ?>						</table>
+					</div>
+				</fieldset>
+			</div>
+<?php if ($num_cats): ?>			<div class="inform">
+				<fieldset>
+					<legend>Edit categories</legend>
+					<div class="infldset">
+						<table id="categoryedit" cellspacing="0" >
+						<thead>
+							<tr>
+								<th class="tcl" scope="col">Name</th>
+								<th scope="col">Position</th>
+								<th>&nbsp;</th>
+							</tr>
+						</thead>
+						<tbody>
+<?php
+
+	@reset($cat_list);
+	for ($i = 0; $i < $num_cats; ++$i)
+	{
+		list(, list($cat_id, $cat_name, $position)) = @each($cat_list);
+
+?>
+							<tr><td><input type="text" name="cat_name[<?php echo $i ?>]" value="<?php echo pun_htmlspecialchars($cat_name) ?>" size="35" maxlength="80" /></td><td><input type="text" name="cat_order[<?php echo $i ?>]" value="<?php echo $position ?>" size="3" maxlength="3" /></td><td>&nbsp;</td></tr>
+<?php
+
+	}
+
+?>
+						</tbody>
+						</table>
+						<div class="fsetsubmit"><input type="submit" name="update" value="Update" /></div>
+					</div>
+				</fieldset>
+			</div>
+<?php endif; ?>		</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_censoring.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,167 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_MOD)
+	message($lang_common['No permission']);
+
+
+// Add a censor word
+if (isset($_POST['add_word']))
+{
+	confirm_referrer('admin_censoring.php');
+
+	$search_for = trim($_POST['new_search_for']);
+	$replace_with = trim($_POST['new_replace_with']);
+
+	if ($search_for == '' || $replace_with == '')
+		message('You must enter both a word to censor and text to replace it with.');
+
+	$db->query('INSERT INTO '.$db->prefix.'censoring (search_for, replace_with) VALUES (\''.$db->escape($search_for).'\', \''.$db->escape($replace_with).'\')') or error('Unable to add censor word', __FILE__, __LINE__, $db->error());
+
+	redirect('admin_censoring.php', 'Censor word added. Redirecting &hellip;');
+}
+
+
+// Update a censor word
+else if (isset($_POST['update']))
+{
+	confirm_referrer('admin_censoring.php');
+
+	$id = intval(key($_POST['update']));
+
+	$search_for = trim($_POST['search_for'][$id]);
+	$replace_with = trim($_POST['replace_with'][$id]);
+
+	if ($search_for == '' || $replace_with == '')
+		message('You must enter both text to search for and text to replace with.');
+
+	$db->query('UPDATE '.$db->prefix.'censoring SET search_for=\''.$db->escape($search_for).'\', replace_with=\''.$db->escape($replace_with).'\' WHERE id='.$id) or error('Unable to update censor word', __FILE__, __LINE__, $db->error());
+
+	redirect('admin_censoring.php', 'Censor word updated. Redirecting &hellip;');
+}
+
+
+// Remove a censor word
+else if (isset($_POST['remove']))
+{
+	confirm_referrer('admin_censoring.php');
+
+	$id = intval(key($_POST['remove']));
+
+	$db->query('DELETE FROM '.$db->prefix.'censoring WHERE id='.$id) or error('Unable to delete censor word', __FILE__, __LINE__, $db->error());
+
+	redirect('admin_censoring.php', 'Censor word removed. Redirecting &hellip;');
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Censoring';
+$focus_element = array('censoring', 'new_search_for');
+require PUN_ROOT.'header.php';
+
+generate_admin_menu('censoring');
+
+?>
+	<div class="blockform">
+		<h2><span>Censoring</span></h2>
+		<div class="box">
+			<form id="censoring" method="post" action="admin_censoring.php?action=foo">
+				<div class="inform">
+					<fieldset>
+						<legend>Add word</legend>
+						<div class="infldset">
+							<p>Enter a word that you want to censor and the replacement text for this word. Wildcards are accepted (i.e. *some* would match somewhere and lonesome). Censor words also affect usernames. New users will not be able to register with usernames containing any censored words. The search is case insensitive. <strong>Censor words must be enabled in <a href="admin_options.php#censoring">Options</a> for this to have any effect.</strong></p>
+							<table  cellspacing="0">
+							<thead>
+								<tr>
+									<th class="tcl" scope="col">Censored&nbsp;word</th>
+									<th class="tc2" scope="col">Replacement&nbsp;text</th>
+									<th class="hidehead" scope="col">Action</th>
+								</tr>
+							</thead>
+							<tbody>
+								<tr>
+									<td><input type="text" name="new_search_for" size="24" maxlength="60" tabindex="1" /></td>
+									<td><input type="text" name="new_replace_with" size="24" maxlength="60" tabindex="2" /></td>
+									<td><input type="submit" name="add_word" value=" Add " tabindex="3" /></td>
+								</tr>
+							</tbody>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Edit/remove words</legend>
+						<div class="infldset">
+<?php
+
+$result = $db->query('SELECT id, search_for, replace_with FROM '.$db->prefix.'censoring ORDER BY id') or error('Unable to fetch censor word list', __FILE__, __LINE__, $db->error());
+if ($db->num_rows($result))
+{
+
+?>
+							<table cellspacing="0" >
+							<thead>
+								<tr>
+									<th class="tcl" scope="col">Censored&nbsp;word</th>
+									<th class="tc2" scope="col">Replacement&nbsp;text</th>
+									<th class="hidehead" scope="col">Actions</th>
+								</tr>
+							</thead>
+							<tbody>
+<?php
+
+	while ($cur_word = $db->fetch_assoc($result))
+		echo "\t\t\t\t\t\t\t\t".'<tr><td><input type="text" name="search_for['.$cur_word['id'].']" value="'.pun_htmlspecialchars($cur_word['search_for']).'" size="24" maxlength="60" /></td><td><input type="text" name="replace_with['.$cur_word['id'].']" value="'.pun_htmlspecialchars($cur_word['replace_with']).'" size="24" maxlength="60" /></td><td><input type="submit" name="update['.$cur_word['id'].']" value="Update" />&nbsp;<input type="submit" name="remove['.$cur_word['id'].']" value="Remove" /></td></tr>'."\n";
+
+?>
+							</tbody>
+							</table>
+<?php
+
+}
+else
+	echo "\t\t\t\t\t\t\t".'<p>No censor words in list.</p>'."\n";
+
+?>
+						</div>
+					</fieldset>
+				</div>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_forums.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,457 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_ADMIN)
+	message($lang_common['No permission']);
+
+
+// Add a "default" forum
+if (isset($_POST['add_forum']))
+{
+	confirm_referrer('admin_forums.php');
+
+	$add_to_cat = intval($_POST['add_to_cat']);
+	if ($add_to_cat < 1)
+		message($lang_common['Bad request']);
+
+	$db->query('INSERT INTO '.$db->prefix.'forums (cat_id) VALUES('.$add_to_cat.')') or error('Unable to create forum', __FILE__, __LINE__, $db->error());
+
+	// Regenerate the quickjump cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_quickjump_cache();
+
+	redirect('admin_forums.php', 'Forum added. Redirecting &hellip;');
+}
+
+
+// Delete a forum
+else if (isset($_GET['del_forum']))
+{
+	confirm_referrer('admin_forums.php');
+
+	$forum_id = intval($_GET['del_forum']);
+	if ($forum_id < 1)
+		message($lang_common['Bad request']);
+
+	if (isset($_POST['del_forum_comply']))	// Delete a forum with all posts
+	{
+		@set_time_limit(0);
+
+		// Prune all posts and topics
+		prune($forum_id, 1, -1);
+
+		// Locate any "orphaned redirect topics" and delete them
+		$result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT JOIN '.$db->prefix.'topics AS t2 ON t1.moved_to=t2.id WHERE t2.id IS NULL AND t1.moved_to IS NOT NULL') or error('Unable to fetch redirect topics', __FILE__, __LINE__, $db->error());
+		$num_orphans = $db->num_rows($result);
+
+		if ($num_orphans)
+		{
+			for ($i = 0; $i < $num_orphans; ++$i)
+				$orphans[] = $db->result($result, $i);
+
+			$db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $orphans).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error());
+		}
+
+		// Delete the forum and any forum specific group permissions
+		$db->query('DELETE FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to delete forum', __FILE__, __LINE__, $db->error());
+		$db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE forum_id='.$forum_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error());
+
+		// Regenerate the quickjump cache
+		require_once PUN_ROOT.'include/cache.php';
+		generate_quickjump_cache();
+
+		redirect('admin_forums.php', 'Forum deleted. Redirecting &hellip;');
+	}
+	else	// If the user hasn't confirmed the delete
+	{
+		$result = $db->query('SELECT forum_name FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error());
+		$forum_name = pun_htmlspecialchars($db->result($result));
+
+
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Forums';
+		require PUN_ROOT.'header.php';
+
+		generate_admin_menu('forums');
+
+?>
+	<div class="blockform">
+		<h2><span>Confirm delete forum</span></h2>
+		<div class="box">
+			<form method="post" action="admin_forums.php?del_forum=<?php echo $forum_id ?>">
+				<div class="inform">
+					<fieldset>
+						<legend>Important! Read before deleting</legend>
+						<div class="infldset">
+							<p>Are you sure that you want to delete the forum "<?php echo $forum_name ?>"?</p>
+							<p>WARNING! Deleting a forum will delete all posts (if any) in that forum!</p>
+						</div>
+					</fieldset>
+				</div>
+				<p><input type="submit" name="del_forum_comply" value="Delete" /><a href="javascript:history.go(-1)">Go back</a></p>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+		require PUN_ROOT.'footer.php';
+	}
+}
+
+
+// Update forum positions
+else if (isset($_POST['update_positions']))
+{
+	confirm_referrer('admin_forums.php');
+
+	while (list($forum_id, $disp_position) = @each($_POST['position']))
+	{
+		if (!@preg_match('#^\d+$#', $disp_position))
+			message('Position must be a positive integer value.');
+
+		$db->query('UPDATE '.$db->prefix.'forums SET disp_position='.$disp_position.' WHERE id='.intval($forum_id)) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
+	}
+
+	// Regenerate the quickjump cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_quickjump_cache();
+
+	redirect('admin_forums.php', 'Forums updated. Redirecting &hellip;');
+}
+
+
+else if (isset($_GET['edit_forum']))
+{
+	$forum_id = intval($_GET['edit_forum']);
+	if ($forum_id < 1)
+		message($lang_common['Bad request']);
+
+	// Update group permissions for $forum_id
+	if (isset($_POST['save']))
+	{
+		confirm_referrer('admin_forums.php');
+
+		// Start with the forum details
+		$forum_name = trim($_POST['forum_name']);
+		$forum_desc = pun_linebreaks(trim($_POST['forum_desc']));
+		$cat_id = intval($_POST['cat_id']);
+		$sort_by = intval($_POST['sort_by']);
+		$redirect_url = isset($_POST['redirect_url']) ? trim($_POST['redirect_url']) : null;
+
+		if ($forum_name == '')
+			message('You must enter a forum name.');
+
+		if ($cat_id < 1)
+			message($lang_common['Bad request']);
+
+		$forum_desc = ($forum_desc != '') ? '\''.$db->escape($forum_desc).'\'' : 'NULL';
+		$redirect_url = ($redirect_url != '') ? '\''.$db->escape($redirect_url).'\'' : 'NULL';
+
+		$db->query('UPDATE '.$db->prefix.'forums SET forum_name=\''.$db->escape($forum_name).'\', forum_desc='.$forum_desc.', redirect_url='.$redirect_url.', sort_by='.$sort_by.', cat_id='.$cat_id.' WHERE id='.$forum_id) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
+
+		// Now let's deal with the permissions
+		if (isset($_POST['read_forum_old']))
+		{
+			$result = $db->query('SELECT g_id, g_read_board, g_post_replies, g_post_topics FROM '.$db->prefix.'groups WHERE g_id!='.PUN_ADMIN) or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+			while ($cur_group = $db->fetch_assoc($result))
+			{
+				$read_forum_new = ($cur_group['g_read_board'] == '1') ? isset($_POST['read_forum_new'][$cur_group['g_id']]) ? '1' : '0' : intval($_POST['read_forum_old'][$cur_group['g_id']]);
+				$post_replies_new = isset($_POST['post_replies_new'][$cur_group['g_id']]) ? '1' : '0';
+				$post_topics_new = isset($_POST['post_topics_new'][$cur_group['g_id']]) ? '1' : '0';
+
+				// Check if the new settings differ from the old
+				if ($read_forum_new != $_POST['read_forum_old'][$cur_group['g_id']] || $post_replies_new != $_POST['post_replies_old'][$cur_group['g_id']] || $post_topics_new != $_POST['post_topics_old'][$cur_group['g_id']])
+				{
+					// If the new settings are identical to the default settings for this group, delete it's row in forum_perms
+					if ($read_forum_new == '1' && $post_replies_new == $cur_group['g_post_replies'] && $post_topics_new == $cur_group['g_post_topics'])
+						$db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE group_id='.$cur_group['g_id'].' AND forum_id='.$forum_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error());
+					else
+					{
+						// Run an UPDATE and see if it affected a row, if not, INSERT
+						$db->query('UPDATE '.$db->prefix.'forum_perms SET read_forum='.$read_forum_new.', post_replies='.$post_replies_new.', post_topics='.$post_topics_new.' WHERE group_id='.$cur_group['g_id'].' AND forum_id='.$forum_id) or error('Unable to insert group forum permissions', __FILE__, __LINE__, $db->error());
+						if (!$db->affected_rows())
+							$db->query('INSERT INTO '.$db->prefix.'forum_perms (group_id, forum_id, read_forum, post_replies, post_topics) VALUES('.$cur_group['g_id'].', '.$forum_id.', '.$read_forum_new.', '.$post_replies_new.', '.$post_topics_new.')') or error('Unable to insert group forum permissions', __FILE__, __LINE__, $db->error());
+					}
+				}
+			}
+		}
+
+		// Regenerate the quickjump cache
+		require_once PUN_ROOT.'include/cache.php';
+		generate_quickjump_cache();
+
+		redirect('admin_forums.php', 'Forum updated. Redirecting &hellip;');
+	}
+	else if (isset($_POST['revert_perms']))
+	{
+		confirm_referrer('admin_forums.php');
+
+		$db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE forum_id='.$forum_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error());
+
+		// Regenerate the quickjump cache
+		require_once PUN_ROOT.'include/cache.php';
+		generate_quickjump_cache();
+
+		redirect('admin_forums.php?edit_forum='.$forum_id, 'Permissions reverted to defaults. Redirecting &hellip;');
+	}
+
+
+	// Fetch forum info
+	$result = $db->query('SELECT id, forum_name, forum_desc, redirect_url, num_topics, sort_by, cat_id FROM '.$db->prefix.'forums WHERE id='.$forum_id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error());
+	if (!$db->num_rows($result))
+		message($lang_common['Bad request']);
+
+	$cur_forum = $db->fetch_assoc($result);
+
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Forums';
+	require PUN_ROOT.'header.php';
+
+	generate_admin_menu('forums');
+
+?>
+	<div class="blockform">
+		<h2><span>Edit forum</span></h2>
+		<div class="box">
+			<form id="edit_forum" method="post" action="admin_forums.php?edit_forum=<?php echo $forum_id ?>">
+				<p class="submittop"><input type="submit" name="save" value="Save changes" tabindex="6" /></p>
+				<div class="inform">
+					<fieldset>
+						<legend>Edit forum details</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Forum name</th>
+									<td><input type="text" name="forum_name" size="35" maxlength="80" value="<?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?>" tabindex="1" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Description (HTML)</th>
+									<td><textarea name="forum_desc" rows="3" cols="50" tabindex="2"><?php echo pun_htmlspecialchars($cur_forum['forum_desc']) ?></textarea></td>
+								</tr>
+								<tr>
+									<th scope="row">Category</th>
+									<td>
+										<select name="cat_id" tabindex="3">
+<?php
+
+	$result = $db->query('SELECT id, cat_name FROM '.$db->prefix.'categories ORDER BY disp_position') or error('Unable to fetch category list', __FILE__, __LINE__, $db->error());
+	while ($cur_cat = $db->fetch_assoc($result))
+	{
+		$selected = ($cur_cat['id'] == $cur_forum['cat_id']) ? ' selected="selected"' : '';
+		echo "\t\t\t\t\t\t\t\t\t\t\t".'<option value="'.$cur_cat['id'].'"'.$selected.'>'.pun_htmlspecialchars($cur_cat['cat_name']).'</option>'."\n";
+	}
+
+?>
+										</select>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Sort topics by</th>
+									<td>
+										<select name="sort_by" tabindex="4">
+											<option value="0"<?php if ($cur_forum['sort_by'] == '0') echo ' selected="selected"' ?>>Last post</option>
+											<option value="1"<?php if ($cur_forum['sort_by'] == '1') echo ' selected="selected"' ?>>Topic start</option>
+										</select>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Redirect URL</th>
+									<td><?php echo ($cur_forum['num_topics']) ? 'Only available in empty forums' : '<input type="text" name="redirect_url" size="45" maxlength="100" value="'.pun_htmlspecialchars($cur_forum['redirect_url']).'" tabindex="5" />'; ?></td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Edit group permissions for this forum</legend>
+						<div class="infldset">
+							<p>In this form, you can set the forum specific permissions for the different user groups. If you haven't made any changes to this forums group permissions, what you see below is the default based on settings in <a href="admin_groups.php">User groups</a>. Administrators always have full permissions and are thus excluded. Permission settings that differ from the default permissions for the user group are marked red. The "Read forum" permission checkbox will be disabled if the group in question lacks the "Read board" permission. For redirect forums, only the "Read forum" permission is editable.</p>
+							<table id="forumperms" cellspacing="0">
+							<thead>
+								<tr>
+									<th class="atcl">&nbsp;</th>
+									<th>Read forum</th>
+									<th>Post replies</th>
+									<th>Post topics</th>
+								</tr>
+							</thead>
+							<tbody>
+<?php
+
+	$result = $db->query('SELECT g.g_id, g.g_title, g.g_read_board, g.g_post_replies, g.g_post_topics, fp.read_forum, fp.post_replies, fp.post_topics FROM '.$db->prefix.'groups AS g LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (g.g_id=fp.group_id AND fp.forum_id='.$forum_id.') WHERE g.g_id!='.PUN_ADMIN.' ORDER BY g.g_id') or error('Unable to fetch group forum permission list', __FILE__, __LINE__, $db->error());
+
+	while ($cur_perm = $db->fetch_assoc($result))
+	{
+		$read_forum = ($cur_perm['read_forum'] != '0') ? true : false;
+		$post_replies = (($cur_perm['g_post_replies'] == '0' && $cur_perm['post_replies'] == '1') || ($cur_perm['g_post_replies'] == '1' && $cur_perm['post_replies'] != '0')) ? true : false;
+		$post_topics = (($cur_perm['g_post_topics'] == '0' && $cur_perm['post_topics'] == '1') || ($cur_perm['g_post_topics'] == '1' && $cur_perm['post_topics'] != '0')) ? true : false;
+
+		// Determine if the current sittings differ from the default or not
+		$read_forum_def = ($cur_perm['read_forum'] == '0') ? false : true;
+		$post_replies_def = (($post_replies && $cur_perm['g_post_replies'] == '0') || (!$post_replies && ($cur_perm['g_post_replies'] == '' || $cur_perm['g_post_replies'] == '1'))) ? false : true;
+		$post_topics_def = (($post_topics && $cur_perm['g_post_topics'] == '0') || (!$post_topics && ($cur_perm['g_post_topics'] == '' || $cur_perm['g_post_topics'] == '1'))) ? false : true;
+
+?>
+								<tr>
+									<th class="atcl"><?php echo pun_htmlspecialchars($cur_perm['g_title']) ?></th>
+									<td<?php if (!$read_forum_def) echo ' class="nodefault"'; ?>>
+										<input type="hidden" name="read_forum_old[<?php echo $cur_perm['g_id'] ?>]" value="<?php echo ($read_forum) ? '1' : '0'; ?>" />
+										<input type="checkbox" name="read_forum_new[<?php echo $cur_perm['g_id'] ?>]" value="1"<?php echo ($read_forum) ? ' checked="checked"' : ''; ?><?php echo ($cur_perm['g_read_board'] == '0') ? ' disabled="disabled"' : ''; ?> />
+									</td>
+									<td<?php if (!$post_replies_def && $cur_forum['redirect_url'] == '') echo ' class="nodefault"'; ?>>
+										<input type="hidden" name="post_replies_old[<?php echo $cur_perm['g_id'] ?>]" value="<?php echo ($post_replies) ? '1' : '0'; ?>" />
+										<input type="checkbox" name="post_replies_new[<?php echo $cur_perm['g_id'] ?>]" value="1"<?php echo ($post_replies) ? ' checked="checked"' : ''; ?><?php echo ($cur_forum['redirect_url'] != '') ? ' disabled="disabled"' : ''; ?> />
+									</td>
+									<td<?php if (!$post_topics_def && $cur_forum['redirect_url'] == '') echo ' class="nodefault"'; ?>>
+										<input type="hidden" name="post_topics_old[<?php echo $cur_perm['g_id'] ?>]" value="<?php echo ($post_topics) ? '1' : '0'; ?>" />
+										<input type="checkbox" name="post_topics_new[<?php echo $cur_perm['g_id'] ?>]" value="1"<?php echo ($post_topics) ? ' checked="checked"' : ''; ?><?php echo ($cur_forum['redirect_url'] != '') ? ' disabled="disabled"' : ''; ?> />
+									</td>
+								</tr>
+<?php
+
+	}
+
+?>
+							</tbody>
+							</table>
+							<div class="fsetsubmit"><input type="submit" name="revert_perms" value="Revert to default" /></div>
+						</div>
+					</fieldset>
+				</div>
+				<p class="submitend"><input type="submit" name="save" value="Save changes" /></p>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Forums';
+require PUN_ROOT.'header.php';
+
+generate_admin_menu('forums');
+
+?>
+	<div class="blockform">
+		<h2><span>Add forum</span></h2>
+		<div class="box">
+			<form method="post" action="admin_forums.php?action=adddel">
+				<div class="inform">
+					<fieldset>
+						<legend>Create a new forum</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Add forum to category<div><input type="submit" name="add_forum" value=" Add " tabindex="2" /></div></th>
+									<td>
+										<select name="add_to_cat" tabindex="1">
+<?php
+
+	$result = $db->query('SELECT id, cat_name FROM '.$db->prefix.'categories ORDER BY disp_position') or error('Unable to fetch category list', __FILE__, __LINE__, $db->error());
+	while ($cur_cat = $db->fetch_assoc($result))
+		echo "\t\t\t\t\t\t\t\t\t".'<option value="'.$cur_cat['id'].'">'.pun_htmlspecialchars($cur_cat['cat_name']).'</option>'."\n";
+
+?>
+										</select>
+										<span>Select the category to which you wish to add a new forum.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+			</form>
+		</div>
+
+		<h2 class="block2"><span>Edit forums</span></h2>
+		<div class="box">
+			<form id="edforum" method="post" action="admin_forums.php?action=edit">
+				<p class="submittop"><input type="submit" name="update_positions" value="Update positions" tabindex="3" /></p>
+<?php
+
+$tabindex_count = 4;
+
+// Display all the categories and forums
+$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.disp_position FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id ORDER BY c.disp_position, c.id, f.disp_position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
+
+$cur_category = 0;
+while ($cur_forum = $db->fetch_assoc($result))
+{
+	if ($cur_forum['cid'] != $cur_category)	// A new category since last iteration?
+	{
+		if ($cur_category != 0)
+			echo "\t\t\t\t\t\t\t".'</table>'."\n\t\t\t\t\t\t".'</div>'."\n\t\t\t\t\t".'</fieldset>'."\n\t\t\t\t".'</div>'."\n";
+
+?>
+				<div class="inform">
+					<fieldset>
+						<legend>Category: <?php echo pun_htmlspecialchars($cur_forum['cat_name']) ?></legend>
+						<div class="infldset">
+							<table cellspacing="0">
+<?php
+
+		$cur_category = $cur_forum['cid'];
+	}
+
+?>
+								<tr>
+									<th><a href="admin_forums.php?edit_forum=<?php echo $cur_forum['fid'] ?>">Edit</a> - <a href="admin_forums.php?del_forum=<?php echo $cur_forum['fid'] ?>">Delete</a></th>
+									<td>Position&nbsp;&nbsp;<input type="text" name="position[<?php echo $cur_forum['fid'] ?>]" size="3" maxlength="3" value="<?php echo $cur_forum['disp_position'] ?>" tabindex="<?php echo $tabindex_count ?>" />
+									&nbsp;&nbsp;<strong><?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?></strong></td>
+								</tr>
+<?php
+
+	$tabindex_count += 2;
+}
+
+?>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<p class="submitend"><input type="submit" name="update_positions" value="Update positions" tabindex="<?php echo $tabindex_count ?>" /></p>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_groups.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,468 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_ADMIN)
+	message($lang_common['No permission']);
+
+
+// Add/edit a group (stage 1)
+if (isset($_POST['add_group']) || isset($_GET['edit_group']))
+{
+	if (isset($_POST['add_group']))
+	{
+		$base_group = intval($_POST['base_group']);
+
+		$result = $db->query('SELECT * FROM '.$db->prefix.'groups WHERE g_id='.$base_group) or error('Unable to fetch user group info', __FILE__, __LINE__, $db->error());
+		$group = $db->fetch_assoc($result);
+
+		$mode = 'add';
+	}
+	else	// We are editing a group
+	{
+		$group_id = intval($_GET['edit_group']);
+		if ($group_id < 1)
+			message($lang_common['Bad request']);
+
+		$result = $db->query('SELECT * FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to fetch user group info', __FILE__, __LINE__, $db->error());
+		if (!$db->num_rows($result))
+			message($lang_common['Bad request']);
+
+		$group = $db->fetch_assoc($result);
+
+		$mode = 'edit';
+	}
+
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / User groups';
+	$required_fields = array('req_title' => 'Group title');
+	$focus_element = array('groups2', 'req_title');
+	require PUN_ROOT.'header.php';
+
+	generate_admin_menu('groups');
+
+?>
+	<div class="blockform">
+		<h2><span>Group settings</span></h2>
+		<div class="box">
+			<form id="groups2" method="post" action="admin_groups.php" onsubmit="return process_form(this)">
+				<p class="submittop"><input type="submit" name="add_edit_group" value=" Save " /></p>
+				<div class="inform">
+					<input type="hidden" name="mode" value="<?php echo $mode ?>" />
+<?php if ($mode == 'edit'): ?>				<input type="hidden" name="group_id" value="<?php echo $group_id ?>" />
+<?php endif; ?><?php if ($mode == 'add'): ?>				<input type="hidden" name="base_group" value="<?php echo $base_group ?>" />
+<?php endif; ?>					<fieldset>
+						<legend>Setup group options and permissions</legend>
+						<div class="infldset">
+							<p>Below options and permissions are the default permissions for the user group. These options apply if no forum specific permissions are in effect.</p>
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Group title</th>
+									<td>
+										<input type="text" name="req_title" size="25" maxlength="50" value="<?php if ($mode == 'edit') echo pun_htmlspecialchars($group['g_title']); ?>" tabindex="1" />
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">User title</th>
+									<td>
+										<input type="text" name="user_title" size="25" maxlength="50" value="<?php echo pun_htmlspecialchars($group['g_user_title']) ?>" tabindex="2" />
+										<span>This title will override any rank users in this group have attained. Leave blank to use default title or rank.</span>
+									</td>
+								</tr>
+<?php if ($group['g_id'] != PUN_ADMIN): ?>								<tr>
+									<th scope="row">Read board</th>
+									<td>
+										<input type="radio" name="read_board" value="1"<?php if ($group['g_read_board'] == '1') echo ' checked="checked"' ?> tabindex="3" />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="read_board" value="0"<?php if ($group['g_read_board'] == '0') echo ' checked="checked"' ?> tabindex="4" />&nbsp;<strong>No</strong>
+										<span>Allow users in this group to view the board. This setting applies to every aspect of the board and can therefore not be overridden by forum specific settings. If this is set to "No", users in this group will only be able to login/logout and register.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Post replies</th>
+									<td>
+										<input type="radio" name="post_replies" value="1"<?php if ($group['g_post_replies'] == '1') echo ' checked="checked"' ?> tabindex="5" />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="post_replies" value="0"<?php if ($group['g_post_replies'] == '0') echo ' checked="checked"' ?> tabindex="6" />&nbsp;<strong>No</strong>
+										<span>Allow users in this group to post replies in topics.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Post topics</th>
+									<td>
+										<input type="radio" name="post_topics" value="1"<?php if ($group['g_post_topics'] == '1') echo ' checked="checked"' ?> tabindex="7" />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="post_topics" value="0"<?php if ($group['g_post_topics'] == '0') echo ' checked="checked"' ?> tabindex="8" />&nbsp;<strong>No</strong>
+										<span>Allow users in this group to post new topics.</span>
+									</td>
+								</tr>
+<?php if ($group['g_id'] != PUN_GUEST): ?>								<tr>
+									<th scope="row">Edit posts</th>
+									<td>
+										<input type="radio" name="edit_posts" value="1"<?php if ($group['g_edit_posts'] == '1') echo ' checked="checked"' ?> tabindex="11" />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="edit_posts" value="0"<?php if ($group['g_edit_posts'] == '0') echo ' checked="checked"' ?> tabindex="12" />&nbsp;<strong>No</strong>
+										<span>Allow users in this group to edit their own posts.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Delete posts</th>
+									<td>
+										<input type="radio" name="delete_posts" value="1"<?php if ($group['g_delete_posts'] == '1') echo ' checked="checked"' ?> tabindex="13" />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="delete_posts" value="0"<?php if ($group['g_delete_posts'] == '0') echo ' checked="checked"' ?> tabindex="14" />&nbsp;<strong>No</strong>
+										<span>Allow users in this group to delete their own posts.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Delete topics</th>
+									<td>
+										<input type="radio" name="delete_topics" value="1"<?php if ($group['g_delete_topics'] == '1') echo ' checked="checked"' ?> tabindex="15" />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="delete_topics" value="0"<?php if ($group['g_delete_topics'] == '0') echo ' checked="checked"' ?> tabindex="16" />&nbsp;<strong>No</strong>
+										<span>Allow users in this group to delete their own topics (including any replies).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Set user title</th>
+									<td>
+										<input type="radio" name="set_title" value="1"<?php if ($group['g_set_title'] == '1') echo ' checked="checked"' ?> tabindex="17" />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="set_title" value="0"<?php if ($group['g_set_title'] == '0') echo ' checked="checked"' ?> tabindex="18" />&nbsp;<strong>No</strong>
+										<span>Allow users in this group to set their own user title.</span>
+									</td>
+								</tr>
+<?php endif; ?>								<tr>
+									<th scope="row">Use search</th>
+									<td>
+										<input type="radio" name="search" value="1"<?php if ($group['g_search'] == '1') echo ' checked="checked"' ?> tabindex="19" />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="search" value="0"<?php if ($group['g_search'] == '0') echo ' checked="checked"' ?> tabindex="20" />&nbsp;<strong>No</strong>
+										<span>Allow users in this group to use the search feature.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Search user list</th>
+									<td>
+										<input type="radio" name="search_users" value="1"<?php if ($group['g_search_users'] == '1') echo ' checked="checked"' ?> tabindex="21" />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="search_users" value="0"<?php if ($group['g_search_users'] == '0') echo ' checked="checked"' ?> tabindex="22" />&nbsp;<strong>No</strong>
+										<span>Allow users in this group to freetext search for users in the user list.</span>
+									</td>
+								</tr>
+<?php if ($group['g_id'] != PUN_GUEST): ?>								<tr>
+									<th scope="row">Edit subjects interval</th>
+									<td>
+										<input type="text" name="edit_subjects_interval" size="5" maxlength="5" value="<?php echo $group['g_edit_subjects_interval'] ?>" tabindex="23" />
+										<span>Number of seconds after post time that users in this group may edit the subject of topics they've posted. Set to 0 to allow edits indefinitely.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Post flood interval</th>
+									<td>
+										<input type="text" name="post_flood" size="5" maxlength="4" value="<?php echo $group['g_post_flood'] ?>" tabindex="24" />
+										<span>Number of seconds that users in this group have to wait between posts. Set to 0 to disable.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Search flood interval</th>
+									<td>
+										<input type="text" name="search_flood" size="5" maxlength="4" value="<?php echo $group['g_search_flood'] ?>" tabindex="25" />
+										<span>Number of seconds that users in this group have to wait between searches. Set to 0 to disable.</span>
+									</td>
+								</tr>
+<?php endif; ?><?php endif; ?>							</table>
+<?php if ($group['g_id'] == PUN_MOD ): ?>							<p class="warntext">Please note that in order for a user in this group to have moderator abilities, he/she must be assigned to moderate one or more forums. This is done via the user administration page of the user's profile.</p>
+<?php endif; ?>						</div>
+					</fieldset>
+				</div>
+				<p class="submitend"><input type="submit" name="add_edit_group" value=" Save " tabindex="26" /></p>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+// Add/edit a group (stage 2)
+else if (isset($_POST['add_edit_group']))
+{
+	confirm_referrer('admin_groups.php');
+
+	// Is this the admin group? (special rules apply)
+	$is_admin_group = (isset($_POST['group_id']) && $_POST['group_id'] == PUN_ADMIN) ? true : false;
+
+	$title = trim($_POST['req_title']);
+	$user_title = trim($_POST['user_title']);
+	$read_board = isset($_POST['read_board']) ? intval($_POST['read_board']) : '1';
+	$post_replies = isset($_POST['post_replies']) ? intval($_POST['post_replies']) : '1';
+	$post_topics = isset($_POST['post_topics']) ? intval($_POST['post_topics']) : '1';
+	$edit_posts = isset($_POST['edit_posts']) ? intval($_POST['edit_posts']) : ($is_admin_group) ? '1' : '0';
+	$delete_posts = isset($_POST['delete_posts']) ? intval($_POST['delete_posts']) : ($is_admin_group) ? '1' : '0';
+	$delete_topics = isset($_POST['delete_topics']) ? intval($_POST['delete_topics']) : ($is_admin_group) ? '1' : '0';
+	$set_title = isset($_POST['set_title']) ? intval($_POST['set_title']) : ($is_admin_group) ? '1' : '0';
+	$search = isset($_POST['search']) ? intval($_POST['search']) : '1';
+	$search_users = isset($_POST['search_users']) ? intval($_POST['search_users']) : '1';
+	$edit_subjects_interval = isset($_POST['edit_subjects_interval']) ? intval($_POST['edit_subjects_interval']) : '0';
+	$post_flood = isset($_POST['post_flood']) ? intval($_POST['post_flood']) : '0';
+	$search_flood = isset($_POST['search_flood']) ? intval($_POST['search_flood']) : '0';
+
+	if ($title == '')
+		message('You must enter a group title.');
+
+	$user_title = ($user_title != '') ? '\''.$db->escape($user_title).'\'' : 'NULL';
+
+	if ($_POST['mode'] == 'add')
+	{
+		$result = $db->query('SELECT 1 FROM '.$db->prefix.'groups WHERE g_title=\''.$db->escape($title).'\'') or error('Unable to check group title collision', __FILE__, __LINE__, $db->error());
+		if ($db->num_rows($result))
+			message('There is already a group with the title \''.pun_htmlspecialchars($title).'\'.');
+
+		$db->query('INSERT INTO '.$db->prefix.'groups (g_title, g_user_title, g_read_board, g_post_replies, g_post_topics, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_edit_subjects_interval, g_post_flood, g_search_flood) VALUES(\''.$db->escape($title).'\', '.$user_title.', '.$read_board.', '.$post_replies.', '.$post_topics.', '.$edit_posts.', '.$delete_posts.', '.$delete_topics.', '.$set_title.', '.$search.', '.$search_users.', '.$edit_subjects_interval.', '.$post_flood.', '.$search_flood.')') or error('Unable to add group', __FILE__, __LINE__, $db->error());
+		$new_group_id = $db->insert_id();
+
+		// Now lets copy the forum specific permissions from the group which this group is based on
+		$result = $db->query('SELECT forum_id, read_forum, post_replies, post_topics FROM '.$db->prefix.'forum_perms WHERE group_id='.intval($_POST['base_group'])) or error('Unable to fetch group forum permission list', __FILE__, __LINE__, $db->error());
+		while ($cur_forum_perm = $db->fetch_assoc($result))
+			$db->query('INSERT INTO '.$db->prefix.'forum_perms (group_id, forum_id, read_forum, post_replies, post_topics) VALUES('.$new_group_id.', '.$cur_forum_perm['forum_id'].', '.$cur_forum_perm['read_forum'].', '.$cur_forum_perm['post_replies'].', '.$cur_forum_perm['post_topics'].')') or error('Unable to insert group forum permissions', __FILE__, __LINE__, $db->error());
+	}
+	else
+	{
+		$result = $db->query('SELECT 1 FROM '.$db->prefix.'groups WHERE g_title=\''.$db->escape($title).'\' AND g_id!='.intval($_POST['group_id'])) or error('Unable to check group title collision', __FILE__, __LINE__, $db->error());
+		if ($db->num_rows($result))
+			message('There is already a group with the title \''.pun_htmlspecialchars($title).'\'.');
+
+		$db->query('UPDATE '.$db->prefix.'groups SET g_title=\''.$db->escape($title).'\', g_user_title='.$user_title.', g_read_board='.$read_board.', g_post_replies='.$post_replies.', g_post_topics='.$post_topics.', g_edit_posts='.$edit_posts.', g_delete_posts='.$delete_posts.', g_delete_topics='.$delete_topics.', g_set_title='.$set_title.', g_search='.$search.', g_search_users='.$search_users.', g_edit_subjects_interval='.$edit_subjects_interval.', g_post_flood='.$post_flood.', g_search_flood='.$search_flood.' WHERE g_id='.intval($_POST['group_id'])) or error('Unable to update group', __FILE__, __LINE__, $db->error());
+	}
+
+	// Regenerate the quickjump cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_quickjump_cache();
+
+	redirect('admin_groups.php', 'Group '.(($_POST['mode'] == 'edit') ? 'edited' : 'added').'. Redirecting &hellip;');
+}
+
+
+// Set default group
+else if (isset($_POST['set_default_group']))
+{
+	confirm_referrer('admin_groups.php');
+
+	$group_id = intval($_POST['default_group']);
+	if ($group_id < 4)
+		message($lang_common['Bad request']);
+
+	$db->query('UPDATE '.$db->prefix.'config SET conf_value='.$group_id.' WHERE conf_name=\'o_default_user_group\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error());
+
+	// Regenerate the config cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_config_cache();
+
+	redirect('admin_groups.php', 'Default group set. Redirecting &hellip;');
+}
+
+
+// Remove a group
+else if (isset($_GET['del_group']))
+{
+	confirm_referrer('admin_groups.php');
+
+	$group_id = intval($_GET['del_group']);
+	if ($group_id < 5)
+		message($lang_common['Bad request']);
+
+	// Make sure we don't remove the default group
+	if ($group_id == $pun_config['o_default_user_group'])
+		message('The default group cannot be removed. In order to delete this group, you must first setup a different group as the default.');
+
+
+	// Check if this group has any members
+	$result = $db->query('SELECT g.g_title, COUNT(u.id) FROM '.$db->prefix.'groups AS g INNER JOIN '.$db->prefix.'users AS u ON g.g_id=u.group_id WHERE g.g_id='.$group_id.' GROUP BY g.g_id, g_title') or error('Unable to fetch group info', __FILE__, __LINE__, $db->error());
+
+	// If the group doesn't have any members or if we've already selected a group to move the members to
+	if (!$db->num_rows($result) || isset($_POST['del_group']))
+	{
+		if (isset($_POST['del_group']))
+		{
+			$move_to_group = intval($_POST['move_to_group']);
+			$db->query('UPDATE '.$db->prefix.'users SET group_id='.$move_to_group.' WHERE group_id='.$group_id) or error('Unable to move users into group', __FILE__, __LINE__, $db->error());
+		}
+
+		// Delete the group and any forum specific permissions
+		$db->query('DELETE FROM '.$db->prefix.'groups WHERE g_id='.$group_id) or error('Unable to delete group', __FILE__, __LINE__, $db->error());
+		$db->query('DELETE FROM '.$db->prefix.'forum_perms WHERE group_id='.$group_id) or error('Unable to delete group forum permissions', __FILE__, __LINE__, $db->error());
+
+		// Regenerate the quickjump cache
+		require_once PUN_ROOT.'include/cache.php';
+		generate_quickjump_cache();
+
+		redirect('admin_groups.php', 'Group removed. Redirecting &hellip;');
+	}
+
+
+	list($group_title, $group_members) = $db->fetch_row($result);
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / User groups';
+	require PUN_ROOT.'header.php';
+
+	generate_admin_menu('groups');
+
+?>
+	<div class="blockform">
+		<h2><span>Remove group</span></h2>
+		<div class="box">
+			<form id="groups" method="post" action="admin_groups.php?del_group=<?php echo $group_id ?>">
+				<div class="inform">
+					<fieldset>
+						<legend>Move users currently in group</legend>
+						<div class="infldset">
+							<p>The group "<?php echo pun_htmlspecialchars($group_title) ?>" currently has <?php echo $group_members ?> members. Please select a group to which these members will be assigned upon removal.</p>
+							<label>Move users to
+							<select name="move_to_group">
+<?php
+
+	$result = $db->query('SELECT g_id, g_title FROM '.$db->prefix.'groups WHERE g_id!='.PUN_GUEST.' AND g_id!='.$group_id.' ORDER BY g_title') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+
+	while ($cur_group = $db->fetch_assoc($result))
+	{
+		if ($cur_group['g_id'] == PUN_MEMBER)	// Pre-select the pre-defined Members group
+			echo "\t\t\t\t\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'" selected="selected">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+		else
+			echo "\t\t\t\t\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+	}
+
+?>
+							</select>
+							</br></label>
+						</div>
+					</fieldset>
+				</div>
+				<p><input type="submit" name="del_group" value="Delete group" /></p>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / User groups';
+require PUN_ROOT.'header.php';
+
+generate_admin_menu('groups');
+
+?>
+	<div class="blockform">
+		<h2><span>Add/setup groups</span></h2>
+		<div class="box">
+			<form id="groups" method="post" action="admin_groups.php?action=foo">
+				<div class="inform">
+					<fieldset>
+						<legend>Add new group</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Base new group on<div><input type="submit" name="add_group" value=" Add " tabindex="2" /></div></th>
+									<td>
+										<select id="base_group" name="base_group" tabindex="1">
+<?php
+
+$result = $db->query('SELECT g_id, g_title FROM '.$db->prefix.'groups WHERE g_id>'.PUN_GUEST.' ORDER BY g_title') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+
+while ($cur_group = $db->fetch_assoc($result))
+{
+	if ($cur_group['g_id'] == $pun_config['o_default_user_group'])
+		echo "\t\t\t\t\t\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'" selected="selected">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+	else
+		echo "\t\t\t\t\t\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+}
+
+?>
+										</select>
+										<span>Select a user group from which the new group will inherit it's permission settings. The next page will let you fine-tune said settings.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Set default group</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Default group<div><input type="submit" name="set_default_group" value=" Save " tabindex="4" /></div></th>
+									<td>
+										<select id="default_group" name="default_group" tabindex="3">
+<?php
+
+$result = $db->query('SELECT g_id, g_title FROM '.$db->prefix.'groups WHERE g_id>'.PUN_GUEST.' ORDER BY g_title') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+
+while ($cur_group = $db->fetch_assoc($result))
+{
+	if ($cur_group['g_id'] == $pun_config['o_default_user_group'])
+		echo "\t\t\t\t\t\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'" selected="selected">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+	else
+		echo "\t\t\t\t\t\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+}
+
+?>
+										</select>
+										<span>This is the default user group, e.g. the group users are placed in when they register. For security reasons, users can't be placed in either the moderator or administrator user groups by default.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+			</form>
+		</div>
+
+		<h2 class="block2"><span>Existing groups</span></h2>
+		<div class="box">
+			<div class="fakeform">
+				<div class="inform">
+					<fieldset>
+						<legend>Edit/remove groups</legend>
+						<div class="infldset">
+							<p>The pre-defined groups Guests, Administrators, Moderators and Members cannot be removed. They can however be edited. Please note though, that in some groups, some options are unavailable (e.g. the <em>edit posts</em> permission for guests). Administrators always have full permissions.</p>
+							<table cellspacing="0">
+<?php
+
+$result = $db->query('SELECT g_id, g_title FROM '.$db->prefix.'groups ORDER BY g_id') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+
+while ($cur_group = $db->fetch_assoc($result))
+	echo "\t\t\t\t\t\t\t\t".'<tr><th scope="row"><a href="admin_groups.php?edit_group='.$cur_group['g_id'].'">Edit</a>'.(($cur_group['g_id'] > PUN_MEMBER) ? ' - <a href="admin_groups.php?del_group='.$cur_group['g_id'].'">Remove</a>' : '').'</th><td>'.pun_htmlspecialchars($cur_group['g_title']).'</td></tr>'."\n";
+
+?>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+			</div>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_index.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,205 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_MOD)
+	message($lang_common['No permission']);
+
+
+$action = isset($_GET['action']) ? $_GET['action'] : null;
+
+// Check for upgrade
+if ($action == 'check_upgrade')
+{
+	if (!ini_get('allow_url_fopen'))
+		message('Unable to check for upgrade since \'allow_url_fopen\' is disabled on this system.');
+
+	$fp = @fopen('http://www.punbb.org/latest_version', 'r');
+	$latest_version = trim(@fread($fp, 16));
+	@fclose($fp);
+
+	if ($latest_version == '')
+		message('Check for upgrade failed for unknown reasons.');
+
+	$cur_version = str_replace(array('.', 'dev', 'beta', ' '), '', strtolower($pun_config['o_cur_version']));
+	$cur_version = (strlen($cur_version) == 2) ? intval($cur_version) * 10 : intval($cur_version);
+
+	$latest_version = str_replace('.', '', strtolower($latest_version));
+	$latest_version = (strlen($latest_version) == 2) ? intval($latest_version) * 10 : intval($latest_version);
+
+	if ($cur_version >= $latest_version)
+		message('You are running the latest version of PunBB.');
+	else
+		message('A new version of PunBB has been released. You can download the latest version at <a href="http://www.punbb.org/">PunBB.org</a>.');
+}
+
+
+// Show phpinfo() output
+else if ($action == 'phpinfo' && $pun_user['g_id'] == PUN_ADMIN)
+{
+	// Is phpinfo() a disabled function?
+	if (strpos(strtolower((string)@ini_get('disable_functions')), 'phpinfo') !== false)
+		message('The PHP function phpinfo() has been disabled on this server.');
+
+	phpinfo();
+	exit;
+}
+
+
+// Get the server load averages (if possible)
+if (@file_exists('/proc/loadavg') && is_readable('/proc/loadavg'))
+{
+	// We use @ just in case
+	$fh = @fopen('/proc/loadavg', 'r');
+	$load_averages = @fread($fh, 64);
+	@fclose($fh);
+
+	$load_averages = @explode(' ', $load_averages);
+	$server_load = isset($load_averages[2]) ? $load_averages[0].' '.$load_averages[1].' '.$load_averages[2] : 'Not available';
+}
+else if (!in_array(PHP_OS, array('WINNT', 'WIN32')) && preg_match('/averages?: ([0-9\.]+),[\s]+([0-9\.]+),[\s]+([0-9\.]+)/i', @exec('uptime'), $load_averages))
+	$server_load = $load_averages[1].' '.$load_averages[2].' '.$load_averages[3];
+else
+	$server_load = 'Not available';
+
+
+// Get number of current visitors
+$result = $db->query('SELECT COUNT(user_id) FROM '.$db->prefix.'online WHERE idle=0') or error('Unable to fetch online count', __FILE__, __LINE__, $db->error());
+$num_online = $db->result($result);
+
+
+// Get the database system version
+switch ($db_type)
+{
+	case 'sqlite':
+		$db_version = 'SQLite '.sqlite_libversion();
+		break;
+
+	default:
+		$result = $db->query('SELECT VERSION()') or error('Unable to fetch version info', __FILE__, __LINE__, $db->error());
+		$db_version = $db->result($result);
+		break;
+}
+
+
+// Collect some additional info about MySQL
+if ($db_type == 'mysql' || $db_type == 'mysqli')
+{
+	$db_version = 'MySQL '.$db_version;
+
+	// Calculate total db size/row count
+	$result = $db->query('SHOW TABLE STATUS FROM `'.$db_name.'`') or error('Unable to fetch table status', __FILE__, __LINE__, $db->error());
+
+	$total_records = $total_size = 0;
+	while ($status = $db->fetch_assoc($result))
+	{
+		$total_records += $status['Rows'];
+		$total_size += $status['Data_length'] + $status['Index_length'];
+	}
+
+	$total_size = $total_size / 1024;
+
+	if ($total_size > 1024)
+		$total_size = round($total_size / 1024, 2).' MB';
+	else
+		$total_size = round($total_size, 2).' KB';
+}
+
+
+// See if MMCache or PHPA is loaded
+if (function_exists('mmcache'))
+	$php_accelerator = '<a href="http://turck-mmcache.sourceforge.net/">Turck MMCache</a>';
+else if (isset($_PHPA))
+	$php_accelerator = '<a href="http://www.php-accelerator.co.uk/">ionCube PHP Accelerator</a>';
+else
+	$php_accelerator = 'N/A';
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin';
+require PUN_ROOT.'header.php';
+
+generate_admin_menu('index');
+
+?>
+	<div class="block">
+		<h2>Forum administration</h2>
+		<div id="adintro" class="box">
+			<div class="inbox">
+				<p>
+					Welcome to the PunBB administration control panel. From here you can control vital aspects of the forum. Depending on whether you are an administrator or a moderator you can<br /><br />
+					&nbsp;- organize categories and forums.<br />
+					&nbsp;- set forum-wide options and preferences.<br />
+					&nbsp;- control permissions for users and guests.<br />
+					&nbsp;- view IP statistics for users.<br />
+					&nbsp;- ban users.<br />
+					&nbsp;- censor words.<br />
+					&nbsp;- set up user ranks.<br />
+					&nbsp;- prune old posts.<br />
+					&nbsp;- handle post reports.
+				</p>
+			</div>
+		</div>
+
+		<h2 class="block2"><span>Statistics</span></h2>
+		<div id="adstats" class="box">
+			<div class="inbox">
+				<dl>
+					<dt>PunBB version</dt>
+					<dd>
+						PunBB <?php echo $pun_config['o_cur_version'] ?> - <a href="admin_index.php?action=check_upgrade">Check for upgrade</a><br />
+						&copy; Copyright 2002, 2003, 2004, 2005 Rickard Andersson
+					</dd>
+					<dt>Server load</dt>
+					<dd>
+						<?php echo $server_load ?> (<?php echo $num_online ?> users online)
+					</dd>
+<?php if ($pun_user['g_id'] == PUN_ADMIN): ?>					<dt>Environment</dt>
+					<dd>
+						Operating system: <?php echo PHP_OS ?><br />
+						PHP: <?php echo phpversion() ?> - <a href="admin_index.php?action=phpinfo">Show info</a><br />
+						Accelerator: <?php echo $php_accelerator."\n" ?>
+					</dd>
+					<dt>Database</dt>
+					<dd>
+						<?php echo $db_version."\n" ?>
+<?php if (isset($total_records) && isset($total_size)): ?>						<br />Rows: <?php echo $total_records."\n" ?>
+						<br />Size: <?php echo $total_size."\n" ?>
+<?php endif; endif; ?>					</dd>
+				</dl>
+			</div>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_loader.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,72 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_MOD)
+	message($lang_common['No permission']);
+
+
+// The plugin to load should be supplied via GET
+$plugin = isset($_GET['plugin']) ? $_GET['plugin'] : '';
+if (!@preg_match('/^AM?P_(\w*?)\.php$/i', $plugin))
+	message($lang_common['Bad request']);
+
+// AP_ == Admins only, AMP_ == admins and moderators
+$prefix = substr($plugin, 0, strpos($plugin, '_'));
+if ($pun_user['g_id'] == PUN_MOD && $prefix == 'AP')
+	message($lang_common['No permission']);
+
+// Make sure the file actually exists
+if (!file_exists(PUN_ROOT.'plugins/'.$plugin))
+	message('There is no plugin called \''.$plugin.'\' in the plugin directory.');
+
+// Construct REQUEST_URI if it isn't set
+if (!isset($_SERVER['REQUEST_URI']))
+	$_SERVER['REQUEST_URI'] = (isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '').'?'.(isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '');
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / '.$plugin;
+require PUN_ROOT.'header.php';
+
+// Attempt to load the plugin. We don't use @ here to supress error messages,
+// because if we did and a parse error occurred in the plugin, we would only
+// get the "blank page of death".
+include PUN_ROOT.'plugins/'.$plugin;
+if (!defined('PUN_PLUGIN_LOADED'))
+	message('Loading of the plugin \''.$plugin.'\' failed.');
+
+// Output the clearer div
+?>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_maintenance.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,186 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+// Tell common.php that we don't want output buffering
+define('PUN_DISABLE_BUFFERING', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_ADMIN)
+	message($lang_common['No permission']);
+
+
+if (isset($_GET['i_per_page']) && isset($_GET['i_start_at']))
+{
+	$per_page = intval($_GET['i_per_page']);
+	$start_at = intval($_GET['i_start_at']);
+	if ($per_page < 1 || $start_at < 1)
+		message($lang_common['Bad request']);
+
+	@set_time_limit(0);
+
+	// If this is the first cycle of posts we empty the search index before we proceed
+	if (isset($_GET['i_empty_index']))
+	{
+		// This is the only potentially "dangerous" thing we can do here, so we check the referer
+		confirm_referrer('admin_maintenance.php');
+
+		$truncate_sql = ($db_type != 'sqlite' && $db_type != 'pgsql') ? 'TRUNCATE TABLE ' : 'DELETE FROM ';
+		$db->query($truncate_sql.$db->prefix.'search_matches') or error('Unable to empty search index match table', __FILE__, __LINE__, $db->error());
+		$db->query($truncate_sql.$db->prefix.'search_words') or error('Unable to empty search index words table', __FILE__, __LINE__, $db->error());
+
+		// Reset the sequence for the search words (not needed for SQLite)
+		switch ($db_type)
+		{
+			case 'mysql':
+			case 'mysqli':
+				$result = $db->query('ALTER TABLE '.$db->prefix.'search_words auto_increment=1') or error('Unable to update table auto_increment', __FILE__, __LINE__, $db->error());
+				break;
+
+			case 'pgsql';
+				$result = $db->query('SELECT setval(\''.$db->prefix.'search_words_id_seq\', 1, false)') or error('Unable to update sequence', __FILE__, __LINE__, $db->error());
+		}
+	}
+
+	$end_at = $start_at + $per_page;
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<title><?php echo pun_htmlspecialchars($pun_config['o_board_title']) ?> / Rebuilding search index &hellip;</title>
+<style type="text/css">
+body {
+	font: 10px Verdana, Arial, Helvetica, sans-serif;
+	color: #333333;
+	background-color: #FFFFFF
+}
+</style>
+</head>
+<body>
+
+Rebuilding index &hellip; This might be a good time to put on some coffee :-)<br /><br />
+
+<?php
+
+	require PUN_ROOT.'include/search_idx.php';
+
+	// Fetch posts to process
+	$result = $db->query('SELECT DISTINCT t.id, p.id, p.message FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id WHERE t.id>='.$start_at.' AND t.id<'.$end_at.' ORDER BY t.id') or error('Unable to fetch topic/post info', __FILE__, __LINE__, $db->error());
+
+	$cur_topic = 0;
+	while ($cur_post = $db->fetch_row($result))
+	{
+		if ($cur_post[0] <> $cur_topic)
+		{
+			// Fetch subject and ID of first post in topic
+			$result2 = $db->query('SELECT p.id, t.subject, MIN(p.posted) AS first FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE t.id='.$cur_post[0].' GROUP BY p.id, t.subject ORDER BY first LIMIT 1') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
+			list($first_post, $subject) = $db->fetch_row($result2);
+
+			$cur_topic = $cur_post[0];
+		}
+
+		echo 'Processing post <strong>'.$cur_post[1].'</strong> in topic <strong>'.$cur_post[0].'</strong><br />'."\n";
+
+		if ($cur_post[1] == $first_post)	// This is the "topic post" so we have to index the subject as well
+			update_search_index('post', $cur_post[1], $cur_post[2], $subject);
+		else
+			update_search_index('post', $cur_post[1], $cur_post[2]);
+	}
+
+	// Check if there is more work to do
+	$result = $db->query('SELECT id FROM '.$db->prefix.'topics WHERE id>'.$end_at) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
+
+	$query_str = ($db->num_rows($result)) ? '?i_per_page='.$per_page.'&i_start_at='.$end_at : '';
+
+	$db->end_transaction();
+	$db->close();
+
+	exit('<script type="text/javascript">window.location="admin_maintenance.php'.$query_str.'"</script><br />JavaScript redirect unsuccessful. Click <a href="admin_maintenance.php'.$query_str.'">here</a> to continue.');
+}
+
+
+// Get the first post ID from the db
+$result = $db->query('SELECT id FROM '.$db->prefix.'topics ORDER BY id LIMIT 1') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
+if ($db->num_rows($result))
+	$first_id = $db->result($result);
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Maintenance';
+require PUN_ROOT.'header.php';
+
+generate_admin_menu('maintenance');
+
+?>
+	<div class="blockform">
+		<h2><span>Forum Maintenance</span></h2>
+		<div class="box">
+			<form method="get" action="admin_maintenance.php">
+				<div class="inform">
+					<fieldset>
+						<legend>Rebuild search index</legend>
+						<div class="infldset">
+							<p>If you've added, edited or removed posts manually in the database or if you're having problems searching, you should rebuild the search index. For best performance you should put the forum in maintenance mode during rebuilding. <strong>Rebuilding the search index can take a long time and will increase server load during the rebuild process!</strong></p>
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Topics per cycle</th>
+									<td>
+										<input type="text" name="i_per_page" size="7" maxlength="7" value="100" tabindex="1" />
+										<span>The number of topics to process per pageview. E.g. if you were to enter 100, one hundred topics would be processed and then the page would refresh. This is to prevent the script from timing out during the rebuild process.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Starting Topic ID</th>
+									<td>
+										<input type="text" name="i_start_at" size="7" maxlength="7" value="<?php echo (isset($first_id)) ? $first_id : 0 ?>" tabindex="2" />
+										<span>The topic ID to start rebuilding at. It's default value is the first available ID in the database. Normally you wouldn't want to change this.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Empty index</th>
+									<td class="inputadmin">
+										<span><input type="checkbox" name="i_empty_index" value="1" tabindex="3" checked="checked" />&nbsp;&nbsp;Select this if you want the search index to be emptied before rebuilding (see below).</span>
+									</td>
+								</tr>
+							</table>
+							<p class="topspace">Once the process has completed you will be redirected back to this page. It is highly recommended that you have JavaScript enabled in your browser during rebuilding (for automatic redirect when a cycle has completed). If you are forced to abort the rebuild process, make a note of the last processed topic ID and enter that ID+1 in "Topic ID to start at" when/if you want to continue ("Empty index" must not be selected).</p>
+							<div class="fsetsubmit"><input type="submit" name="rebuild_index" value="Rebuild index" tabindex="4" /></div>
+						</div>
+					</fieldset>
+				</div>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_options.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,702 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_ADMIN)
+	message($lang_common['No permission']);
+
+
+if (isset($_POST['form_sent']))
+{
+	// Custom referrer check (so we can output a custom error message)
+	if (!preg_match('#^'.preg_quote(str_replace('www.', '', $pun_config['o_base_url']).'/admin_options.php', '#').'#i', str_replace('www.', '', (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''))))
+		message('Bad HTTP_REFERER. If you have moved these forums from one location to another or switched domains, you need to update the Base URL manually in the database (look for o_base_url in the config table) and then clear the cache by deleting all .php files in the /cache directory.');
+
+	$form = array_map('trim', $_POST['form']);
+
+	if ($form['board_title'] == '')
+		message('You must enter a board title.');
+
+	// Clean default_lang
+	$form['default_lang'] = preg_replace('#[\.\\\/]#', '', $form['default_lang']);
+
+	require PUN_ROOT.'include/email.php';
+
+	$form['admin_email'] = strtolower($form['admin_email']);
+	if (!is_valid_email($form['admin_email']))
+		message('The admin e-mail address you entered is invalid.');
+
+	$form['webmaster_email'] = strtolower($form['webmaster_email']);
+	if (!is_valid_email($form['webmaster_email']))
+		message('The webmaster e-mail address you entered is invalid.');
+
+	if ($form['mailing_list'] != '')
+		$form['mailing_list'] = strtolower(preg_replace('/[\s]/', '', $form['mailing_list']));
+
+	// Make sure base_url doesn't end with a slash
+	if (substr($form['base_url'], -1) == '/')
+		$form['base_url'] = substr($form['base_url'], 0, -1);
+
+	// Clean avatars_dir
+	$form['avatars_dir'] = str_replace("\0", '', $form['avatars_dir']);
+
+	// Make sure avatars_dir doesn't end with a slash
+	if (substr($form['avatars_dir'], -1) == '/')
+		$form['avatars_dir'] = substr($form['avatars_dir'], 0, -1);
+
+	if ($form['additional_navlinks'] != '')
+		$form['additional_navlinks'] = trim(pun_linebreaks($form['additional_navlinks']));
+
+	if ($form['announcement_message'] != '')
+		$form['announcement_message'] = pun_linebreaks($form['announcement_message']);
+	else
+	{
+		$form['announcement_message'] = 'Enter your announcement here.';
+
+		if ($form['announcement'] == '1')
+			$form['announcement'] = '0';
+	}
+
+	if ($form['rules_message'] != '')
+		$form['rules_message'] = pun_linebreaks($form['rules_message']);
+	else
+	{
+		$form['rules_message'] = 'Enter your rules here.';
+
+		if ($form['rules'] == '1')
+			$form['rules'] = '0';
+	}
+
+	if ($form['maintenance_message'] != '')
+		$form['maintenance_message'] = pun_linebreaks($form['maintenance_message']);
+	else
+	{
+		$form['maintenance_message'] = 'The forums are temporarily down for maintenance. Please try again in a few minutes.\n\n/Administrator';
+
+		if ($form['maintenance'] == '1')
+			$form['maintenance'] = '0';
+	}
+
+	$form['timeout_visit'] = intval($form['timeout_visit']);
+	$form['timeout_online'] = intval($form['timeout_online']);
+	$form['redirect_delay'] = intval($form['redirect_delay']);
+	$form['topic_review'] = intval($form['topic_review']);
+	$form['disp_topics_default'] = intval($form['disp_topics_default']);
+	$form['disp_posts_default'] = intval($form['disp_posts_default']);
+	$form['indent_num_spaces'] = intval($form['indent_num_spaces']);
+	$form['avatars_width'] = intval($form['avatars_width']);
+	$form['avatars_height'] = intval($form['avatars_height']);
+	$form['avatars_size'] = intval($form['avatars_size']);
+
+	if ($form['timeout_online'] >= $form['timeout_visit'])
+		message('The value of "Timeout online" must be smaller than the value of "Timeout visit".');
+
+	while (list($key, $input) = @each($form))
+	{
+		// Only update values that have changed
+		if (array_key_exists('o_'.$key, $pun_config) && $pun_config['o_'.$key] != $input)
+		{
+			if ($input != '' || is_int($input))
+				$value = '\''.$db->escape($input).'\'';
+			else
+				$value = 'NULL';
+
+			$db->query('UPDATE '.$db->prefix.'config SET conf_value='.$value.' WHERE conf_name=\'o_'.$db->escape($key).'\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error());
+		}
+	}
+
+	// Regenerate the config cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_config_cache();
+
+	redirect('admin_options.php', 'Options updated. Redirecting &hellip;');
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Options';
+$form_name = 'update_options';
+require PUN_ROOT.'header.php';
+
+generate_admin_menu('options');
+
+?>
+	<div class="blockform">
+		<h2><span>Options</span></h2>
+		<div class="box">
+			<form method="post" action="admin_options.php?action=foo">
+				<p class="submittop"><input type="submit" name="save" value="Save changes" /></p>
+				<div class="inform">
+				<input type="hidden" name="form_sent" value="1" />
+					<fieldset>
+						<legend>Essentials</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Board title</th>
+									<td>
+										<input type="text" name="form[board_title]" size="50" maxlength="255" value="<?php echo pun_htmlspecialchars($pun_config['o_board_title']) ?>" />
+										<span>The title of this bulletin board (shown at the top of every page). This field may <strong>not</strong> contain HTML.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Board description</th>
+									<td>
+										<input type="text" name="form[board_desc]" size="50" maxlength="255" value="<?php echo pun_htmlspecialchars($pun_config['o_board_desc']) ?>" />
+										<span>A short description of this bulletin board (shown at the top of every page). This field may contain HTML.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Base URL</th>
+									<td>
+										<input type="text" name="form[base_url]" size="50" maxlength="100" value="<?php echo $pun_config['o_base_url'] ?>" />
+										<span>The complete URL of the forum without trailing slash (i.e. http://www.mydomain.com/forums). This <strong>must</strong> be correct in order for all admin and moderator features to work. If you get "Bad referer" errors, it's probably incorrect.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Server timezone</th>
+									<td>
+										<select name="form[server_timezone]">
+											<option value="-12"<?php if ($pun_config['o_server_timezone'] == -12 ) echo ' selected="selected"' ?>>-12</option>
+											<option value="-11"<?php if ($pun_config['o_server_timezone'] == -11) echo ' selected="selected"' ?>>-11</option>
+											<option value="-10"<?php if ($pun_config['o_server_timezone'] == -10) echo ' selected="selected"' ?>>-10</option>
+											<option value="-9.5"<?php if ($pun_config['o_server_timezone'] == -9.5) echo ' selected="selected"' ?>>-09.5</option>
+											<option value="-9"<?php if ($pun_config['o_server_timezone'] == -9 ) echo ' selected="selected"' ?>>-09</option>
+											<option value="-8.5"<?php if ($pun_config['o_server_timezone'] == -8.5) echo ' selected="selected"' ?>>-08.5</option>
+											<option value="-8"<?php if ($pun_config['o_server_timezone'] == -8 ) echo ' selected="selected"' ?>>-08 PST</option>
+											<option value="-7"<?php if ($pun_config['o_server_timezone'] == -7 ) echo ' selected="selected"' ?>>-07 MST</option>
+											<option value="-6"<?php if ($pun_config['o_server_timezone'] == -6 ) echo ' selected="selected"' ?>>-06 CST</option>
+											<option value="-5"<?php if ($pun_config['o_server_timezone'] == -5 ) echo ' selected="selected"' ?>>-05 EST</option>
+											<option value="-4"<?php if ($pun_config['o_server_timezone'] == -4 ) echo ' selected="selected"' ?>>-04 AST</option>
+											<option value="-3.5"<?php if ($pun_config['o_server_timezone'] == -3.5) echo ' selected="selected"' ?>>-03.5</option>
+											<option value="-3"<?php if ($pun_config['o_server_timezone'] == -3 ) echo ' selected="selected"' ?>>-03 ADT</option>
+											<option value="-2"<?php if ($pun_config['o_server_timezone'] == -2 ) echo ' selected="selected"' ?>>-02</option>
+											<option value="-1"<?php if ($pun_config['o_server_timezone'] == -1) echo ' selected="selected"' ?>>-01</option>
+											<option value="0"<?php if ($pun_config['o_server_timezone'] == 0) echo ' selected="selected"' ?>>00 GMT</option>
+											<option value="1"<?php if ($pun_config['o_server_timezone'] == 1) echo ' selected="selected"' ?>>+01 CET</option>
+											<option value="2"<?php if ($pun_config['o_server_timezone'] == 2 ) echo ' selected="selected"' ?>>+02</option>
+											<option value="3"<?php if ($pun_config['o_server_timezone'] == 3 ) echo ' selected="selected"' ?>>+03</option>
+											<option value="3.5"<?php if ($pun_config['o_server_timezone'] == 3.5) echo ' selected="selected"' ?>>+03.5</option>
+											<option value="4"<?php if ($pun_config['o_server_timezone'] == 4 ) echo ' selected="selected"' ?>>+04</option>
+											<option value="4.5"<?php if ($pun_config['o_server_timezone'] == 4.5) echo ' selected="selected"' ?>>+04.5</option>
+											<option value="5"<?php if ($pun_config['o_server_timezone'] == 5 ) echo ' selected="selected"' ?>>+05</option>
+											<option value="5.5"<?php if ($pun_config['o_server_timezone'] == 5.5) echo ' selected="selected"' ?>>+05.5</option>
+											<option value="6"<?php if ($pun_config['o_server_timezone'] == 6 ) echo ' selected="selected"' ?>>+06</option>
+											<option value="6.5"<?php if ($pun_config['o_server_timezone'] == 6.5) echo ' selected="selected"' ?>>+06.5</option>
+											<option value="7"<?php if ($pun_config['o_server_timezone'] == 7 ) echo ' selected="selected"' ?>>+07</option>
+											<option value="8"<?php if ($pun_config['o_server_timezone'] == 8 ) echo ' selected="selected"' ?>>+08</option>
+											<option value="9"<?php if ($pun_config['o_server_timezone'] == 9 ) echo ' selected="selected"' ?>>+09</option>
+											<option value="9.5"<?php if ($pun_config['o_server_timezone'] == 9.5) echo ' selected="selected"' ?>>+09.5</option>
+											<option value="10"<?php if ($pun_config['o_server_timezone'] == 10) echo ' selected="selected"' ?>>+10</option>
+											<option value="10.5"<?php if ($pun_config['o_server_timezone'] == 10.5) echo ' selected="selected"' ?>>+10.5</option>
+											<option value="11"<?php if ($pun_config['o_server_timezone'] == 11) echo ' selected="selected"' ?>>+11</option>
+											<option value="11.5"<?php if ($pun_config['o_server_timezone'] == 11.5) echo ' selected="selected"' ?>>+11.5</option>
+											<option value="12"<?php if ($pun_config['o_server_timezone'] == 12 ) echo ' selected="selected"' ?>>+12</option>
+											<option value="13"<?php if ($pun_config['o_server_timezone'] == 13 ) echo ' selected="selected"' ?>>+13</option>
+										</select>
+										<span>The timezone of the server where PunBB is installed.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Default language</th>
+									<td>
+										<select name="form[default_lang]">
+<?php
+
+		$languages = array();
+		$d = dir(PUN_ROOT.'lang');
+		while (($entry = $d->read()) !== false)
+		{
+			if ($entry != '.' && $entry != '..' && is_dir(PUN_ROOT.'lang/'.$entry) && file_exists(PUN_ROOT.'lang/'.$entry.'/common.php'))
+				$languages[] = $entry;
+		}
+		$d->close();
+
+		@natsort($languages);
+
+		while (list(, $temp) = @each($languages))
+		{
+			if ($pun_config['o_default_lang'] == $temp)
+				echo "\t\t\t\t\t\t\t\t\t\t\t".'<option value="'.$temp.'" selected="selected">'.$temp.'</option>'."\n";
+			else
+				echo "\t\t\t\t\t\t\t\t\t\t\t".'<option value="'.$temp.'">'.$temp.'</option>'."\n";
+		}
+
+?>
+										</select>
+										<span>This is the default language style used if the visitor is a guest or a user that hasn't changed from the default in his/her profile. If you remove a language pack, this must be updated.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Default style</th>
+									<td>
+										<select name="form[default_style]">
+<?php
+
+		$styles = array();
+		$d = dir(PUN_ROOT.'style');
+		while (($entry = $d->read()) !== false)
+		{
+			if (substr($entry, strlen($entry)-4) == '.css')
+				$styles[] = substr($entry, 0, strlen($entry)-4);
+		}
+		$d->close();
+
+		@natsort($styles);
+
+		while (list(, $temp) = @each($styles))
+		{
+			if ($pun_config['o_default_style'] == $temp)
+				echo "\t\t\t\t\t\t\t\t\t".'<option value="'.$temp.'" selected="selected">'.str_replace('_', ' ', $temp).'</option>'."\n";
+			else
+				echo "\t\t\t\t\t\t\t\t\t".'<option value="'.$temp.'">'.str_replace('_', ' ', $temp).'</option>'."\n";
+		}
+
+?>
+										</select>
+										<span>This is the default style used for guests and users who haven't changed from the default in their profile.</span></td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Time and timeouts</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Time format</th>
+									<td>
+										<input type="text" name="form[time_format]" size="25" maxlength="25" value="<?php echo pun_htmlspecialchars($pun_config['o_time_format']) ?>" />
+										<span>[Current format: <?php echo date($pun_config['o_time_format']) ?>]&nbsp;See <a href="http://www.php.net/manual/en/function.date.php">here</a> for formatting options.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Date format</th>
+									<td>
+										<input type="text" name="form[date_format]" size="25" maxlength="25" value="<?php echo pun_htmlspecialchars($pun_config['o_date_format']) ?>" />
+										<span>[Current format: <?php echo date($pun_config['o_date_format']) ?>]&nbsp;See <a href="http://www.php.net/manual/en/function.date.php">here</a> for formatting options.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Visit timeout</th>
+									<td>
+										<input type="text" name="form[timeout_visit]" size="5" maxlength="5" value="<?php echo $pun_config['o_timeout_visit'] ?>" />
+										<span>Number of seconds a user must be idle before his/hers last visit data is updated (primarily affects new message indicators).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Online timeout</th>
+									<td>
+										<input type="text" name="form[timeout_online]" size="5" maxlength="5" value="<?php echo $pun_config['o_timeout_online'] ?>" />
+										<span>Number of seconds a user must be idle before being removed from the online users list.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Redirect time</th>
+									<td>
+										<input type="text" name="form[redirect_delay]" size="3" maxlength="3" value="<?php echo $pun_config['o_redirect_delay'] ?>" />
+										<span>Number of seconds to wait when redirecting. If set to 0, no redirect page will be displayed (not recommended).</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Display</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Version number</th>
+									<td>
+										<input type="radio" name="form[show_version]" value="1"<?php if ($pun_config['o_show_version'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[show_version]" value="0"<?php if ($pun_config['o_show_version'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Show version number in footer.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">User info in posts</th>
+									<td>
+										<input type="radio" name="form[show_user_info]" value="1"<?php if ($pun_config['o_show_user_info'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[show_user_info]" value="0"<?php if ($pun_config['o_show_user_info'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Show information about the poster under the username in topic view. The information affected is location, register date, post count and the contact links (e-mail and URL).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">User post count</th>
+									<td>
+										<input type="radio" name="form[show_post_count]" value="1"<?php if ($pun_config['o_show_post_count'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[show_post_count]" value="0"<?php if ($pun_config['o_show_post_count'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Show the number of posts a user has made (affects topic view, profile and userlist).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Smilies</th>
+									<td>
+										<input type="radio" name="form[smilies]" value="1"<?php if ($pun_config['o_smilies'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[smilies]" value="0"<?php if ($pun_config['o_smilies'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Convert smilies to small icons.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Smilies in signatures</th>
+									<td>
+										<input type="radio" name="form[smilies_sig]" value="1"<?php if ($pun_config['o_smilies_sig'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[smilies_sig]" value="0"<?php if ($pun_config['o_smilies_sig'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Convert smilies to small icons in user signatures.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Make clickable links</th>
+									<td>
+										<input type="radio" name="form[make_links]" value="1"<?php if ($pun_config['o_make_links'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[make_links]" value="0"<?php if ($pun_config['o_make_links'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>When enabled, PunBB will automatically detect any URL's in posts and make them clickable hyperlinks.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Topic review</th>
+									<td>
+										<input type="text" name="form[topic_review]" size="3" maxlength="3" value="<?php echo $pun_config['o_topic_review'] ?>" />
+										<span>Maximum number of posts to display when posting (newest first). 0 to disable.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Topics per page default</th>
+									<td>
+										<input type="text" name="form[disp_topics_default]" size="3" maxlength="3" value="<?php echo $pun_config['o_disp_topics_default'] ?>" />
+										<span>The default number of topics to display per page in a forum. Users can personalize this setting.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Posts per page default</th>
+									<td>
+										<input type="text" name="form[disp_posts_default]" size="3" maxlength="3" value="<?php echo $pun_config['o_disp_posts_default'] ?>" />
+										<span>The default number of posts to display per page in a topic. Users can personalize this setting.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Indent size</th>
+									<td>
+										<input type="text" name="form[indent_num_spaces]" size="3" maxlength="3" value="<?php echo $pun_config['o_indent_num_spaces'] ?>" />
+										<span>If set to 8, a regular tab will be used when displaying text within the [code][/code] tag. Otherwise this many spaces will be used to indent the text.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Features</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Quick post</th>
+									<td>
+										<input type="radio" name="form[quickpost]" value="1"<?php if ($pun_config['o_quickpost'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[quickpost]" value="0"<?php if ($pun_config['o_quickpost'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>When enabled, PunBB will add a quick post form at the bottom of topics. This way users can post directly from the topic view.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Users online</th>
+									<td>
+										<input type="radio" name="form[users_online]" value="1"<?php if ($pun_config['o_users_online'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[users_online]" value="0"<?php if ($pun_config['o_users_online'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Display info on the index page about guests and registered users currently browsing the forums.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row"><a name="censoring">Censor words</a></th>
+									<td>
+										<input type="radio" name="form[censoring]" value="1"<?php if ($pun_config['o_censoring'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[censoring]" value="0"<?php if ($pun_config['o_censoring'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Enable this to censor specific words in the forum. See <a href="admin_censoring.php">Censoring</a> for more info.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row"><a name="ranks">User ranks</a></th>
+									<td>
+										<input type="radio" name="form[ranks]" value="1"<?php if ($pun_config['o_ranks'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[ranks]" value="0"<?php if ($pun_config['o_ranks'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Enable this to use user ranks. See <a href="admin_ranks.php">Ranks</a> for more info.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">User has posted earlier</th>
+									<td>
+										<input type="radio" name="form[show_dot]" value="1"<?php if ($pun_config['o_show_dot'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[show_dot]" value="0"<?php if ($pun_config['o_show_dot'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>This feature displays a dot in front of topics in viewforum.php in case the currently logged in user has posted in that topic earlier. Disable if you are experiencing high server load.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Quick jump</th>
+									<td>
+										<input type="radio" name="form[quickjump]" value="1"<?php if ($pun_config['o_quickjump'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[quickjump]" value="0"<?php if ($pun_config['o_quickjump'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Enable the quick jump (jump to forum) drop list.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">GZip output</th>
+									<td>
+										<input type="radio" name="form[gzip]" value="1"<?php if ($pun_config['o_gzip'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[gzip]" value="0"<?php if ($pun_config['o_gzip'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>If enabled, PunBB will gzip the output sent to browsers. This will reduce bandwidth usage, but use a little more CPU. This feature requires that PHP is configured with zlib (--with-zlib). Note: If you already have one of the Apache modules mod_gzip or mod_deflate set up to compress PHP scripts, you should disable this feature.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Search all forums</th>
+									<td>
+										<input type="radio" name="form[search_all_forums]" value="1"<?php if ($pun_config['o_search_all_forums'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[search_all_forums]" value="0"<?php if ($pun_config['o_search_all_forums'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>When disabled, searches will only be allowed in one forum at a time. Disable if server load is high due to excessive searching.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Additional menu items</th>
+									<td>
+										<textarea name="form[additional_navlinks]" rows="3" cols="55"><?php echo pun_htmlspecialchars($pun_config['o_additional_navlinks']) ?></textarea>
+										<span>By entering HTML hyperlinks into this textbox, any number of items can be added to the navigation menu at the top of all pages. The format for adding new links is X = &lt;a href="URL"&gt;LINK&lt;/a&gt; where X is the position at which the link should be inserted (e.g. 0 to insert at the beginning and 2 to insert after "User list"). Separate entries with a linebreak.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Reports</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Report method</th>
+									<td>
+										<input type="radio" name="form[report_method]" value="0"<?php if ($pun_config['o_report_method'] == '0') echo ' checked="checked"' ?> />&nbsp;Internal&nbsp;&nbsp;&nbsp;<input type="radio" name="form[report_method]" value="1"<?php if ($pun_config['o_report_method'] == '1') echo ' checked="checked"' ?> />&nbsp;E-mail&nbsp;&nbsp;&nbsp;<input type="radio" name="form[report_method]" value="2"<?php if ($pun_config['o_report_method'] == '2') echo ' checked="checked"' ?> />&nbsp;Both
+										<span>Select the method for handling topic/post reports. You can choose whether topic/post reports should be handled by the internal report system,  e-mailed to the addresses on the mailing list (see below) or both.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Report new registrations</th>
+									<td>
+										<input type="radio" name="form[regs_report]" value="1"<?php if ($pun_config['o_regs_report'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[regs_report]" value="0"<?php if ($pun_config['o_regs_report'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>If enabled, PunBB will notify users on the mailing list (see below) when a new user registers in the forums.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Mailing list</th>
+									<td>
+										<textarea name="form[mailing_list]" rows="5" cols="55"><?php echo pun_htmlspecialchars($pun_config['o_mailing_list']) ?></textarea>
+										<span>A comma separated list of subscribers. The people on this list are the recipients of reports.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Avatars</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Use avatars</th>
+									<td>
+										<input type="radio" name="form[avatars]" value="1"<?php if ($pun_config['o_avatars'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[avatars]" value="0"<?php if ($pun_config['o_avatars'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>When enabled, users will be able to upload an avatar which will be displayed under their title/rank.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Upload directory</th>
+									<td>
+										<input type="text" name="form[avatars_dir]" size="35" maxlength="50" value="<?php echo pun_htmlspecialchars($pun_config['o_avatars_dir']) ?>" />
+										<span>The upload directory for avatars (relative to the PunBB root directory). PHP must have write permissions to this directory.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Max width</th>
+									<td>
+										<input type="text" name="form[avatars_width]" size="5" maxlength="5" value="<?php echo $pun_config['o_avatars_width'] ?>" />
+										<span>The maximum allowed width of avatars in pixels (60 is recommended).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Max height</th>
+									<td>
+										<input type="text" name="form[avatars_height]" size="5" maxlength="5" value="<?php echo $pun_config['o_avatars_height'] ?>" />
+										<span>The maximum allowed height of avatars in pixels (60 is recommended).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Max size</th>
+									<td>
+										<input type="text" name="form[avatars_size]" size="6" maxlength="6" value="<?php echo $pun_config['o_avatars_size'] ?>" />
+										<span>The maximum allowed size of avatars in bytes (10240 is recommended).</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>E-mail</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Admin e-mail</th>
+									<td>
+										<input type="text" name="form[admin_email]" size="50" maxlength="50" value="<?php echo $pun_config['o_admin_email'] ?>" />
+										<span>The e-mail address of the forum administrator.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Webmaster e-mail</th>
+									<td>
+										<input type="text" name="form[webmaster_email]" size="50" maxlength="50" value="<?php echo $pun_config['o_webmaster_email'] ?>" />
+										<span>This is the address that all e-mails sent by the forum will be addressed from.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Subscriptions</th>
+									<td>
+										<input type="radio" name="form[subscriptions]" value="1"<?php if ($pun_config['o_subscriptions'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[subscriptions]" value="0"<?php if ($pun_config['o_subscriptions'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Enable users to subscribe to topics (recieve e-mail when someone replies).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">SMTP server address</th>
+									<td>
+										<input type="text" name="form[smtp_host]" size="30" maxlength="100" value="<?php echo pun_htmlspecialchars($pun_config['o_smtp_host']) ?>" />
+										<span>The address of an external SMTP server to send e-mails with. You can specify a custom port number if the SMTP server doesn't run on the default port 25 (example: mail.myhost.com:3580). Leave blank to use the local mail program.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">SMTP username</th>
+									<td>
+										<input type="text" name="form[smtp_user]" size="25" maxlength="50" value="<?php echo pun_htmlspecialchars($pun_config['o_smtp_user']) ?>" />
+										<span>Username for SMTP server. Only enter a username if it is required by the SMTP server (most servers <strong>do not</strong> require authentication).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">SMTP password</th>
+									<td>
+										<input type="text" name="form[smtp_pass]" size="25" maxlength="50" value="<?php echo pun_htmlspecialchars($pun_config['o_smtp_pass']) ?>" />
+										<span>Password for SMTP server. Only enter a password if it is required by the SMTP server (most servers <strong>do not</strong> require authentication).</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Registration</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Allow new registrations</th>
+									<td>
+										<input type="radio" name="form[regs_allow]" value="1"<?php if ($pun_config['o_regs_allow'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[regs_allow]" value="0"<?php if ($pun_config['o_regs_allow'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Controls whether this forum accepts new registrations. Disable only under special circumstances.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Verify registrations</th>
+									<td>
+										<input type="radio" name="form[regs_verify]" value="1"<?php if ($pun_config['o_regs_verify'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[regs_verify]" value="0"<?php if ($pun_config['o_regs_verify'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>When enabled, users are e-mailed a random password when they register. They can then log in and change the password in their profile if they see fit. This feature also requires users to verify new e-mail addresses if they choose to change from the one they registered with. This is an effective way of avoiding registration abuse and making sure that all users have "correct" e-mail addresses in their profiles.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Use forum rules</th>
+									<td>
+										<input type="radio" name="form[rules]" value="1"<?php if ($pun_config['o_rules'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[rules]" value="0"<?php if ($pun_config['o_rules'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>When enabled, users must agree to a set of rules when registering (enter text below). The rules will always be available through a link in the navigation table at the top of every page.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Rules</th>
+									<td>
+										<textarea name="form[rules_message]" rows="10" cols="55"><?php echo pun_htmlspecialchars($pun_config['o_rules_message']) ?></textarea>
+										<span>Here you can enter any rules or other information that the user must review and accept when registering. If you enabled rules above you have to enter something here, otherwise it will be disabled. This text will not be parsed like regular posts and thus may contain HTML.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Announcement</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Display announcement</th>
+									<td>
+										<input type="radio" name="form[announcement]" value="1"<?php if ($pun_config['o_announcement'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[announcement]" value="0"<?php if ($pun_config['o_announcement'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Enable this to display the below message in the forums.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Announcement message</th>
+									<td>
+										<textarea name="form[announcement_message]" rows="5" cols="55"><?php echo pun_htmlspecialchars($pun_config['o_announcement_message']) ?></textarea>
+										<span>This text will not be parsed like regular posts and thus may contain HTML.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Maintenance</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row"><a name="maintenance">Maintenance mode</a></th>
+									<td>
+										<input type="radio" name="form[maintenance]" value="1"<?php if ($pun_config['o_maintenance'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[maintenance]" value="0"<?php if ($pun_config['o_maintenance'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>When enabled, the board will only be available to administrators. This should be used if the board needs to taken down temporarily for maintenance. WARNING! Do not log out when the board is in maintenance mode. You will not be able to login again.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Maintenance message</th>
+									<td>
+										<textarea name="form[maintenance_message]" rows="5" cols="55"><?php echo pun_htmlspecialchars($pun_config['o_maintenance_message']) ?></textarea>
+										<span>The message that will be displayed to users when the board is in maintenance mode. If left blank a default message will be used. This text will not be parsed like regular posts and thus may contain HTML.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<p class="submitend"><input type="submit" name="save" value="Save changes" /></p>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_permissions.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,226 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_ADMIN)
+	message($lang_common['No permission']);
+
+
+if (isset($_POST['form_sent']))
+{
+	confirm_referrer('admin_permissions.php');
+
+	$form = array_map('intval', $_POST['form']);
+
+	while (list($key, $input) = @each($form))
+	{
+		// Only update values that have changed
+		if (array_key_exists('p_'.$key, $pun_config) && $pun_config['p_'.$key] != $input)
+			$db->query('UPDATE '.$db->prefix.'config SET conf_value='.$input.' WHERE conf_name=\'p_'.$db->escape($key).'\'') or error('Unable to update board config', __FILE__, __LINE__, $db->error());
+	}
+
+	// Regenerate the config cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_config_cache();
+
+	redirect('admin_permissions.php', 'Permissions updated. Redirecting &hellip;');
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Permissions';
+require PUN_ROOT.'header.php';
+generate_admin_menu('permissions');
+
+?>
+	<div class="blockform">
+		<h2><span>Permissions</span></h2>
+		<div class="box">
+			<form method="post" action="admin_permissions.php">
+				<p class="submittop"><input type="submit" name="save" value="Save changes" /></p>
+				<div class="inform">
+				<input type="hidden" name="form_sent" value="1" />
+					<fieldset>
+						<legend>Posting</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">BBCode</th>
+									<td>
+										<input type="radio" name="form[message_bbcode]" value="1"<?php if ($pun_config['p_message_bbcode'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[message_bbcode]" value="0"<?php if ($pun_config['p_message_bbcode'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow BBCode in posts (recommended).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Image tag</th>
+									<td>
+										<input type="radio" name="form[message_img_tag]" value="1"<?php if ($pun_config['p_message_img_tag'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[message_img_tag]" value="0"<?php if ($pun_config['p_message_img_tag'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow the BBCode [img][/img] tag in posts.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">All caps message</th>
+									<td>
+										<input type="radio" name="form[message_all_caps]" value="1"<?php if ($pun_config['p_message_all_caps'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[message_all_caps]" value="0"<?php if ($pun_config['p_message_all_caps'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow a message to contain only capital letters.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">All caps subject</th>
+									<td>
+										<input type="radio" name="form[subject_all_caps]" value="1"<?php if ($pun_config['p_subject_all_caps'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[subject_all_caps]" value="0"<?php if ($pun_config['p_subject_all_caps'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow a subject to contain only capital letters.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Require guest e-mail</th>
+									<td>
+										<input type="radio" name="form[force_guest_email]" value="1"<?php if ($pun_config['p_force_guest_email'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[force_guest_email]" value="0"<?php if ($pun_config['p_force_guest_email'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Require guests to supply an e-mail address when posting.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Signatures</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">BBCodes in signatures</th>
+									<td>
+										<input type="radio" name="form[sig_bbcode]" value="1"<?php if ($pun_config['p_sig_bbcode'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[sig_bbcode]" value="0"<?php if ($pun_config['p_sig_bbcode'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow BBCodes in user signatures.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Image tag in signatures</th>
+									<td>
+										<input type="radio" name="form[sig_img_tag]" value="1"<?php if ($pun_config['p_sig_img_tag'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[sig_img_tag]" value="0"<?php if ($pun_config['p_sig_img_tag'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow the BBCode [img][/img] tag in user signatures (not recommended).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">All caps signature</th>
+									<td>
+										<input type="radio" name="form[sig_all_caps]" value="1"<?php if ($pun_config['p_sig_all_caps'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[sig_all_caps]" value="0"<?php if ($pun_config['p_sig_all_caps'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow a signature to contain only capital letters.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Maximum signature length</th>
+									<td>
+										<input type="text" name="form[sig_length]" size="5" maxlength="5" value="<?php echo $pun_config['p_sig_length'] ?>" />
+										<span>The maximum number of characters a user signature may contain.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Maximum signature lines</th>
+									<td>
+										<input type="text" name="form[sig_lines]" size="3" maxlength="3" value="<?php echo $pun_config['p_sig_lines'] ?>" />
+										<span>The maximum number of lines a user signature may contain.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Moderators</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Edit user profiles</th>
+									<td>
+										<input type="radio" name="form[mod_edit_users]" value="1"<?php if ($pun_config['p_mod_edit_users'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[mod_edit_users]" value="0"<?php if ($pun_config['p_mod_edit_users'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow moderators to edit user profiles.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Rename users</th>
+									<td>
+										<input type="radio" name="form[mod_rename_users]" value="1"<?php if ($pun_config['p_mod_rename_users'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[mod_rename_users]" value="0"<?php if ($pun_config['p_mod_rename_users'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow moderators to rename users. Other moderators and administrators are excluded.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Change user passwords</th>
+									<td>
+										<input type="radio" name="form[mod_change_passwords]" value="1"<?php if ($pun_config['p_mod_change_passwords'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[mod_change_passwords]" value="0"<?php if ($pun_config['p_mod_change_passwords'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow moderators to change user passwords. Other moderators and administrators are excluded.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Ban users</th>
+									<td>
+										<input type="radio" name="form[mod_ban_users]" value="1"<?php if ($pun_config['p_mod_ban_users'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[mod_ban_users]" value="0"<?php if ($pun_config['p_mod_ban_users'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow moderators to ban users (and edit/remove current bans).</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Registration</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Allow banned e-mail addresses</th>
+									<td>
+										<input type="radio" name="form[allow_banned_email]" value="1"<?php if ($pun_config['p_allow_banned_email'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[allow_banned_email]" value="0"<?php if ($pun_config['p_allow_banned_email'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Allow users to register with or change to a banned e-mail address/domain. If left at it's default setting (yes) this action will be allowed, but an alert e-mail will be sent to the mailing list (an effective way of detecting multiple registrations).</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Allow duplicate e-mail addresses</th>
+									<td>
+										<input type="radio" name="form[allow_dupe_email]" value="1"<?php if ($pun_config['p_allow_dupe_email'] == '1') echo ' checked="checked"' ?> />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="form[allow_dupe_email]" value="0"<?php if ($pun_config['p_allow_dupe_email'] == '0') echo ' checked="checked"' ?> />&nbsp;<strong>No</strong>
+										<span>Controls whether users should be allowed to register with an e-mail address that another user already has. If allowed, an alert e-mail will be sent to the mailing list if a duplicate is detected.</span>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<p class="submitend"><input type="submit" name="save" value="Save changes" /></p>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_prune.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,230 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_ADMIN)
+	message($lang_common['No permission']);
+
+
+if (isset($_GET['action']) || isset($_POST['prune']) || isset($_POST['prune_comply']))
+{
+	if (isset($_POST['prune_comply']))
+	{
+		confirm_referrer('admin_prune.php');
+
+		$prune_from = $_POST['prune_from'];
+		$prune_days = intval($_POST['prune_days']);
+		$prune_date = ($prune_days) ? time() - ($prune_days*86400) : -1;
+
+		@set_time_limit(0);
+
+		if ($prune_from == 'all')
+		{
+			$result = $db->query('SELECT id FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
+			$num_forums = $db->num_rows($result);
+
+			for ($i = 0; $i < $num_forums; ++$i)
+			{
+				$fid = $db->result($result, $i);
+
+				prune($fid, $_POST['prune_sticky'], $prune_date);
+				update_forum($fid);
+			}
+		}
+		else
+		{
+			$prune_from = intval($prune_from);
+			prune($prune_from, $_POST['prune_sticky'], $prune_date);
+			update_forum($prune_from);
+		}
+
+		// Locate any "orphaned redirect topics" and delete them
+		$result = $db->query('SELECT t1.id FROM '.$db->prefix.'topics AS t1 LEFT JOIN '.$db->prefix.'topics AS t2 ON t1.moved_to=t2.id WHERE t2.id IS NULL AND t1.moved_to IS NOT NULL') or error('Unable to fetch redirect topics', __FILE__, __LINE__, $db->error());
+		$num_orphans = $db->num_rows($result);
+
+		if ($num_orphans)
+		{
+			for ($i = 0; $i < $num_orphans; ++$i)
+				$orphans[] = $db->result($result, $i);
+
+			$db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.implode(',', $orphans).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error());
+		}
+
+		redirect('admin_prune.php', 'Posts pruned. Redirecting &hellip;');
+	}
+
+
+	$prune_days = $_POST['req_prune_days'];
+	if (!@preg_match('#^\d+$#', $prune_days))
+		message('Days to prune must be a positive integer.');
+
+	$prune_date = time() - ($prune_days*86400);
+	$prune_from = $_POST['prune_from'];
+
+	// Concatenate together the query for counting number or topics to prune
+	$sql = 'SELECT COUNT(id) FROM '.$db->prefix.'topics WHERE last_post<'.$prune_date.' AND moved_to IS NULL';
+
+	if ($_POST['prune_sticky'] == '0')
+		$sql .= ' AND sticky=\'0\'';
+
+	if ($prune_from != 'all')
+	{
+		$prune_from = intval($prune_from);
+		$sql .= ' AND forum_id='.$prune_from;
+
+		// Fetch the forum name (just for cosmetic reasons)
+		$result = $db->query('SELECT forum_name FROM '.$db->prefix.'forums WHERE id='.$prune_from) or error('Unable to fetch forum name', __FILE__, __LINE__, $db->error());
+		$forum = '"'.pun_htmlspecialchars($db->result($result)).'"';
+	}
+	else
+		$forum = 'all forums';
+
+	$result = $db->query($sql) or error('Unable to fetch topic prune count', __FILE__, __LINE__, $db->error());
+	$num_topics = $db->result($result);
+
+	if (!$num_topics)
+		message('There are no topics that are '.$prune_days.' days old. Please decrease the value of "Days old" and try again.');
+
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Prune';
+	require PUN_ROOT.'header.php';
+
+	generate_admin_menu('prune');
+
+?>
+	<div class="blockform">
+		<h2><span>Prune</span></h2>
+		<div class="box">
+			<form method="post" action="admin_prune.php?action=foo">
+				<div class="inform">
+					<input type="hidden" name="prune_days" value="<?php echo $prune_days ?>" />
+					<input type="hidden" name="prune_sticky" value="<?php echo $_POST['prune_sticky'] ?>" />
+					<input type="hidden" name="prune_from" value="<?php echo $prune_from ?>" />
+					<fieldset>
+						<legend>Confirm prune posts</legend>
+						<div class="infldset">
+							<p>Are you sure that you want to prune all topics older than <?php echo $prune_days ?> days from <?php echo $forum ?>? (<?php echo $num_topics ?> topics)</p>
+							<p>WARNING! Pruning posts deletes them permanently.</p>
+						</div>
+					</fieldset>
+				</div>
+				<p><input type="submit" name="prune_comply" value="Prune" /><a href="javascript:history.go(-1)">Go back</a></p>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+else
+{
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Prune';
+	$required_fields = array('req_prune_days' => 'Days old');
+	$focus_element = array('prune', 'req_prune_days');
+	require PUN_ROOT.'header.php';
+
+	generate_admin_menu('prune');
+
+?>
+	<div class="blockform">
+		<h2><span>Prune</span></h2>
+		<div class="box">
+			<form id="prune" method="post" action="admin_prune.php?action=foo" onsubmit="return process_form(this)">
+				<div class="inform">
+				<input type="hidden" name="form_sent" value="1" />
+					<fieldset>
+						<legend>Prune old posts</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Days old</th>
+									<td>
+										<input type="text" name="req_prune_days" size="3" maxlength="3" tabindex="1" />
+										<span>The number of days "old" a topic must be to be pruned. E.g. if you were to enter 30, every topic that didn't contain a post dated less than 30 days old would be deleted.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Prune sticky topics</th>
+									<td>
+										<input type="radio" name="prune_sticky" value="1" tabindex="2" checked="checked" />&nbsp;<strong>Yes</strong>&nbsp;&nbsp;&nbsp;<input type="radio" name="prune_sticky" value="0" />&nbsp;<strong>No</strong>
+										<span>When enabled sticky topics will also be pruned.</span>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">Prune from forum</th>
+									<td>
+										<select name="prune_from" tabindex="3">
+											<option value="all">All forums</option>
+<?php
+
+	$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id WHERE f.redirect_url IS NULL ORDER BY c.disp_position, c.id, f.disp_position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
+
+	$cur_category = 0;
+	while ($forum = $db->fetch_assoc($result))
+	{
+		if ($forum['cid'] != $cur_category)	// Are we still in the same category?
+		{
+			if ($cur_category)
+				echo "\t\t\t\t\t\t\t\t\t\t\t".'</optgroup>'."\n";
+
+			echo "\t\t\t\t\t\t\t\t\t\t\t".'<optgroup label="'.pun_htmlspecialchars($forum['cat_name']).'">'."\n";
+			$cur_category = $forum['cid'];
+		}
+
+		echo "\t\t\t\t\t\t\t\t\t\t\t\t".'<option value="'.$forum['fid'].'">'.pun_htmlspecialchars($forum['forum_name']).'</option>'."\n";
+	}
+
+?>
+											</optgroup>
+										</select>
+										<span>The forum from which you want to prune posts.</span>
+									</td>
+								</tr>
+							</table>
+							<p class="topspace">Use this feature with caution. Pruned posts can <strong>never</strong> be recovered. For best performance you should put the forum in maintenance mode during pruning.</p>
+							<div class="fsetsubmit"><input type="submit" name="prune" value="Prune" tabindex="5" /></div>
+						</div>
+					</fieldset>
+				</div>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_ranks.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,195 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_ADMIN)
+	message($lang_common['No permission']);
+
+
+// Add a rank
+if (isset($_POST['add_rank']))
+{
+	confirm_referrer('admin_ranks.php');
+
+	$rank = trim($_POST['new_rank']);
+	$min_posts = $_POST['new_min_posts'];
+
+	if ($rank == '')
+		message('You must enter a rank title.');
+
+	if (!@preg_match('#^\d+$#', $min_posts))
+		message('Minimum posts must be a positive integer value.');
+
+	// Make sure there isn't already a rank with the same min_posts value
+	$result = $db->query('SELECT 1 FROM '.$db->prefix.'ranks WHERE min_posts='.$min_posts) or error('Unable to fetch rank info', __FILE__, __LINE__, $db->error());
+	if ($db->num_rows($result))
+		message('There is already a rank with a minimun posts value of '.$min_posts.'.');
+
+	$db->query('INSERT INTO '.$db->prefix.'ranks (rank, min_posts) VALUES(\''.$db->escape($rank).'\', '.$min_posts.')') or error('Unable to add rank', __FILE__, __LINE__, $db->error());
+
+	// Regenerate the ranks cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_ranks_cache();
+
+	redirect('admin_ranks.php', 'Rank added. Redirecting &hellip;');
+}
+
+
+// Update a rank
+else if (isset($_POST['update']))
+{
+	confirm_referrer('admin_ranks.php');
+
+	$id = intval(key($_POST['update']));
+
+	$rank = trim($_POST['rank'][$id]);
+	$min_posts = trim($_POST['min_posts'][$id]);
+
+	if ($rank == '')
+		message('You must enter a rank title.');
+
+	if (!@preg_match('#^\d+$#', $min_posts))
+		message('Minimum posts must be a positive integer value.');
+
+	// Make sure there isn't already a rank with the same min_posts value
+	$result = $db->query('SELECT 1 FROM '.$db->prefix.'ranks WHERE id!='.$id.' AND min_posts='.$min_posts) or error('Unable to fetch rank info', __FILE__, __LINE__, $db->error());
+	if ($db->num_rows($result))
+		message('There is already a rank with a minimun posts value of '.$min_posts.'.');
+
+	$db->query('UPDATE '.$db->prefix.'ranks SET rank=\''.$db->escape($rank).'\', min_posts='.$min_posts.' WHERE id='.$id) or error('Unable to update rank', __FILE__, __LINE__, $db->error());
+
+	// Regenerate the ranks cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_ranks_cache();
+
+	redirect('admin_ranks.php', 'Rank updated. Redirecting &hellip;');
+}
+
+
+// Remove a rank
+else if (isset($_POST['remove']))
+{
+	confirm_referrer('admin_ranks.php');
+
+	$id = intval(key($_POST['remove']));
+
+	$db->query('DELETE FROM '.$db->prefix.'ranks WHERE id='.$id) or error('Unable to delete rank', __FILE__, __LINE__, $db->error());
+
+	// Regenerate the ranks cache
+	require_once PUN_ROOT.'include/cache.php';
+	generate_ranks_cache();
+
+	redirect('admin_ranks.php', 'Rank removed. Redirecting &hellip;');
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Ranks';
+$focus_element = array('ranks', 'new_rank');
+require PUN_ROOT.'header.php';
+
+generate_admin_menu('ranks');
+
+?>
+	<div class="blockform">
+		<h2><span>Ranks</span></h2>
+		<div class="box">
+			<form id="ranks" method="post" action="admin_ranks.php?action=foo">
+				<div class="inform">
+					<fieldset>
+						<legend>Add rank</legend>
+						<div class="infldset">
+							<p>Enter a rank and the minimum number of posts that a user has to have to aquire the rank. Different ranks cannot have the same value for minimum posts. If a title is set for a user, the title will be displayed instead of any rank. <strong>User ranks must be enabled in <a href="admin_options.php#ranks">Options</a> for this to have any effect.</strong></p>
+							<table  cellspacing="0">
+							<thead>
+								<tr>
+									<th class="tcl" scope="col">Rank&nbsp;title</th>
+									<th class="tc2" scope="col">Minimum&nbsp;posts</th>
+									<th class="hidehead" scope="col">Action</th>
+								</tr>
+							</thead>
+							<tbody>
+								<tr>
+									<td><input type="text" name="new_rank" size="24" maxlength="50" tabindex="1" /></td>
+									<td><input type="text" name="new_min_posts" size="7" maxlength="7" tabindex="2" /></td>
+									<td><input type="submit" name="add_rank" value=" Add " tabindex="3" /></td>
+								</tr>
+							</tbody>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend>Edit/remove ranks</legend>
+						<div class="infldset">
+<?php
+
+$result = $db->query('SELECT id, rank, min_posts FROM '.$db->prefix.'ranks ORDER BY min_posts') or error('Unable to fetch rank list', __FILE__, __LINE__, $db->error());
+if ($db->num_rows($result))
+{
+
+?>
+							<table  cellspacing="0">
+							<thead>
+								<tr>
+									<th class="tcl" scope="col"><strong>Rank&nbsp;title</strong></th>
+									<th class="tc2" scope="col"><strong>Minimum&nbsp;Posts</strong></th>
+									<th class="hidehead" scope="col">Actions</th>
+								</tr>
+							</thead>
+							<tbody>
+<?php
+
+	while ($cur_rank = $db->fetch_assoc($result))
+		echo "\t\t\t\t\t\t\t\t".'<tr><td><input type="text" name="rank['.$cur_rank['id'].']" value="'.pun_htmlspecialchars($cur_rank['rank']).'" size="24" maxlength="50" /></td><td><input type="text" name="min_posts['.$cur_rank['id'].']" value="'.$cur_rank['min_posts'].'" size="7" maxlength="7" /></td><td><input type="submit" name="update['.$cur_rank['id'].']" value="Update" />&nbsp;<input type="submit" name="remove['.$cur_rank['id'].']" value="Remove" /></td></tr>'."\n";
+
+?>
+							</tbody>
+							</table>
+<?php
+
+}
+else
+	echo "\t\t\t\t\t\t\t".'<p>No ranks in list.</p>'."\n";
+
+?>
+						</div>
+					</fieldset>
+				</div>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_reports.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,161 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_MOD)
+	message($lang_common['No permission']);
+
+
+// Zap a report
+if (isset($_POST['zap_id']))
+{
+	confirm_referrer('admin_reports.php');
+
+	$zap_id = intval(key($_POST['zap_id']));
+
+	$result = $db->query('SELECT zapped FROM '.$db->prefix.'reports WHERE id='.$zap_id) or error('Unable to fetch report info', __FILE__, __LINE__, $db->error());
+	$zapped = $db->result($result);
+
+	if ($zapped == '')
+		$db->query('UPDATE '.$db->prefix.'reports SET zapped='.time().', zapped_by='.$pun_user['id'].' WHERE id='.$zap_id) or error('Unable to zap report', __FILE__, __LINE__, $db->error());
+
+	redirect('admin_reports.php', 'Report zapped. Redirecting &hellip;');
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Reports';
+require PUN_ROOT.'header.php';
+
+generate_admin_menu('reports');
+
+?>
+	<div class="blockform">
+		<h2><span>New reports</span></h2>
+		<div class="box">
+			<form method="post" action="admin_reports.php?action=zap">
+<?php
+
+$result = $db->query('SELECT r.id, r.post_id, r.topic_id, r.forum_id, r.reported_by, r.created, r.message, t.subject, f.forum_name, u.username AS reporter FROM '.$db->prefix.'reports AS r LEFT JOIN '.$db->prefix.'topics AS t ON r.topic_id=t.id LEFT JOIN '.$db->prefix.'forums AS f ON r.forum_id=f.id LEFT JOIN '.$db->prefix.'users AS u ON r.reported_by=u.id WHERE r.zapped IS NULL ORDER BY created DESC') or error('Unable to fetch report list', __FILE__, __LINE__, $db->error());
+
+if ($db->num_rows($result))
+{
+	while ($cur_report = $db->fetch_assoc($result))
+	{
+		$reporter = ($cur_report['reporter'] != '') ? '<a href="profile.php?id='.$cur_report['reported_by'].'">'.pun_htmlspecialchars($cur_report['reporter']).'</a>' : 'Deleted user';
+		$forum = ($cur_report['forum_name'] != '') ? '<a href="viewforum.php?id='.$cur_report['forum_id'].'">'.pun_htmlspecialchars($cur_report['forum_name']).'</a>' : 'Deleted';
+		$topic = ($cur_report['subject'] != '') ? '<a href="viewtopic.php?id='.$cur_report['topic_id'].'">'.pun_htmlspecialchars($cur_report['subject']).'</a>' : 'Deleted';
+		$post = ($cur_report['post_id'] != '') ? str_replace("\n", '<br />', pun_htmlspecialchars($cur_report['message'])) : 'Deleted';
+		$postid = ($cur_report['post_id'] != '') ? '<a href="viewtopic.php?pid='.$cur_report['post_id'].'#p'.$cur_report['post_id'].'">Post #'.$cur_report['post_id'].'</a>' : 'Deleted';
+
+?>
+				<div class="inform">
+					<fieldset>
+						<legend>Reported <?php echo format_time($cur_report['created']) ?></legend>
+						<div class="infldset">
+							<table cellspacing="0">
+								<tr>
+									<th scope="row">Forum&nbsp;&raquo;&nbsp;Topic&nbsp;&raquo;&nbsp;Post</th>
+									<td><?php echo $forum ?>&nbsp;&raquo;&nbsp;<?php echo $topic ?>&nbsp;&raquo;&nbsp;<?php echo $postid ?></td>
+								</tr>
+								<tr>
+									<th scope="row">Report by <?php echo $reporter ?><div><input type="submit" name="zap_id[<?php echo $cur_report['id'] ?>]" value=" Zap " /></div></th>
+									<td><?php echo $post ?></td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+<?php
+
+	}
+}
+else
+	echo "\t\t\t\t".'<p>There are no new reports.</p>'."\n";
+
+?>
+			</form>
+		</div>
+	</div>
+
+	<div class="blockform block2">
+		<h2><span>10 last zapped reports</span></h2>
+		<div class="box">
+			<div class="fakeform">
+<?php
+
+$result = $db->query('SELECT r.id, r.post_id, r.topic_id, r.forum_id, r.reported_by, r.message, r.zapped, r.zapped_by AS zapped_by_id, t.subject, f.forum_name, u.username AS reporter, u2.username AS zapped_by FROM '.$db->prefix.'reports AS r LEFT JOIN '.$db->prefix.'topics AS t ON r.topic_id=t.id LEFT JOIN '.$db->prefix.'forums AS f ON r.forum_id=f.id LEFT JOIN '.$db->prefix.'users AS u ON r.reported_by=u.id LEFT JOIN '.$db->prefix.'users AS u2 ON r.zapped_by=u2.id WHERE r.zapped IS NOT NULL ORDER BY zapped DESC LIMIT 10') or error('Unable to fetch report list', __FILE__, __LINE__, $db->error());
+
+if ($db->num_rows($result))
+{
+	while ($cur_report = $db->fetch_assoc($result))
+	{
+		$reporter = ($cur_report['reporter'] != '') ? '<a href="profile.php?id='.$cur_report['reported_by'].'">'.pun_htmlspecialchars($cur_report['reporter']).'</a>' : 'Deleted user';
+		$forum = ($cur_report['forum_name'] != '') ? '<a href="viewforum.php?id='.$cur_report['forum_id'].'">'.pun_htmlspecialchars($cur_report['forum_name']).'</a>' : 'Deleted';
+		$topic = ($cur_report['subject'] != '') ? '<a href="viewtopic.php?id='.$cur_report['topic_id'].'">'.pun_htmlspecialchars($cur_report['subject']).'</a>' : 'Deleted';
+		$post = ($cur_report['post_id'] != '') ? str_replace("\n", '<br />', pun_htmlspecialchars($cur_report['message'])) : 'Post deleted';
+		$post_id = ($cur_report['post_id'] != '') ? '<a href="viewtopic.php?pid='.$cur_report['post_id'].'#p'.$cur_report['post_id'].'">Post #'.$cur_report['post_id'].'</a>' : 'Deleted';
+		$zapped_by = ($cur_report['zapped_by'] != '') ? '<a href="profile.php?id='.$cur_report['zapped_by_id'].'">'.pun_htmlspecialchars($cur_report['zapped_by']).'</a>' : 'N/A';
+
+?>
+				<div class="inform">
+					<fieldset>
+						<legend>Zapped <?php echo format_time($cur_report['zapped']) ?></legend>
+						<div class="infldset">
+							<table cellspacing="0">
+								<tr>
+									<th scope="row">Forum&nbsp;&raquo;&nbsp;Topic&nbsp;&raquo;&nbsp;Post</th>
+									<td><?php echo $forum ?>&nbsp;&raquo;&nbsp;<?php echo $topic ?>&nbsp;&raquo;&nbsp;<?php echo $post_id ?></td>
+								</tr>
+								<tr>
+									<th scope="row">Reported by <?php echo $reporter ?><div class="topspace">Zapped by <?php echo $zapped_by ?></div></th>
+									<td><?php echo $post ?></td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+<?php
+
+	}
+}
+else
+	echo "\t\t\t\t".'<p>There are no zapped reports.</p>'."\n";
+
+?>
+			</div>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/admin_users.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,511 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the admin template
+define('PUN_ADMIN_CONSOLE', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+require PUN_ROOT.'include/common_admin.php';
+
+
+if ($pun_user['g_id'] > PUN_MOD)
+	message($lang_common['No permission']);
+
+
+// Show IP statistics for a certain user ID
+if (isset($_GET['ip_stats']))
+{
+	$ip_stats = intval($_GET['ip_stats']);
+	if ($ip_stats < 1)
+		message($lang_common['Bad request']);
+
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Users';
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<div><a href="javascript:history.go(-1)">Go back</a></div>
+	</div>
+</div>
+
+<div id="users1" class="blocktable">
+	<h2><span>Users</span></h2>
+	<div class="box">
+		<div class="inbox">
+			<table cellspacing="0">
+			<thead>
+				<tr>
+					<th class="tcl" scope="col">IP address</th>
+					<th class="tc2" scope="col">Last used</th>
+					<th class="tc3" scope="col">Times found</th>
+					<th class="tcr" scope="col">Action</th>
+				</tr>
+			</thead>
+			<tbody>
+<?php
+
+	$result = $db->query('SELECT poster_ip, MAX(posted) AS last_used, COUNT(id) AS used_times FROM '.$db->prefix.'posts WHERE poster_id='.$ip_stats.' GROUP BY poster_ip ORDER BY last_used DESC') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+	if ($db->num_rows($result))
+	{
+		while ($cur_ip = $db->fetch_assoc($result))
+		{
+
+?>
+				<tr>
+					<td class="tcl"><a href="moderate.php?get_host=<?php echo $cur_ip['poster_ip'] ?>"><?php echo $cur_ip['poster_ip'] ?></a></td>
+					<td class="tc2"><?php echo format_time($cur_ip['last_used']) ?></td>
+					<td class="tc3"><?php echo $cur_ip['used_times'] ?></td>
+					<td class="tcr"><a href="admin_users.php?show_users=<?php echo $cur_ip['poster_ip'] ?>">Find more users for this ip</a></td>
+				</tr>
+<?php
+
+		}
+	}
+	else
+		echo "\t\t\t\t".'<tr><td class="tcl" colspan="4">There are currently no posts by that user in the forum.</td></tr>'."\n";
+
+?>
+			</tbody>
+			</table>
+		</div>
+	</div>
+</div>
+
+<div class="linksb">
+	<div class="inbox">
+		<div><a href="javascript:history.go(-1)">Go back</a></div>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+if (isset($_GET['show_users']))
+{
+	$ip = $_GET['show_users'];
+
+	if (!@preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $ip))
+		message('The supplied IP address is not correctly formatted.');
+
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Users';
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<div><a href="javascript:history.go(-1)">Go back</a></div>
+	</div>
+</div>
+
+<div id="users2" class="blocktable">
+	<h2><span>Users</span></h2>
+	<div class="box">
+		<div class="inbox">
+			<table cellspacing="0">
+			<thead>
+				<tr>
+					<th class="tcl" scope="col">Username</th>
+					<th class="tc2" scope="col">E-mail</th>
+					<th class="tc3" scope="col">Title/Status</th>
+					<th class="tc4" scope="col">Posts</th>
+					<th class="tc5" scope="col">Admin note</th>
+					<th class="tcr" scope="col">Actions</th>
+				</tr>
+			</thead>
+			<tbody>
+<?php
+
+	$result = $db->query('SELECT DISTINCT poster_id, poster FROM '.$db->prefix.'posts WHERE poster_ip=\''.$db->escape($ip).'\' ORDER BY poster DESC') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+	$num_posts = $db->num_rows($result);
+
+	if ($num_posts)
+	{
+		// Loop through users and print out some info
+		for ($i = 0; $i < $num_posts; ++$i)
+		{
+			list($poster_id, $poster) = $db->fetch_row($result);
+
+			$result2 = $db->query('SELECT u.id, u.username, u.email, u.title, u.num_posts, u.admin_note, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1 AND u.id='.$poster_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+
+			if (($user_data = $db->fetch_assoc($result2)))
+			{
+				$user_title = get_title($user_data);
+
+				$actions = '<a href="admin_users.php?ip_stats='.$user_data['id'].'">View IP stats</a> - <a href="search.php?action=show_user&amp;user_id='.$user_data['id'].'">Show posts</a>';
+
+?>
+				<tr>
+					<td class="tcl"><?php echo '<a href="profile.php?id='.$user_data['id'].'">'.pun_htmlspecialchars($user_data['username']).'</a>' ?></td>
+					<td class="tc2"><a href="mailto:<?php echo $user_data['email'] ?>"><?php echo $user_data['email'] ?></a></td>
+					<td class="tc3"><?php echo $user_title ?></td>
+					<td class="tc4"><?php echo $user_data['num_posts'] ?></td>
+					<td class="tc5"><?php echo ($user_data['admin_note'] != '') ? $user_data['admin_note'] : '&nbsp;' ?></td>
+					<td class="tcr"><?php echo $actions ?></td>
+				</tr>
+<?php
+
+			}
+			else
+			{
+
+?>
+				<tr>
+					<td class="tcl"><?php echo pun_htmlspecialchars($poster) ?></td>
+					<td class="tc2">&nbsp;</td>
+					<td class="tc3">Guest</td>
+					<td class="tc4">&nbsp;</td>
+					<td class="tc5">&nbsp;</td>
+					<td class="tcr">&nbsp;</td>
+				</tr>
+<?php
+
+			}
+		}
+	}
+	else
+		echo "\t\t\t\t".'<tr><td class="tcl" colspan="6">The supplied IP address could not be found in the database.</td></tr>'."\n";
+
+?>
+			</tbody>
+			</table>
+		</div>
+	</div>
+</div>
+
+<div class="linksb">
+	<div class="inbox">
+		<div><a href="javascript:history.go(-1)">Go back</a></div>
+	</div>
+</div>
+<?php
+	require PUN_ROOT.'footer.php';
+}
+
+
+else if (isset($_POST['find_user']))
+{
+	$form = $_POST['form'];
+	$form['username'] = $_POST['username'];
+
+	// trim() all elements in $form
+	$form = array_map('trim', $form);
+	$conditions = array();
+
+	$posts_greater = trim($_POST['posts_greater']);
+	$posts_less = trim($_POST['posts_less']);
+	$last_post_after = trim($_POST['last_post_after']);
+	$last_post_before = trim($_POST['last_post_before']);
+	$registered_after = trim($_POST['registered_after']);
+	$registered_before = trim($_POST['registered_before']);
+	$order_by = $_POST['order_by'];
+	$direction = $_POST['direction'];
+	$user_group = $_POST['user_group'];
+
+	if (preg_match('/[^0-9]/', $posts_greater.$posts_less))
+		message('You entered a non-numeric value into a numeric only column.');
+
+	// Try to convert date/time to timestamps
+	if ($last_post_after != '')
+		$last_post_after = strtotime($last_post_after);
+	if ($last_post_before != '')
+		$last_post_before = strtotime($last_post_before);
+	if ($registered_after != '')
+		$registered_after = strtotime($registered_after);
+	if ($registered_before != '')
+		$registered_before = strtotime($registered_before);
+
+	if ($last_post_after == -1 || $last_post_before == -1 || $registered_after == -1 || $registered_before == -1)
+		message('You entered an invalid date/time.');
+
+	if ($last_post_after != '')
+		$conditions[] = 'u.last_post>'.$last_post_after;
+	if ($last_post_before != '')
+		$conditions[] = 'u.last_post<'.$last_post_before;
+	if ($registered_after != '')
+		$conditions[] = 'u.registered>'.$registered_after;
+	if ($registered_before != '')
+		$conditions[] = 'u.registered<'.$registered_before;
+
+	$like_command = ($db_type == 'pgsql') ? 'ILIKE' : 'LIKE';
+	while (list($key, $input) = @each($form))
+	{
+		if ($input != '' && in_array($key, array('username', 'email', 'title', 'realname', 'url', 'jabber', 'icq', 'msn', 'aim', 'yahoo', 'location', 'signature', 'admin_note')))
+			$conditions[] = 'u.'.$db->escape($key).' '.$like_command.' \''.$db->escape(str_replace('*', '%', $input)).'\'';
+	}
+
+	if ($posts_greater != '')
+		$conditions[] = 'u.num_posts>'.$posts_greater;
+	if ($posts_less != '')
+		$conditions[] = 'u.num_posts<'.$posts_less;
+
+	if ($user_group != 'all')
+		$conditions[] = 'u.group_id='.intval($user_group);
+
+	if (empty($conditions))
+		message('You didn\'t enter any search terms.');
+
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Users';
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<div><a href="javascript:history.go(-1)">Go back</a></div>
+	</div>
+</div>
+
+<div id="users2" class="blocktable">
+	<h2><span>Users</span></h2>
+	<div class="box">
+		<div class="inbox">
+			<table cellspacing="0">
+			<thead>
+				<tr>
+					<th class="tcl" scope="col">Username</th>
+					<th class="tc2" scope="col">E-mail</th>
+					<th class="tc3" scope="col">Title/Status</th>
+					<th class="tc4" scope="col">Posts</th>
+					<th class="tc5" scope="col">Admin note</th>
+					<th class="tcr" scope="col">Actions</th>
+				</tr>
+			</thead>
+			<tbody>
+<?php
+
+	$result = $db->query('SELECT u.id, u.username, u.email, u.title, u.num_posts, u.admin_note, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1 AND '.implode(' AND ', $conditions).' ORDER BY '.$db->escape($order_by).' '.$db->escape($direction)) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+	if ($db->num_rows($result))
+	{
+		while ($user_data = $db->fetch_assoc($result))
+		{
+			$user_title = get_title($user_data);
+
+			// This script is a special case in that we want to display "Not verified" for non-verified users
+			if (($user_data['g_id'] == '' || $user_data['g_id'] == PUN_UNVERIFIED) && $user_title != $lang_common['Banned'])
+				$user_title = '<span class="warntext">Not verified</span>';
+
+			$actions = '<a href="admin_users.php?ip_stats='.$user_data['id'].'">View IP stats</a> - <a href="search.php?action=show_user&amp;user_id='.$user_data['id'].'">Show posts</a>';
+
+?>
+				<tr>
+					<td class="tcl"><?php echo '<a href="profile.php?id='.$user_data['id'].'">'.pun_htmlspecialchars($user_data['username']).'</a>' ?></td>
+					<td class="tc2"><a href="mailto:<?php echo $user_data['email'] ?>"><?php echo $user_data['email'] ?></a></td>
+					<td class="tc3"><?php echo $user_title ?></td>
+					<td class="tc4"><?php echo $user_data['num_posts'] ?></td>
+					<td class="tc5"><?php echo ($user_data['admin_note'] != '') ? $user_data['admin_note'] : '&nbsp;' ?></td>
+					<td class="tcr"><?php echo $actions ?></td>
+				</tr>
+<?php
+
+		}
+	}
+	else
+		echo "\t\t\t\t".'<tr><td class="tcl" colspan="6">No match.</td></tr>'."\n";
+
+?>
+			</tbody>
+			</table>
+		</div>
+	</div>
+</div>
+
+<div class="linksb">
+	<div class="inbox">
+		<div><a href="javascript:history.go(-1)">Go back</a></div>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+else
+{
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Admin / Users';
+	$focus_element = array('find_user', 'username');
+	require PUN_ROOT.'header.php';
+
+	generate_admin_menu('users');
+
+?>
+	<div class="blockform">
+		<h2><span>User search</span></h2>
+		<div class="box">
+			<form id="find_user" method="post" action="admin_users.php?action=find_user">
+				<p class="submittop"><input type="submit" name="find_user" value="Submit search" tabindex="1" /></p>
+				<div class="inform">
+					<fieldset>
+						<legend>Enter search criteria</legend>
+						<div class="infldset">
+							<p>Search for users in the database. You can enter one or more terms to search for. Wildcards in the form of asterisks (*) are accepted.</p>
+							<table  class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">Username</th>
+									<td><input type="text" name="username" size="25" maxlength="25" tabindex="2" /></td>
+								</tr>
+								<tr>
+									<th scope="row">E-mail address</th>
+									<td><input type="text" name="form[email]" size="30" maxlength="50" tabindex="3" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Title</th>
+									<td><input type="text" name="form[title]" size="30" maxlength="50" tabindex="4" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Real name</th>
+									<td><input type="text" name="form[realname]" size="30" maxlength="40" tabindex="5" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Website</th>
+									<td><input type="text" name="form[url]" size="35" maxlength="100" tabindex="6" /></td>
+								</tr>
+								<tr>
+									<th scope="row">ICQ</th>
+									<td><input type="text" name="form[icq]" size="12" maxlength="12" tabindex="7" /></td>
+								</tr>
+								<tr>
+									<th scope="row">MSN Messenger</th>
+									<td><input type="text" name="form[msn]" size="30" maxlength="50" tabindex="8" /></td>
+								</tr>
+								<tr>
+									<th scope="row">AOL IM</th>
+									<td><input type="text" name="form[aim]" size="20" maxlength="20" tabindex="9" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Yahoo! Messenger</th>
+									<td><input type="text" name="form[yahoo]" size="20" maxlength="20" tabindex="10" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Location</th>
+									<td><input type="text" name="form[location]" size="30" maxlength="30" tabindex="11" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Signature</th>
+									<td><input type="text" name="form[signature]" size="35" maxlength="512" tabindex="12" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Admin note</th>
+									<td><input type="text" name="form[admin_note]" size="30" maxlength="30" tabindex="13" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Number of posts greater than</th>
+									<td><input type="text" name="posts_greater" size="5" maxlength="8" tabindex="14" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Number of posts less than</th>
+									<td><input type="text" name="posts_less" size="5" maxlength="8" tabindex="15" /></td>
+								</tr>
+								<tr>
+									<th scope="row">Last post is after</th>
+									<td><input type="text" name="last_post_after" size="24" maxlength="19" tabindex="16" />
+									<span>(yyyy-mm-dd hh:mm:ss)</span></td>
+								</tr>
+								<tr>
+									<th scope="row">Last post is before</th>
+									<td><input type="text" name="last_post_before" size="24" maxlength="19" tabindex="17" />
+									<span>(yyyy-mm-dd hh:mm:ss)</span></td>
+								</tr>
+								<tr>
+									<th scope="row">Registered after</th>
+									<td><input type="text" name="registered_after" size="24" maxlength="19" tabindex="18" />
+									<span>(yyyy-mm-dd hh:mm:ss)</span></td>
+								</tr>
+								<tr>
+									<th scope="row">Registered before</th>
+									<td><input type="text" name="registered_before" size="24" maxlength="19" tabindex="19" />
+									<span>(yyyy-mm-dd hh:mm:ss)</span></td>
+								</tr>
+								<tr>
+									<th scope="row">Order by</th>
+									<td>
+										<select name="order_by" tabindex="20">
+											<option value="username" selected="selected">username</option>
+											<option value="email">e-mail</option>
+											<option value="num_posts">posts</option>
+											<option value="last_post">last post</option>
+											<option value="registered">registered</option>
+										</select>&nbsp;&nbsp;&nbsp;<select name="direction" tabindex="21">
+											<option value="ASC" selected="selected">ascending</option>
+											<option value="DESC">descending</option>
+										</select>
+									</td>
+								</tr>
+								<tr>
+									<th scope="row">User group</th>
+									<td>
+										<select name="user_group" tabindex="22">
+												<option value="all" selected="selected">All groups</option>
+<?php
+
+	$result = $db->query('SELECT g_id, g_title FROM '.$db->prefix.'groups WHERE g_id!='.PUN_GUEST.' ORDER BY g_title') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+
+	while ($cur_group = $db->fetch_assoc($result))
+		echo "\t\t\t\t\t\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+
+?>
+										</select>
+									</td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+				<p class="submitend"><input type="submit" name="find_user" value="Submit search" tabindex="23" /></p>
+			</form>
+		</div>
+
+		<h2 class="block2"><span>IP search</span></h2>
+		<div class="box">
+			<form method="get" action="admin_users.php">
+				<div class="inform">
+					<fieldset>
+						<legend>Enter IP to search for</legend>
+						<div class="infldset">
+							<table class="aligntop" cellspacing="0">
+								<tr>
+									<th scope="row">IP address<div><input type="submit" value=" Find " tabindex="25" /></div></th>
+									<td><input type="text" name="show_users" size="18" maxlength="15" tabindex="24" />
+									<span>The IP address to search for in the post database.</span></td>
+								</tr>
+							</table>
+						</div>
+					</fieldset>
+				</div>
+			</form>
+		</div>
+	</div>
+	<div class="clearer"></div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/cache/.htaccess	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,4 @@
+<Limit GET POST PUT>
+Order Allow,Deny
+Deny from All
+</Limit>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/cache/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/delete.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,127 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+if ($pun_user['g_read_board'] == '0')
+	message($lang_common['No view']);
+
+
+$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
+if ($id < 1)
+	message($lang_common['Bad request']);
+
+// Fetch some info about the post, the topic and the forum
+$result = $db->query('SELECT f.id AS fid, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics, t.id AS tid, t.subject, t.posted, t.closed, p.poster, p.poster_id, p.message, p.hide_smilies FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id='.$id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+if (!$db->num_rows($result))
+	message($lang_common['Bad request']);
+
+$cur_post = $db->fetch_assoc($result);
+
+// Sort out who the moderators are and if we are currently a moderator (or an admin)
+$mods_array = ($cur_post['moderators'] != '') ? unserialize($cur_post['moderators']) : array();
+$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && array_key_exists($pun_user['username'], $mods_array))) ? true : false;
+
+// Determine whether this post is the "topic post" or not
+$result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$cur_post['tid'].' ORDER BY posted LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+$topic_post_id = $db->result($result);
+
+$is_topic_post = ($id == $topic_post_id) ? true : false;
+
+// Do we have permission to edit this post?
+if (($pun_user['g_delete_posts'] == '0' ||
+	($pun_user['g_delete_topics'] == '0' && $is_topic_post) ||
+	$cur_post['poster_id'] != $pun_user['id'] ||
+	$cur_post['closed'] == '1') &&
+	!$is_admmod)
+	message($lang_common['No permission']);
+
+// Load the delete.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/delete.php';
+
+
+if (isset($_POST['delete']))
+{
+	if ($is_admmod)
+		confirm_referrer('delete.php');
+
+	require PUN_ROOT.'include/search_idx.php';
+
+	if ($is_topic_post)
+	{
+		// Delete the topic and all of it's posts
+		delete_topic($cur_post['tid']);
+		update_forum($cur_post['fid']);
+
+		redirect('viewforum.php?id='.$cur_post['fid'], $lang_delete['Topic del redirect']);
+	}
+	else
+	{
+		// Delete just this one post
+		delete_post($id, $cur_post['tid']);
+		update_forum($cur_post['fid']);
+
+		redirect('viewtopic.php?id='.$cur_post['tid'], $lang_delete['Post del redirect']);
+	}
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_delete['Delete post'];
+require PUN_ROOT.'header.php';
+
+require PUN_ROOT.'include/parser.php';
+$cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']);
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li><li>&nbsp;&raquo;&nbsp;<a href="viewforum.php?id=<?php echo $cur_post['fid'] ?>"><?php echo pun_htmlspecialchars($cur_post['forum_name']) ?></a></li><li>&nbsp;&raquo;&nbsp;<?php echo pun_htmlspecialchars($cur_post['subject']) ?></li></ul>
+	</div>
+</div>
+
+<div class="blockform">
+	<h2><span><?php echo $lang_delete['Delete post'] ?></span></h2>
+	<div class="box">
+		<form method="post" action="delete.php?id=<?php echo $id ?>">
+			<div class="inform">
+				<fieldset>
+					<legend class="warntext"><?php echo $lang_delete['Warning'] ?></legend>
+					<div class="infldset">
+						<div class="postmsg">
+							<p><?php echo $lang_common['Author'] ?>: <strong><?php echo pun_htmlspecialchars($cur_post['poster']) ?></strong></p>
+							<?php echo $cur_post['message'] ?>
+						</div>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="delete" value="<?php echo $lang_delete['Delete'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/edit.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,264 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+if ($pun_user['g_read_board'] == '0')
+	message($lang_common['No view']);
+
+
+$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
+if ($id < 1)
+	message($lang_common['Bad request']);
+
+// Fetch some info about the post, the topic and the forum
+$result = $db->query('SELECT f.id AS fid, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics, t.id AS tid, t.subject, t.posted, t.closed, p.poster, p.poster_id, p.message, p.hide_smilies FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id='.$id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+if (!$db->num_rows($result))
+	message($lang_common['Bad request']);
+
+$cur_post = $db->fetch_assoc($result);
+
+// Sort out who the moderators are and if we are currently a moderator (or an admin)
+$mods_array = ($cur_post['moderators'] != '') ? unserialize($cur_post['moderators']) : array();
+$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && array_key_exists($pun_user['username'], $mods_array))) ? true : false;
+
+// Determine whether this post is the "topic post" or not
+$result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$cur_post['tid'].' ORDER BY posted LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+$topic_post_id = $db->result($result);
+
+$can_edit_subject = ($id == $topic_post_id && (($pun_user['g_edit_subjects_interval'] == '0' || (time() - $cur_post['posted']) < $pun_user['g_edit_subjects_interval']) || $is_admmod)) ? true : false;
+
+// Do we have permission to edit this post?
+if (($pun_user['g_edit_posts'] == '0' ||
+	$cur_post['poster_id'] != $pun_user['id'] ||
+	$cur_post['closed'] == '1') &&
+	!$is_admmod)
+	message($lang_common['No permission']);
+
+// Load the post.php/edit.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/post.php';
+
+// Start with a clean slate
+$errors = array();
+
+
+if (isset($_POST['form_sent']))
+{
+	if ($is_admmod)
+		confirm_referrer('edit.php');
+
+	// If it is a topic it must contain a subject
+	if ($can_edit_subject)
+	{
+		$subject = pun_trim($_POST['req_subject']);
+
+		if ($subject == '')
+			$errors[] = $lang_post['No subject'];
+		else if (pun_strlen($subject) > 70)
+			$errors[] = $lang_post['Too long subject'];
+		else if ($pun_config['p_subject_all_caps'] == '0' && strtoupper($subject) == $subject && $pun_user['g_id'] > PUN_MOD)
+			$subject = ucwords(strtolower($subject));
+	}
+
+	// Clean up message from POST
+	$message = pun_linebreaks(pun_trim($_POST['req_message']));
+
+	if ($message == '')
+		$errors[] = $lang_post['No message'];
+	else if (strlen($message) > 65535)
+		$errors[] = $lang_post['Too long message'];
+	else if ($pun_config['p_message_all_caps'] == '0' && strtoupper($message) == $message && $pun_user['g_id'] > PUN_MOD)
+		$message = ucwords(strtolower($message));
+
+	// Validate BBCode syntax
+	if ($pun_config['p_message_bbcode'] == '1' && strpos($message, '[') !== false && strpos($message, ']') !== false)
+	{
+		require PUN_ROOT.'include/parser.php';
+		$message = preparse_bbcode($message, $errors);
+	}
+
+
+	$hide_smilies = isset($_POST['hide_smilies']) ? intval($_POST['hide_smilies']) : 0;
+	if ($hide_smilies != '1') $hide_smilies = '0';
+
+	// Did everything go according to plan?
+	if (empty($errors) && !isset($_POST['preview']))
+	{
+		$edited_sql = (!isset($_POST['silent']) || !$is_admmod) ? $edited_sql = ', edited='.time().', edited_by=\''.$db->escape($pun_user['username']).'\'' : '';
+
+		require PUN_ROOT.'include/search_idx.php';
+
+		if ($can_edit_subject)
+		{
+			// Update the topic and any redirect topics
+			$db->query('UPDATE '.$db->prefix.'topics SET subject=\''.$db->escape($subject).'\' WHERE id='.$cur_post['tid'].' OR moved_to='.$cur_post['tid']) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
+
+			// We changed the subject, so we need to take that into account when we update the search words
+			update_search_index('edit', $id, $message, $subject);
+		}
+		else
+			update_search_index('edit', $id, $message);
+
+		// Update the post
+		$db->query('UPDATE '.$db->prefix.'posts SET message=\''.$db->escape($message).'\', hide_smilies=\''.$hide_smilies.'\''.$edited_sql.' WHERE id='.$id) or error('Unable to update post', __FILE__, __LINE__, $db->error());
+
+		redirect('viewtopic.php?pid='.$id.'#p'.$id, $lang_post['Edit redirect']);
+	}
+}
+
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_post['Edit post'];
+$required_fields = array('req_subject' => $lang_common['Subject'], 'req_message' => $lang_common['Message']);
+$focus_element = array('edit', 'req_message');
+require PUN_ROOT.'header.php';
+
+$cur_index = 1;
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li><li>&nbsp;&raquo;&nbsp;<a href="viewforum.php?id=<?php echo $cur_post['fid'] ?>"><?php echo pun_htmlspecialchars($cur_post['forum_name']) ?></a></li><li>&nbsp;&raquo;&nbsp;<?php echo pun_htmlspecialchars($cur_post['subject']) ?></li></ul>
+	</div>
+</div>
+
+<?php
+
+// If there are errors, we display them
+if (!empty($errors))
+{
+
+?>
+<div id="posterror" class="block">
+	<h2><span><?php echo $lang_post['Post errors'] ?></span></h2>
+	<div class="box">
+		<div class="inbox"
+			<p><?php echo $lang_post['Post errors info'] ?></p>
+			<ul>
+<?php
+
+	while (list(, $cur_error) = each($errors))
+		echo "\t\t\t\t".'<li><strong>'.$cur_error.'</strong></li>'."\n";
+?>
+			</ul>
+		</div>
+	</div>
+</div>
+
+<?php
+
+}
+else if (isset($_POST['preview']))
+{
+	require_once PUN_ROOT.'include/parser.php';
+	$preview_message = parse_message($message, $hide_smilies);
+
+?>
+<div id="postpreview" class="blockpost">
+	<h2><span><?php echo $lang_post['Post preview'] ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<div class="postright">
+				<div class="postmsg">
+					<?php echo $preview_message."\n" ?>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+
+<?php
+
+}
+
+?>
+<div class="blockform">
+	<h2><?php echo $lang_post['Edit post'] ?></h2>
+	<div class="box">
+		<form id="edit" method="post" action="edit.php?id=<?php echo $id ?>&amp;action=edit" onsubmit="return process_form(this)">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_post['Edit post legend'] ?></legend>
+					<input type="hidden" name="form_sent" value="1" />
+					<div class="infldset txtarea">
+<?php if ($can_edit_subject): ?>						<label><?php echo $lang_common['Subject'] ?><br />
+						<input class="longinput" type="text" name="req_subject" size="80" maxlength="70" tabindex="<?php echo $cur_index++ ?>" value="<?php echo pun_htmlspecialchars(isset($_POST['req_subject']) ? $_POST['req_subject'] : $cur_post['subject']) ?>" /><br /></label>
+<?php endif; ?>						<label><?php echo $lang_common['Message'] ?><br />
+						<textarea name="req_message" rows="20" cols="95" tabindex="<?php echo $cur_index++ ?>"><?php echo pun_htmlspecialchars(isset($_POST['req_message']) ? $message : $cur_post['message']) ?></textarea><br /></label>
+						<ul class="bblinks">
+							<li><a href="help.php#bbcode" onclick="window.open(this.href); return false;"><?php echo $lang_common['BBCode'] ?></a>: <?php echo ($pun_config['p_message_bbcode'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+							<li><a href="help.php#img" onclick="window.open(this.href); return false;"><?php echo $lang_common['img tag'] ?></a>: <?php echo ($pun_config['p_message_img_tag'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+							<li><a href="help.php#smilies" onclick="window.open(this.href); return false;"><?php echo $lang_common['Smilies'] ?></a>: <?php echo ($pun_config['o_smilies'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+						</ul>
+					</div>
+				</fieldset>
+<?php
+
+$checkboxes = array();
+if ($pun_config['o_smilies'] == '1')
+{
+	if (isset($_POST['hide_smilies']) || $cur_post['hide_smilies'] == '1')
+		$checkboxes[] = '<label><input type="checkbox" name="hide_smilies" value="1" checked="checked" tabindex="'.($cur_index++).'" />&nbsp;'.$lang_post['Hide smilies'];
+	else
+		$checkboxes[] = '<label><input type="checkbox" name="hide_smilies" value="1" tabindex="'.($cur_index++).'" />&nbsp;'.$lang_post['Hide smilies'];
+}
+
+if ($is_admmod)
+{
+	if ((isset($_POST['form_sent']) && isset($_POST['silent'])) || !isset($_POST['form_sent']))
+		$checkboxes[] = '<label><input type="checkbox" name="silent" value="1" tabindex="'.($cur_index++).'" checked="checked" />&nbsp;'.$lang_post['Silent edit'];
+	else
+		$checkboxes[] = '<label><input type="checkbox" name="silent" value="1" tabindex="'.($cur_index++).'" />&nbsp;'.$lang_post['Silent edit'];
+}
+
+if (!empty($checkboxes))
+{
+
+?>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_common['Options'] ?></legend>
+					<div class="infldset">
+						<div class="rbox">
+							<?php echo implode('</label>'."\n\t\t\t\t\t\t\t", $checkboxes).'</label>'."\n" ?>
+						</div>
+					</div>
+				</fieldset>
+<?php
+
+	}
+
+?>
+			</div>
+			<p><input type="submit" name="submit" value="<?php echo $lang_common['Submit'] ?>" tabindex="<?php echo $cur_index++ ?>" accesskey="s" /><input type="submit" name="preview" value="<?php echo $lang_post['Preview'] ?>" tabindex="<?php echo $cur_index++ ?>" accesskey="p" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/extern.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,330 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************
+
+
+  INSTRUCTIONS
+
+  This script is used to include information about your board from
+  pages outside the forums and to syndicate news about recent
+  discussions via RSS. The script can display a list of recent
+  discussions (sorted by post time or last post time), a list of
+  active users or a collection of general board statistics. The
+  script can be called directly via an URL (for RSS), from a PHP
+  include command or through the use of Server Side Includes (SSI).
+
+  The scripts behaviour is controlled via variables supplied in the
+  URL to the script. The different variables are: action (what to
+  output), show (how many topics to display), fid (the ID or ID's of
+  the forum(s) to poll for topics), nfid (the ID or ID's of forums
+  that should be excluded) and type (output as HTML or RSS). The
+  only mandatory variable is action. Possible/default values are:
+
+    action: active (show most recently active topics) (HTML or RSS)
+            new (show newest topics) (HTML or RSS)
+            online (show users online) (HTML)
+            online_full (as above, but includes a full list) (HTML)
+            stats (show board statistics) (HTML)
+
+    show:   Any integer value between 1 and 50. This variables is
+            ignored for RSS output. The default is 15.
+
+    fid:    One or more forum ID's (comma-separated). If ignored,
+            topics from all guest-readable forums will be polled.
+
+    nfid:   One or more forum ID's (comma-separated) that are to be
+            excluded. E.g. the ID of a a test forum.
+
+    type:   RSS. Anything else means HTML output.
+
+  Here are some examples using PHP include().
+
+    Show the 15 most recently active topics from all forums:
+    include('http://host.com/forums/extern.php?action=active');
+
+    Show the 10 newest topics from forums with ID 5, 6 and 7:
+    include('http://host.com/forums/extern.php?action=new&show=10&fid=5,6,7');
+
+    Show users online:
+    include('http://host.com/forums/extern.php?action=online');
+
+    Show users online with full listing of users:
+    include('http://host.com/forums/extern.php?action=online_full');
+
+    Show board statistics:
+    include('http://host.com/forums/extern.php?action=stats');
+
+  Here are some examples using SSI.
+
+    Show the 5 newest topics from forums with ID 11 and 22:
+    <!--#include virtual="forums/extern.php?action=new&show=5&fid=11,22" -->
+
+    Show board statistics:
+    <!--#include virtual="forums/extern.php?action=stats" -->
+
+  And finally some examples using extern.php to output an RSS 0.91
+  feed.
+
+    Output the 15 most recently active topics:
+    http://host.com/extern.php?action=active&type=RSS
+
+    Output the 15 newest topics from forum with ID=2:
+    http://host.com/extern.php?action=active&type=RSS&fid=2
+
+  Below you will find some variables you can edit to tailor the
+  scripts behaviour to your needs.
+
+
+/***********************************************************************/
+
+// The maximum number of topics that will be displayed
+$show_max_topics = 60;
+
+// The length at which topic subjects will be truncated (for HTML output)
+$max_subject_length = 30;
+
+/***********************************************************************/
+
+// DO NOT EDIT ANYTHING BELOW THIS LINE! (unless you know what you are doing)
+
+
+define('PUN_ROOT', './');
+@include PUN_ROOT.'config.php';
+
+// If PUN isn't defined, config.php is missing or corrupt
+if (!defined('PUN'))
+	exit('The file \'config.php\' doesn\'t exist or is corrupt. Please run install.php to install PunBB first.');
+
+
+// Make sure PHP reports all errors except E_NOTICE
+error_reporting(E_ALL ^ E_NOTICE);
+
+// Turn off magic_quotes_runtime
+set_magic_quotes_runtime(0);
+
+
+// Load the functions script
+require PUN_ROOT.'include/functions.php';
+
+// Load DB abstraction layer and try to connect
+require PUN_ROOT.'include/dblayer/common_db.php';
+
+// Load cached config
+@include PUN_ROOT.'cache/cache_config.php';
+if (!defined('PUN_CONFIG_LOADED'))
+{
+    require PUN_ROOT.'include/cache.php';
+    generate_config_cache();
+    require PUN_ROOT.'cache/cache_config.php';
+}
+
+// Make sure we (guests) have permission to read the forums
+$result = $db->query('SELECT g_read_board FROM '.$db->prefix.'groups WHERE g_id=3') or error('Unable to fetch group info', __FILE__, __LINE__, $db->error());
+if ($db->result($result) == '0')
+	exit('No permission');
+
+
+// Attempt to load the common language file
+@include PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/common.php';
+if (!isset($lang_common))
+	exit('There is no valid language pack \''.$pun_config['o_default_lang'].'\' installed. Please reinstall a language of that name.');
+
+// Check if we are to display a maintenance message
+if ($pun_config['o_maintenance'] && !defined('PUN_TURN_OFF_MAINT'))
+	maintenance_message();
+
+if (!isset($_GET['action']))
+	exit('No parameters supplied. See extern.php for instructions.');
+
+
+//
+// Converts the CDATA end sequence ]]> into ]]&gt;
+//
+function escape_cdata($str)
+{
+	return str_replace(']]>', ']]&gt;', $str);
+}
+
+
+//
+// Show recent discussions
+//
+if ($_GET['action'] == 'active' || $_GET['action'] == 'new')
+{
+	$order_by = ($_GET['action'] == 'active') ? 't.last_post' : 't.posted';
+	$forum_sql = '';
+
+	// Was any specific forum ID's supplied?
+	if (isset($_GET['fid']) && $_GET['fid'] != '')
+	{
+		$fids = explode(',', trim($_GET['fid']));
+		$fids = array_map('intval', $fids);
+
+		if (!empty($fids))
+			$forum_sql = ' AND f.id IN('.implode(',', $fids).')';
+	}
+
+	// Any forum ID's to exclude?
+	if (isset($_GET['nfid']) && $_GET['nfid'] != '')
+	{
+		$nfids = explode(',', trim($_GET['nfid']));
+		$nfids = array_map('intval', $nfids);
+
+		if (!empty($nfids))
+			$forum_sql = ' AND f.id NOT IN('.implode(',', $nfids).')';
+	}
+
+	// Should we output this as RSS?
+	if (isset($_GET['type']) && strtoupper($_GET['type']) == 'RSS')
+	{
+		$rss_description = ($_GET['action'] == 'active') ? $lang_common['RSS Desc Active'] : $lang_common['RSS Desc New'];
+		$url_action = ($_GET['action'] == 'active') ? '&amp;action=new' : '';
+
+		// Send XML/no cache headers
+		header('Content-Type: text/xml');
+		header('Expires: '.gmdate('D, d M Y H:i:s').' GMT');
+		header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+		header('Pragma: public');
+
+		// It's time for some syndication!
+		echo '<?xml version="1.0" encoding="'.$lang_common['lang_encoding'].'"?>'."\r\n";
+		echo '<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://my.netscape.com/publish/formats/rss-0.91.dtd">'."\r\n";
+		echo '<rss version="0.91">'."\r\n";
+		echo '<channel>'."\r\n";
+		echo "\t".'<title>'.pun_htmlspecialchars($pun_config['o_board_title']).'</title>'."\r\n";
+		echo "\t".'<link>'.$pun_config['o_base_url'].'/</link>'."\r\n";
+		echo "\t".'<description>'.pun_htmlspecialchars($rss_description.' '.$pun_config['o_board_title']).'</description>'."\r\n";
+		echo "\t".'<language>en-us</language>'."\r\n";
+
+		// Fetch 15 topics
+		$result = $db->query('SELECT t.id, t.poster, t.subject, t.posted, t.last_post, f.id AS fid, f.forum_name FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=3) WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL'.$forum_sql.' ORDER BY '.$order_by.' DESC LIMIT 15') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
+
+		while ($cur_topic = $db->fetch_assoc($result))
+		{
+			if ($pun_config['o_censoring'] == '1')
+				$cur_topic['subject'] = censor_words($cur_topic['subject']);
+
+			echo "\t".'<item>'."\r\n";
+			echo "\t\t".'<title>'.pun_htmlspecialchars($cur_topic['subject']).'</title>'."\r\n";
+			echo "\t\t".'<link>'.$pun_config['o_base_url'].'/viewtopic.php?id='.$cur_topic['id'].$url_action.'</link>'."\r\n";
+			echo "\t\t".'<description><![CDATA['.escape_cdata($lang_common['Forum'].': <a href="'.$pun_config['o_base_url'].'/viewforum.php?id='.$cur_topic['fid'].'">'.$cur_topic['forum_name'].'</a><br />'."\r\n".$lang_common['Author'].': '.$cur_topic['poster'].'<br />'."\r\n".$lang_common['Posted'].': '.date('r', $cur_topic['posted']).'<br />'."\r\n".$lang_common['Last post'].': '.date('r', $cur_topic['last_post'])).']]></description>'."\r\n";
+			echo "\t".'</item>'."\r\n";
+		}
+
+		echo '</channel>'."\r\n";
+		echo '</rss>';
+	}
+
+
+	// Output regular HTML
+	else
+	{
+		$show = isset($_GET['show']) ? intval($_GET['show']) : 15;
+		if ($show < 1 || $show > 50)
+			$show = 15;
+
+		// Fetch $show topics
+		$result = $db->query('SELECT t.id, t.subject FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=3) WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.moved_to IS NULL'.$forum_sql.' ORDER BY '.$order_by.' DESC LIMIT '.$show) or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
+
+		while ($cur_topic = $db->fetch_assoc($result))
+		{
+			if ($pun_config['o_censoring'] == '1')
+				$cur_topic['subject'] = censor_words($cur_topic['subject']);
+
+			if (pun_strlen($cur_topic['subject']) > $max_subject_length)
+				$subject_truncated = pun_htmlspecialchars(trim(substr($cur_topic['subject'], 0, ($max_subject_length-5)))).' &hellip;';
+			else
+				$subject_truncated = pun_htmlspecialchars($cur_topic['subject']);
+
+			echo '<li><a href="'.$pun_config['o_base_url'].'/viewtopic.php?id='.$cur_topic['id'].'&amp;action=new" title="'.pun_htmlspecialchars($cur_topic['subject']).'">'.$subject_truncated.'</a></li>'."\n";
+		}
+	}
+
+	return;
+}
+
+
+//
+// Show users online
+//
+else if ($_GET['action'] == 'online' || $_GET['action'] == 'online_full')
+{
+	// Load the index.php language file
+	require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php';
+	
+	// Fetch users online info and generate strings for output
+	$num_guests = $num_users = 0;
+	$users = array();
+	$result = $db->query('SELECT user_id, ident FROM '.$db->prefix.'online WHERE idle=0 ORDER BY ident', true) or error('Unable to fetch online list', __FILE__, __LINE__, $db->error());
+
+	while ($pun_user_online = $db->fetch_assoc($result))
+	{
+		if ($pun_user_online['user_id'] > 1)
+		{
+			$users[] = '<a href="'.$pun_config['o_base_url'].'/profile.php?id='.$pun_user_online['user_id'].'">'.pun_htmlspecialchars($pun_user_online['ident']).'</a>';
+			++$num_users;
+		}
+		else
+			++$num_guests;
+	}
+
+	echo $lang_index['Guests online'].': '.$num_guests.'<br />';
+
+	if ($_GET['action'] == 'online_full')
+		echo $lang_index['Users online'].': '.implode(', ', $users).'<br />';
+	else
+		echo $lang_index['Users online'].': '.$num_users.'<br />';
+
+	return;
+}
+
+
+//
+// Show board statistics
+//
+else if ($_GET['action'] == 'stats')
+{
+	// Load the index.php language file
+	require PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/index.php';
+
+	// Collect some statistics from the database
+	$result = $db->query('SELECT COUNT(id)-1 FROM '.$db->prefix.'users') or error('Unable to fetch total user count', __FILE__, __LINE__, $db->error());
+	$stats['total_users'] = $db->result($result);
+
+	$result = $db->query('SELECT id, username FROM '.$db->prefix.'users ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $db->error());
+	$stats['last_user'] = $db->fetch_assoc($result);
+
+	$result = $db->query('SELECT SUM(num_topics), SUM(num_posts) FROM '.$db->prefix.'forums') or error('Unable to fetch topic/post count', __FILE__, __LINE__, $db->error());
+	list($stats['total_topics'], $stats['total_posts']) = $db->fetch_row($result);
+
+	echo $lang_index['No of users'].': '.$stats['total_users'].'<br />';
+	echo $lang_index['Newest user'].': <a href="'.$pun_config['o_base_url'].'/profile.php?id='.$stats['last_user']['id'].'">'.pun_htmlspecialchars($stats['last_user']['username']).'</a><br />';
+	echo $lang_index['No of topics'].': '.$stats['total_topics'].'<br />';
+	echo $lang_index['No of posts'].': '.$stats['total_posts'];
+
+	return;
+}
+
+
+else
+	exit('Bad request');
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/footer.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,146 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Make sure no one attempts to run this script "directly"
+if (!defined('PUN'))
+	exit;
+
+$tpl_temp = trim(ob_get_contents());
+$tpl_main = str_replace('<pun_main>', $tpl_temp, $tpl_main);
+ob_end_clean();
+// END SUBST - <pun_main>
+
+
+// START SUBST - <pun_footer>
+ob_start();
+
+?>
+<div id="brdfooter" class="block">
+	<h2><span><?php echo $lang_common['Board footer'] ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+<?php
+
+// If no footer style has been specified, we use the default (only copyright/debug info)
+$footer_style = isset($footer_style) ? $footer_style : NULL;
+
+if ($footer_style == 'index' || $footer_style == 'search')
+{
+	if (!$pun_user['is_guest'])
+	{
+		echo "\n\t\t\t".'<dl id="searchlinks" class="conl">'."\n\t\t\t\t".'<dt><strong>'.$lang_common['Search links'].'</strong></dt>'."\n\t\t\t\t".'<dd><a href="search.php?action=show_24h">'.$lang_common['Show recent posts'].'</a></dd>'."\n";
+		echo "\t\t\t\t".'<dd><a href="search.php?action=show_unanswered">'.$lang_common['Show unanswered posts'].'</a></dd>'."\n";
+
+		if ($pun_config['o_subscriptions'] == '1')
+			echo "\t\t\t\t".'<dd><a href="search.php?action=show_subscriptions">'.$lang_common['Show subscriptions'].'</a></dd>'."\n";
+
+		echo "\t\t\t\t".'<dd><a href="search.php?action=show_user&amp;user_id='.$pun_user['id'].'">'.$lang_common['Show your posts'].'</a></dd>'."\n\t\t\t".'</dl>'."\n";
+	}
+	else
+	{
+		if ($pun_user['g_search'] == '1')
+		{
+			echo "\n\t\t\t".'<dl id="searchlinks" class="conl">'."\n\t\t\t\t".'<dt><strong>'.$lang_common['Search links'].'</strong></dt><dd><a href="search.php?action=show_24h">'.$lang_common['Show recent posts'].'</a></dd>'."\n";
+			echo "\t\t\t\t".'<dd><a href="search.php?action=show_unanswered">'.$lang_common['Show unanswered posts'].'</a></dd>'."\n\t\t\t".'</dl>'."\n";
+		}
+	}
+}
+else if ($footer_style == 'viewforum' || $footer_style == 'viewtopic')
+{
+	echo "\n\t\t\t".'<div class="conl">'."\n";
+
+	// Display the "Jump to" drop list
+	if ($pun_config['o_quickjump'] == '1')
+	{
+		// Load cached quickjump
+		@include PUN_ROOT.'cache/cache_quickjump_'.$pun_user['g_id'].'.php';
+		if (!defined('PUN_QJ_LOADED'))
+		{
+			require_once PUN_ROOT.'include/cache.php';
+			generate_quickjump_cache($pun_user['g_id']);
+			require PUN_ROOT.'cache/cache_quickjump_'.$pun_user['g_id'].'.php';
+		}
+	}
+
+	if ($footer_style == 'viewforum' && $is_admmod)
+		echo "\t\t\t".'<p id="modcontrols"><a href="moderate.php?fid='.$forum_id.'&amp;p='.$p.'">'.$lang_common['Moderate forum'].'</a></p>'."\n";
+	else if ($footer_style == 'viewtopic' && $is_admmod)
+	{
+		echo "\t\t\t".'<dl id="modcontrols"><dt><strong>'.$lang_topic['Mod controls'].'</strong></dt><dd><a href="moderate.php?fid='.$forum_id.'&amp;tid='.$id.'&amp;p='.$p.'">'.$lang_common['Delete posts'].'</a></dd>'."\n";
+		echo "\t\t\t".'<dd><a href="moderate.php?fid='.$forum_id.'&amp;move_topics='.$id.'">'.$lang_common['Move topic'].'</a></dd>'."\n";
+
+		if ($cur_topic['closed'] == '1')
+			echo "\t\t\t".'<dd><a href="moderate.php?fid='.$forum_id.'&amp;open='.$id.'">'.$lang_common['Open topic'].'</a></dd>'."\n";
+		else
+			echo "\t\t\t".'<dd><a href="moderate.php?fid='.$forum_id.'&amp;close='.$id.'">'.$lang_common['Close topic'].'</a></dd>'."\n";
+
+		if ($cur_topic['sticky'] == '1')
+			echo "\t\t\t".'<dd><a href="moderate.php?fid='.$forum_id.'&amp;unstick='.$id.'">'.$lang_common['Unstick topic'].'</a></dd></dl>'."\n";
+		else
+			echo "\t\t\t".'<dd><a href="moderate.php?fid='.$forum_id.'&amp;stick='.$id.'">'.$lang_common['Stick topic'].'</a></dd></dl>'."\n";
+	}
+
+	echo "\t\t\t".'</div>'."\n";
+}
+
+?>
+			<p class="conr">Powered by <a href="http://www.punbb.org/">PunBB</a><?php if ($pun_config['o_show_version'] == '1') echo ' '.$pun_config['o_cur_version']; ?><br />&copy; Copyright 2002&#8211;2005 Rickard Andersson</p>
+<?php
+
+// Display debug info (if enabled/defined)
+if (defined('PUN_DEBUG'))
+{
+	// Calculate script generation time
+	list($usec, $sec) = explode(' ', microtime());
+	$time_diff = sprintf('%.3f', ((float)$usec + (float)$sec) - $pun_start);
+	echo "\t\t\t".'<p class="conr">[ Generated in '.$time_diff.' seconds, '.$db->get_num_queries().' queries executed ]</p>'."\n";
+}
+
+?>
+			<div class="clearer"></div>
+		</div>
+	</div>
+</div>
+<?php
+
+
+// End the transaction
+$db->end_transaction();
+
+// Display executed queries (if enabled)
+if (defined('PUN_SHOW_QUERIES'))
+	display_saved_queries();
+
+$tpl_temp = trim(ob_get_contents());
+$tpl_main = str_replace('<pun_footer>', $tpl_temp, $tpl_main);
+ob_end_clean();
+// END SUBST - <pun_footer>
+
+
+// Close the db connection (and free up any result data)
+$db->close();
+
+// Spit out the page
+exit($tpl_main);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/header.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,225 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Make sure no one attempts to run this script "directly"
+if (!defined('PUN'))
+	exit;
+
+// Send no-cache headers
+header('Expires: Thu, 21 Jul 1977 07:30:00 GMT');	// When yours truly first set eyes on this world! :)
+header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
+header('Cache-Control: post-check=0, pre-check=0', false);
+header('Pragma: no-cache');		// For HTTP/1.0 compability
+
+
+// Load the template
+if (defined('PUN_ADMIN_CONSOLE'))
+	$tpl_main = file_get_contents(PUN_ROOT.'include/template/admin.tpl');
+else if (defined('PUN_HELP'))
+	$tpl_main = file_get_contents(PUN_ROOT.'include/template/help.tpl');
+else
+	$tpl_main = file_get_contents(PUN_ROOT.'include/template/main.tpl');
+
+
+// START SUBST - <pun_include "*">
+while (preg_match('#<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">#', $tpl_main, $cur_include))
+{
+	if (!file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]))
+		error('Unable to process user include '.htmlspecialchars($cur_include[0]).' from template main.tpl. There is no such file in folder /include/user/');
+
+	ob_start();
+	include PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2];
+	$tpl_temp = ob_get_contents();
+	$tpl_main = str_replace($cur_include[0], $tpl_temp, $tpl_main);
+    ob_end_clean();
+}
+// END SUBST - <pun_include "*">
+
+
+// START SUBST - <pun_content_direction>
+$tpl_main = str_replace('<pun_content_direction>', $lang_common['lang_direction'], $tpl_main);
+// END SUBST - <pun_content_direction>
+
+
+// START SUBST - <pun_char_encoding>
+$tpl_main = str_replace('<pun_char_encoding>', $lang_common['lang_encoding'], $tpl_main);
+// END SUBST - <pun_char_encoding>
+
+
+// START SUBST - <pun_head>
+ob_start();
+
+// Is this a page that we want search index spiders to index?
+if (!defined('PUN_ALLOW_INDEX'))
+	echo '<meta name="ROBOTS" content="NOINDEX, FOLLOW" />'."\n";
+
+?>
+<title><?php echo $page_title ?></title>
+<link rel="stylesheet" type="text/css" href="style/<?php echo $pun_user['style'].'.css' ?>" />
+<?php
+
+if (defined('PUN_ADMIN_CONSOLE'))
+	echo '<link rel="stylesheet" type="text/css" href="style/imports/base_admin.css" />'."\n";
+
+if (isset($required_fields))
+{
+	// Output JavaScript to validate form (make sure required fields are filled out)
+
+?>
+<script type="text/javascript">
+<!--
+function process_form(the_form)
+{
+	var element_names = new Object()
+<?php
+
+	// Output a JavaScript array with localised field names
+	while (list($elem_orig, $elem_trans) = @each($required_fields))
+		echo "\t".'element_names["'.$elem_orig.'"] = "'.addslashes(str_replace('&nbsp;', ' ', $elem_trans)).'"'."\n";
+
+?>
+
+	if (document.all || document.getElementById)
+	{
+		for (i = 0; i < the_form.length; ++i)
+		{
+			var elem = the_form.elements[i]
+			if (elem.name && elem.name.substring(0, 4) == "req_")
+			{
+				if (elem.type && (elem.type=="text" || elem.type=="textarea" || elem.type=="password" || elem.type=="file") && elem.value=='')
+				{
+					alert("\"" + element_names[elem.name] + "\" <?php echo $lang_common['required field'] ?>")
+					elem.focus()
+					return false
+				}
+			}
+		}
+	}
+
+	return true
+}
+// -->
+</script>
+<?php
+
+}
+
+$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? strtolower($_SERVER['HTTP_USER_AGENT']) : '';
+if (strpos($user_agent, 'msie') !== false && strpos($user_agent, 'windows') !== false && strpos($user_agent, 'opera') === false)
+	echo '<script type="text/javascript" src="style/imports/minmax.js"></script>';
+
+$tpl_temp = trim(ob_get_contents());
+$tpl_main = str_replace('<pun_head>', $tpl_temp, $tpl_main);
+ob_end_clean();
+// END SUBST - <pun_head>
+
+
+// START SUBST - <body>
+if (isset($focus_element))
+{
+	$tpl_main = str_replace('<body onload="', '<body onload="document.getElementById(\''.$focus_element[0].'\').'.$focus_element[1].'.focus();', $tpl_main);
+	$tpl_main = str_replace('<body>', '<body onload="document.getElementById(\''.$focus_element[0].'\').'.$focus_element[1].'.focus()">', $tpl_main);
+}
+// END SUBST - <body>
+
+
+// START SUBST - <pun_page>
+$tpl_main = str_replace('<pun_page>', htmlspecialchars(basename($_SERVER['PHP_SELF'], '.php')), $tpl_main);
+// END SUBST - <pun_title>
+
+
+// START SUBST - <pun_title>
+$tpl_main = str_replace('<pun_title>', '<h1><span>'.pun_htmlspecialchars($pun_config['o_board_title']).'</span></h1>', $tpl_main);
+// END SUBST - <pun_title>
+
+
+// START SUBST - <pun_desc>
+$tpl_main = str_replace('<pun_desc>', '<p><span>'.$pun_config['o_board_desc'].'</span></p>', $tpl_main);
+// END SUBST - <pun_desc>
+
+
+// START SUBST - <pun_navlinks>
+$tpl_main = str_replace('<pun_navlinks>','<div id="brdmenu" class="inbox">'."\n\t\t\t". generate_navlinks()."\n\t\t".'</div>', $tpl_main);
+// END SUBST - <pun_navlinks>
+
+
+// START SUBST - <pun_status>
+if ($pun_user['is_guest'])
+	$tpl_temp = '<div id="brdwelcome" class="inbox">'."\n\t\t\t".'<p>'.$lang_common['Not logged in'].'</p>'."\n\t\t".'</div>';
+else
+{
+	$tpl_temp = '<div id="brdwelcome" class="inbox">'."\n\t\t\t".'<ul class="conl">'."\n\t\t\t\t".'<li>'.$lang_common['Logged in as'].' <strong>'.pun_htmlspecialchars($pun_user['username']).'</strong></li>'."\n\t\t\t\t".'<li>'.$lang_common['Last visit'].': '.format_time($pun_user['last_visit']).'</li>';
+
+	if ($pun_user['g_id'] < PUN_GUEST)
+	{
+		$result_header = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'reports WHERE zapped IS NULL') or error('Unable to fetch reports info', __FILE__, __LINE__, $db->error());
+
+		if ($db->result($result_header))
+			$tpl_temp .= "\n\t\t\t\t".'<li class="reportlink"><strong><a href="admin_reports.php">There are new reports</a></strong></li>';
+
+		if ($pun_config['o_maintenance'] == '1')
+			$tpl_temp .= "\n\t\t\t\t".'<li class="maintenancelink"><strong><a href="admin_options.php#maintenance">Maintenance mode is enabled!</a></strong></li>';
+	}
+
+	if (in_array(basename($_SERVER['PHP_SELF']), array('index.php', 'search.php')))
+		$tpl_temp .= "\n\t\t\t".'</ul>'."\n\t\t\t".'<ul class="conr">'."\n\t\t\t\t".'<li><a href="search.php?action=show_new">'.$lang_common['Show new posts'].'</a></li>'."\n\t\t\t\t".'<li><a href="misc.php?action=markread">'.$lang_common['Mark all as read'].'</a></li>'."\n\t\t\t".'</ul>'."\n\t\t\t".'<div class="clearer"></div>'."\n\t\t".'</div>';
+	else
+		$tpl_temp .= "\n\t\t\t".'</ul>'."\n\t\t\t".'<div class="clearer"></div>'."\n\t\t".'</div>';
+}
+
+$tpl_main = str_replace('<pun_status>', $tpl_temp, $tpl_main);
+// END SUBST - <pun_status>
+
+
+// START SUBST - <pun_announcement>
+if ($pun_config['o_announcement'] == '1')
+{
+	ob_start();
+
+?>
+<div id="announce" class="block">
+	<h2><span><?php echo $lang_common['Announcement'] ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<div><?php echo $pun_config['o_announcement_message'] ?></div>
+		</div>
+	</div>
+</div>
+<?php
+
+	$tpl_temp = trim(ob_get_contents());
+	$tpl_main = str_replace('<pun_announcement>', $tpl_temp, $tpl_main);
+	ob_end_clean();
+}
+else
+	$tpl_main = str_replace('<pun_announcement>', '', $tpl_main);
+// END SUBST - <pun_announcement>
+
+
+// START SUBST - <pun_main>
+ob_start();
+
+
+define('PUN_HEADER', 1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/help.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,157 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Tell header.php to use the help template
+define('PUN_HELP', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+if ($pun_user['g_read_board'] == '0')
+	message($lang_common['No view']);
+
+
+// Load the help.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/help.php';
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_help['Help'];
+require PUN_ROOT.'header.php';
+
+?>
+<h2><?php echo $lang_common['BBCode'] ?></h2>
+<div class="box">
+	<div class="inbox">
+		<p><a name="bbcode"></a><?php echo $lang_help['BBCode info 1'] ?></p><br />
+		<p><?php echo $lang_help['BBCode info 2'] ?></p>
+	</div>
+</div>
+<h2><?php echo $lang_help['Text style'] ?></h2>
+<div class="box">
+	<p><?php echo $lang_help['Text style info'] ?></p><br />
+	<div style="padding-left: 4px">
+		[b]<?php echo $lang_help['Bold text'] ?>[/b] <?php echo $lang_help['produces'] ?> <b><?php echo $lang_help['Bold text'] ?></b><br />
+		[u]<?php echo $lang_help['Underlined text'] ?>[/u] <?php echo $lang_help['produces'] ?> <span class="bbu"><?php echo $lang_help['Underlined text'] ?></span><br />
+		[i]<?php echo $lang_help['Italic text'] ?>[/i] <?php echo $lang_help['produces'] ?> <i><?php echo $lang_help['Italic text'] ?></i><br />
+		[color=#FF0000]<?php echo $lang_help['Red text'] ?>[/color] <?php echo $lang_help['produces'] ?> <span style="color: #ff0000"><?php echo $lang_help['Red text'] ?></span><br />
+		[color=blue]<?php echo $lang_help['Blue text'] ?>[/color] <?php echo $lang_help['produces'] ?> <span style="color: blue"><?php echo $lang_help['Blue text'] ?></span>
+	</div>
+</div>
+<h2><?php echo $lang_help['Links and images'] ?></h2>
+<div class="box">
+	<p><?php echo $lang_help['Links info'] ?></p><br />
+	<div style="padding-left: 4px">
+		[url=<?php echo $pun_config['o_base_url'].'/' ?>]<?php echo pun_htmlspecialchars($pun_config['o_board_title']) ?>[/url] <?php echo $lang_help['produces'] ?> <a href="<?php echo $pun_config['o_base_url'].'/' ?>"><?php echo pun_htmlspecialchars($pun_config['o_board_title']) ?></a><br />
+		[url]<?php echo $pun_config['o_base_url'].'/' ?>[/url] <?php echo $lang_help['produces'] ?> <a href="<?php echo $pun_config['o_base_url'] ?>"><?php echo $pun_config['o_base_url'].'/' ?></a><br />
+		[email]myname@mydomain.com[/email] <?php echo $lang_help['produces'] ?> <a href="mailto:myname@mydomain.com">myname@mydomain.com</a><br />
+		[email=myname@mydomain.com]<?php echo $lang_help['My e-mail address'] ?>[/email] <?php echo $lang_help['produces'] ?> <a href="mailto:myname@mydomain.com"><?php echo $lang_help['My e-mail address'] ?></a><br /><br />
+	</div>
+	<p><a name="img"></a><?php echo $lang_help['Images info'] ?></p>
+	<div>[img]http://www.punbb.org/img/small_logo.png[/img] <?php echo $lang_help['produces'] ?> <img src="http://www.punbb.org/img/small_logo.png" alt="http://www.punbb.org/img/small_logo.png" /></div>
+</div>
+<h2><?php echo $lang_help['Quotes'] ?></h2>
+<div class="box">
+	<div style="padding-left: 4px">
+		<?php echo $lang_help['Quotes info'] ?><br /><br />
+		&nbsp;&nbsp;&nbsp;&nbsp;[quote=James]<?php echo $lang_help['Quote text'] ?>[/quote]<br /><br />
+		<?php echo $lang_help['produces quote box'] ?><br /><br />
+		<div class="postmsg">
+			<blockquote><div class="incqbox"><h4>James <?php echo $lang_common['wrote'] ?>:</h4><p><?php echo $lang_help['Quote text'] ?></p></div></blockquote>
+		</div>
+		<br />
+		<?php echo $lang_help['Quotes info 2'] ?><br /><br />
+		&nbsp;&nbsp;&nbsp;&nbsp;[quote]<?php echo $lang_help['Quote text'] ?>[/quote]<br /><br />
+		<?php echo $lang_help['produces quote box'] ?><br /><br />
+		<div class="postmsg">
+			<blockquote><div class="incqbox"><p><?php echo $lang_help['Quote text'] ?></p></div></blockquote>
+		</div>
+	</div>
+</div>
+<h2><?php echo $lang_help['Code'] ?></h2>
+<div class="box">
+	<div style="padding-left: 4px">
+		<?php echo $lang_help['Code info'] ?><br /><br />
+		&nbsp;&nbsp;&nbsp;&nbsp;[code]<?php echo $lang_help['Code text'] ?>[/code]<br /><br />
+		<?php echo $lang_help['produces code box'] ?><br /><br />
+		<div class="postmsg">
+			<div class="codebox"><div class="incqbox"><h4><?php echo $lang_common['Code'] ?>:</h4><div class="scrollbox" style="height: 4.5em"><pre><?php echo $lang_help['Code text'] ?></pre></div></div></div>
+		</div>
+	</div>
+</div>
+<h2><?php echo $lang_help['Nested tags'] ?></h2>
+<div class="box">
+	<div style="padding-left: 4px">
+		<?php echo $lang_help['Nested tags info'] ?><br /><br />
+		&nbsp;&nbsp;&nbsp;&nbsp;[b][u]<?php echo $lang_help['Bold, underlined text'] ?>[/u][/b] <?php echo $lang_help['produces'] ?> <span class="bbu"><b><?php echo $lang_help['Bold, underlined text'] ?></b></span><br /><br />
+	</div>
+</div>
+<h2><?php echo $lang_common['Smilies'] ?></h2>
+<div class="box">
+	<div style="padding-left: 4px">
+		<a name="smilies"></a><?php echo $lang_help['Smilies info'] ?><br /><br />
+<?php
+
+// Display the smiley set
+require PUN_ROOT.'include/parser.php';
+
+$num_smilies = count($smiley_text);
+for ($i = 0; $i < $num_smilies; ++$i)
+{
+	// Is there a smiley at the current index?
+	if (!isset($smiley_text[$i]))
+		continue;
+
+	echo "\t\t".'&nbsp;&nbsp;&nbsp;&nbsp;'.$smiley_text[$i];
+
+	// Save the current text and image
+	$cur_img = $smiley_img[$i];
+	$cur_text = $smiley_text[$i];
+
+	// Loop through the rest of the array and see if there are any duplicate images
+	// (more than one text representation for one image)
+	for ($next = $i + 1; $next < $num_smilies; ++$next)
+	{
+		// Did we find a dupe?
+		if (isset($smiley_img[$next]) && $smiley_img[$i] == $smiley_img[$next])
+		{
+			echo ' '.$lang_common['and'].' '.$smiley_text[$next];
+
+			// Remove the dupe so we won't display it twice
+			unset($smiley_text[$next]);
+			unset($smiley_img[$next]);
+		}
+	}
+
+	echo ' '.$lang_help['produces'].' <img src="img/smilies/'.$cur_img.'" width="15" height="15" alt="'.$cur_text.'" /><br />'."\n";
+}
+
+?>
+		<br />
+	</div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/img/avatars/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/img/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
Binary file punbb/img/smilies/big_smile.png has changed
Binary file punbb/img/smilies/cool.png has changed
Binary file punbb/img/smilies/hmm.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/img/smilies/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
Binary file punbb/img/smilies/lol.png has changed
Binary file punbb/img/smilies/mad.png has changed
Binary file punbb/img/smilies/neutral.png has changed
Binary file punbb/img/smilies/roll.png has changed
Binary file punbb/img/smilies/sad.png has changed
Binary file punbb/img/smilies/smile.png has changed
Binary file punbb/img/smilies/tongue.png has changed
Binary file punbb/img/smilies/wink.png has changed
Binary file punbb/img/smilies/yikes.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/cache.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,205 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Make sure no one attempts to run this script "directly"
+if (!defined('PUN'))
+	exit;
+
+
+//
+// If we are running pre PHP 4.2.0, we add our own implementation of var_export
+//
+if (!function_exists('var_export'))
+{
+	function var_export()
+	{
+		$args = func_get_args();
+		$indent = (isset($args[2])) ? $args[2] : '';
+
+		if (is_array($args[0]))
+		{
+			$output = 'array ('."\n";
+
+			foreach ($args[0] as $k => $v)
+			{
+				if (is_numeric($k))
+					$output .= $indent.'  '.$k.' => ';
+				else
+					$output .= $indent.'  \''.str_replace('\'', '\\\'', str_replace('\\', '\\\\', $k)).'\' => ';
+
+				if (is_array($v))
+					$output .= var_export($v, true, $indent.'  ');
+				else
+				{
+					if (gettype($v) != 'string' && !empty($v))
+						$output .= $v.','."\n";
+					else
+						$output .= '\''.str_replace('\'', '\\\'', str_replace('\\', '\\\\', $v)).'\','."\n";
+				}
+			}
+
+			$output .= ($indent != '') ? $indent.'),'."\n" : ')';
+		}
+		else
+			$output = $args[0];
+
+		if ($args[1] == true)
+			return $output;
+		else
+			echo $output;
+	}
+}
+
+
+//
+// Generate the config cache PHP script
+//
+function generate_config_cache()
+{
+	global $db;
+
+	// Get the forum config from the DB
+	$result = $db->query('SELECT * FROM '.$db->prefix.'config', true) or error('Unable to fetch forum config', __FILE__, __LINE__, $db->error());
+	while ($cur_config_item = $db->fetch_row($result))
+		$output[$cur_config_item[0]] = $cur_config_item[1];
+
+	// Output config as PHP code
+	$fh = @fopen(PUN_ROOT.'cache/cache_config.php', 'wb');
+	if (!$fh)
+		error('Unable to write configuration cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__);
+
+	fwrite($fh, '<?php'."\n\n".'define(\'PUN_CONFIG_LOADED\', 1);'."\n\n".'$pun_config = '.var_export($output, true).';'."\n\n".'?>');
+
+	fclose($fh);
+}
+
+
+//
+// Generate the bans cache PHP script
+//
+function generate_bans_cache()
+{
+	global $db;
+
+	// Get the ban list from the DB
+	$result = $db->query('SELECT * FROM '.$db->prefix.'bans', true) or error('Unable to fetch ban list', __FILE__, __LINE__, $db->error());
+
+	$output = array();
+	while ($cur_ban = $db->fetch_assoc($result))
+		$output[] = $cur_ban;
+
+	// Output ban list as PHP code
+	$fh = @fopen(PUN_ROOT.'cache/cache_bans.php', 'wb');
+	if (!$fh)
+		error('Unable to write bans cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__);
+
+	fwrite($fh, '<?php'."\n\n".'define(\'PUN_BANS_LOADED\', 1);'."\n\n".'$pun_bans = '.var_export($output, true).';'."\n\n".'?>');
+
+	fclose($fh);
+}
+
+
+//
+// Generate the ranks cache PHP script
+//
+function generate_ranks_cache()
+{
+	global $db;
+
+	// Get the rank list from the DB
+	$result = $db->query('SELECT * FROM '.$db->prefix.'ranks ORDER BY min_posts', true) or error('Unable to fetch rank list', __FILE__, __LINE__, $db->error());
+
+	$output = array();
+	while ($cur_rank = $db->fetch_assoc($result))
+		$output[] = $cur_rank;
+
+	// Output ranks list as PHP code
+	$fh = @fopen(PUN_ROOT.'cache/cache_ranks.php', 'wb');
+	if (!$fh)
+		error('Unable to write ranks cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__);
+
+	fwrite($fh, '<?php'."\n\n".'define(\'PUN_RANKS_LOADED\', 1);'."\n\n".'$pun_ranks = '.var_export($output, true).';'."\n\n".'?>');
+
+	fclose($fh);
+}
+
+
+//
+// Generate quickjump cache PHP scripts
+//
+function generate_quickjump_cache($group_id = false)
+{
+	global $db, $lang_common, $pun_user;
+
+	// If a group_id was supplied, we generate the quickjump cache for that group only
+	if ($group_id !== false)
+		$groups[0] = $group_id;
+	else
+	{
+		// A group_id was now supplied, so we generate the quickjump cache for all groups
+		$result = $db->query('SELECT g_id FROM '.$db->prefix.'groups') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+		$num_groups = $db->num_rows($result);
+
+		for ($i = 0; $i < $num_groups; ++$i)
+			$groups[] = $db->result($result, $i);
+	}
+
+	// Loop through the groups in $groups and output the cache for each of them
+	while (list(, $group_id) = @each($groups))
+	{
+		// Output quickjump as PHP code
+		$fh = @fopen(PUN_ROOT.'cache/cache_quickjump_'.$group_id.'.php', 'wb');
+		if (!$fh)
+			error('Unable to write quickjump cache file to cache directory. Please make sure PHP has write access to the directory \'cache\'', __FILE__, __LINE__);
+
+		$output = '<?php'."\n\n".'if (!defined(\'PUN\')) exit;'."\n".'define(\'PUN_QJ_LOADED\', 1);'."\n\n".'?>';
+		$output .= "\t\t\t\t".'<form id="qjump" method="get" action="viewforum.php">'."\n\t\t\t\t\t".'<div><label><?php echo $lang_common[\'Jump to\'] ?>'."\n\n\t\t\t\t\t".'<br /><select name="id" onchange="window.location=(\'viewforum.php?id=\'+this.options[this.selectedIndex].value)">'."\n";
+
+
+		$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.redirect_url FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$group_id.') WHERE fp.read_forum IS NULL OR fp.read_forum=1 ORDER BY c.disp_position, c.id, f.disp_position', true) or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
+
+		$cur_category = 0;
+		while ($cur_forum = $db->fetch_assoc($result))
+		{
+			if ($cur_forum['cid'] != $cur_category)	// A new category since last iteration?
+			{
+				if ($cur_category)
+					$output .= "\t\t\t\t\t\t".'</optgroup>'."\n";
+
+				$output .= "\t\t\t\t\t\t".'<optgroup label="'.pun_htmlspecialchars($cur_forum['cat_name']).'">'."\n";
+				$cur_category = $cur_forum['cid'];
+			}
+
+			$redirect_tag = ($cur_forum['redirect_url'] != '') ? ' &gt;&gt;&gt;' : '';
+			$output .= "\t\t\t\t\t\t\t".'<option value="'.$cur_forum['fid'].'"<?php echo ($forum_id == '.$cur_forum['fid'].') ? \' selected="selected"\' : \'\' ?>>'.pun_htmlspecialchars($cur_forum['forum_name']).$redirect_tag.'</option>'."\n";
+		}
+
+		$output .= "\t\t\t\t\t".'</optgroup>'."\n\t\t\t\t\t".'</select>'."\n\t\t\t\t\t".'<input type="submit" value="<?php echo $lang_common[\'Go\'] ?>" accesskey="g" />'."\n\t\t\t\t\t".'</label></div>'."\n\t\t\t\t".'</form>'."\n";
+
+		fwrite($fh, $output);
+
+		fclose($fh);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/common.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,147 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+// Enable DEBUG mode by removing // from the following line
+//define('PUN_DEBUG', 1);
+
+// This displays all executed queries in the page footer.
+// DO NOT enable this in a production environment!
+//define('PUN_SHOW_QUERIES', 1);
+
+if (!defined('PUN_ROOT'))
+	exit('The constant PUN_ROOT must be defined and point to a valid PunBB installation root directory.');
+
+
+// Load the functions script
+require PUN_ROOT.'include/functions.php';
+
+// Reverse the effect of register_globals
+unregister_globals();
+
+
+@include PUN_ROOT.'config.php';
+
+// If PUN isn't defined, config.php is missing or corrupt
+if (!defined('PUN'))
+	exit('The file \'config.php\' doesn\'t exist or is corrupt. Please run <a href="install.php">install.php</a> to install PunBB first.');
+
+
+// Record the start time (will be used to calculate the generation time for the page)
+list($usec, $sec) = explode(' ', microtime());
+$pun_start = ((float)$usec + (float)$sec);
+
+// Make sure PHP reports all errors except E_NOTICE. PunBB supports E_ALL, but a lot of scripts it may interact with, do not.
+error_reporting(E_ALL ^ E_NOTICE);
+
+// Turn off magic_quotes_runtime
+set_magic_quotes_runtime(0);
+
+// Strip slashes from GET/POST/COOKIE (if magic_quotes_gpc is enabled)
+if (get_magic_quotes_gpc())
+{
+	function stripslashes_array($array)
+	{
+		return is_array($array) ? array_map('stripslashes_array', $array) : stripslashes($array);
+	}
+
+	$_GET = stripslashes_array($_GET);
+	$_POST = stripslashes_array($_POST);
+	$_COOKIE = stripslashes_array($_COOKIE);
+}
+
+// Seed the random number generator
+mt_srand((double)microtime()*1000000);
+
+// If a cookie name is not specified in config.php, we use the default (punbb_cookie)
+if (empty($cookie_name))
+	$cookie_name = 'punbb_cookie';
+
+// Define a few commonly used constants
+define('PUN_UNVERIFIED', 32000);
+define('PUN_ADMIN', 1);
+define('PUN_MOD', 2);
+define('PUN_GUEST', 3);
+define('PUN_MEMBER', 4);
+
+
+// Load DB abstraction layer and connect
+require PUN_ROOT.'include/dblayer/common_db.php';
+
+// Start a transaction
+$db->start_transaction();
+
+// Load cached config
+@include PUN_ROOT.'cache/cache_config.php';
+if (!defined('PUN_CONFIG_LOADED'))
+{
+	require PUN_ROOT.'include/cache.php';
+	generate_config_cache();
+	require PUN_ROOT.'cache/cache_config.php';
+}
+
+
+// Enable output buffering
+if (!defined('PUN_DISABLE_BUFFERING'))
+{
+	// For some very odd reason, "Norton Internet Security" unsets this
+	$_SERVER['HTTP_ACCEPT_ENCODING'] = isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : '';
+
+	// Should we use gzip output compression?
+	if ($pun_config['o_gzip'] && extension_loaded('zlib') && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false || strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !== false))
+		ob_start('ob_gzhandler');
+	else
+		ob_start();
+}
+
+
+// Check/update/set cookie and fetch user info
+$pun_user = array();
+check_cookie($pun_user);
+
+// Attempt to load the common language file
+@include PUN_ROOT.'lang/'.$pun_user['language'].'/common.php';
+if (!isset($lang_common))
+	exit('There is no valid language pack \''.pun_htmlspecialchars($pun_user['language']).'\' installed. Please reinstall a language of that name.');
+
+// Check if we are to display a maintenance message
+if ($pun_config['o_maintenance'] && $pun_user['g_id'] > PUN_ADMIN && !defined('PUN_TURN_OFF_MAINT'))
+	maintenance_message();
+
+
+// Load cached bans
+@include PUN_ROOT.'cache/cache_bans.php';
+if (!defined('PUN_BANS_LOADED'))
+{
+	require_once PUN_ROOT.'include/cache.php';
+	generate_bans_cache();
+	require PUN_ROOT.'cache/cache_bans.php';
+}
+
+// Check if current user is banned
+check_bans();
+
+
+// Update online list
+update_users_online();
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/common_admin.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,149 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+// Make sure no one attempts to run this script "directly"
+if (!defined('PUN'))
+	exit;
+
+
+//
+// Display the admin navigation menu
+//
+function generate_admin_menu($page = '')
+{
+	global $pun_config, $pun_user;
+
+	$is_admin = $pun_user['g_id'] == PUN_ADMIN ? true : false;
+
+?>
+<div id="adminconsole" class="block2col">
+	<div id="adminmenu" class="blockmenu">
+		<h2><span><?php echo ($is_admin) ? 'Admin' : 'Moderator' ?> menu</span></h2>
+		<div class="box">
+			<div class="inbox">
+				<ul>
+					<li<?php if ($page == 'index') echo ' class="isactive"'; ?>><a href="admin_index.php">Index</a></li>
+<?php if ($is_admin): ?>					<li<?php if ($page == 'categories') echo ' class="isactive"'; ?>><a href="admin_categories.php">Categories</a></li>
+<?php endif; ?><?php if ($is_admin): ?>					<li<?php if ($page == 'forums') echo ' class="isactive"'; ?>><a href="admin_forums.php">Forums</a></li>
+<?php endif; ?>					<li<?php if ($page == 'users') echo ' class="isactive"'; ?>><a href="admin_users.php">Users</a></li>
+<?php if ($is_admin): ?>					<li<?php if ($page == 'groups') echo ' class="isactive"'; ?>><a href="admin_groups.php">User groups</a></li>
+<?php endif; ?><?php if ($is_admin): ?>					<li<?php if ($page == 'options') echo ' class="isactive"'; ?>><a href="admin_options.php">Options</a></li>
+<?php endif; ?><?php if ($is_admin): ?>					<li<?php if ($page == 'permissions') echo ' class="isactive"'; ?>><a href="admin_permissions.php">Permissions</a></li>
+<?php endif; ?>					<li<?php if ($page == 'censoring') echo ' class="isactive"'; ?>><a href="admin_censoring.php">Censoring</a></li>
+<?php if ($is_admin): ?>					<li<?php if ($page == 'ranks') echo ' class="isactive"'; ?>><a href="admin_ranks.php">Ranks</a></li>
+<?php endif; ?><?php if ($is_admin || $pun_config['p_mod_ban_users'] == '1'): ?>					<li<?php if ($page == 'bans') echo ' class="isactive"'; ?>><a href="admin_bans.php">Bans</a></li>
+<?php endif; ?><?php if ($is_admin): ?>					<li<?php if ($page == 'prune') echo ' class="isactive"'; ?>><a href="admin_prune.php">Prune</a></li>
+<?php endif; ?><?php if ($is_admin): ?>					<li<?php if ($page == 'maintenance') echo ' class="isactive"'; ?>><a href="admin_maintenance.php">Maintenance</a></li>
+<?php endif; ?>					<li<?php if ($page == 'reports') echo ' class="isactive"'; ?>><a href="admin_reports.php">Reports</a></li>
+				</ul>
+			</div>
+		</div>
+<?php
+
+	// See if there are any plugins
+	$plugins = array();
+	$d = dir(PUN_ROOT.'plugins');
+	while (($entry = $d->read()) !== false)
+	{
+		$prefix = substr($entry, 0, strpos($entry, '_'));
+		$suffix = substr($entry, strlen($entry) - 4);
+
+		if ($suffix == '.php' && ((!$is_admin && $prefix == 'AMP') || ($is_admin && ($prefix == 'AP' || $prefix == 'AMP'))))
+			$plugins[] = array(substr(substr($entry, strpos($entry, '_') + 1), 0, -4), $entry);
+	}
+	$d->close();
+
+	// Did we find any plugins?
+	if (!empty($plugins))
+	{
+
+?>
+		<h2 class="block2"><span>Plugins</span></h2>
+		<div class="box">
+			<div class="inbox">
+				<ul>
+<?php
+
+		while (list(, $cur_plugin) = @each($plugins))
+			echo "\t\t\t\t\t".'<li'.(($page == $cur_plugin[1]) ? ' class="isactive"' : '').'><a href="admin_loader.php?plugin='.$cur_plugin[1].'">'.str_replace('_', ' ', $cur_plugin[0]).'</a></li>'."\n";
+
+?>
+				</ul>
+			</div>
+		</div>
+<?php
+
+	}
+
+?>
+	</div>
+
+<?php
+
+}
+
+
+//
+// Delete topics from $forum_id that are "older than" $prune_date (if $prune_sticky is 1, sticky topics will also be deleted)
+//
+function prune($forum_id, $prune_sticky, $prune_date)
+{
+	global $db;
+
+	$extra_sql = ($prune_date != -1) ? ' AND last_post<'.$prune_date : '';
+
+	if (!$prune_sticky)
+		$extra_sql .= ' AND sticky=\'0\'';
+
+	// Fetch topics to prune
+	$result = $db->query('SELECT id FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id.$extra_sql, true) or error('Unable to fetch topics', __FILE__, __LINE__, $db->error());
+
+	$topic_ids = '';
+	while ($row = $db->fetch_row($result))
+		$topic_ids .= (($topic_ids != '') ? ',' : '').$row[0];
+
+	if ($topic_ids != '')
+	{
+		// Fetch posts to prune
+		$result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id IN('.$topic_ids.')', true) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error());
+
+		$post_ids = '';
+		while ($row = $db->fetch_row($result))
+			$post_ids .= (($post_ids != '') ? ',' : '').$row[0];
+
+		if ($post_ids != '')
+		{
+			// Delete topics
+			$db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.$topic_ids.')') or error('Unable to prune topics', __FILE__, __LINE__, $db->error());
+			// Delete subscriptions
+			$db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id IN('.$topic_ids.')') or error('Unable to prune subscriptions', __FILE__, __LINE__, $db->error());
+			// Delete posts
+			$db->query('DELETE FROM '.$db->prefix.'posts WHERE id IN('.$post_ids.')') or error('Unable to prune posts', __FILE__, __LINE__, $db->error());
+
+			// We removed a bunch of posts, so now we have to update the search index
+			require_once PUN_ROOT.'include/search_idx.php';
+			strip_search_index($post_ids);
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/dblayer/common_db.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,70 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Make sure no one attempts to run this script "directly"
+if (!defined('PUN'))
+	exit;
+
+
+//
+// Return current timestamp (with microseconds) as a float (used in dblayer)
+//
+if (defined('PUN_SHOW_QUERIES'))
+{
+	function get_microtime()
+	{
+		list($usec, $sec) = explode(' ', microtime());
+		return ((float)$usec + (float)$sec);
+	}
+}
+
+
+// Load the appropriate DB layer class
+switch ($db_type)
+{
+	case 'mysql':
+		require PUN_ROOT.'include/dblayer/mysql.php';
+		break;
+
+	case 'mysqli':
+		require PUN_ROOT.'include/dblayer/mysqli.php';
+		break;
+
+	case 'pgsql':
+		require PUN_ROOT.'include/dblayer/pgsql.php';
+		break;
+
+	case 'sqlite':
+		require PUN_ROOT.'include/dblayer/sqlite.php';
+		break;
+
+	default:
+		error('\''.$db_type.'\' is not a valid database type. Please check settings in config.php.', __FILE__, __LINE__);
+		break;
+}
+
+
+// Create the database adapter object (and open/connect to/select db)
+$db = new DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/dblayer/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/dblayer/mysql.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,190 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Make sure we have built in support for MySQL
+if (!function_exists('mysql_connect'))
+	exit('This PHP environment doesn\'t have MySQL support built in. MySQL support is required if you want to use a MySQL database to run this forum. Consult the PHP documentation for further assistance.');
+
+
+class DBLayer
+{
+	var $prefix;
+	var $link_id;
+	var $query_result;
+
+	var $saved_queries = array();
+	var $num_queries = 0;
+
+
+	function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect)
+	{
+		$this->prefix = $db_prefix;
+
+		if ($p_connect)
+			$this->link_id = @mysql_pconnect($db_host, $db_username, $db_password);
+		else
+			$this->link_id = @mysql_connect($db_host, $db_username, $db_password);
+
+		if ($this->link_id)
+		{
+			if (@mysql_select_db($db_name, $this->link_id))
+				return $this->link_id;
+			else
+				error('Unable to select database. MySQL reported: '.mysql_error(), __FILE__, __LINE__);
+		}
+		else
+			error('Unable to connect to MySQL server. MySQL reported: '.mysql_error(), __FILE__, __LINE__);
+	}
+
+
+	function start_transaction()
+	{
+		return;
+	}
+
+
+	function end_transaction()
+	{
+		return;
+	}
+
+
+	function query($sql, $unbuffered = false)
+	{
+		if (defined('PUN_SHOW_QUERIES'))
+			$q_start = get_microtime();
+
+		if ($unbuffered)
+			$this->query_result = @mysql_unbuffered_query($sql, $this->link_id);
+		else
+			$this->query_result = @mysql_query($sql, $this->link_id);
+
+		if ($this->query_result)
+		{
+			if (defined('PUN_SHOW_QUERIES'))
+				$this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start));
+
+			++$this->num_queries;
+
+			return $this->query_result;
+		}
+		else
+		{
+			if (defined('PUN_SHOW_QUERIES'))
+				$this->saved_queries[] = array($sql, 0);
+
+			return false;
+		}
+	}
+
+
+	function result($query_id = 0, $row = 0)
+	{
+		return ($query_id) ? @mysql_result($query_id, $row) : false;
+	}
+
+
+	function fetch_assoc($query_id = 0)
+	{
+		return ($query_id) ? @mysql_fetch_assoc($query_id) : false;
+	}
+
+
+	function fetch_row($query_id = 0)
+	{
+		return ($query_id) ? @mysql_fetch_row($query_id) : false;
+	}
+
+
+	function num_rows($query_id = 0)
+	{
+		return ($query_id) ? @mysql_num_rows($query_id) : false;
+	}
+
+
+	function affected_rows()
+	{
+		return ($this->link_id) ? @mysql_affected_rows($this->link_id) : false;
+	}
+
+
+	function insert_id()
+	{
+		return ($this->link_id) ? @mysql_insert_id($this->link_id) : false;
+	}
+
+
+	function get_num_queries()
+	{
+		return $this->num_queries;
+	}
+
+
+	function get_saved_queries()
+	{
+		return $this->saved_queries;
+	}
+
+
+	function free_result($query_id = false)
+	{
+		return ($query_id) ? @mysql_free_result($query_id) : false;
+	}
+
+
+	function escape($str)
+	{
+		if (is_array($str))
+			return '';
+		else if (function_exists('mysql_real_escape_string'))
+			return mysql_real_escape_string($str, $this->link_id);
+		else
+			return mysql_escape_string($str);
+	}
+
+
+	function error()
+	{
+		$result['error_sql'] = @current(@end($this->saved_queries));
+		$result['error_no'] = @mysql_errno($this->link_id);
+		$result['error_msg'] = @mysql_error($this->link_id);
+
+		return $result;
+	}
+
+
+	function close()
+	{
+		if ($this->link_id)
+		{
+			if ($this->query_result)
+				@mysql_free_result($this->query_result);
+
+			return @mysql_close($this->link_id);
+		}
+		else
+			return false;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/dblayer/mysqli.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,188 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Make sure we have built in support for MySQL
+if (!function_exists('mysqli_connect'))
+	exit('This PHP environment doesn\'t have Improved MySQL (mysqli) support built in. Improved MySQL support is required if you want to use a MySQL 4.1 (or later) database to run this forum. Consult the PHP documentation for further assistance.');
+
+
+class DBLayer
+{
+	var $prefix;
+	var $link_id;
+	var $query_result;
+
+	var $saved_queries = array();
+	var $num_queries = 0;
+
+
+	function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $foo)
+	{
+		$this->prefix = $db_prefix;
+
+		// Was a custom port supplied with $db_host?
+		if (strpos($db_host, ':') !== false)
+			list($db_host, $db_port) = explode(':', $db_host);
+
+		if (isset($db_port))
+			$this->link_id = @mysqli_connect($db_host, $db_username, $db_password, $db_name, $db_port);
+		else
+			$this->link_id = @mysqli_connect($db_host, $db_username, $db_password, $db_name);
+
+		if (!$this->link_id)
+			error('Unable to connect to MySQL and select database. MySQL reported: '.mysqli_connect_error(), __FILE__, __LINE__);
+	}
+
+
+	function start_transaction()
+	{
+		return;
+	}
+
+
+	function end_transaction()
+	{
+		return;
+	}
+
+
+	function query($sql, $unbuffered = false)
+	{
+		if (defined('PUN_SHOW_QUERIES'))
+			$q_start = get_microtime();
+
+		$this->query_result = @mysqli_query($this->link_id, $sql);
+
+		if ($this->query_result)
+		{
+			if (defined('PUN_SHOW_QUERIES'))
+				$this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start));
+
+			++$this->num_queries;
+
+			return $this->query_result;
+		}
+		else
+		{
+			if (defined('PUN_SHOW_QUERIES'))
+				$this->saved_queries[] = array($sql, 0);
+
+			return false;
+		}
+	}
+
+
+	function result($query_id = 0, $row = 0)
+	{
+		if ($query_id)
+		{
+			if ($row)
+				@mysqli_data_seek($query_id, $row);
+
+			$cur_row = @mysqli_fetch_row($query_id);
+			return $cur_row[0];
+		}
+		else
+			return false;
+	}
+
+
+	function fetch_assoc($query_id = 0)
+	{
+		return ($query_id) ? @mysqli_fetch_assoc($query_id) : false;
+	}
+
+
+	function fetch_row($query_id = 0)
+	{
+		return ($query_id) ? @mysqli_fetch_row($query_id) : false;
+	}
+
+
+	function num_rows($query_id = 0)
+	{
+		return ($query_id) ? @mysqli_num_rows($query_id) : false;
+	}
+
+
+	function affected_rows()
+	{
+		return ($this->link_id) ? @mysqli_affected_rows($this->link_id) : false;
+	}
+
+
+	function insert_id()
+	{
+		return ($this->link_id) ? @mysqli_insert_id($this->link_id) : false;
+	}
+
+
+	function get_num_queries()
+	{
+		return $this->num_queries;
+	}
+
+
+	function get_saved_queries()
+	{
+		return $this->saved_queries;
+	}
+
+
+	function free_result($query_id = false)
+	{
+		return ($query_id) ? @mysqli_free_result($query_id) : false;
+	}
+
+
+	function escape($str)
+	{
+		return is_array($str) ? '' : mysqli_real_escape_string($this->link_id, $str);
+	}
+
+
+	function error()
+	{
+		$result['error_sql'] = @current(@end($this->saved_queries));
+		$result['error_no'] = @mysqli_errno($this->link_id);
+		$result['error_msg'] = @mysqli_error($this->link_id);
+
+		return $result;
+	}
+
+
+	function close()
+	{
+		if ($this->link_id)
+		{
+			if ($this->query_result)
+				@mysqli_free_result($this->query_result);
+
+			return @mysqli_close($this->link_id);
+		}
+		else
+			return false;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/dblayer/pgsql.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,264 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Make sure we have built in support for PostgreSQL
+if (!function_exists('pg_connect'))
+	exit('This PHP environment doesn\'t have PostgreSQL support built in. PostgreSQL support is required if you want to use a PostgreSQL database to run this forum. Consult the PHP documentation for further assistance.');
+
+
+class DBLayer
+{
+	var $prefix;
+	var $link_id;
+	var $query_result;
+	var $last_query_text = array();
+	var $in_transaction = 0;
+
+	var $saved_queries = array();
+	var $num_queries = 0;
+
+	var $error_no = false;
+	var $error_msg = 'Unknown';
+
+
+	function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect)
+	{
+		$this->prefix = $db_prefix;
+
+		if ($db_host != '')
+		{
+			if (strpos($db_host, ':') !== false)
+			{
+				list($db_host, $dbport) = explode(':', $db_host);
+				$connect_str[] = 'host='.$db_host.' port='.$dbport;
+			}
+			else
+			{
+				if ($db_host != 'localhost')
+					$connect_str[] = 'host='.$db_host;
+			}
+		}
+
+		if ($db_name)
+			$connect_str[] = 'dbname='.$db_name;
+
+		if ($db_username != '')
+			$connect_str[] = 'user='.$db_username;
+
+		if ($db_password != '')
+			$connect_str[] = 'password='.$db_password;
+
+		if ($p_connect)
+			$this->link_id = @pg_pconnect(implode(' ', $connect_str));
+		else
+			$this->link_id = @pg_connect(implode(' ', $connect_str));
+
+		if (!$this->link_id)
+			error('Unable to connect to PostgreSQL server', __FILE__, __LINE__);
+		else
+			return $this->link_id;
+	}
+
+
+	function start_transaction()
+	{
+		++$this->in_transaction;
+
+		return (@pg_query($this->link_id, 'BEGIN')) ? true : false;
+	}
+
+
+	function end_transaction()
+	{
+		--$this->in_transaction;
+
+		if (@pg_query($this->link_id, 'COMMIT'))
+			return true;
+		else
+		{
+			@pg_query($this->link_id, 'ROLLBACK');
+			return false;
+		}
+	}
+
+
+	function query($sql, $unbuffered = false)	// $unbuffered is ignored since there is no pgsql_unbuffered_query()
+	{
+		if (strrpos($sql, 'LIMIT') !== false)
+			$sql = preg_replace('#LIMIT ([0-9]+),([ 0-9]+)#', 'LIMIT \\2 OFFSET \\1', $sql);
+
+		if (defined('PUN_SHOW_QUERIES'))
+			$q_start = get_microtime();
+
+		@pg_send_query($this->link_id, $sql);
+		$this->query_result = @pg_get_result($this->link_id);
+
+		if (pg_result_status($this->query_result) != PGSQL_FATAL_ERROR)
+		{
+			if (defined('PUN_SHOW_QUERIES'))
+				$this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start));
+
+			++$this->num_queries;
+
+			$this->last_query_text[$this->query_result] = $sql;
+
+			return $this->query_result;
+		}
+		else
+		{
+			if (defined('PUN_SHOW_QUERIES'))
+				$this->saved_queries[] = array($sql, 0);
+
+			$this->error_msg = @pg_result_error($this->query_result);
+
+			if ($this->in_transaction)
+				@pg_query($this->link_id, 'ROLLBACK');
+
+			--$this->in_transaction;
+
+			return false;
+		}
+	}
+
+
+	function result($query_id = 0, $row = 0)
+	{
+		return ($query_id) ? @pg_fetch_result($query_id, $row, 0) : false;
+	}
+
+
+	function fetch_assoc($query_id = 0)
+	{
+		return ($query_id) ? @pg_fetch_assoc($query_id) : false;
+	}
+
+
+	function fetch_row($query_id = 0)
+	{
+		return ($query_id) ? @pg_fetch_row($query_id) : false;
+	}
+
+
+	function num_rows($query_id = 0)
+	{
+		return ($query_id) ? @pg_num_rows($query_id) : false;
+	}
+
+
+	function affected_rows()
+	{
+		return ($this->query_result) ? @pg_affected_rows($this->query_result) : false;
+	}
+
+
+	function insert_id()
+	{
+		$query_id = $this->query_result;
+
+		if ($query_id && $this->last_query_text[$query_id] != '')
+		{
+			if (preg_match('/^INSERT INTO ([a-z0-9\_\-]+)/is', $this->last_query_text[$query_id], $table_name))
+			{
+				// Hack (don't ask)
+				if (substr($table_name[1], -6) == 'groups')
+					$table_name[1] .= '_g';
+
+				$temp_q_id = @pg_query($this->link_id, 'SELECT currval(\''.$table_name[1].'_id_seq\')');
+				return ($temp_q_id) ? intval(@pg_fetch_result($temp_q_id, 0)) : false;
+			}
+		}
+
+		return false;
+	}
+
+
+	function get_num_queries()
+	{
+		return $this->num_queries;
+	}
+
+
+	function get_saved_queries()
+	{
+		return $this->saved_queries;
+	}
+
+
+	function free_result($query_id = false)
+	{
+		if (!$query_id)
+			$query_id = $this->query_result;
+
+		return ($query_id) ? @pg_free_result($query_id) : false;
+	}
+
+
+	function escape($str)
+	{
+		return is_array($str) ? '' : pg_escape_string($str);
+	}
+
+
+	function error()
+	{
+		$result['error_sql'] = @current(@end($this->saved_queries));
+		$result['error_no'] = false;
+/*
+		if (!empty($this->query_result))
+		{
+			$result['error_msg'] = trim(@pg_result_error($this->query_result));
+			if ($result['error_msg'] != '')
+				return $result;
+		}
+
+		$result['error_msg'] = (!empty($this->link_id)) ? trim(@pg_last_error($this->link_id)) : trim(@pg_last_error());
+*/
+		$result['error_msg'] = $this->error_msg;
+
+		return $result;
+	}
+
+
+	function close()
+	{
+		if ($this->link_id)
+		{
+			if ($this->in_transaction)
+			{
+				if (defined('PUN_SHOW_QUERIES'))
+					$this->saved_queries[] = array('COMMIT', 0);
+
+				@pg_query($this->link_id, 'COMMIT');
+			}
+
+			if ($this->query_result)
+				@pg_free_result($this->query_result);
+
+			return @pg_close($this->link_id);
+		}
+		else
+			return false;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/dblayer/sqlite.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,253 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Make sure we have built in support for SQLite
+if (!function_exists('sqlite_open'))
+	exit('This PHP environment doesn\'t have SQLite support built in. SQLite support is required if you want to use a SQLite database to run this forum. Consult the PHP documentation for further assistance.');
+
+
+class DBLayer
+{
+	var $prefix;
+	var $link_id;
+	var $query_result;
+	var $in_transaction = 0;
+
+	var $saved_queries = array();
+	var $num_queries = 0;
+
+	var $error_no = false;
+	var $error_msg = 'Unknown';
+
+
+	function DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, $p_connect)
+	{
+		// Prepend $db_name with the path to the forum root directory
+		$db_name = PUN_ROOT.$db_name;
+
+		$this->prefix = $db_prefix;
+
+		if (!file_exists($db_name))
+		{
+			@touch($db_name);
+			@chmod($db_name, 0666);
+			if (!file_exists($db_name))
+				error('Unable to create new database \''.$db_name.'\'. Permission denied', __FILE__, __LINE__);
+		}
+
+		if (!is_readable($db_name))
+			error('Unable to open database \''.$db_name.'\' for reading. Permission denied', __FILE__, __LINE__);
+
+		if (!is_writable($db_name))
+			error('Unable to open database \''.$db_name.'\' for writing. Permission denied', __FILE__, __LINE__);
+
+		if ($p_connect)
+			$this->link_id = @sqlite_popen($db_name, 0666, $sqlite_error);
+		else
+			$this->link_id = @sqlite_open($db_name, 0666, $sqlite_error);
+
+		if (!$this->link_id)
+			error('Unable to open database \''.$db_name.'\'. SQLite reported: '.$sqlite_error, __FILE__, __LINE__);
+		else
+			return $this->link_id;
+	}
+
+
+	function start_transaction()
+	{
+		++$this->in_transaction;
+
+		return (@sqlite_query($this->link_id, 'BEGIN')) ? true : false;
+	}
+
+
+	function end_transaction()
+	{
+		--$this->in_transaction;
+
+		if (@sqlite_query($this->link_id, 'COMMIT'))
+			return true;
+		else
+		{
+			@sqlite_query($this->link_id, 'ROLLBACK');
+			return false;
+		}
+	}
+
+
+	function query($sql, $unbuffered = false)
+	{
+		if (defined('PUN_SHOW_QUERIES'))
+			$q_start = get_microtime();
+
+		if ($unbuffered)
+			$this->query_result = @sqlite_unbuffered_query($this->link_id, $sql);
+		else
+			$this->query_result = @sqlite_query($this->link_id, $sql);
+
+		if ($this->query_result)
+		{
+			if (defined('PUN_SHOW_QUERIES'))
+				$this->saved_queries[] = array($sql, sprintf('%.5f', get_microtime() - $q_start));
+
+			++$this->num_queries;
+
+			return $this->query_result;
+		}
+		else
+		{
+			if (defined('PUN_SHOW_QUERIES'))
+				$this->saved_queries[] = array($sql, 0);
+
+			$this->error_no = @sqlite_last_error($this->link_id);
+			$this->error_msg = @sqlite_error_string($this->error_no);
+
+			if ($this->in_transaction)
+				@sqlite_query($this->link_id, 'ROLLBACK');
+
+			--$this->in_transaction;
+
+			return false;
+		}
+	}
+
+
+	function result($query_id = 0, $row = 0)
+	{
+		if ($query_id)
+		{
+			if ($row != 0)
+				@sqlite_seek($query_id, $row);
+
+			return @current(@sqlite_current($query_id));
+		}
+		else
+			return false;
+	}
+
+
+	function fetch_assoc($query_id = 0)
+	{
+		if ($query_id)
+		{
+			$cur_row = @sqlite_fetch_array($query_id, SQLITE_ASSOC);
+			if ($cur_row)
+			{
+				// Horrible hack to get rid of table names and table aliases from the array keys
+				while (list($key, $value) = @each($cur_row))
+				{
+				    $dot_spot = strpos($key, '.');
+				    if ($dot_spot !== false)
+				    {
+				        unset($cur_row[$key]);
+				        $key = substr($key, $dot_spot+1);
+				        $cur_row[$key] = $value;
+				    }
+				}
+			}
+
+			return $cur_row;
+		}
+		else
+			return false;
+	}
+
+
+	function fetch_row($query_id = 0)
+	{
+		return ($query_id) ? @sqlite_fetch_array($query_id, SQLITE_NUM) : false;
+	}
+
+
+	function num_rows($query_id = 0)
+	{
+		return ($query_id) ? @sqlite_num_rows($query_id) : false;
+	}
+
+
+	function affected_rows()
+	{
+		return ($this->query_result) ? @sqlite_changes($this->query_result) : false;
+	}
+
+
+	function insert_id()
+	{
+		return ($this->link_id) ? @sqlite_last_insert_rowid($this->link_id) : false;
+	}
+
+
+	function get_num_queries()
+	{
+		return $this->num_queries;
+	}
+
+
+	function get_saved_queries()
+	{
+		return $this->saved_queries;
+	}
+
+
+	function free_result($query_id = false)
+	{
+		return true;
+	}
+
+
+	function escape($str)
+	{
+		return is_array($str) ? '' : sqlite_escape_string($str);
+	}
+
+
+	function error()
+	{
+		$result['error_sql'] = @current(@end($this->saved_queries));
+		$result['error_no'] = $this->error_no;
+		$result['error_msg'] = $this->error_msg;
+
+		return $result;
+	}
+
+
+	function close()
+	{
+		if ($this->link_id)
+		{
+			if ($this->in_transaction)
+			{
+				if (defined('PUN_SHOW_QUERIES'))
+					$this->saved_queries[] = array('COMMIT', 0);
+
+				@sqlite_query($this->link_id, 'COMMIT');
+			}
+
+			return @sqlite_close($this->link_id);
+		}
+		else
+			return false;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/email.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,186 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// Make sure no one attempts to run this script "directly"
+if (!defined('PUN'))
+	exit;
+
+
+//
+// Validate an e-mail address
+//
+function is_valid_email($email)
+{
+	if (strlen($email) > 50)
+		return false;
+
+	return preg_match('/^(([^<>()[\]\\.,;:\s@"\']+(\.[^<>()[\]\\.,;:\s@"\']+)*)|("[^"\']+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email);
+}
+
+
+//
+// Check if $email is banned
+//
+function is_banned_email($email)
+{
+	global $db, $pun_bans;
+
+	foreach ($pun_bans as $cur_ban)
+	{
+		if ($cur_ban['email'] != '' &&
+			($email == $cur_ban['email'] ||
+			(strpos($cur_ban['email'], '@') === false && stristr($email, '@'.$cur_ban['email']))))
+			return true;
+	}
+
+	return false;
+}
+
+
+//
+// Wrapper for PHP's mail()
+//
+function pun_mail($to, $subject, $message, $from = '')
+{
+	global $pun_config, $lang_common;
+
+	// Default sender/return address
+	if (!$from)
+		$from = '"'.str_replace('"', '', $pun_config['o_board_title'].' '.$lang_common['Mailer']).'" <'.$pun_config['o_webmaster_email'].'>';
+
+	// Do a little spring cleaning
+	$to = trim(preg_replace('#[\n\r]+#s', '', $to));
+	$subject = trim(preg_replace('#[\n\r]+#s', '', $subject));
+	$from = trim(preg_replace('#[\n\r:]+#s', '', $from));
+
+	$headers = 'From: '.$from."\r\n".'Date: '.date('r')."\r\n".'MIME-Version: 1.0'."\r\n".'Content-transfer-encoding: 8bit'."\r\n".'Content-type: text/plain; charset='.$lang_common['lang_encoding']."\r\n".'X-Mailer: PunBB Mailer';
+
+	// Make sure all linebreaks are CRLF in message (and strip out any NULL bytes)
+	$message = str_replace(array("\n", "\0"), array("\r\n", ''), pun_linebreaks($message));
+
+	if ($pun_config['o_smtp_host'] != '')
+		smtp_mail($to, $subject, $message, $headers);
+	else
+	{
+		// Change the linebreaks used in the headers according to OS
+		if (strtoupper(substr(PHP_OS, 0, 3)) == 'MAC')
+			$headers = str_replace("\r\n", "\r", $headers);
+		else if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN')
+			$headers = str_replace("\r\n", "\n", $headers);
+
+		mail($to, $subject, $message, $headers);
+	}
+}
+
+
+//
+// This function was originally a part of the phpBB Group forum software phpBB2 (http://www.phpbb.com).
+// They deserve all the credit for writing it. I made small modifications for it to suit PunBB and it's coding standards.
+//
+function server_parse($socket, $expected_response)
+{
+	$server_response = '';
+	while (substr($server_response, 3, 1) != ' ')
+	{
+		if (!($server_response = fgets($socket, 256)))
+			error('Couldn\'t get mail server response codes. Please contact the forum administrator.', __FILE__, __LINE__);
+	}
+
+	if (!(substr($server_response, 0, 3) == $expected_response))
+		error('Unable to send e-mail. Please contact the forum administrator with the following error message reported by the SMTP server: "'.$server_response.'"', __FILE__, __LINE__);
+}
+
+
+//
+// This function was originally a part of the phpBB Group forum software phpBB2 (http://www.phpbb.com).
+// They deserve all the credit for writing it. I made small modifications for it to suit PunBB and it's coding standards.
+//
+function smtp_mail($to, $subject, $message, $headers = '')
+{
+	global $pun_config;
+
+	$recipients = explode(',', $to);
+
+	// Are we using port 25 or a custom port?
+	if (strpos($pun_config['o_smtp_host'], ':') !== false)
+		list($smtp_host, $smtp_port) = explode(':', $pun_config['o_smtp_host']);
+	else
+	{
+		$smtp_host = $pun_config['o_smtp_host'];
+		$smtp_port = 25;
+	}
+
+	if (!($socket = fsockopen($smtp_host, $smtp_port, $errno, $errstr, 15)))
+		error('Could not connect to smtp host "'.$pun_config['o_smtp_host'].'" ('.$errno.') ('.$errstr.')', __FILE__, __LINE__);
+
+	server_parse($socket, '220');
+
+	if ($pun_config['o_smtp_user'] != '' && $pun_config['o_smtp_pass'] != '')
+	{
+		fwrite($socket, 'EHLO '.$smtp_host."\r\n");
+		server_parse($socket, '250');
+
+		fwrite($socket, 'AUTH LOGIN'."\r\n");
+		server_parse($socket, '334');
+
+		fwrite($socket, base64_encode($pun_config['o_smtp_user'])."\r\n");
+		server_parse($socket, '334');
+
+		fwrite($socket, base64_encode($pun_config['o_smtp_pass'])."\r\n");
+		server_parse($socket, '235');
+	}
+	else
+	{
+		fwrite($socket, 'HELO '.$smtp_host."\r\n");
+		server_parse($socket, '250');
+	}
+
+	fwrite($socket, 'MAIL FROM: <'.$pun_config['o_webmaster_email'].'>'."\r\n");
+	server_parse($socket, '250');
+
+	$to_header = 'To: ';
+
+	@reset($recipients);
+	while (list(, $email) = @each($recipients))
+	{
+		fwrite($socket, 'RCPT TO: <'.$email.'>'."\r\n");
+		server_parse($socket, '250');
+
+		$to_header .= '<'.$email.'>, ';
+	}
+
+	fwrite($socket, 'DATA'."\r\n");
+	server_parse($socket, '354');
+
+	fwrite($socket, 'Subject: '.$subject."\r\n".$to_header."\r\n".$headers."\r\n\r\n".$message."\r\n");
+
+	fwrite($socket, '.'."\r\n");
+	server_parse($socket, '250');
+
+	fwrite($socket, 'QUIT'."\r\n");
+	fclose($socket);
+
+	return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/functions.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,1110 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+//
+// Cookie stuff!
+//
+function check_cookie(&$pun_user)
+{
+	global $db, $db_type, $pun_config, $cookie_name, $cookie_seed;
+
+	$now = time();
+	$expire = $now + 31536000;	// The cookie expires after a year
+
+	// We assume it's a guest
+	$cookie = array('user_id' => 1, 'password_hash' => 'Guest');
+
+	// If a cookie is set, we get the user_id and password hash from it
+	if (isset($_COOKIE[$cookie_name]))
+		list($cookie['user_id'], $cookie['password_hash']) = @unserialize($_COOKIE[$cookie_name]);
+
+	if ($cookie['user_id'] > 1)
+	{
+		// Check if there's a user with the user ID and password hash from the cookie
+		$result = $db->query('SELECT u.*, g.*, o.logged, o.idle FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.user_id=u.id WHERE u.id='.intval($cookie['user_id'])) or error('Unable to fetch user information', __FILE__, __LINE__, $db->error());
+		$pun_user = $db->fetch_assoc($result);
+
+		// If user authorisation failed
+		if (!isset($pun_user['id']) || md5($cookie_seed.$pun_user['password']) !== $cookie['password_hash'])
+		{
+			pun_setcookie(0, random_pass(8), $expire);
+			set_default_user();
+
+			return;
+		}
+
+		// Set a default language if the user selected language no longer exists
+		if (!@file_exists(PUN_ROOT.'lang/'.$pun_user['language']))
+			$pun_user['language'] = $pun_config['o_default_lang'];
+
+		// Set a default style if the user selected style no longer exists
+		if (!@file_exists(PUN_ROOT.'style/'.$pun_user['style'].'.css'))
+			$pun_user['style'] = $pun_config['o_default_style'];
+
+		if (!$pun_user['disp_topics'])
+			$pun_user['disp_topics'] = $pun_config['o_disp_topics_default'];
+		if (!$pun_user['disp_posts'])
+			$pun_user['disp_posts'] = $pun_config['o_disp_posts_default'];
+
+		if ($pun_user['save_pass'] == '0')
+			$expire = 0;
+
+		// Define this if you want this visit to affect the online list and the users last visit data
+		if (!defined('PUN_QUIET_VISIT'))
+		{
+			// Update the online list
+			if (!$pun_user['logged'])
+			{
+				$pun_user['logged'] = $now;
+
+				// With MySQL/MySQLi, REPLACE INTO avoids a user having two rows in the online table
+				switch ($db_type)
+				{
+					case 'mysql':
+					case 'mysqli':
+						$db->query('REPLACE INTO '.$db->prefix.'online (user_id, ident, logged) VALUES('.$pun_user['id'].', \''.$db->escape($pun_user['username']).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error());
+						break;
+
+					default:
+						$db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) VALUES('.$pun_user['id'].', \''.$db->escape($pun_user['username']).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error());
+						break;
+				}
+			}
+			else
+			{
+				// Special case: We've timed out, but no other user has browsed the forums since we timed out
+				if ($pun_user['logged'] < ($now-$pun_config['o_timeout_visit']))
+				{
+					$db->query('UPDATE '.$db->prefix.'users SET last_visit='.$pun_user['logged'].' WHERE id='.$pun_user['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error());
+					$pun_user['last_visit'] = $pun_user['logged'];
+				}
+
+				$idle_sql = ($pun_user['idle'] == '1') ? ', idle=0' : '';
+				$db->query('UPDATE '.$db->prefix.'online SET logged='.$now.$idle_sql.' WHERE user_id='.$pun_user['id']) or error('Unable to update online list', __FILE__, __LINE__, $db->error());
+			}
+		}
+
+		$pun_user['is_guest'] = false;
+	}
+	else
+		set_default_user();
+}
+
+
+//
+// Fill $pun_user with default values (for guests)
+//
+function set_default_user()
+{
+	global $db, $db_type, $pun_user, $pun_config;
+
+	$remote_addr = get_remote_address();
+
+	// Fetch guest user
+	$result = $db->query('SELECT u.*, g.*, o.logged FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'groups AS g ON u.group_id=g.g_id LEFT JOIN '.$db->prefix.'online AS o ON o.ident=\''.$remote_addr.'\' WHERE u.id=1') or error('Unable to fetch guest information', __FILE__, __LINE__, $db->error());
+	if (!$db->num_rows($result))
+		exit('Unable to fetch guest information. The table \''.$db->prefix.'users\' must contain an entry with id = 1 that represents anonymous users.');
+
+	$pun_user = $db->fetch_assoc($result);
+
+	// Update online list
+	if (!$pun_user['logged'])
+	{
+		$pun_user['logged'] = time();
+
+		// With MySQL/MySQLi, REPLACE INTO avoids a user having two rows in the online table
+		switch ($db_type)
+		{
+			case 'mysql':
+			case 'mysqli':
+				$db->query('REPLACE INTO '.$db->prefix.'online (user_id, ident, logged) VALUES(1, \''.$db->escape($remote_addr).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error());
+				break;
+
+			default:
+				$db->query('INSERT INTO '.$db->prefix.'online (user_id, ident, logged) VALUES(1, \''.$db->escape($remote_addr).'\', '.$pun_user['logged'].')') or error('Unable to insert into online list', __FILE__, __LINE__, $db->error());
+				break;
+		}
+	}
+	else
+		$db->query('UPDATE '.$db->prefix.'online SET logged='.time().' WHERE ident=\''.$db->escape($remote_addr).'\'') or error('Unable to update online list', __FILE__, __LINE__, $db->error());
+
+	$pun_user['disp_topics'] = $pun_config['o_disp_topics_default'];
+	$pun_user['disp_posts'] = $pun_config['o_disp_posts_default'];
+	$pun_user['timezone'] = $pun_config['o_server_timezone'];
+	$pun_user['language'] = $pun_config['o_default_lang'];
+	$pun_user['style'] = $pun_config['o_default_style'];
+	$pun_user['is_guest'] = true;
+}
+
+
+//
+// Set a cookie, PunBB style!
+//
+function pun_setcookie($user_id, $password_hash, $expire)
+{
+	global $cookie_name, $cookie_path, $cookie_domain, $cookie_secure, $cookie_seed;
+
+	// Enable sending of a P3P header by removing // from the following line (try this if login is failing in IE6)
+//	@header('P3P: CP="CUR ADM"');
+
+	if (version_compare(PHP_VERSION, '5.2.0', '>='))
+		setcookie($cookie_name, serialize(array($user_id, md5($cookie_seed.$password_hash))), $expire, $cookie_path, $cookie_domain, $cookie_secure, true);
+	else
+		setcookie($cookie_name, serialize(array($user_id, md5($cookie_seed.$password_hash))), $expire, $cookie_path.'; HttpOnly', $cookie_domain, $cookie_secure);
+}
+
+
+//
+// Check whether the connecting user is banned (and delete any expired bans while we're at it)
+//
+function check_bans()
+{
+	global $db, $pun_config, $lang_common, $pun_user, $pun_bans;
+
+	// Admins aren't affected
+	if ($pun_user['g_id'] == PUN_ADMIN || !$pun_bans)
+		return;
+
+	// Add a dot at the end of the IP address to prevent banned address 192.168.0.5 from matching e.g. 192.168.0.50
+	$user_ip = get_remote_address().'.';
+	$bans_altered = false;
+
+	foreach ($pun_bans as $cur_ban)
+	{
+		// Has this ban expired?
+		if ($cur_ban['expire'] != '' && $cur_ban['expire'] <= time())
+		{
+			$db->query('DELETE FROM '.$db->prefix.'bans WHERE id='.$cur_ban['id']) or error('Unable to delete expired ban', __FILE__, __LINE__, $db->error());
+			$bans_altered = true;
+			continue;
+		}
+
+		if ($cur_ban['username'] != '' && !strcasecmp($pun_user['username'], $cur_ban['username']))
+		{
+			$db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($pun_user['username']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error());
+			message($lang_common['Ban message'].' '.(($cur_ban['expire'] != '') ? $lang_common['Ban message 2'].' '.strtolower(format_time($cur_ban['expire'], true)).'. ' : '').(($cur_ban['message'] != '') ? $lang_common['Ban message 3'].'<br /><br /><strong>'.pun_htmlspecialchars($cur_ban['message']).'</strong><br /><br />' : '<br /><br />').$lang_common['Ban message 4'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.', true);
+		}
+
+		if ($cur_ban['ip'] != '')
+		{
+			$cur_ban_ips = explode(' ', $cur_ban['ip']);
+
+			for ($i = 0; $i < count($cur_ban_ips); ++$i)
+			{
+				$cur_ban_ips[$i] = $cur_ban_ips[$i].'.';
+
+				if (substr($user_ip, 0, strlen($cur_ban_ips[$i])) == $cur_ban_ips[$i])
+				{
+					$db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($pun_user['username']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error());
+					message($lang_common['Ban message'].' '.(($cur_ban['expire'] != '') ? $lang_common['Ban message 2'].' '.strtolower(format_time($cur_ban['expire'], true)).'. ' : '').(($cur_ban['message'] != '') ? $lang_common['Ban message 3'].'<br /><br /><strong>'.pun_htmlspecialchars($cur_ban['message']).'</strong><br /><br />' : '<br /><br />').$lang_common['Ban message 4'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.', true);
+				}
+			}
+		}
+	}
+
+	// If we removed any expired bans during our run-through, we need to regenerate the bans cache
+	if ($bans_altered)
+	{
+		require_once PUN_ROOT.'include/cache.php';
+		generate_bans_cache();
+	}
+}
+
+
+//
+// Update "Users online"
+//
+function update_users_online()
+{
+	global $db, $pun_config, $pun_user;
+
+	$now = time();
+
+	// Fetch all online list entries that are older than "o_timeout_online"
+	$result = $db->query('SELECT * FROM '.$db->prefix.'online WHERE logged<'.($now-$pun_config['o_timeout_online'])) or error('Unable to fetch old entries from online list', __FILE__, __LINE__, $db->error());
+	while ($cur_user = $db->fetch_assoc($result))
+	{
+		// If the entry is a guest, delete it
+		if ($cur_user['user_id'] == '1')
+			$db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape($cur_user['ident']).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error());
+		else
+		{
+			// If the entry is older than "o_timeout_visit", update last_visit for the user in question, then delete him/her from the online list
+			if ($cur_user['logged'] < ($now-$pun_config['o_timeout_visit']))
+			{
+				$db->query('UPDATE '.$db->prefix.'users SET last_visit='.$cur_user['logged'].' WHERE id='.$cur_user['user_id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error());
+				$db->query('DELETE FROM '.$db->prefix.'online WHERE user_id='.$cur_user['user_id']) or error('Unable to delete from online list', __FILE__, __LINE__, $db->error());
+			}
+			else if ($cur_user['idle'] == '0')
+				$db->query('UPDATE '.$db->prefix.'online SET idle=1 WHERE user_id='.$cur_user['user_id']) or error('Unable to insert into online list', __FILE__, __LINE__, $db->error());
+		}
+	}
+}
+
+
+//
+// Generate the "navigator" that appears at the top of every page
+//
+function generate_navlinks()
+{
+	global $pun_config, $lang_common, $pun_user;
+
+	// Index and Userlist should always be displayed
+	$links[] = '<li id="navindex"><a href="index.php">'.$lang_common['Index'].'</a>';
+	$links[] = '<li id="navuserlist"><a href="userlist.php">'.$lang_common['User list'].'</a>';
+
+	if ($pun_config['o_rules'] == '1')
+		$links[] = '<li id="navrules"><a href="misc.php?action=rules">'.$lang_common['Rules'].'</a>';
+
+	if ($pun_user['is_guest'])
+	{
+		if ($pun_user['g_search'] == '1')
+			$links[] = '<li id="navsearch"><a href="search.php">'.$lang_common['Search'].'</a>';
+
+		$links[] = '<li id="navregister"><a href="register.php">'.$lang_common['Register'].'</a>';
+		$links[] = '<li id="navlogin"><a href="login.php">'.$lang_common['Login'].'</a>';
+
+		$info = $lang_common['Not logged in'];
+	}
+	else
+	{
+		if ($pun_user['g_id'] > PUN_MOD)
+		{
+			if ($pun_user['g_search'] == '1')
+				$links[] = '<li id="navsearch"><a href="search.php">'.$lang_common['Search'].'</a>';
+
+			$links[] = '<li id="navprofile"><a href="profile.php?id='.$pun_user['id'].'">'.$lang_common['Profile'].'</a>';
+			$links[] = '<li id="navlogout"><a href="login.php?action=out&amp;id='.$pun_user['id'].'">'.$lang_common['Logout'].'</a>';
+		}
+		else
+		{
+			$links[] = '<li id="navsearch"><a href="search.php">'.$lang_common['Search'].'</a>';
+			$links[] = '<li id="navprofile"><a href="profile.php?id='.$pun_user['id'].'">'.$lang_common['Profile'].'</a>';
+			$links[] = '<li id="navadmin"><a href="admin_index.php">'.$lang_common['Admin'].'</a>';
+			$links[] = '<li id="navlogout"><a href="login.php?action=out&amp;id='.$pun_user['id'].'">'.$lang_common['Logout'].'</a>';
+		}
+	}
+
+	// Are there any additional navlinks we should insert into the array before imploding it?
+	if ($pun_config['o_additional_navlinks'] != '')
+	{
+		if (preg_match_all('#([0-9]+)\s*=\s*(.*?)\n#s', $pun_config['o_additional_navlinks']."\n", $extra_links))
+		{
+			// Insert any additional links into the $links array (at the correct index)
+			for ($i = 0; $i < count($extra_links[1]); ++$i)
+				array_splice($links, $extra_links[1][$i], 0, array('<li id="navextra'.($i + 1).'">'.$extra_links[2][$i]));
+		}
+	}
+
+	return '<ul>'."\n\t\t\t\t".implode($lang_common['Link separator'].'</li>'."\n\t\t\t\t", $links).'</li>'."\n\t\t\t".'</ul>';
+}
+
+
+//
+// Display the profile navigation menu
+//
+function generate_profile_menu($page = '')
+{
+	global $lang_profile, $pun_config, $pun_user, $id;
+
+?>
+<div id="profile" class="block2col">
+	<div class="blockmenu">
+		<h2><span><?php echo $lang_profile['Profile menu'] ?></span></h2>
+		<div class="box">
+			<div class="inbox">
+				<ul>
+					<li<?php if ($page == 'essentials') echo ' class="isactive"'; ?>><a href="profile.php?section=essentials&amp;id=<?php echo $id ?>"><?php echo $lang_profile['Section essentials'] ?></a></li>
+					<li<?php if ($page == 'personal') echo ' class="isactive"'; ?>><a href="profile.php?section=personal&amp;id=<?php echo $id ?>"><?php echo $lang_profile['Section personal'] ?></a></li>
+					<li<?php if ($page == 'messaging') echo ' class="isactive"'; ?>><a href="profile.php?section=messaging&amp;id=<?php echo $id ?>"><?php echo $lang_profile['Section messaging'] ?></a></li>
+					<li<?php if ($page == 'personality') echo ' class="isactive"'; ?>><a href="profile.php?section=personality&amp;id=<?php echo $id ?>"><?php echo $lang_profile['Section personality'] ?></a></li>
+					<li<?php if ($page == 'display') echo ' class="isactive"'; ?>><a href="profile.php?section=display&amp;id=<?php echo $id ?>"><?php echo $lang_profile['Section display'] ?></a></li>
+					<li<?php if ($page == 'privacy') echo ' class="isactive"'; ?>><a href="profile.php?section=privacy&amp;id=<?php echo $id ?>"><?php echo $lang_profile['Section privacy'] ?></a></li>
+<?php if ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_ban_users'] == '1')): ?>					<li<?php if ($page == 'admin') echo ' class="isactive"'; ?>><a href="profile.php?section=admin&amp;id=<?php echo $id ?>"><?php echo $lang_profile['Section admin'] ?></a></li>
+<?php endif; ?>				</ul>
+			</div>
+		</div>
+	</div>
+<?php
+
+}
+
+
+//
+// Update posts, topics, last_post, last_post_id and last_poster for a forum (redirect topics are not included)
+//
+function update_forum($forum_id)
+{
+	global $db;
+
+	$result = $db->query('SELECT COUNT(id), SUM(num_replies) FROM '.$db->prefix.'topics WHERE moved_to IS NULL AND forum_id='.$forum_id) or error('Unable to fetch forum topic count', __FILE__, __LINE__, $db->error());
+	list($num_topics, $num_posts) = $db->fetch_row($result);
+
+	$num_posts = $num_posts + $num_topics;		// $num_posts is only the sum of all replies (we have to add the topic posts)
+
+	$result = $db->query('SELECT last_post, last_post_id, last_poster FROM '.$db->prefix.'topics WHERE forum_id='.$forum_id.' AND moved_to IS NULL ORDER BY last_post DESC LIMIT 1') or error('Unable to fetch last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error());
+	if ($db->num_rows($result))		// There are topics in the forum
+	{
+		list($last_post, $last_post_id, $last_poster) = $db->fetch_row($result);
+
+		$db->query('UPDATE '.$db->prefix.'forums SET num_topics='.$num_topics.', num_posts='.$num_posts.', last_post='.$last_post.', last_post_id='.$last_post_id.', last_poster=\''.$db->escape($last_poster).'\' WHERE id='.$forum_id) or error('Unable to update last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error());
+	}
+	else	// There are no topics
+		$db->query('UPDATE '.$db->prefix.'forums SET num_topics=0, num_posts=0, last_post=NULL, last_post_id=NULL, last_poster=NULL WHERE id='.$forum_id) or error('Unable to update last_post/last_post_id/last_poster', __FILE__, __LINE__, $db->error());
+}
+
+
+//
+// Delete a topic and all of it's posts
+//
+function delete_topic($topic_id)
+{
+	global $db;
+
+	// Delete the topic and any redirect topics
+	$db->query('DELETE FROM '.$db->prefix.'topics WHERE id='.$topic_id.' OR moved_to='.$topic_id) or error('Unable to delete topic', __FILE__, __LINE__, $db->error());
+
+	// Create a list of the post ID's in this topic
+	$post_ids = '';
+	$result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error());
+	while ($row = $db->fetch_row($result))
+		$post_ids .= ($post_ids != '') ? ','.$row[0] : $row[0];
+
+	// Make sure we have a list of post ID's
+	if ($post_ids != '')
+	{
+		strip_search_index($post_ids);
+
+		// Delete posts in topic
+		$db->query('DELETE FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to delete posts', __FILE__, __LINE__, $db->error());
+	}
+
+	// Delete any subscriptions for this topic
+	$db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id='.$topic_id) or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error());
+}
+
+
+//
+// Delete a single post
+//
+function delete_post($post_id, $topic_id)
+{
+	global $db;
+
+	$result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id.' ORDER BY id DESC LIMIT 2') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+	list($last_id, ,) = $db->fetch_row($result);
+	list($second_last_id, $second_poster, $second_posted) = $db->fetch_row($result);
+
+	// Delete the post
+	$db->query('DELETE FROM '.$db->prefix.'posts WHERE id='.$post_id) or error('Unable to delete post', __FILE__, __LINE__, $db->error());
+
+	strip_search_index($post_id);
+
+	// Count number of replies in the topic
+	$result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'posts WHERE topic_id='.$topic_id) or error('Unable to fetch post count for topic', __FILE__, __LINE__, $db->error());
+	$num_replies = $db->result($result, 0) - 1;
+
+	// If the message we deleted is the most recent in the topic (at the end of the topic)
+	if ($last_id == $post_id)
+	{
+		// If there is a $second_last_id there is more than 1 reply to the topic
+		if (!empty($second_last_id))
+			$db->query('UPDATE '.$db->prefix.'topics SET last_post='.$second_posted.', last_post_id='.$second_last_id.', last_poster=\''.$db->escape($second_poster).'\', num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
+		else
+			// We deleted the only reply, so now last_post/last_post_id/last_poster is posted/id/poster from the topic itself
+			$db->query('UPDATE '.$db->prefix.'topics SET last_post=posted, last_post_id=id, last_poster=poster, num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
+	}
+	else
+		// Otherwise we just decrement the reply counter
+		$db->query('UPDATE '.$db->prefix.'topics SET num_replies='.$num_replies.' WHERE id='.$topic_id) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
+}
+
+
+//
+// Replace censored words in $text
+//
+function censor_words($text)
+{
+	global $db;
+	static $search_for, $replace_with;
+
+	// If not already built in a previous call, build an array of censor words and their replacement text
+	if (!isset($search_for))
+	{
+		$result = $db->query('SELECT search_for, replace_with FROM '.$db->prefix.'censoring') or error('Unable to fetch censor word list', __FILE__, __LINE__, $db->error());
+		$num_words = $db->num_rows($result);
+
+		$search_for = array();
+		for ($i = 0; $i < $num_words; ++$i)
+		{
+			list($search_for[$i], $replace_with[$i]) = $db->fetch_row($result);
+			$search_for[$i] = '/\b('.str_replace('\*', '\w*?', preg_quote($search_for[$i], '/')).')\b/i';
+		}
+	}
+
+	if (!empty($search_for))
+		$text = substr(preg_replace($search_for, $replace_with, ' '.$text.' '), 1, -1);
+
+	return $text;
+}
+
+
+//
+// Determines the correct title for $user
+// $user must contain the elements 'username', 'title', 'posts', 'g_id' and 'g_user_title'
+//
+function get_title($user)
+{
+	global $db, $pun_config, $pun_bans, $lang_common;
+	static $ban_list, $pun_ranks;
+
+	// If not already built in a previous call, build an array of lowercase banned usernames
+	if (empty($ban_list))
+	{
+		$ban_list = array();
+
+		foreach ($pun_bans as $cur_ban)
+			$ban_list[] = strtolower($cur_ban['username']);
+	}
+
+	// If not already loaded in a previous call, load the cached ranks
+	if ($pun_config['o_ranks'] == '1' && empty($pun_ranks))
+	{
+		@include PUN_ROOT.'cache/cache_ranks.php';
+		if (!defined('PUN_RANKS_LOADED'))
+		{
+			require_once PUN_ROOT.'include/cache.php';
+			generate_ranks_cache();
+			require PUN_ROOT.'cache/cache_ranks.php';
+		}
+	}
+
+	// If the user has a custom title
+	if ($user['title'] != '')
+		$user_title = pun_htmlspecialchars($user['title']);
+	// If the user is banned
+	else if (in_array(strtolower($user['username']), $ban_list))
+		$user_title = $lang_common['Banned'];
+	// If the user group has a default user title
+	else if ($user['g_user_title'] != '')
+		$user_title = pun_htmlspecialchars($user['g_user_title']);
+	// If the user is a guest
+	else if ($user['g_id'] == PUN_GUEST)
+		$user_title = $lang_common['Guest'];
+	else
+	{
+		// Are there any ranks?
+		if ($pun_config['o_ranks'] == '1' && !empty($pun_ranks))
+		{
+			@reset($pun_ranks);
+			while (list(, $cur_rank) = @each($pun_ranks))
+			{
+				if (intval($user['num_posts']) >= $cur_rank['min_posts'])
+					$user_title = pun_htmlspecialchars($cur_rank['rank']);
+			}
+		}
+
+		// If the user didn't "reach" any rank (or if ranks are disabled), we assign the default
+		if (!isset($user_title))
+			$user_title = $lang_common['Member'];
+	}
+
+	return $user_title;
+}
+
+
+//
+// Generate a string with numbered links (for multipage scripts)
+//
+function paginate($num_pages, $cur_page, $link_to)
+{
+	$pages = array();
+	$link_to_all = false;
+
+	// If $cur_page == -1, we link to all pages (used in viewforum.php)
+	if ($cur_page == -1)
+	{
+		$cur_page = 1;
+		$link_to_all = true;
+	}
+
+	if ($num_pages <= 1)
+		$pages = array('<strong>1</strong>');
+	else
+	{
+		if ($cur_page > 3)
+		{
+			$pages[] = '<a href="'.$link_to.'&amp;p=1">1</a>';
+
+			if ($cur_page != 4)
+				$pages[] = '&hellip;';
+		}
+
+		// Don't ask me how the following works. It just does, OK? :-)
+		for ($current = $cur_page - 2, $stop = $cur_page + 3; $current < $stop; ++$current)
+		{
+			if ($current < 1 || $current > $num_pages)
+				continue;
+			else if ($current != $cur_page || $link_to_all)
+				$pages[] = '<a href="'.$link_to.'&amp;p='.$current.'">'.$current.'</a>';
+			else
+				$pages[] = '<strong>'.$current.'</strong>';
+		}
+
+		if ($cur_page <= ($num_pages-3))
+		{
+			if ($cur_page != ($num_pages-3))
+				$pages[] = '&hellip;';
+
+			$pages[] = '<a href="'.$link_to.'&amp;p='.$num_pages.'">'.$num_pages.'</a>';
+		}
+	}
+
+	return implode('&nbsp;', $pages);
+}
+
+
+//
+// Display a message
+//
+function message($message, $no_back_link = false)
+{
+	global $db, $lang_common, $pun_config, $pun_start, $tpl_main;
+
+	if (!defined('PUN_HEADER'))
+	{
+		global $pun_user;
+
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Info'];
+		require PUN_ROOT.'header.php';
+	}
+
+?>
+
+<div id="msg" class="block">
+	<h2><span><?php echo $lang_common['Info'] ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+		<p><?php echo $message ?></p>
+<?php if (!$no_back_link): ?>		<p><a href="javascript: history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+<?php endif; ?>		</div>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+//
+// Format a time string according to $time_format and timezones
+//
+function format_time($timestamp, $date_only = false)
+{
+	global $pun_config, $lang_common, $pun_user;
+
+	if ($timestamp == '')
+		return $lang_common['Never'];
+
+	$diff = ($pun_user['timezone'] - $pun_config['o_server_timezone']) * 3600;
+	$timestamp += $diff;
+	$now = time();
+
+	$date = date($pun_config['o_date_format'], $timestamp);
+	$today = date($pun_config['o_date_format'], $now+$diff);
+	$yesterday = date($pun_config['o_date_format'], $now+$diff-86400);
+
+	if ($date == $today)
+		$date = $lang_common['Today'];
+	else if ($date == $yesterday)
+		$date = $lang_common['Yesterday'];
+
+	if (!$date_only)
+		return $date.' '.date($pun_config['o_time_format'], $timestamp);
+	else
+		return $date;
+}
+
+
+//
+// If we are running pre PHP 4.3.0, we add our own implementation of file_get_contents
+//
+if (!function_exists('file_get_contents'))
+{
+	function file_get_contents($filename, $use_include_path = 0)
+	{
+		$data = '';
+
+		if ($fh = fopen($filename, 'rb', $use_include_path))
+		{
+			$data = fread($fh, filesize($filename));
+			fclose($fh);
+		}
+
+		return $data;
+	}
+}
+
+
+//
+// Make sure that HTTP_REFERER matches $pun_config['o_base_url']/$script
+//
+function confirm_referrer($script)
+{
+	global $pun_config, $lang_common;
+
+	if (!preg_match('#^'.preg_quote(str_replace('www.', '', $pun_config['o_base_url']).'/'.$script, '#').'#i', str_replace('www.', '', (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''))))
+		message($lang_common['Bad referrer']);
+}
+
+
+//
+// Generate a random password of length $len
+//
+function random_pass($len)
+{
+	$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+
+	$password = '';
+	for ($i = 0; $i < $len; ++$i)
+		$password .= substr($chars, (mt_rand() % strlen($chars)), 1);
+
+	return $password;
+}
+
+
+//
+// Compute a hash of $str
+// Uses sha1() if available. If not, SHA1 through mhash() if available. If not, fall back on md5().
+//
+function pun_hash($str)
+{
+	if (function_exists('sha1'))	// Only in PHP 4.3.0+
+		return sha1($str);
+	else if (function_exists('mhash'))	// Only if Mhash library is loaded
+		return bin2hex(mhash(MHASH_SHA1, $str));
+	else
+		return md5($str);
+}
+
+
+//
+// Try to determine the correct remote IP-address
+//
+function get_remote_address()
+{
+	return $_SERVER['REMOTE_ADDR'];
+}
+
+
+//
+// Equivalent to htmlspecialchars(), but allows &#[0-9]+ (for unicode)
+//
+function pun_htmlspecialchars($str)
+{
+	$str = preg_replace('/&(?!#[0-9]+;)/s', '&amp;', $str);
+	$str = str_replace(array('<', '>', '"'), array('&lt;', '&gt;', '&quot;'), $str);
+
+	return $str;
+}
+
+
+//
+// Equivalent to strlen(), but counts &#[0-9]+ as one character (for unicode)
+//
+function pun_strlen($str)
+{
+	return strlen(preg_replace('/&#([0-9]+);/', '!', $str));
+}
+
+
+//
+// Convert \r\n and \r to \n
+//
+function pun_linebreaks($str)
+{
+	return str_replace("\r", "\n", str_replace("\r\n", "\n", $str));
+}
+
+
+//
+// A more aggressive version of trim()
+//
+function pun_trim($str)
+{
+	global $lang_common;
+
+	if (strpos($lang_common['lang_encoding'], '8859') !== false)
+	{
+		$fishy_chars = array(chr(0x81), chr(0x8D), chr(0x8F), chr(0x90), chr(0x9D), chr(0xA0));
+		return trim(str_replace($fishy_chars, ' ', $str));
+	}
+	else
+		return trim($str);
+}
+
+
+//
+// Display a message when board is in maintenance mode
+//
+function maintenance_message()
+{
+	global $db, $pun_config, $lang_common, $pun_user;
+
+	// Deal with newlines, tabs and multiple spaces
+	$pattern = array("\t", '  ', '  ');
+	$replace = array('&nbsp; &nbsp; ', '&nbsp; ', ' &nbsp;');
+	$message = str_replace($pattern, $replace, $pun_config['o_maintenance_message']);
+
+
+	// Load the maintenance template
+	$tpl_maint = trim(file_get_contents(PUN_ROOT.'include/template/maintenance.tpl'));
+
+
+	// START SUBST - <pun_include "*">
+	while (preg_match('#<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">#', $tpl_maint, $cur_include))
+	{
+		if (!file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]))
+			error('Unable to process user include '.htmlspecialchars($cur_include[0]).' from template maintenance.tpl. There is no such file in folder /include/user/');
+
+		ob_start();
+		include PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2];
+		$tpl_temp = ob_get_contents();
+		$tpl_maint = str_replace($cur_include[0], $tpl_temp, $tpl_maint);
+	    ob_end_clean();
+	}
+	// END SUBST - <pun_include "*">
+
+
+	// START SUBST - <pun_content_direction>
+	$tpl_maint = str_replace('<pun_content_direction>', $lang_common['lang_direction'], $tpl_maint);
+	// END SUBST - <pun_content_direction>
+
+
+	// START SUBST - <pun_char_encoding>
+	$tpl_maint = str_replace('<pun_char_encoding>', $lang_common['lang_encoding'], $tpl_maint);
+	// END SUBST - <pun_char_encoding>
+
+
+	// START SUBST - <pun_head>
+	ob_start();
+
+?>
+<title><?php echo pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Maintenance'] ?></title>
+<link rel="stylesheet" type="text/css" href="style/<?php echo $pun_user['style'].'.css' ?>" />
+<?php
+
+	$tpl_temp = trim(ob_get_contents());
+	$tpl_maint = str_replace('<pun_head>', $tpl_temp, $tpl_maint);
+	ob_end_clean();
+	// END SUBST - <pun_head>
+
+
+	// START SUBST - <pun_maint_heading>
+	$tpl_maint = str_replace('<pun_maint_heading>', $lang_common['Maintenance'], $tpl_maint);
+	// END SUBST - <pun_maint_heading>
+
+
+	// START SUBST - <pun_maint_message>
+	$tpl_maint = str_replace('<pun_maint_message>', $message, $tpl_maint);
+	// END SUBST - <pun_maint_message>
+
+
+	// End the transaction
+	$db->end_transaction();
+
+
+	// Close the db connection (and free up any result data)
+	$db->close();
+
+	exit($tpl_maint);
+}
+
+
+//
+// Display $message and redirect user to $destination_url
+//
+function redirect($destination_url, $message)
+{
+	global $db, $pun_config, $lang_common, $pun_user;
+
+	if ($destination_url == '')
+		$destination_url = 'index.php';
+
+	// If the delay is 0 seconds, we might as well skip the redirect all together
+	if ($pun_config['o_redirect_delay'] == '0')
+		header('Location: '.str_replace('&amp;', '&', $destination_url));
+
+
+	// Load the redirect template
+	$tpl_redir = trim(file_get_contents(PUN_ROOT.'include/template/redirect.tpl'));
+
+
+	// START SUBST - <pun_include "*">
+	while (preg_match('#<pun_include "([^/\\\\]*?)\.(php[45]?|inc|html?|txt)">#', $tpl_redir, $cur_include))
+	{
+		if (!file_exists(PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2]))
+			error('Unable to process user include '.htmlspecialchars($cur_include[0]).' from template redirect.tpl. There is no such file in folder /include/user/');
+
+		ob_start();
+		include PUN_ROOT.'include/user/'.$cur_include[1].'.'.$cur_include[2];
+		$tpl_temp = ob_get_contents();
+		$tpl_redir = str_replace($cur_include[0], $tpl_temp, $tpl_redir);
+	    ob_end_clean();
+	}
+	// END SUBST - <pun_include "*">
+
+
+	// START SUBST - <pun_content_direction>
+	$tpl_redir = str_replace('<pun_content_direction>', $lang_common['lang_direction'], $tpl_redir);
+	// END SUBST - <pun_content_direction>
+
+
+	// START SUBST - <pun_char_encoding>
+	$tpl_redir = str_replace('<pun_char_encoding>', $lang_common['lang_encoding'], $tpl_redir);
+	// END SUBST - <pun_char_encoding>
+
+
+	// START SUBST - <pun_head>
+	ob_start();
+
+?>
+<meta http-equiv="refresh" content="<?php echo $pun_config['o_redirect_delay'] ?>;URL=<?php echo str_replace(array('<', '>', '"'), array('&lt;', '&gt;', '&quot;'), $destination_url) ?>" />
+<title><?php echo pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Redirecting'] ?></title>
+<link rel="stylesheet" type="text/css" href="style/<?php echo $pun_user['style'].'.css' ?>" />
+<?php
+
+	$tpl_temp = trim(ob_get_contents());
+	$tpl_redir = str_replace('<pun_head>', $tpl_temp, $tpl_redir);
+	ob_end_clean();
+	// END SUBST - <pun_head>
+
+
+	// START SUBST - <pun_redir_heading>
+	$tpl_redir = str_replace('<pun_redir_heading>', $lang_common['Redirecting'], $tpl_redir);
+	// END SUBST - <pun_redir_heading>
+
+
+	// START SUBST - <pun_redir_text>
+	$tpl_temp = $message.'<br /><br />'.'<a href="'.$destination_url.'">'.$lang_common['Click redirect'].'</a>';
+	$tpl_redir = str_replace('<pun_redir_text>', $tpl_temp, $tpl_redir);
+	// END SUBST - <pun_redir_text>
+
+
+	// START SUBST - <pun_footer>
+	ob_start();
+
+	// End the transaction
+	$db->end_transaction();
+
+	// Display executed queries (if enabled)
+	if (defined('PUN_SHOW_QUERIES'))
+		display_saved_queries();
+
+	$tpl_temp = trim(ob_get_contents());
+	$tpl_redir = str_replace('<pun_footer>', $tpl_temp, $tpl_redir);
+	ob_end_clean();
+	// END SUBST - <pun_footer>
+
+
+	// Close the db connection (and free up any result data)
+	$db->close();
+
+	exit($tpl_redir);
+}
+
+
+//
+// Display a simple error message
+//
+function error($message, $file, $line, $db_error = false)
+{
+	global $pun_config;
+
+	// Set a default title if the script failed before $pun_config could be populated
+	if (empty($pun_config))
+		$pun_config['o_board_title'] = 'PunBB';
+
+	// Empty output buffer and stop buffering
+	@ob_end_clean();
+
+	// "Restart" output buffering if we are using ob_gzhandler (since the gzip header is already sent)
+	if (!empty($pun_config['o_gzip']) && extension_loaded('zlib') && (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false || strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') !== false))
+		ob_start('ob_gzhandler');
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<title><?php echo pun_htmlspecialchars($pun_config['o_board_title']) ?> / Error</title>
+<style type="text/css">
+<!--
+BODY {MARGIN: 10% 20% auto 20%; font: 10px Verdana, Arial, Helvetica, sans-serif}
+#errorbox {BORDER: 1px solid #B84623}
+H2 {MARGIN: 0; COLOR: #FFFFFF; BACKGROUND-COLOR: #B84623; FONT-SIZE: 1.1em; PADDING: 5px 4px}
+#errorbox DIV {PADDING: 6px 5px; BACKGROUND-COLOR: #F1F1F1}
+-->
+</style>
+</head>
+<body>
+
+<div id="errorbox">
+	<h2>An error was encountered</h2>
+	<div>
+<?php
+
+	if (defined('PUN_DEBUG'))
+	{
+		echo "\t\t".'<strong>File:</strong> '.$file.'<br />'."\n\t\t".'<strong>Line:</strong> '.$line.'<br /><br />'."\n\t\t".'<strong>PunBB reported</strong>: '.$message."\n";
+
+		if ($db_error)
+		{
+			echo "\t\t".'<br /><br /><strong>Database reported:</strong> '.pun_htmlspecialchars($db_error['error_msg']).(($db_error['error_no']) ? ' (Errno: '.$db_error['error_no'].')' : '')."\n";
+
+			if ($db_error['error_sql'] != '')
+				echo "\t\t".'<br /><br /><strong>Failed query:</strong> '.pun_htmlspecialchars($db_error['error_sql'])."\n";
+		}
+	}
+	else
+		echo "\t\t".'Error: <strong>'.$message.'.</strong>'."\n";
+
+?>
+	</div>
+</div>
+
+</body>
+</html>
+<?php
+
+	// If a database connection was established (before this error) we close it
+	if ($db_error)
+		$GLOBALS['db']->close();
+
+	exit;
+}
+
+// DEBUG FUNCTIONS BELOW
+
+//
+// Display executed queries (if enabled)
+//
+function display_saved_queries()
+{
+	global $db, $lang_common;
+
+	// Get the queries so that we can print them out
+	$saved_queries = $db->get_saved_queries();
+
+?>
+
+<div id="debug" class="blocktable">
+	<h2><span><?php echo $lang_common['Debug table'] ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<table cellspacing="0">
+			<thead>
+				<tr>
+					<th class="tcl" scope="col">Time (s)</th>
+					<th class="tcr" scope="col">Query</th>
+				</tr>
+			</thead>
+			<tbody>
+<?php
+
+	$query_time_total = 0.0;
+	while (list(, $cur_query) = @each($saved_queries))
+	{
+		$query_time_total += $cur_query[1];
+
+?>
+				<tr>
+					<td class="tcl"><?php echo ($cur_query[1] != 0) ? $cur_query[1] : '&nbsp;' ?></td>
+					<td class="tcr"><?php echo pun_htmlspecialchars($cur_query[0]) ?></td>
+				</tr>
+<?php
+
+	}
+
+?>
+				<tr>
+					<td class="tcl" colspan="2">Total query time: <?php echo $query_time_total ?> s</td>
+				</tr>
+			</tbody>
+			</table>
+		</div>
+	</div>
+</div>
+<?php
+
+}
+
+
+//
+// Unset any variables instantiated as a result of register_globals being enabled
+//
+function unregister_globals()
+{
+	$register_globals = @ini_get('register_globals');
+	if ($register_globals === "" || $register_globals === "0" || strtolower($register_globals === "off"))
+		return;
+
+	// Prevent script.php?GLOBALS[foo]=bar
+	if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS']))
+		exit('I\'ll have a steak sandwich and... a steak sandwich.');
+	
+	// Variables that shouldn't be unset
+	$no_unset = array('GLOBALS', '_GET', '_POST', '_COOKIE', '_REQUEST', '_SERVER', '_ENV', '_FILES');
+
+	// Remove elements in $GLOBALS that are present in any of the superglobals
+	$input = array_merge($_GET, $_POST, $_COOKIE, $_SERVER, $_ENV, $_FILES, isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array());
+	foreach ($input as $k => $v)
+	{
+		if (!in_array($k, $no_unset) && isset($GLOBALS[$k]))
+		{
+			unset($GLOBALS[$k]);
+			unset($GLOBALS[$k]);	// Double unset to circumvent the zend_hash_del_key_or_index hole in PHP <4.4.3 and <5.1.4
+		}
+	}
+}
+
+
+//
+// Dump contents of variable(s)
+//
+function dump()
+{
+	echo '<pre>';
+
+	$num_args = func_num_args();
+
+	for ($i = 0; $i < $num_args; ++$i)
+	{
+		print_r(func_get_arg($i));
+		echo "\n\n";
+	}
+
+	echo '</pre>';
+	exit;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/parser.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,477 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+// Make sure no one attempts to run this script "directly"
+if (!defined('PUN'))
+	exit;
+
+
+// Here you can add additional smilies if you like (please note that you must escape singlequote and backslash)
+$smiley_text = array(':)', '=)', ':|', '=|', ':(', '=(', ':D', '=D', ':o', ':O', ';)', ':/', ':P', ':lol:', ':mad:', ':rolleyes:', ':cool:');
+$smiley_img = array('smile.png', 'smile.png', 'neutral.png', 'neutral.png', 'sad.png', 'sad.png', 'big_smile.png', 'big_smile.png', 'yikes.png', 'yikes.png', 'wink.png', 'hmm.png', 'tongue.png', 'lol.png', 'mad.png', 'roll.png', 'cool.png');
+
+// Uncomment the next row if you add smilies that contain any of the characters &"'<>
+//$smiley_text = array_map('pun_htmlspecialchars', $smiley_text);
+
+
+//
+// Make sure all BBCodes are lower case and do a little cleanup
+//
+function preparse_bbcode($text, &$errors, $is_signature = false)
+{
+	// Change all simple BBCodes to lower case
+	$a = array('[B]', '[I]', '[U]', '[/B]', '[/I]', '[/U]');
+	$b = array('[b]', '[i]', '[u]', '[/b]', '[/i]', '[/u]');
+	$text = str_replace($a, $b, $text);
+
+	// Do the more complex BBCodes (also strip excessive whitespace and useless quotes)
+	$a = array( '#\[url=("|\'|)(.*?)\\1\]\s*#i',
+				'#\[url\]\s*#i',
+				'#\s*\[/url\]#i',
+				'#\[email=("|\'|)(.*?)\\1\]\s*#i',
+				'#\[email\]\s*#i',
+				'#\s*\[/email\]#i',
+				'#\[img\]\s*(.*?)\s*\[/img\]#is',
+				'#\[colou?r=("|\'|)(.*?)\\1\](.*?)\[/colou?r\]#is');
+
+	$b = array(	'[url=$2]',
+				'[url]',
+				'[/url]',
+				'[email=$2]',
+				'[email]',
+				'[/email]',
+				'[img]$1[/img]',
+				'[color=$2]$3[/color]');
+
+	if (!$is_signature)
+	{
+		// For non-signatures, we have to do the quote and code tags as well
+		$a[] = '#\[quote=(&quot;|"|\'|)(.*?)\\1\]\s*#i';
+		$a[] = '#\[quote\]\s*#i';
+		$a[] = '#\s*\[/quote\]\s*#i';
+		$a[] = '#\[code\][\r\n]*(.*?)\s*\[/code\]\s*#is';
+
+		$b[] = '[quote=$1$2$1]';
+		$b[] = '[quote]';
+		$b[] = '[/quote]'."\n";
+		$b[] = '[code]$1[/code]'."\n";
+	}
+
+	// Run this baby!
+	$text = preg_replace($a, $b, $text);
+
+	if (!$is_signature)
+	{
+		$overflow = check_tag_order($text, $error);
+
+		if ($error)
+			// A BBCode error was spotted in check_tag_order()
+			$errors[] = $error;
+		else if ($overflow)
+			// The quote depth level was too high, so we strip out the inner most quote(s)
+			$text = substr($text, 0, $overflow[0]).substr($text, $overflow[1], (strlen($text) - $overflow[0]));
+	}
+	else
+	{
+		global $lang_prof_reg;
+
+		if (preg_match('#\[quote=(&quot;|"|\'|)(.*)\\1\]|\[quote\]|\[/quote\]|\[code\]|\[/code\]#i', $text))
+			message($lang_prof_reg['Signature quote/code']);
+	}
+
+	return trim($text);
+}
+
+
+//
+// Parse text and make sure that [code] and [quote] syntax is correct
+//
+function check_tag_order($text, &$error)
+{
+	global $lang_common;
+
+	// The maximum allowed quote depth
+	$max_depth = 3;
+
+	$cur_index = 0;
+	$q_depth = 0;
+
+	while (true)
+	{
+		// Look for regular code and quote tags
+		$c_start = strpos($text, '[code]');
+		$c_end = strpos($text, '[/code]');
+		$q_start = strpos($text, '[quote]');
+		$q_end = strpos($text, '[/quote]');
+
+		// Look for [quote=username] style quote tags
+		if (preg_match('#\[quote=(&quot;|"|\'|)(.*)\\1\]#sU', $text, $matches))
+			$q2_start = strpos($text, $matches[0]);
+		else
+			$q2_start = 65536;
+
+		// Deal with strpos() returning false when the string is not found
+		// (65536 is one byte longer than the maximum post length)
+		if ($c_start === false) $c_start = 65536;
+		if ($c_end === false) $c_end = 65536;
+		if ($q_start === false) $q_start = 65536;
+		if ($q_end === false) $q_end = 65536;
+
+		// If none of the strings were found
+		if (min($c_start, $c_end, $q_start, $q_end, $q2_start) == 65536)
+			break;
+
+		// We are interested in the first quote (regardless of the type of quote)
+		$q3_start = ($q_start < $q2_start) ? $q_start : $q2_start;
+
+		// We found a [quote] or a [quote=username]
+		if ($q3_start < min($q_end, $c_start, $c_end))
+		{
+			$step = ($q_start < $q2_start) ? 7 : strlen($matches[0]);
+
+			$cur_index += $q3_start + $step;
+
+			// Did we reach $max_depth?
+			if ($q_depth == $max_depth)
+				$overflow_begin = $cur_index - $step;
+
+			++$q_depth;
+			$text = substr($text, $q3_start + $step);
+		}
+
+		// We found a [/quote]
+		else if ($q_end < min($q_start, $c_start, $c_end))
+		{
+			if ($q_depth == 0)
+			{
+				$error = $lang_common['BBCode error'].' '.$lang_common['BBCode error 1'];
+				return;
+			}
+
+			$q_depth--;
+			$cur_index += $q_end+8;
+
+			// Did we reach $max_depth?
+			if ($q_depth == $max_depth)
+				$overflow_end = $cur_index;
+
+			$text = substr($text, $q_end+8);
+		}
+
+		// We found a [code]
+		else if ($c_start < min($c_end, $q_start, $q_end))
+		{
+			// Make sure there's a [/code] and that any new [code] doesn't occur before the end tag
+			$tmp = strpos($text, '[/code]');
+			$tmp2 = strpos(substr($text, $c_start+6), '[code]');
+			if ($tmp2 !== false)
+				$tmp2 += $c_start+6;
+
+			if ($tmp === false || ($tmp2 !== false && $tmp2 < $tmp))
+			{
+				$error = $lang_common['BBCode error'].' '.$lang_common['BBCode error 2'];
+				return;
+			}
+			else
+				$text = substr($text, $tmp+7);
+
+			$cur_index += $tmp+7;
+		}
+
+		// We found a [/code] (this shouldn't happen since we handle both start and end tag in the if clause above)
+		else if ($c_end < min($c_start, $q_start, $q_end))
+		{
+			$error = $lang_common['BBCode error'].' '.$lang_common['BBCode error 3'];
+			return;
+		}
+	}
+
+	// If $q_depth <> 0 something is wrong with the quote syntax
+	if ($q_depth)
+	{
+		$error = $lang_common['BBCode error'].' '.$lang_common['BBCode error 4'];
+		return;
+	}
+	else if ($q_depth < 0)
+	{
+		$error = $lang_common['BBCode error'].' '.$lang_common['BBCode error 5'];
+		return;
+	}
+
+	// If the quote depth level was higher than $max_depth we return the index for the
+	// beginning and end of the part we should strip out
+	if (isset($overflow_begin))
+		return array($overflow_begin, $overflow_end);
+	else
+		return null;
+}
+
+
+//
+// Split text into chunks ($inside contains all text inside $start and $end, and $outside contains all text outside)
+//
+function split_text($text, $start, $end)
+{
+	global $pun_config;
+
+	$tokens = explode($start, $text);
+
+	$outside[] = $tokens[0];
+
+	$num_tokens = count($tokens);
+	for ($i = 1; $i < $num_tokens; ++$i)
+	{
+		$temp = explode($end, $tokens[$i]);
+		$inside[] = $temp[0];
+		$outside[] = $temp[1];
+	}
+
+	if ($pun_config['o_indent_num_spaces'] != 8 && $start == '[code]')
+	{
+		$spaces = str_repeat(' ', $pun_config['o_indent_num_spaces']);
+		$inside = str_replace("\t", $spaces, $inside);
+	}
+
+	return array($inside, $outside);
+}
+
+
+//
+// Truncate URL if longer than 55 characters (add http:// or ftp:// if missing)
+//
+function handle_url_tag($url, $link = '')
+{
+	global $pun_user;
+
+	$full_url = str_replace(array(' ', '\'', '`', '"'), array('%20', '', '', ''), $url);
+	if (strpos($url, 'www.') === 0)			// If it starts with www, we add http://
+		$full_url = 'http://'.$full_url;
+	else if (strpos($url, 'ftp.') === 0)	// Else if it starts with ftp, we add ftp://
+		$full_url = 'ftp://'.$full_url;
+	else if (!preg_match('#^([a-z0-9]{3,6})://#', $url, $bah)) 	// Else if it doesn't start with abcdef://, we add http://
+		$full_url = 'http://'.$full_url;
+
+	// Ok, not very pretty :-)
+	$link = ($link == '' || $link == $url) ? ((strlen($url) > 55) ? substr($url, 0 , 39).' &hellip; '.substr($url, -10) : $url) : stripslashes($link);
+
+	return '<a href="'.$full_url.'">'.$link.'</a>';
+}
+
+
+//
+// Turns an URL from the [img] tag into an <img> tag or a <a href...> tag
+//
+function handle_img_tag($url, $is_signature = false)
+{
+	global $lang_common, $pun_config, $pun_user;
+
+	$img_tag = '<a href="'.$url.'">&lt;'.$lang_common['Image link'].'&gt;</a>';
+
+	if ($is_signature && $pun_user['show_img_sig'] != '0')
+		$img_tag = '<img class="sigimage" src="'.$url.'" alt="'.htmlspecialchars($url).'" />';
+	else if (!$is_signature && $pun_user['show_img'] != '0')
+		$img_tag = '<img class="postimg" src="'.$url.'" alt="'.htmlspecialchars($url).'" />';
+
+	return $img_tag;
+}
+
+
+//
+// Convert BBCodes to their HTML equivalent
+//
+function do_bbcode($text)
+{
+	global $lang_common, $pun_user;
+
+	if (strpos($text, 'quote') !== false)
+	{
+		$text = str_replace('[quote]', '</p><blockquote><div class="incqbox"><p>', $text);
+		$text = preg_replace('#\[quote=(&quot;|"|\'|)(.*)\\1\]#seU', '"</p><blockquote><div class=\"incqbox\"><h4>".str_replace(array(\'[\', \'\\"\'), array(\'&#91;\', \'"\'), \'$2\')." ".$lang_common[\'wrote\'].":</h4><p>"', $text);
+		$text = preg_replace('#\[\/quote\]\s*#', '</p></div></blockquote><p>', $text);
+	}
+
+	$pattern = array('#\[b\](.*?)\[/b\]#s',
+					 '#\[i\](.*?)\[/i\]#s',
+					 '#\[u\](.*?)\[/u\]#s',
+					 '#\[url\]([^\[]*?)\[/url\]#e',
+					 '#\[url=([^\[]*?)\](.*?)\[/url\]#e',
+					 '#\[email\]([^\[]*?)\[/email\]#',
+					 '#\[email=([^\[]*?)\](.*?)\[/email\]#',
+					 '#\[color=([a-zA-Z]*|\#?[0-9a-fA-F]{6})](.*?)\[/color\]#s');
+
+	$replace = array('<strong>$1</strong>',
+					 '<em>$1</em>',
+					 '<span class="bbu">$1</span>',
+					 'handle_url_tag(\'$1\')',
+					 'handle_url_tag(\'$1\', \'$2\')',
+					 '<a href="mailto:$1">$1</a>',
+					 '<a href="mailto:$1">$2</a>',
+					 '<span style="color: $1">$2</span>');
+
+	// This thing takes a while! :)
+	$text = preg_replace($pattern, $replace, $text);
+
+	return $text;
+}
+
+
+//
+// Make hyperlinks clickable
+//
+function do_clickable($text)
+{
+	global $pun_user;
+
+	$text = ' '.$text;
+
+	$text = preg_replace('#([\s\(\)])(https?|ftp|news){1}://([\w\-]+\.([\w\-]+\.)*[\w]+(:[0-9]+)?(/[^"\s\(\)<\[]*)?)#ie', '\'$1\'.handle_url_tag(\'$2://$3\')', $text);
+	$text = preg_replace('#([\s\(\)])(www|ftp)\.(([\w\-]+\.)*[\w]+(:[0-9]+)?(/[^"\s\(\)<\[]*)?)#ie', '\'$1\'.handle_url_tag(\'$2.$3\', \'$2.$3\')', $text);
+
+	return substr($text, 1);
+}
+
+
+//
+// Convert a series of smilies to images
+//
+function do_smilies($text)
+{
+	global $smiley_text, $smiley_img;
+
+	$text = ' '.$text.' ';
+
+	$num_smilies = count($smiley_text);
+	for ($i = 0; $i < $num_smilies; ++$i)
+		$text = preg_replace("#(?<=.\W|\W.|^\W)".preg_quote($smiley_text[$i], '#')."(?=.\W|\W.|\W$)#m", '$1<img src="img/smilies/'.$smiley_img[$i].'" width="15" height="15" alt="'.substr($smiley_img[$i], 0, strrpos($smiley_img[$i], '.')).'" />$2', $text);
+
+	return substr($text, 1, -1);
+}
+
+
+//
+// Parse message text
+//
+function parse_message($text, $hide_smilies)
+{
+	global $pun_config, $lang_common, $pun_user;
+
+	if ($pun_config['o_censoring'] == '1')
+		$text = censor_words($text);
+
+	// Convert applicable characters to HTML entities
+	$text = pun_htmlspecialchars($text);
+
+	// If the message contains a code tag we have to split it up (text within [code][/code] shouldn't be touched)
+	if (strpos($text, '[code]') !== false && strpos($text, '[/code]') !== false)
+	{
+		list($inside, $outside) = split_text($text, '[code]', '[/code]');
+		$outside = array_map('ltrim', $outside);
+		$text = implode('<">', $outside);
+	}
+
+	if ($pun_config['o_make_links'] == '1')
+		$text = do_clickable($text);
+
+	if ($pun_config['o_smilies'] == '1' && $pun_user['show_smilies'] == '1' && $hide_smilies == '0')
+		$text = do_smilies($text);
+
+	if ($pun_config['p_message_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false)
+	{
+		$text = do_bbcode($text);
+
+		if ($pun_config['p_message_img_tag'] == '1')
+		{
+//			$text = preg_replace('#\[img\]((ht|f)tps?://)([^\s<"]*?)\.(jpg|jpeg|png|gif)\[/img\]#e', 'handle_img_tag(\'$1$3.$4\')', $text);
+			$text = preg_replace('#\[img\]((ht|f)tps?://)([^\s<"]*?)\[/img\]#e', 'handle_img_tag(\'$1$3\')', $text);
+		}
+	}
+
+	// Deal with newlines, tabs and multiple spaces
+	$pattern = array("\n", "\t", '  ', '  ');
+	$replace = array('<br />', '&nbsp; &nbsp; ', '&nbsp; ', ' &nbsp;');
+	$text = str_replace($pattern, $replace, $text);
+
+	// If we split up the message before we have to concatenate it together again (code tags)
+	if (isset($inside))
+	{
+		$outside = explode('<">', $text);
+		$text = '';
+
+		$num_tokens = count($outside);
+
+		for ($i = 0; $i < $num_tokens; ++$i)
+		{
+			$text .= $outside[$i];
+			if (isset($inside[$i]))
+			{
+				$num_lines = ((substr_count($inside[$i], "\n")) + 3) * 1.5;
+				$height_str = ($num_lines > 35) ? '35em' : $num_lines.'em';
+				$text .= '</p><div class="codebox"><div class="incqbox"><h4>'.$lang_common['Code'].':</h4><div class="scrollbox" style="height: '.$height_str.'"><pre>'.$inside[$i].'</pre></div></div></div><p>';
+			}
+		}
+	}
+
+	// Add paragraph tag around post, but make sure there are no empty paragraphs
+	$text = str_replace('<p></p>', '', '<p>'.$text.'</p>');
+
+	return $text;
+}
+
+
+//
+// Parse signature text
+//
+function parse_signature($text)
+{
+	global $pun_config, $lang_common, $pun_user;
+
+	if ($pun_config['o_censoring'] == '1')
+		$text = censor_words($text);
+
+	$text = pun_htmlspecialchars($text);
+
+	if ($pun_config['o_make_links'] == '1')
+		$text = do_clickable($text);
+
+	if ($pun_config['o_smilies_sig'] == '1' && $pun_user['show_smilies'] != '0')
+		$text = do_smilies($text);
+
+	if ($pun_config['p_sig_bbcode'] == '1' && strpos($text, '[') !== false && strpos($text, ']') !== false)
+	{
+		$text = do_bbcode($text);
+
+		if ($pun_config['p_sig_img_tag'] == '1')
+		{
+//			$text = preg_replace('#\[img\]((ht|f)tps?://)([^\s<"]*?)\.(jpg|jpeg|png|gif)\[/img\]#e', 'handle_img_tag(\'$1$3.$4\', true)', $text);
+			$text = preg_replace('#\[img\]((ht|f)tps?://)([^\s<"]*?)\[/img\]#e', 'handle_img_tag(\'$1$3\', true)', $text);
+		}
+	}
+
+	// Deal with newlines, tabs and multiple spaces
+	$pattern = array("\n", "\t", '  ', '  ');
+	$replace = array('<br />', '&nbsp; &nbsp; ', '&nbsp; ', ' &nbsp;');
+	$text = str_replace($pattern, $replace, $text);
+
+	return $text;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/search_idx.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,231 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// The contents of this file are very much inspired by the file functions_search.php
+// from the phpBB Group forum software phpBB2 (http://www.phpbb.com). 
+
+
+// Make sure no one attempts to run this script "directly"
+if (!defined('PUN'))
+	exit;
+
+
+//
+// "Cleans up" a text string and returns an array of unique words
+// This function depends on the current locale setting
+//
+function split_words($text)
+{
+	global $pun_user;
+	static $noise_match, $noise_replace, $stopwords;
+
+	if (empty($noise_match))
+	{
+		$noise_match = 		array('[quote', '[code', '[url', '[img', '[email', '[color', '[colour', 'quote]', 'code]', 'url]', 'img]', 'email]', 'color]', 'colour]', '^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '~', '+', '[', ']', '{', '}', ':', '\\', '/', '=', '#', ';', '!', '*');
+		$noise_replace =	array('',       '',      '',     '',     '',       '',       '',        '',       '',      '',     '',     '',       '',       '',        ' ', ' ', ' ', ' ', ' ', ' ', ' ', '',  '',   ' ', ' ', ' ', ' ', '',  ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '' ,  ' ', ' ', ' ', ' ', ' ', ' ');
+
+		$stopwords = (array)@file(PUN_ROOT.'lang/'.$pun_user['language'].'/stopwords.txt');
+		$stopwords = array_map('trim', $stopwords);
+	}
+
+	// Clean up
+	$patterns[] = '#&[\#a-z0-9]+?;#i';
+	$patterns[] = '#\b[\w]+:\/\/[a-z0-9\.\-]+(\/[a-z0-9\?\.%_\-\+=&\/~]+)?#';
+	$patterns[] = '#\[\/?[a-z\*=\+\-]+(\:?[0-9a-z]+)?:[a-z0-9]{10,}(\:[a-z0-9]+)?=?.*?\]#';
+	$text = preg_replace($patterns, ' ', ' '.strtolower($text).' ');
+
+	// Filter out junk
+	$text = str_replace($noise_match, $noise_replace, $text);
+
+	// Strip out extra whitespace between words
+	$text = trim(preg_replace('#\s+#', ' ', $text));
+
+	// Fill an array with all the words
+	$words = explode(' ', $text);
+
+	if (!empty($words))
+	{
+		while (list($i, $word) = @each($words))
+		{
+			$words[$i] = trim($word, '.');
+			$num_chars = pun_strlen($word);
+
+			if ($num_chars < 3 || $num_chars > 20 || in_array($word, $stopwords))
+				unset($words[$i]);
+		}
+	}
+
+	return array_unique($words);
+}
+
+
+//
+// Updates the search index with the contents of $post_id (and $subject)
+//
+function update_search_index($mode, $post_id, $message, $subject = null)
+{
+	global $db_type, $db;
+
+	// Split old and new post/subject to obtain array of 'words'
+	$words_message = split_words($message);
+	$words_subject = ($subject) ? split_words($subject) : array();
+
+	if ($mode == 'edit')
+	{
+		$result = $db->query('SELECT w.id, w.word, m.subject_match FROM '.$db->prefix.'search_words AS w INNER JOIN '.$db->prefix.'search_matches AS m ON w.id=m.word_id WHERE m.post_id='.$post_id, true) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error());
+
+		// Declare here to stop array_keys() and array_diff() from complaining if not set
+		$cur_words['post'] = array();
+		$cur_words['subject'] = array();
+
+		while ($row = $db->fetch_row($result))
+		{
+			$match_in = ($row[2]) ? 'subject' : 'post';
+			$cur_words[$match_in][$row[1]] = $row[0];
+		}
+
+		$db->free_result($result);
+
+		$words['add']['post'] = array_diff($words_message, array_keys($cur_words['post']));
+		$words['add']['subject'] = array_diff($words_subject, array_keys($cur_words['subject']));
+		$words['del']['post'] = array_diff(array_keys($cur_words['post']), $words_message);
+		$words['del']['subject'] = array_diff(array_keys($cur_words['subject']), $words_subject);
+	}
+	else
+	{
+		$words['add']['post'] = $words_message;
+		$words['add']['subject'] = $words_subject;
+		$words['del']['post'] = array();
+		$words['del']['subject'] = array();
+	}
+
+	unset($words_message);
+	unset($words_subject);
+
+	// Get unique words from the above arrays
+	$unique_words = array_unique(array_merge($words['add']['post'], $words['add']['subject']));
+
+	if (!empty($unique_words))
+	{
+		$result = $db->query('SELECT id, word FROM '.$db->prefix.'search_words WHERE word IN('.implode(',', preg_replace('#^(.*)$#', '\'\1\'', $unique_words)).')', true) or error('Unable to fetch search index words', __FILE__, __LINE__, $db->error());
+
+		$word_ids = array();
+		while ($row = $db->fetch_row($result))
+			$word_ids[$row[1]] = $row[0];
+
+		$db->free_result($result);
+
+		$new_words = array_diff($unique_words, array_keys($word_ids));
+		unset($unique_words);
+
+		if (!empty($new_words))
+		{
+			switch ($db_type)
+			{
+				case 'mysql':
+				case 'mysqli':
+					$db->query('INSERT INTO '.$db->prefix.'search_words (word) VALUES'.implode(',', preg_replace('#^(.*)$#', '(\'\1\')', $new_words))) or error('Unable to insert search index words', __FILE__, __LINE__, $db->error());
+					break;
+
+				default:
+					while (list(, $word) = @each($new_words))
+						$db->query('INSERT INTO '.$db->prefix.'search_words (word) VALUES(\''.$word.'\')') or error('Unable to insert search index words', __FILE__, __LINE__, $db->error());
+					break;
+			}
+		}
+
+		unset($new_words);
+	}
+
+	// Delete matches (only if editing a post)
+	while (list($match_in, $wordlist) = @each($words['del']))
+	{
+		$subject_match = ($match_in == 'subject') ? 1 : 0;
+
+		if (!empty($wordlist))
+		{
+			$sql = '';
+			while (list(, $word) = @each($wordlist))
+				$sql .= (($sql != '') ? ',' : '').$cur_words[$match_in][$word];
+
+			$db->query('DELETE FROM '.$db->prefix.'search_matches WHERE word_id IN('.$sql.') AND post_id='.$post_id.' AND subject_match='.$subject_match) or error('Unable to delete search index word matches', __FILE__, __LINE__, $db->error());
+		}
+	}
+
+	// Add new matches
+	while (list($match_in, $wordlist) = @each($words['add']))
+	{
+		$subject_match = ($match_in == 'subject') ? 1 : 0;
+
+		if (!empty($wordlist))
+			$db->query('INSERT INTO '.$db->prefix.'search_matches (post_id, word_id, subject_match) SELECT '.$post_id.', id, '.$subject_match.' FROM '.$db->prefix.'search_words WHERE word IN('.implode(',', preg_replace('#^(.*)$#', '\'\1\'', $wordlist)).')') or error('Unable to insert search index word matches', __FILE__, __LINE__, $db->error());
+	}
+
+	unset($words);
+}
+
+
+//
+// Strip search index of indexed words in $post_ids
+//
+function strip_search_index($post_ids)
+{
+	global $db_type, $db;
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+		{
+			$result = $db->query('SELECT word_id FROM '.$db->prefix.'search_matches WHERE post_id IN('.$post_ids.') GROUP BY word_id') or error('Unable to fetch search index word match', __FILE__, __LINE__, $db->error());
+
+			if ($db->num_rows($result))
+			{
+				$word_ids = '';
+				while ($row = $db->fetch_row($result))
+					$word_ids .= ($word_ids != '') ? ','.$row[0] : $row[0];
+
+				$result = $db->query('SELECT word_id FROM '.$db->prefix.'search_matches WHERE word_id IN('.$word_ids.') GROUP BY word_id HAVING COUNT(word_id)=1') or error('Unable to fetch search index word match', __FILE__, __LINE__, $db->error());
+
+				if ($db->num_rows($result))
+				{
+					$word_ids = '';
+					while ($row = $db->fetch_row($result))
+						$word_ids .= ($word_ids != '') ? ','.$row[0] : $row[0];
+
+					$db->query('DELETE FROM '.$db->prefix.'search_words WHERE id IN('.$word_ids.')') or error('Unable to delete search index word', __FILE__, __LINE__, $db->error());
+				}
+			}
+
+			break;
+		}
+
+		default:
+			$db->query('DELETE FROM '.$db->prefix.'search_words WHERE id IN(SELECT word_id FROM '.$db->prefix.'search_matches WHERE word_id IN(SELECT word_id FROM '.$db->prefix.'search_matches WHERE post_id IN('.$post_ids.') GROUP BY word_id) GROUP BY word_id HAVING COUNT(word_id)=1)') or error('Unable to delete from search index', __FILE__, __LINE__, $db->error());
+			break;
+	}
+
+	$db->query('DELETE FROM '.$db->prefix.'search_matches WHERE post_id IN('.$post_ids.')') or error('Unable to delete search index word match', __FILE__, __LINE__, $db->error());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/template/admin.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,34 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" dir="<pun_content_direction>">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=<pun_char_encoding>" />
+<pun_head>
+</head>
+<body>
+
+<div id="punwrap">
+<div id="punadmin" class="pun">
+
+<div id="brdheader" class="block">
+	<div class="box">
+		<div id="brdtitle" class="inbox">
+			<pun_title>
+			<pun_desc>
+		</div>
+		<pun_navlinks>
+		<pun_status>
+	</div>
+</div>
+
+<pun_announcement>
+
+<pun_main>
+
+<pun_footer>
+
+</div>
+</div>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/template/help.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" dir="<pun_content_direction>">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=<pun_char_encoding>" />
+<pun_head>
+</head>
+<body>
+
+<div id="punwrap">
+<div id="helpfile" class="pun">
+
+<pun_main>
+
+</div>
+</div>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/template/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/template/main.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,34 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" dir="<pun_content_direction>">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=<pun_char_encoding>" />
+<pun_head>
+</head>
+<body>
+
+<div id="punwrap">
+<div id="pun<pun_page>" class="pun">
+
+<div id="brdheader" class="block">
+	<div class="box">
+		<div id="brdtitle" class="inbox">
+			<pun_title>
+			<pun_desc>
+		</div>
+		<pun_navlinks>
+		<pun_status>
+	</div>
+</div>
+
+<pun_announcement>
+
+<pun_main>
+
+<pun_footer>
+
+</div>
+</div>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/template/maintenance.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" dir="<pun_content_direction>">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=<pun_char_encoding>" />
+<pun_head>
+</head>
+<body>
+
+<div id="punwrap">
+<div id="punmaint" class="pun">
+
+<div class="block">
+	<h2><pun_maint_heading></h2>
+	<div class="box">
+		<div class="inbox">
+			<p><pun_maint_message></p>
+		</div>
+	</div>
+</div>
+
+</div>
+</div>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/include/template/redirect.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" dir="<pun_content_direction>">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=<pun_char_encoding>" />
+<pun_head>
+</head>
+<body>
+
+<div id="punwrap">
+<div id="punredirect" class="pun">
+
+<div class="block">
+	<h2><pun_redir_heading></h2>
+	<div class="box">
+		<div class="inbox">
+			<p><pun_redir_text></p>
+		</div>
+	</div>
+</div>
+
+<pun_footer>
+
+</div>
+</div>
+
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/index.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,213 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+if ($pun_user['g_read_board'] == '0')
+	message($lang_common['No view']);
+
+
+// Load the index.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/index.php';
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']);
+define('PUN_ALLOW_INDEX', 1);
+require PUN_ROOT.'header.php';
+
+// Print the categories and forums
+$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.forum_desc, f.redirect_url, f.moderators, f.num_topics, f.num_posts, f.last_post, f.last_post_id, f.last_poster FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE fp.read_forum IS NULL OR fp.read_forum=1 ORDER BY c.disp_position, c.id, f.disp_position', true) or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
+
+$cur_category = 0;
+$cat_count = 0;
+while ($cur_forum = $db->fetch_assoc($result))
+{
+	$moderators = '';
+
+	if ($cur_forum['cid'] != $cur_category)	// A new category since last iteration?
+	{
+		if ($cur_category != 0)
+			echo "\t\t\t".'</tbody>'."\n\t\t\t".'</table>'."\n\t\t".'</div>'."\n\t".'</div>'."\n".'</div>'."\n\n";
+
+		++$cat_count;
+
+?>
+<div id="idx<?php echo $cat_count ?>" class="blocktable">
+	<h2><span><?php echo pun_htmlspecialchars($cur_forum['cat_name']) ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<table cellspacing="0">
+			<thead>
+				<tr>
+					<th class="tcl" scope="col"><?php echo $lang_common['Forum'] ?></th>
+					<th class="tc2" scope="col"><?php echo $lang_index['Topics'] ?></th>
+					<th class="tc3" scope="col"><?php echo $lang_common['Posts'] ?></th>
+					<th class="tcr" scope="col"><?php echo $lang_common['Last post'] ?></th>
+				</tr>
+			</thead>
+			<tbody>
+<?php
+
+		$cur_category = $cur_forum['cid'];
+	}
+
+	$item_status = '';
+	$icon_text = $lang_common['Normal icon'];
+	$icon_type = 'icon';
+
+	// Are there new posts?
+	if (!$pun_user['is_guest'] && $cur_forum['last_post'] > $pun_user['last_visit'])
+	{
+		$item_status = 'inew';
+		$icon_text = $lang_common['New icon'];
+		$icon_type = 'icon inew';
+	}
+
+	// Is this a redirect forum?
+	if ($cur_forum['redirect_url'] != '')
+	{
+		$forum_field = '<h3><a href="'.pun_htmlspecialchars($cur_forum['redirect_url']).'" title="'.$lang_index['Link to'].' '.pun_htmlspecialchars($cur_forum['redirect_url']).'">'.pun_htmlspecialchars($cur_forum['forum_name']).'</a></h3>';
+		$num_topics = $num_posts = '&nbsp;';
+		$item_status = 'iredirect';
+		$icon_text = $lang_common['Redirect icon'];
+		$icon_type = 'icon';
+	}
+	else
+	{
+		$forum_field = '<h3><a href="viewforum.php?id='.$cur_forum['fid'].'">'.pun_htmlspecialchars($cur_forum['forum_name']).'</a></h3>';
+		$num_topics = $cur_forum['num_topics'];
+		$num_posts = $cur_forum['num_posts'];
+	}
+
+	if ($cur_forum['forum_desc'] != '')
+		$forum_field .= "\n\t\t\t\t\t\t\t\t".$cur_forum['forum_desc'];
+
+
+	// If there is a last_post/last_poster.
+	if ($cur_forum['last_post'] != '')
+		$last_post = '<a href="viewtopic.php?pid='.$cur_forum['last_post_id'].'#p'.$cur_forum['last_post_id'].'">'.format_time($cur_forum['last_post']).'</a> <span class="byuser">'.$lang_common['by'].' '.pun_htmlspecialchars($cur_forum['last_poster']).'</span>';
+	else
+		$last_post = '&nbsp;';
+
+	if ($cur_forum['moderators'] != '')
+	{
+		$mods_array = unserialize($cur_forum['moderators']);
+		$moderators = array();
+
+		while (list($mod_username, $mod_id) = @each($mods_array))
+			$moderators[] = '<a href="profile.php?id='.$mod_id.'">'.pun_htmlspecialchars($mod_username).'</a>';
+
+		$moderators = "\t\t\t\t\t\t\t\t".'<p><em>('.$lang_common['Moderated by'].'</em> '.implode(', ', $moderators).')</p>'."\n";
+	}
+
+?>
+ 				<tr<?php if ($item_status != '') echo ' class="'.$item_status.'"'; ?>>
+					<td class="tcl">
+						<div class="intd">
+							<div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo $icon_text ?></div></div>
+							<div class="tclcon">
+								<?php echo $forum_field."\n".$moderators ?>
+							</div>
+						</div>
+					</td>
+					<td class="tc2"><?php echo $num_topics ?></td>
+					<td class="tc3"><?php echo $num_posts ?></td>
+					<td class="tcr"><?php echo $last_post ?></td>
+				</tr>
+<?php
+
+}
+
+// Did we output any categories and forums?
+if ($cur_category > 0)
+	echo "\t\t\t".'</tbody>'."\n\t\t\t".'</table>'."\n\t\t".'</div>'."\n\t".'</div>'."\n".'</div>'."\n\n";
+else
+	echo '<div id="idx0" class="block"><div class="box"><div class="inbox"><p>'.$lang_index['Empty board'].'</p></div></div></div>';
+
+
+// Collect some statistics from the database
+$result = $db->query('SELECT COUNT(id)-1 FROM '.$db->prefix.'users') or error('Unable to fetch total user count', __FILE__, __LINE__, $db->error());
+$stats['total_users'] = $db->result($result);
+
+$result = $db->query('SELECT id, username FROM '.$db->prefix.'users ORDER BY registered DESC LIMIT 1') or error('Unable to fetch newest registered user', __FILE__, __LINE__, $db->error());
+$stats['last_user'] = $db->fetch_assoc($result);
+
+$result = $db->query('SELECT SUM(num_topics), SUM(num_posts) FROM '.$db->prefix.'forums') or error('Unable to fetch topic/post count', __FILE__, __LINE__, $db->error());
+list($stats['total_topics'], $stats['total_posts']) = $db->fetch_row($result);
+
+?>
+<div id="brdstats" class="block">
+	<h2><span><?php echo $lang_index['Board info'] ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<dl class="conr">
+				<dt><strong><?php echo $lang_index['Board stats'] ?></strong></dt>
+				<dd><?php echo $lang_index['No of users'].': <strong>'. $stats['total_users'] ?></strong></dd>
+				<dd><?php echo $lang_index['No of topics'].': <strong>'.$stats['total_topics'] ?></strong></dd>
+				<dd><?php echo $lang_index['No of posts'].': <strong>'.$stats['total_posts'] ?></strong></dd>
+			</dl>
+			<dl class="conl">
+				<dt><strong><?php echo $lang_index['User info'] ?></strong></dt>
+				<dd><?php echo $lang_index['Newest user'] ?>: <a href="profile.php?id=<?php echo $stats['last_user']['id'] ?>"><?php echo pun_htmlspecialchars($stats['last_user']['username']) ?></a></dd>
+<?php
+
+if ($pun_config['o_users_online'] == '1')
+{
+	// Fetch users online info and generate strings for output
+	$num_guests = 0;
+	$users = array();
+	$result = $db->query('SELECT user_id, ident FROM '.$db->prefix.'online WHERE idle=0 ORDER BY ident', true) or error('Unable to fetch online list', __FILE__, __LINE__, $db->error());
+
+	while ($pun_user_online = $db->fetch_assoc($result))
+	{
+		if ($pun_user_online['user_id'] > 1)
+			$users[] = "\n\t\t\t\t".'<dd><a href="profile.php?id='.$pun_user_online['user_id'].'">'.pun_htmlspecialchars($pun_user_online['ident']).'</a>';
+		else
+			++$num_guests;
+	}
+
+	$num_users = count($users);
+	echo "\t\t\t\t".'<dd>'. $lang_index['Users online'].': <strong>'.$num_users.'</strong></dd>'."\n\t\t\t\t".'<dd>'.$lang_index['Guests online'].': <strong>'.$num_guests.'</strong></dd>'."\n\t\t\t".'</dl>'."\n";
+
+
+	if ($num_users > 0)
+		echo "\t\t\t".'<dl id="onlinelist" class= "clearb">'."\n\t\t\t\t".'<dt><strong>'.$lang_index['Online'].':&nbsp;</strong></dt>'."\t\t\t\t".implode(',</dd> ', $users).'</dd>'."\n\t\t\t".'</dl>'."\n";
+	else
+		echo "\t\t\t".'<div class="clearer"></div>'."\n";
+
+}
+else
+	echo "\t\t".'</dl>'."\n\t\t\t".'<div class="clearer"></div>'."\n";
+
+
+?>
+		</div>
+	</div>
+</div>
+<?php
+
+$footer_style = 'index';
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/install.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,1454 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// The PunBB version this script installs
+$punbb_version = '1.2.15';
+
+
+define('PUN_ROOT', './');
+if (file_exists(PUN_ROOT.'config.php'))
+	exit('The file \'config.php\' already exists which would mean that PunBB is already installed. You should go <a href="index.php">here</a> instead.');
+
+
+// Make sure we are running at least PHP 4.1.0
+if (intval(str_replace('.', '', phpversion())) < 410)
+	exit('You are running PHP version '.PHP_VERSION.'. PunBB requires at least PHP 4.1.0 to run properly. You must upgrade your PHP installation before you can continue.');
+
+// Disable error reporting for uninitialized variables
+error_reporting(E_ALL);
+
+// Turn off PHP time limit
+@set_time_limit(0);
+
+
+if (!isset($_POST['form_sent']))
+{
+	// Determine available database extensions
+	$dual_mysql = false;
+	$db_extensions = array();
+	if (function_exists('mysqli_connect'))
+		$db_extensions[] = array('mysqli', 'MySQL Improved');
+	if (function_exists('mysql_connect'))
+	{
+		$db_extensions[] = array('mysql', 'MySQL Standard');
+
+		if (count($db_extensions) > 1)
+			$dual_mysql = true;
+	}
+	if (function_exists('sqlite_open'))
+		$db_extensions[] = array('sqlite', 'SQLite');
+	if (function_exists('pg_connect'))
+		$db_extensions[] = array('pgsql', 'PostgreSQL');
+
+	if (empty($db_extensions))
+		exit('This PHP environment does not have support for any of the databases that PunBB supports. PHP needs to have support for either MySQL, PostgreSQL or SQLite in order for PunBB to be installed.');
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<title>PunBB Installation</title>
+<link rel="stylesheet" type="text/css" href="style/Oxygen.css" />
+<script type="text/javascript">
+<!--
+function process_form(the_form)
+{
+	var element_names = new Object()
+	element_names["req_db_type"] = "Database type"
+	element_names["req_db_host"] = "Database server hostname"
+	element_names["req_db_name"] = "Database name"
+	element_names["db_prefix"] = "Table prefix"
+	element_names["req_username"] = "Administrator username"
+	element_names["req_password1"] = "Administrator password 1"
+	element_names["req_password2"] = "Administrator password 2"
+	element_names["req_email"] = "Administrator's e-mail"
+	element_names["req_base_url"] = "Base URL"
+
+	if (document.all || document.getElementById)
+	{
+		for (i = 0; i < the_form.length; ++i)
+		{
+			var elem = the_form.elements[i]
+			if (elem.name && elem.name.substring(0, 4) == "req_")
+			{
+				if (elem.type && (elem.type=="text" || elem.type=="textarea" || elem.type=="password" || elem.type=="file") && elem.value=='')
+				{
+					alert("\"" + element_names[elem.name] + "\" is a required field in this form.")
+					elem.focus()
+					return false
+				}
+			}
+		}
+	}
+
+	return true
+}
+// -->
+</script>
+</head>
+<body onload="document.getElementById('install').req_db_type.focus()">
+
+<div id="puninstall" style="margin: auto 10% auto 10%">
+<div class="pun">
+
+<div class="block">
+	<h2><span>PunBB Installation</span></h2>
+	<div class="box">
+		<div class="inbox">
+			<p>Welcome to PunBB installation! You are about to install PunBB. In order to install PunBB you must complete the form set out below. If you encounter any difficulties with the installation, please refer to the documentation.</p>
+		</div>
+	</div>
+</div>
+
+<div class="blockform">
+	<h2><span>Install PunBB 1.2</span></h2>
+	<div class="box">
+		<form id="install" method="post" action="install.php" onsubmit="this.start.disabled=true;if(process_form(this)){return true;}else{this.start.disabled=false;return false;}">
+		<div><input type="hidden" name="form_sent" value="1" /></div>
+			<div class="inform">
+				<div class="forminfo">
+					<h3>Database setup</h3>
+					<p>Please enter the requested information in order to setup your database for PunBB. You must know all the information asked for before proceeding with the installation.</p>
+				</div>
+				<fieldset>
+				<legend>Select your database type</legend>
+					<div class="infldset">
+						<p>PunBB currently supports MySQL, PostgreSQL and SQLite. If your database of choice is missing from the drop-down menu below, it means this PHP environment does not have support for that particular database. More information regarding support for particular versions of each database can be found in the FAQ.</p>
+<?php if ($dual_mysql): ?>						<p>PunBB has detected that your PHP environment supports two different ways of communicating with MySQL. The two options are called standard and improved. If you are uncertain which one to use, start by trying improved and if that fails, try standard.</p>
+<?php endif; ?>						<label><strong>Database type</strong>
+						<br /><select name="req_db_type">
+<?php
+
+	foreach ($db_extensions as $db_type)
+		echo "\t\t\t\t\t\t\t".'<option value="'.$db_type[0].'">'.$db_type[1].'</option>'."\n";
+
+?>
+						</select>
+						<br /></label>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend>Enter your database server hostname</legend>
+					<div class="infldset">
+						<p>The address of the database server (example: localhost, db.myhost.com or 192.168.0.15). You can specify a custom port number if your database doesn't run on the default port (example: localhost:3580). For SQLite support, just enter anything or leave it at 'localhost'.</p>
+						<label><strong>Database server hostname</strong><br /><input type="text" name="req_db_host" value="localhost" size="50" maxlength="100" /><br /></label>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend>Enter then name of your database</legend>
+					<div class="infldset">
+						<p>The name of the database that PunBB will be installed into. The database must exist. For SQLite, this is the relative path to the database file. If the SQLite database file does not exist, PunBB will attempt to create it.</p>
+						<label for="req_db_name"><strong>Database name</strong><br /><input id="req_db_name" type="text" name="req_db_name" size="30" maxlength="50" /><br /></label>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend>Enter your database username and password</legend>
+					<div class="infldset">
+						<p>Enter the username and password with which you connect to the database. Ignore for SQLite.</p>
+						<label class="conl">Database username<br /><input type="text" name="db_username" size="30" maxlength="50" /><br /></label>
+						<label class="conl">Database password<br /><input type="text" name="db_password" size="30" maxlength="50" /><br /></label>
+						<div class="clearer"></div>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend>Enter database table prefix</legend>
+					<div class="infldset">
+						<p>If you like you can specify a table prefix. This way you can run multiple copies of PunBB in the same database (example: foo_).</p>
+						<label>Table prefix<br /><input id="db_prefix" type="text" name="db_prefix" size="20" maxlength="30" /><br /></label>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<div class="forminfo">
+					<h3>Administration setup</h3>
+					<p>Please enter the requested information in order to setup an administrator for your PunBB installation</p>
+				</div>
+				<fieldset>
+					<legend>Enter Administrators username</legend>
+					<div class="infldset">
+						<p>The username of the forum administrator. You can later create more administrators and moderators. Usernames can be between 2 and 25 characters long.</p>
+						<label><strong>Administrator username</strong><br /><input type="text" name="req_username" size="25" maxlength="25" /><br /></label>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend>Enter and confirm Administrator password</legend>
+					<div class="infldset">
+					<p>Passwords can be between 4 and 16 characters long. Passwords are case sensitive.</p>
+						<label class="conl"><strong>Password</strong><br /><input id="req_password1" type="text" name="req_password1" size="16" maxlength="16" /><br /></label>
+						<label class="conl"><strong>Confirm password</strong><br /><input type="text" name="req_password2" size="16" maxlength="16" /><br /></label>
+						<div class="clearer"></div>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend>Enter Administrator's e-mail</legend>
+					<div class="infldset">
+						<p>The e-mail address of the forum administrator.</p>
+						<label for="req_email"><strong>Administrator's e-mail</strong><br /><input id="req_email" type="text" name="req_email" size="50" maxlength="50" /><br /></label>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend>Enter the Base URL of your PunBB installation</legend>
+					<div class="infldset">
+						<p>The URL (without trailing slash) of your PunBB forum (example: http://forum.myhost.com or http://myhost.com/~myuser). This <strong>must</strong> be correct or administrators and moderators will not be able to submit any forms. Please note that the preset value below is just an educated guess by PunBB.</p>
+						<label><strong>Base URL</strong><br /><input type="text" name="req_base_url" value="http://<?php echo $_SERVER['SERVER_NAME'].str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME'])) ?>" size="60" maxlength="100" /><br /></label>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="start" value="Start install" /></p>
+		</form>
+	</div>
+</div>
+
+</div>
+</div>
+
+</body>
+</html>
+<?php
+
+}
+else
+{
+	//
+	// Strip slashes only if magic_quotes_gpc is on.
+	//
+	function unescape($str)
+	{
+		return (get_magic_quotes_gpc() == 1) ? stripslashes($str) : $str;
+	}
+
+
+	//
+	// Compute a hash of $str.
+	// Uses sha1() if available. If not, SHA1 through mhash() if available. If not, fall back on md5().
+	//
+	function pun_hash($str)
+	{
+		if (function_exists('sha1'))	// Only in PHP 4.3.0+
+			return sha1($str);
+		else if (function_exists('mhash'))	// Only if Mhash library is loaded
+			return bin2hex(mhash(MHASH_SHA1, $str));
+		else
+			return md5($str);
+	}
+
+
+	//
+	// A temporary replacement for the full error handler found in functions.php.
+	// It's here because a function called error() must be callable in the database abstraction layer.
+	//
+	function error($message, $file = false, $line = false, $db_error = false)
+	{
+		if ($file !== false && $line !== false)
+			echo '<strong style="color: A00000">An error occured on line '.$line.' in file '.$file.'.</strong><br /><br />';
+		else
+			echo '<strong style="color: A00000">An error occured.</strong><br /><br />';
+
+		echo '<strong>PunBB reported:</strong> '.htmlspecialchars($message).'<br /><br />';
+
+		if ($db_error !== false)
+			echo '<strong>Database reported:</strong> '.htmlspecialchars($db_error['error_msg']).(($db_error['error_no']) ? ' (Errno: '.$db_error['error_no'].')' : '');
+
+		exit;
+	}
+
+
+	$db_type = $_POST['req_db_type'];
+	$db_host = trim($_POST['req_db_host']);
+	$db_name = trim($_POST['req_db_name']);
+	$db_username = unescape(trim($_POST['db_username']));
+	$db_password = unescape(trim($_POST['db_password']));
+	$db_prefix = trim($_POST['db_prefix']);
+	$username = unescape(trim($_POST['req_username']));
+	$email = strtolower(trim($_POST['req_email']));
+	$password1 = unescape(trim($_POST['req_password1']));
+	$password2 = unescape(trim($_POST['req_password2']));
+
+
+	// Make sure base_url doesn't end with a slash
+	if (substr($_POST['req_base_url'], -1) == '/')
+		$base_url = substr($_POST['req_base_url'], 0, -1);
+	else
+		$base_url = $_POST['req_base_url'];
+
+
+	// Validate username and passwords
+	if (strlen($username) < 2)
+		error('Usernames must be at least 2 characters long. Please go back and correct.');
+	if (strlen($password1) < 4)
+		error('Passwords must be at least 4 characters long. Please go back and correct.');
+	if ($password1 != $password2)
+		error('Passwords do not match. Please go back and correct.');
+	if (!strcasecmp($username, 'Guest'))
+		error('The username guest is reserved. Please go back and correct.');
+	if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username))
+		error('Usernames may not be in the form of an IP address. Please go back and correct.');
+	if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $username))
+		error('Usernames may not contain any of the text formatting tags (BBCode) that the forum uses. Please go back and correct.');
+
+	if (strlen($email) > 50 || !preg_match('/^(([^<>()[\]\\.,;:\s@"\']+(\.[^<>()[\]\\.,;:\s@"\']+)*)|("[^"\']+"))@((\[\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\])|(([a-zA-Z\d\-]+\.)+[a-zA-Z]{2,}))$/', $email))
+		error('The administrator e-mail address you entered is invalid. Please go back and correct.');
+
+
+	// Load the appropriate DB layer class
+	switch ($db_type)
+	{
+		case 'mysql':
+			require PUN_ROOT.'include/dblayer/mysql.php';
+			break;
+
+		case 'mysqli':
+			require PUN_ROOT.'include/dblayer/mysqli.php';
+			break;
+
+		case 'pgsql':
+			require PUN_ROOT.'include/dblayer/pgsql.php';
+			break;
+
+		case 'sqlite':
+			require PUN_ROOT.'include/dblayer/sqlite.php';
+			break;
+
+		default:
+			error('\''.$db_type.'\' is not a valid database type.');
+	}
+
+	// Create the database object (and connect/select db)
+	$db = new DBLayer($db_host, $db_username, $db_password, $db_name, $db_prefix, false);
+
+
+	// Do some DB type specific checks
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			break;
+
+		case 'pgsql':
+			// Make sure we are running at least PHP 4.3.0 (needed only for PostgreSQL)
+			if (version_compare(PHP_VERSION, '4.3.0', '<'))
+				error('You are running PHP version '.PHP_VERSION.'. PunBB requires at least PHP 4.3.0 to run properly when using PostgreSQL. You must upgrade your PHP installation or use a different database before you can continue.');
+			break;
+
+		case 'sqlite':
+			if (strtolower($db_prefix) == 'sqlite_')
+				error('The table prefix \'sqlite_\' is reserved for use by the SQLite engine. Please choose a different prefix.');
+			break;
+	}
+
+
+	// Make sure PunBB isn't already installed
+	$result = $db->query('SELECT 1 FROM '.$db_prefix.'users WHERE id=1');
+	if ($db->num_rows($result))
+		error('A table called "'.$db_prefix.'users" is already present in the database "'.$db_name.'". This could mean that PunBB is already installed or that another piece of software is installed and is occupying one or more of the table names PunBB requires. If you want to install multiple copies of PunBB in the same database, you must choose a different table prefix.');
+
+
+	// Create all tables
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."bans (
+					id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+					username VARCHAR(200),
+					ip VARCHAR(255),
+					email VARCHAR(50),
+					message VARCHAR(255),
+					expire INT(10) UNSIGNED,
+					PRIMARY KEY (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$db->start_transaction();
+
+			$sql = 'CREATE TABLE '.$db_prefix."bans (
+					id SERIAL,
+					username VARCHAR(200),
+					ip VARCHAR(255),
+					email VARCHAR(50),
+					message VARCHAR(255),
+					expire INT,
+					PRIMARY KEY (id)
+					)";
+			break;
+
+		case 'sqlite':
+			$db->start_transaction();
+
+			$sql = 'CREATE TABLE '.$db_prefix."bans (
+					id INTEGER NOT NULL,
+					username VARCHAR(200),
+					ip  VARCHAR(255),
+					email VARCHAR(50),
+					message VARCHAR(255),
+					expire INTEGER,
+					PRIMARY KEY (id)
+					)";
+			break;
+
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'bans. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."categories (
+					id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+					cat_name VARCHAR(80) NOT NULL DEFAULT 'New Category',
+					disp_position INT(10) NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."categories (
+					id SERIAL,
+					cat_name VARCHAR(80) NOT NULL DEFAULT 'New Category',
+					disp_position INT NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."categories (
+					id INTEGER NOT NULL,
+					cat_name VARCHAR(80) NOT NULL DEFAULT 'New Category',
+					disp_position INTEGER NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'categories. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."censoring (
+					id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+					search_for VARCHAR(60) NOT NULL DEFAULT '',
+					replace_with VARCHAR(60) NOT NULL DEFAULT '',
+					PRIMARY KEY (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."censoring (
+					id SERIAL,
+					search_for VARCHAR(60) NOT NULL DEFAULT '',
+					replace_with VARCHAR(60) NOT NULL DEFAULT '',
+					PRIMARY KEY (id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."censoring (
+					id INTEGER NOT NULL,
+					search_for VARCHAR(60) NOT NULL DEFAULT '',
+					replace_with VARCHAR(60) NOT NULL DEFAULT '',
+					PRIMARY KEY (id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'censoring. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."config (
+					conf_name VARCHAR(255) NOT NULL DEFAULT '',
+					conf_value TEXT,
+					PRIMARY KEY (conf_name)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."config (
+					conf_name VARCHAR(255) NOT NULL DEFAULT '',
+					conf_value TEXT,
+					PRIMARY KEY (conf_name)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."config (
+					conf_name VARCHAR(255) NOT NULL DEFAULT '',
+					conf_value TEXT,
+					PRIMARY KEY (conf_name)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'config. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."forum_perms (
+					group_id INT(10) NOT NULL DEFAULT 0,
+					forum_id INT(10) NOT NULL DEFAULT 0,
+					read_forum TINYINT(1) NOT NULL DEFAULT 1,
+					post_replies TINYINT(1) NOT NULL DEFAULT 1,
+					post_topics TINYINT(1) NOT NULL DEFAULT 1,
+					PRIMARY KEY (group_id, forum_id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."forum_perms (
+					group_id INT NOT NULL DEFAULT 0,
+					forum_id INT NOT NULL DEFAULT 0,
+					read_forum SMALLINT NOT NULL DEFAULT 1,
+					post_replies SMALLINT NOT NULL DEFAULT 1,
+					post_topics SMALLINT NOT NULL DEFAULT 1,
+					PRIMARY KEY (group_id, forum_id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."forum_perms (
+					group_id INTEGER NOT NULL DEFAULT 0,
+					forum_id INTEGER NOT NULL DEFAULT 0,
+					read_forum INTEGER NOT NULL DEFAULT 1,
+					post_replies INTEGER NOT NULL DEFAULT 1,
+					post_topics INTEGER NOT NULL DEFAULT 1,
+					PRIMARY KEY (group_id, forum_id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'forum_perms. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."forums (
+					id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+					forum_name VARCHAR(80) NOT NULL DEFAULT 'New forum',
+					forum_desc TEXT,
+					redirect_url VARCHAR(100),
+					moderators TEXT,
+					num_topics MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0,
+					num_posts MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0,
+					last_post INT(10) UNSIGNED,
+					last_post_id INT(10) UNSIGNED,
+					last_poster VARCHAR(200),
+					sort_by TINYINT(1) NOT NULL DEFAULT 0,
+					disp_position INT(10) NOT NULL DEFAULT 0,
+					cat_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."forums (
+					id SERIAL,
+					forum_name VARCHAR(80) NOT NULL DEFAULT 'New forum',
+					forum_desc TEXT,
+					redirect_url VARCHAR(100),
+					moderators TEXT,
+					num_topics INT NOT NULL DEFAULT 0,
+					num_posts INT NOT NULL DEFAULT 0,
+					last_post INT,
+					last_post_id INT,
+					last_poster VARCHAR(200),
+					sort_by SMALLINT NOT NULL DEFAULT 0,
+					disp_position INT NOT NULL DEFAULT 0,
+					cat_id INT NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."forums (
+					id INTEGER NOT NULL,
+					forum_name VARCHAR(80) NOT NULL DEFAULT 'New forum',
+					forum_desc TEXT,
+					redirect_url VARCHAR(100),
+					moderators TEXT,
+					num_topics INTEGER NOT NULL DEFAULT 0,
+					num_posts INTEGER NOT NULL DEFAULT 0,
+					last_post INTEGER,
+					last_post_id INTEGER,
+					last_poster VARCHAR(200),
+					sort_by INTEGER NOT NULL DEFAULT 0,
+					disp_position INTEGER NOT NULL DEFAULT 0,
+					cat_id INTEGER NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'forums. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."groups (
+					g_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+					g_title VARCHAR(50) NOT NULL DEFAULT '',
+					g_user_title VARCHAR(50),
+					g_read_board TINYINT(1) NOT NULL DEFAULT 1,
+					g_post_replies TINYINT(1) NOT NULL DEFAULT 1,
+					g_post_topics TINYINT(1) NOT NULL DEFAULT 1,
+					g_post_polls TINYINT(1) NOT NULL DEFAULT 1,
+					g_edit_posts TINYINT(1) NOT NULL DEFAULT 1,
+					g_delete_posts TINYINT(1) NOT NULL DEFAULT 1,
+					g_delete_topics TINYINT(1) NOT NULL DEFAULT 1,
+					g_set_title TINYINT(1) NOT NULL DEFAULT 1,
+					g_search TINYINT(1) NOT NULL DEFAULT 1,
+					g_search_users TINYINT(1) NOT NULL DEFAULT 1,
+					g_edit_subjects_interval SMALLINT(6) NOT NULL DEFAULT 300,
+					g_post_flood SMALLINT(6) NOT NULL DEFAULT 30,
+					g_search_flood SMALLINT(6) NOT NULL DEFAULT 30,
+					PRIMARY KEY (g_id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."groups (
+					g_id SERIAL,
+					g_title VARCHAR(50) NOT NULL DEFAULT '',
+					g_user_title VARCHAR(50),
+					g_read_board SMALLINT NOT NULL DEFAULT 1,
+					g_post_replies SMALLINT NOT NULL DEFAULT 1,
+					g_post_topics SMALLINT NOT NULL DEFAULT 1,
+					g_post_polls SMALLINT NOT NULL DEFAULT 1,
+					g_edit_posts SMALLINT NOT NULL DEFAULT 1,
+					g_delete_posts SMALLINT NOT NULL DEFAULT 1,
+					g_delete_topics SMALLINT NOT NULL DEFAULT 1,
+					g_set_title SMALLINT NOT NULL DEFAULT 1,
+					g_search SMALLINT NOT NULL DEFAULT 1,
+					g_search_users SMALLINT NOT NULL DEFAULT 1,
+					g_edit_subjects_interval SMALLINT NOT NULL DEFAULT 300,
+					g_post_flood SMALLINT NOT NULL DEFAULT 30,
+					g_search_flood SMALLINT NOT NULL DEFAULT 30,
+					PRIMARY KEY (g_id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."groups (
+					g_id INTEGER NOT NULL,
+					g_title VARCHAR(50) NOT NULL DEFAULT '',
+					g_user_title VARCHAR(50),
+					g_read_board INTEGER NOT NULL DEFAULT 1,
+					g_post_replies INTEGER NOT NULL DEFAULT 1,
+					g_post_topics INTEGER NOT NULL DEFAULT 1,
+					g_post_polls INTEGER NOT NULL DEFAULT 1,
+					g_edit_posts INTEGER NOT NULL DEFAULT 1,
+					g_delete_posts INTEGER NOT NULL DEFAULT 1,
+					g_delete_topics INTEGER NOT NULL DEFAULT 1,
+					g_set_title INTEGER NOT NULL DEFAULT 1,
+					g_search INTEGER NOT NULL DEFAULT 1,
+					g_search_users INTEGER NOT NULL DEFAULT 1,
+					g_edit_subjects_interval INTEGER NOT NULL DEFAULT 300,
+					g_post_flood INTEGER NOT NULL DEFAULT 30,
+					g_search_flood INTEGER NOT NULL DEFAULT 30,
+					PRIMARY KEY (g_id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'groups. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."online (
+					user_id INT(10) UNSIGNED NOT NULL DEFAULT 1,
+					ident VARCHAR(200) NOT NULL DEFAULT '',
+					logged INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					idle TINYINT(1) NOT NULL DEFAULT 0
+					) TYPE=HEAP;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."online (
+					user_id INT NOT NULL DEFAULT 1,
+					ident VARCHAR(200) NOT NULL DEFAULT '',
+					logged INT NOT NULL DEFAULT 0,
+					idle SMALLINT NOT NULL DEFAULT 0
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."online (
+					user_id INTEGER NOT NULL DEFAULT 1,
+					ident VARCHAR(200) NOT NULL DEFAULT '',
+					logged INTEGER NOT NULL DEFAULT 0,
+					idle INTEGER NOT NULL DEFAULT 0
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'online. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."posts (
+					id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+					poster VARCHAR(200) NOT NULL DEFAULT '',
+					poster_id INT(10) UNSIGNED NOT NULL DEFAULT 1,
+					poster_ip VARCHAR(15),
+					poster_email VARCHAR(50),
+					message TEXT,
+					hide_smilies TINYINT(1) NOT NULL DEFAULT 0,
+					posted INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					edited INT(10) UNSIGNED,
+					edited_by VARCHAR(200),
+					topic_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."posts (
+					id SERIAL,
+					poster VARCHAR(200) NOT NULL DEFAULT '',
+					poster_id INT NOT NULL DEFAULT 1,
+					poster_ip VARCHAR(15),
+					poster_email VARCHAR(50),
+					message TEXT,
+					hide_smilies SMALLINT NOT NULL DEFAULT 0,
+					posted INT NOT NULL DEFAULT 0,
+					edited INT,
+					edited_by VARCHAR(200),
+					topic_id INT NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."posts (
+					id INTEGER NOT NULL,
+					poster VARCHAR(200) NOT NULL DEFAULT '',
+					poster_id INTEGER NOT NULL DEFAULT 1,
+					poster_ip VARCHAR(15),
+					poster_email VARCHAR(50),
+					message TEXT,
+					hide_smilies INTEGER NOT NULL DEFAULT 0,
+					posted INTEGER NOT NULL DEFAULT 0,
+					edited INTEGER,
+					edited_by VARCHAR(200),
+					topic_id INTEGER NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'posts. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."ranks (
+					id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+					rank VARCHAR(50) NOT NULL DEFAULT '',
+					min_posts MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."ranks (
+					id SERIAL,
+					rank VARCHAR(50) NOT NULL DEFAULT '',
+					min_posts INT NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."ranks (
+					id INTEGER NOT NULL,
+					rank VARCHAR(50) NOT NULL DEFAULT '',
+					min_posts INTEGER NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'titles. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."reports (
+					id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+					post_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					topic_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					forum_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					reported_by INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					created INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					message TEXT,
+					zapped INT(10) UNSIGNED,
+					zapped_by INT(10) UNSIGNED,
+					PRIMARY KEY (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."reports (
+					id SERIAL,
+					post_id INT NOT NULL DEFAULT 0,
+					topic_id INT NOT NULL DEFAULT 0,
+					forum_id INT NOT NULL DEFAULT 0,
+					reported_by INT NOT NULL DEFAULT 0,
+					created INT NOT NULL DEFAULT 0,
+					message TEXT,
+					zapped INT,
+					zapped_by INT,
+					PRIMARY KEY (id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."reports (
+					id INTEGER NOT NULL,
+					post_id INTEGER NOT NULL DEFAULT 0,
+					topic_id INTEGER NOT NULL DEFAULT 0,
+					forum_id INTEGER NOT NULL DEFAULT 0,
+					reported_by INTEGER NOT NULL DEFAULT 0,
+					created INTEGER NOT NULL DEFAULT 0,
+					message TEXT,
+					zapped INTEGER,
+					zapped_by INTEGER,
+					PRIMARY KEY (id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'reports. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."search_cache (
+					id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					ident VARCHAR(200) NOT NULL DEFAULT '',
+					search_data TEXT,
+					PRIMARY KEY (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."search_cache (
+					id INT NOT NULL DEFAULT 0,
+					ident VARCHAR(200) NOT NULL DEFAULT '',
+					search_data TEXT,
+					PRIMARY KEY (id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."search_cache (
+					id INTEGER NOT NULL DEFAULT 0,
+					ident VARCHAR(200) NOT NULL DEFAULT '',
+					search_data TEXT,
+					PRIMARY KEY (id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'search_cache. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."search_matches (
+					post_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					word_id MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0,
+					subject_match TINYINT(1) NOT NULL DEFAULT 0
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."search_matches (
+					post_id INT NOT NULL DEFAULT 0,
+					word_id INT NOT NULL DEFAULT 0,
+					subject_match SMALLINT NOT NULL DEFAULT 0
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."search_matches (
+					post_id INTEGER NOT NULL DEFAULT 0,
+					word_id INTEGER NOT NULL DEFAULT 0,
+					subject_match INTEGER NOT NULL DEFAULT 0
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'search_matches. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."search_words (
+					id MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT,
+					word VARCHAR(20) BINARY NOT NULL DEFAULT '',
+					PRIMARY KEY (word),
+					KEY ".$db_prefix."search_words_id_idx (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."search_words (
+					id SERIAL,
+					word VARCHAR(20) NOT NULL DEFAULT '',
+					PRIMARY KEY (word)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."search_words (
+					id INTEGER NOT NULL,
+					word VARCHAR(20) NOT NULL DEFAULT '',
+					PRIMARY KEY (id),
+					UNIQUE (word)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'search_words. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."subscriptions (
+					user_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					topic_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					PRIMARY KEY (user_id, topic_id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."subscriptions (
+					user_id INT NOT NULL DEFAULT 0,
+					topic_id INT NOT NULL DEFAULT 0,
+					PRIMARY KEY (user_id, topic_id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."subscriptions (
+					user_id INTEGER NOT NULL DEFAULT 0,
+					topic_id INTEGER NOT NULL DEFAULT 0,
+					PRIMARY KEY (user_id, topic_id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'subscriptions. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."topics (
+					id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+					poster VARCHAR(200) NOT NULL DEFAULT '',
+					subject VARCHAR(255) NOT NULL DEFAULT '',
+					posted INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					last_post INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					last_post_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					last_poster VARCHAR(200),
+					num_views MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0,
+					num_replies MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT 0,
+					closed TINYINT(1) NOT NULL DEFAULT 0,
+					sticky TINYINT(1) NOT NULL DEFAULT 0,
+					moved_to INT(10) UNSIGNED,
+					forum_id INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."topics (
+					id SERIAL,
+					poster VARCHAR(200) NOT NULL DEFAULT '',
+					subject VARCHAR(255) NOT NULL DEFAULT '',
+					posted INT NOT NULL DEFAULT 0,
+					last_post INT NOT NULL DEFAULT 0,
+					last_post_id INT NOT NULL DEFAULT 0,
+					last_poster VARCHAR(200),
+					num_views INT NOT NULL DEFAULT 0,
+					num_replies INT NOT NULL DEFAULT 0,
+					closed SMALLINT NOT NULL DEFAULT 0,
+					sticky SMALLINT NOT NULL DEFAULT 0,
+					moved_to INT,
+					forum_id INT NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."topics (
+					id INTEGER NOT NULL,
+					poster VARCHAR(200) NOT NULL DEFAULT '',
+					subject VARCHAR(255) NOT NULL DEFAULT '',
+					posted INTEGER NOT NULL DEFAULT 0,
+					last_post INTEGER NOT NULL DEFAULT 0,
+					last_post_id INTEGER NOT NULL DEFAULT 0,
+					last_poster VARCHAR(200),
+					num_views INTEGER NOT NULL DEFAULT 0,
+					num_replies INTEGER NOT NULL DEFAULT 0,
+					closed INTEGER NOT NULL DEFAULT 0,
+					sticky INTEGER NOT NULL DEFAULT 0,
+					moved_to INTEGER,
+					forum_id INTEGER NOT NULL DEFAULT 0,
+					PRIMARY KEY (id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'topics. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'CREATE TABLE '.$db_prefix."users (
+					id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+					group_id INT(10) UNSIGNED NOT NULL DEFAULT 4,
+					username VARCHAR(200) NOT NULL DEFAULT '',
+					password VARCHAR(40) NOT NULL DEFAULT '',
+					email VARCHAR(50) NOT NULL DEFAULT '',
+					title VARCHAR(50),
+					realname VARCHAR(40),
+					url VARCHAR(100),
+					jabber VARCHAR(75),
+					icq VARCHAR(12),
+					msn VARCHAR(50),
+					aim VARCHAR(30),
+					yahoo VARCHAR(30),
+					location VARCHAR(30),
+					use_avatar TINYINT(1) NOT NULL DEFAULT 0,
+					signature TEXT,
+					disp_topics TINYINT(3) UNSIGNED,
+					disp_posts TINYINT(3) UNSIGNED,
+					email_setting TINYINT(1) NOT NULL DEFAULT 1,
+					save_pass TINYINT(1) NOT NULL DEFAULT 1,
+					notify_with_post TINYINT(1) NOT NULL DEFAULT 0,
+					show_smilies TINYINT(1) NOT NULL DEFAULT 1,
+					show_img TINYINT(1) NOT NULL DEFAULT 1,
+					show_img_sig TINYINT(1) NOT NULL DEFAULT 1,
+					show_avatars TINYINT(1) NOT NULL DEFAULT 1,
+					show_sig TINYINT(1) NOT NULL DEFAULT 1,
+					timezone FLOAT NOT NULL DEFAULT 0,
+					language VARCHAR(25) NOT NULL DEFAULT 'English',
+					style VARCHAR(25) NOT NULL DEFAULT 'Oxygen',
+					num_posts INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					last_post INT(10) UNSIGNED,
+					registered INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					registration_ip VARCHAR(15) NOT NULL DEFAULT '0.0.0.0',
+					last_visit INT(10) UNSIGNED NOT NULL DEFAULT 0,
+					admin_note VARCHAR(30),
+					activate_string VARCHAR(50),
+					activate_key VARCHAR(8),
+					PRIMARY KEY (id)
+					) TYPE=MyISAM;";
+			break;
+
+		case 'pgsql':
+			$sql = 'CREATE TABLE '.$db_prefix."users (
+					id SERIAL,
+					group_id INT NOT NULL DEFAULT 4,
+					username VARCHAR(200) NOT NULL DEFAULT '',
+					password VARCHAR(40) NOT NULL DEFAULT '',
+					email VARCHAR(50) NOT NULL DEFAULT '',
+					title VARCHAR(50),
+					realname VARCHAR(40),
+					url VARCHAR(100),
+					jabber VARCHAR(75),
+					icq VARCHAR(12),
+					msn VARCHAR(50),
+					aim VARCHAR(30),
+					yahoo VARCHAR(30),
+					location VARCHAR(30),
+					use_avatar SMALLINT NOT NULL DEFAULT 0,
+					signature TEXT,
+					disp_topics SMALLINT,
+					disp_posts SMALLINT,
+					email_setting SMALLINT NOT NULL DEFAULT 1,
+					save_pass SMALLINT NOT NULL DEFAULT 1,
+					notify_with_post SMALLINT NOT NULL DEFAULT 0,
+					show_smilies SMALLINT NOT NULL DEFAULT 1,
+					show_img SMALLINT NOT NULL DEFAULT 1,
+					show_img_sig SMALLINT NOT NULL DEFAULT 1,
+					show_avatars SMALLINT NOT NULL DEFAULT 1,
+					show_sig SMALLINT NOT NULL DEFAULT 1,
+					timezone REAL NOT NULL DEFAULT 0,
+					language VARCHAR(25) NOT NULL DEFAULT 'English',
+					style VARCHAR(25) NOT NULL DEFAULT 'Oxygen',
+					num_posts INT NOT NULL DEFAULT 0,
+					last_post INT,
+					registered INT NOT NULL DEFAULT 0,
+					registration_ip VARCHAR(15) NOT NULL DEFAULT '0.0.0.0',
+					last_visit INT NOT NULL DEFAULT 0,
+					admin_note VARCHAR(30),
+					activate_string VARCHAR(50),
+					activate_key VARCHAR(8),
+					PRIMARY KEY (id)
+					)";
+			break;
+
+		case 'sqlite':
+			$sql = 'CREATE TABLE '.$db_prefix."users (
+					id INTEGER NOT NULL,
+					group_id INTEGER NOT NULL DEFAULT 4,
+					username VARCHAR(200) NOT NULL DEFAULT '',
+					password VARCHAR(40) NOT NULL DEFAULT '',
+					email VARCHAR(50) NOT NULL DEFAULT '',
+					title VARCHAR(50),
+					realname VARCHAR(40),
+					url VARCHAR(100),
+					jabber VARCHAR(75),
+					icq VARCHAR(12),
+					msn VARCHAR(50),
+					aim VARCHAR(30),
+					yahoo VARCHAR(30),
+					location VARCHAR(30),
+					use_avatar INTEGER NOT NULL DEFAULT 0,
+					signature TEXT,
+					disp_topics INTEGER,
+					disp_posts INTEGER,
+					email_setting INTEGER NOT NULL DEFAULT 1,
+					save_pass INTEGER NOT NULL DEFAULT 1,
+					notify_with_post INTEGER NOT NULL DEFAULT 0,
+					show_smilies INTEGER NOT NULL DEFAULT 1,
+					show_img INTEGER NOT NULL DEFAULT 1,
+					show_img_sig INTEGER NOT NULL DEFAULT 1,
+					show_avatars INTEGER NOT NULL DEFAULT 1,
+					show_sig INTEGER NOT NULL DEFAULT 1,
+					timezone FLOAT NOT NULL DEFAULT 0,
+					language VARCHAR(25) NOT NULL DEFAULT 'English',
+					style VARCHAR(25) NOT NULL DEFAULT 'Oxygen',
+					num_posts INTEGER NOT NULL DEFAULT 0,
+					last_post INTEGER,
+					registered INTEGER NOT NULL DEFAULT 0,
+					registration_ip VARCHAR(15) NOT NULL DEFAULT '0.0.0.0',
+					last_visit INTEGER NOT NULL DEFAULT 0,
+					admin_note VARCHAR(30),
+					activate_string VARCHAR(50),
+					activate_key VARCHAR(8),
+					PRIMARY KEY (id)
+					)";
+			break;
+	}
+
+	$db->query($sql) or error('Unable to create table '.$db_prefix.'users. Please check your settings and try again.',  __FILE__, __LINE__, $db->error());
+
+
+	// Add some indexes
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			// We use MySQL's ALTER TABLE ... ADD INDEX syntax instead of CREATE INDEX to avoid problems with users lacking the INDEX privilege
+			$queries[] = 'ALTER TABLE '.$db_prefix.'online ADD UNIQUE INDEX '.$db_prefix.'online_user_id_ident_idx(user_id,ident)';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'online ADD INDEX '.$db_prefix.'online_user_id_idx(user_id)';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'posts ADD INDEX '.$db_prefix.'posts_topic_id_idx(topic_id)';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'posts ADD INDEX '.$db_prefix.'posts_multi_idx(poster_id, topic_id)';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'reports ADD INDEX '.$db_prefix.'reports_zapped_idx(zapped)';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'search_matches ADD INDEX '.$db_prefix.'search_matches_word_id_idx(word_id)';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'search_matches ADD INDEX '.$db_prefix.'search_matches_post_id_idx(post_id)';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'topics ADD INDEX '.$db_prefix.'topics_forum_id_idx(forum_id)';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'topics ADD INDEX '.$db_prefix.'topics_moved_to_idx(moved_to)';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'users ADD INDEX '.$db_prefix.'users_registered_idx(registered)';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'search_cache ADD INDEX '.$db_prefix.'search_cache_ident_idx(ident(8))';
+			$queries[] = 'ALTER TABLE '.$db_prefix.'users ADD INDEX '.$db_prefix.'users_username_idx(username(8))';
+			break;
+
+		default:
+			$queries[] = 'CREATE INDEX '.$db_prefix.'online_user_id_idx ON '.$db_prefix.'online(user_id)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'posts_topic_id_idx ON '.$db_prefix.'posts(topic_id)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'posts_multi_idx ON '.$db_prefix.'posts(poster_id, topic_id)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'reports_zapped_idx ON '.$db_prefix.'reports(zapped)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'search_matches_word_id_idx ON '.$db_prefix.'search_matches(word_id)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'search_matches_post_id_idx ON '.$db_prefix.'search_matches(post_id)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'topics_forum_id_idx ON '.$db_prefix.'topics(forum_id)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'topics_moved_to_idx ON '.$db_prefix.'topics(moved_to)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'users_registered_idx ON '.$db_prefix.'users(registered)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'users_username_idx ON '.$db_prefix.'users(username)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'search_cache_ident_idx ON '.$db_prefix.'search_cache(ident)';
+			$queries[] = 'CREATE INDEX '.$db_prefix.'search_words_id_idx ON '.$db_prefix.'search_words(id)';
+			break;
+	}
+
+	@reset($queries);
+	while (list(, $sql) = @each($queries))
+		$db->query($sql) or error('Unable to create indexes. Please check your configuration and try again.',  __FILE__, __LINE__, $db->error());
+
+
+
+	$now = time();
+
+	// Insert the four preset groups
+	$db->query('INSERT INTO '.$db->prefix."groups (g_title, g_user_title, g_read_board, g_post_replies, g_post_topics, g_post_polls, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_edit_subjects_interval, g_post_flood, g_search_flood) VALUES('Administrators', 'Administrator', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error());
+	$db->query('INSERT INTO '.$db->prefix."groups (g_title, g_user_title, g_read_board, g_post_replies, g_post_topics, g_post_polls, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_edit_subjects_interval, g_post_flood, g_search_flood) VALUES('Moderators', 'Moderator', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error());
+	$db->query('INSERT INTO '.$db->prefix."groups (g_title, g_user_title, g_read_board, g_post_replies, g_post_topics, g_post_polls, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_edit_subjects_interval, g_post_flood, g_search_flood) VALUES('Guest', NULL, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0)") or error('Unable to add group', __FILE__, __LINE__, $db->error());
+	$db->query('INSERT INTO '.$db->prefix."groups (g_title, g_user_title, g_read_board, g_post_replies, g_post_topics, g_post_polls, g_edit_posts, g_delete_posts, g_delete_topics, g_set_title, g_search, g_search_users, g_edit_subjects_interval, g_post_flood, g_search_flood) VALUES('Members', NULL, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 300, 60, 30)") or error('Unable to add group', __FILE__, __LINE__, $db->error());
+
+	// Insert guest and first admin user
+	$db->query('INSERT INTO '.$db_prefix."users (group_id, username, password, email) VALUES(3, 'Guest', 'Guest', 'Guest')")
+		or error('Unable to add guest user. Please check your configuration and try again.');
+
+	$db->query('INSERT INTO '.$db_prefix."users (group_id, username, password, email, num_posts, last_post, registered, registration_ip, last_visit) VALUES(1, '".$db->escape($username)."', '".pun_hash($password1)."', '$email', 1, ".$now.", ".$now.", '127.0.0.1', ".$now.')')
+		or error('Unable to add administrator user. Please check your configuration and try again.');
+
+	// Insert config data
+	$config = array(
+		'o_cur_version'				=> "'$punbb_version'",
+		'o_board_title'				=> "'My PunBB forum'",
+		'o_board_desc'				=> "'Unfortunately no one can be told what PunBB is - you have to see it for yourself.'",
+		'o_server_timezone'			=> "'0'",
+		'o_time_format'				=> "'H:i:s'",
+		'o_date_format'				=> "'Y-m-d'",
+		'o_timeout_visit'			=> "'600'",
+		'o_timeout_online'			=> "'300'",
+		'o_redirect_delay'			=> "'1'",
+		'o_show_version'			=> "'0'",
+		'o_show_user_info'			=> "'1'",
+		'o_show_post_count'			=> "'1'",
+		'o_smilies'					=> "'1'",
+		'o_smilies_sig'				=> "'1'",
+		'o_make_links'				=> "'1'",
+		'o_default_lang'			=> "'English'",
+		'o_default_style'			=> "'Oxygen'",
+		'o_default_user_group'		=> "'4'",
+		'o_topic_review'			=> "'15'",
+		'o_disp_topics_default'		=> "'30'",
+		'o_disp_posts_default'		=> "'25'",
+		'o_indent_num_spaces'		=> "'4'",
+		'o_quickpost'				=> "'1'",
+		'o_users_online'			=> "'1'",
+		'o_censoring'				=> "'0'",
+		'o_ranks'					=> "'1'",
+		'o_show_dot'				=> "'0'",
+		'o_quickjump'				=> "'1'",
+		'o_gzip'					=> "'0'",
+		'o_additional_navlinks'		=> "''",
+		'o_report_method'			=> "'0'",
+		'o_regs_report'				=> "'0'",
+		'o_mailing_list'			=> "'$email'",
+		'o_avatars'					=> "'1'",
+		'o_avatars_dir'				=> "'img/avatars'",
+		'o_avatars_width'			=> "'60'",
+		'o_avatars_height'			=> "'60'",
+		'o_avatars_size'			=> "'10240'",
+		'o_search_all_forums'		=> "'1'",
+		'o_base_url'				=> "'$base_url'",
+		'o_admin_email'				=> "'$email'",
+		'o_webmaster_email'			=> "'$email'",
+		'o_subscriptions'			=> "'1'",
+		'o_smtp_host'				=> "NULL",
+		'o_smtp_user'				=> "NULL",
+		'o_smtp_pass'				=> "NULL",
+		'o_regs_allow'				=> "'1'",
+		'o_regs_verify'				=> "'0'",
+		'o_announcement'			=> "'0'",
+		'o_announcement_message'	=> "'Enter your announcement here.'",
+		'o_rules'					=> "'0'",
+		'o_rules_message'			=> "'Enter your rules here.'",
+		'o_maintenance'				=> "'0'",
+		'o_maintenance_message'		=> "'The forums are temporarily down for maintenance. Please try again in a few minutes.<br />\\n<br />\\n/Administrator'",
+		'p_mod_edit_users'			=> "'1'",
+		'p_mod_rename_users'		=> "'0'",
+		'p_mod_change_passwords'	=> "'0'",
+		'p_mod_ban_users'			=> "'0'",
+		'p_message_bbcode'			=> "'1'",
+		'p_message_img_tag'			=> "'1'",
+		'p_message_all_caps'		=> "'1'",
+		'p_subject_all_caps'		=> "'1'",
+		'p_sig_all_caps'			=> "'1'",
+		'p_sig_bbcode'				=> "'1'",
+		'p_sig_img_tag'				=> "'0'",
+		'p_sig_length'				=> "'400'",
+		'p_sig_lines'				=> "'4'",
+		'p_allow_banned_email'		=> "'1'",
+		'p_allow_dupe_email'		=> "'0'",
+		'p_force_guest_email'		=> "'1'"
+	);
+
+	while (list($conf_name, $conf_value) = @each($config))
+	{
+		$db->query('INSERT INTO '.$db_prefix."config (conf_name, conf_value) VALUES('$conf_name', $conf_value)")
+			or error('Unable to insert into table '.$db_prefix.'config. Please check your configuration and try again.');
+	}
+
+	// Insert some other default data
+	$db->query('INSERT INTO '.$db_prefix."categories (cat_name, disp_position) VALUES('Test category', 1)")
+		or error('Unable to insert into table '.$db_prefix.'categories. Please check your configuration and try again.');
+
+	$db->query('INSERT INTO '.$db_prefix."forums (forum_name, forum_desc, num_topics, num_posts, last_post, last_post_id, last_poster, disp_position, cat_id) VALUES('Test forum', 'This is just a test forum', 1, 1, ".$now.", 1, '".$db->escape($username)."', 1, 1)")
+		or error('Unable to insert into table '.$db_prefix.'forums. Please check your configuration and try again.');
+
+	$db->query('INSERT INTO '.$db_prefix."topics (poster, subject, posted, last_post, last_post_id, last_poster, forum_id) VALUES('".$db->escape($username)."', 'Test post', ".$now.", ".$now.", 1, '".$db->escape($username)."', 1)")
+		or error('Unable to insert into table '.$db_prefix.'topics. Please check your configuration and try again.');
+
+	$db->query('INSERT INTO '.$db_prefix."posts (poster, poster_id, poster_ip, message, posted, topic_id) VALUES('".$db->escape($username)."', 2, '127.0.0.1', 'If you are looking at this (which I guess you are), the install of PunBB appears to have worked! Now log in and head over to the administration control panel to configure your forum.', ".$now.', 1)')
+		or error('Unable to insert into table '.$db_prefix.'posts. Please check your configuration and try again.');
+
+	$db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('New member', 0)")
+		or error('Unable to insert into table '.$db_prefix.'ranks. Please check your configuration and try again.');
+
+	$db->query('INSERT INTO '.$db_prefix."ranks (rank, min_posts) VALUES('Member', 10)")
+		or error('Unable to insert into table '.$db_prefix.'ranks. Please check your configuration and try again.');
+
+
+	if ($db_type == 'pgsql' || $db_type == 'sqlite')
+		$db->end_transaction();
+
+
+
+	$alerts = '';
+	// Check if the cache directory is writable
+	if (!@is_writable('./cache/'))
+		$alerts .= '<p style="font-size: 1.1em"><span style="color: #C03000"><strong>The cache directory is currently not writable!</strong></span> In order for PunBB to function properly, the directory named <em>cache</em> must be writable by PHP. Use chmod to set the appropriate directory permissions. If in doubt, chmod to 0777.</p>';
+
+	// Check if default avatar directory is writable
+	if (!@is_writable('./img/avatars/'))
+		$alerts .= '<p style="font-size: 1.1em"><span style="color: #C03000"><strong>The avatar directory is currently not writable!</strong></span> If you want users to be able to upload their own avatar images you must see to it that the directory named <em>img/avatars</em> is writable by PHP. You can later choose to save avatar images in a different directory (see Admin/Options). Use chmod to set the appropriate directory permissions. If in doubt, chmod to 0777.</p>';
+
+
+	/// Display config.php and give further instructions
+	$config = '<?php'."\n\n".'$db_type = \''.$db_type."';\n".'$db_host = \''.$db_host."';\n".'$db_name = \''.$db_name."';\n".'$db_username = \''.$db_username."';\n".'$db_password = \''.$db_password."';\n".'$db_prefix = \''.$db_prefix."';\n".'$p_connect = false;'."\n\n".'$cookie_name = '."'punbb_cookie';\n".'$cookie_domain = '."'';\n".'$cookie_path = '."'/';\n".'$cookie_secure = 0;'."\n".'$cookie_seed = \''.substr(md5(time()), -8)."';\n\ndefine('PUN', 1);";
+
+
+?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<title>PunBB Installation</title>
+<link rel="stylesheet" type="text/css" href="style/Oxygen.css" />
+</head>
+<body>
+
+<div id="puninstall" style="margin: auto 10% auto 10%">
+<div class="pun">
+
+<div class="blockform">
+	<h2>Final instructions</h2>
+	<div class="box">
+		<div class="fakeform">
+			<div class="inform">
+				<div class="forminfo">
+					<p>To finalize the installation all you need to do is to <strong>copy and paste the text in the text box below into a file called config.php and then upload this file to the root directory of your PunBB installation</strong>. Make sure there are no linebreaks or spaces before &lt;?php. You can later edit config.php if you reconfigure your setup (e.g. change the database password or ).</p>
+<?php if ($alerts != ''): ?>					<?php echo $alerts."\n" ?>
+<?php endif; ?>				</div>
+				<fieldset>
+					<legend>Copy contents to config.php</legend>
+					<div class="infldset">
+						<textarea cols="80" rows="20"><?php echo htmlspecialchars($config) ?></textarea>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<div class="forminfo">
+					<p>Once you have created config.php with the contents above, PunBB is installed!</p>
+					<p><a href="index.php">Go to forum index</a></p>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+
+</div>
+</div>
+
+</body>
+</html>
+<?php
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/common.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,153 @@
+<?php
+
+/*
+// Determine what locale to use
+switch (PHP_OS)
+{
+	case 'WINNT':
+	case 'WIN32':
+		$locale = 'english';
+		break;
+
+	case 'FreeBSD':
+	case 'NetBSD':
+	case 'OpenBSD':
+		$locale = 'en_US.US-ASCII';
+		break;
+
+	default:
+		$locale = 'en_US';
+		break;
+}
+
+// Attempt to set the locale
+setlocale(LC_CTYPE, $locale);
+*/
+
+// Language definitions for frequently used strings
+$lang_common = array(
+
+// Text orientation and encoding
+'lang_direction'		=>	'ltr',	// ltr (Left-To-Right) or rtl (Right-To-Left)
+'lang_encoding'			=>	'iso-8859-1',
+'lang_multibyte'		=>	false,
+
+// Notices
+'Bad request'			=>	'Bad request. The link you followed is incorrect or outdated.',
+'No view'				=>	'You do not have permission to view these forums.',
+'No permission'			=>	'You do not have permission to access this page.',
+'Bad referrer'			=>	'Bad HTTP_REFERER. You were referred to this page from an unauthorized source. If the problem persists please make sure that \'Base URL\' is correctly set in Admin/Options and that you are visiting the forum by navigating to that URL. More information regarding the referrer check can be found in the PunBB documentation.',
+
+// Topic/forum indicators
+'New icon'				=>	'There are new posts',
+'Normal icon'			=>	'<!-- -->',
+'Closed icon'			=>	'This topic is closed',
+'Redirect icon'			=>	'Redirected forum',
+
+// Miscellaneous
+'Announcement'			=>	'Announcement',
+'Options'				=>	'Options',
+'Actions'				=>	'Actions',
+'Submit'				=>	'Submit',	// "name" of submit buttons
+'Ban message'			=>	'You are banned from this forum.',
+'Ban message 2'			=>	'The ban expires at the end of',
+'Ban message 3'			=>	'The administrator or moderator that banned you left the following message:',
+'Ban message 4'			=>	'Please direct any inquiries to the forum administrator at',
+'Never'					=>	'Never',
+'Today'					=>	'Today',
+'Yesterday'				=>	'Yesterday',
+'Info'					=>	'Info',		// a common table header
+'Go back'				=>	'Go back',
+'Maintenance'			=>	'Maintenance',
+'Redirecting'			=>	'Redirecting',
+'Click redirect'		=>	'Click here if you do not want to wait any longer (or if your browser does not automatically forward you)',
+'on'					=>	'on',		// as in "BBCode is on"
+'off'					=>	'off',
+'Invalid e-mail'		=>	'The e-mail address you entered is invalid.',
+'required field'		=>	'is a required field in this form.',	// for javascript form validation
+'Last post'				=>	'Last post',
+'by'					=>	'by',	// as in last post by someuser
+'New posts'				=>	'New&nbsp;posts',	// the link that leads to the first new post (use &nbsp; for spaces)
+'New posts info'		=>	'Go to the first new post in this topic.',	// the popup text for new posts links
+'Username'				=>	'Username',
+'Password'				=>	'Password',
+'E-mail'				=>	'E-mail',
+'Send e-mail'			=>	'Send e-mail',
+'Moderated by'			=>	'Moderated by',
+'Registered'			=>	'Registered',
+'Subject'				=>	'Subject',
+'Message'				=>	'Message',
+'Topic'					=>	'Topic',
+'Forum'					=>	'Forum',
+'Posts'					=>	'Posts',
+'Replies'				=>	'Replies',
+'Author'				=>	'Author',
+'Pages'					=>	'Pages',
+'BBCode'				=>	'BBCode',	// You probably shouldn't change this
+'img tag'				=>	'[img] tag',
+'Smilies'				=>	'Smilies',
+'and'					=>	'and',
+'Image link'			=>	'image',	// This is displayed (i.e. <image>) instead of images when "Show images" is disabled in the profile
+'wrote'					=>	'wrote',	// For [quote]'s
+'Code'					=>	'Code',		// For [code]'s
+'Mailer'				=>	'Mailer',	// As in "MyForums Mailer" in the signature of outgoing e-mails
+'Important information'	=>	'Important information',
+'Write message legend'	=>	'Write your message and submit',
+
+// Title
+'Title'					=>	'Title',
+'Member'				=>	'Member',	// Default title
+'Moderator'				=>	'Moderator',
+'Administrator'			=>	'Administrator',
+'Banned'				=>	'Banned',
+'Guest'					=>	'Guest',
+
+// Stuff for include/parser.php
+'BBCode error'			=>	'The BBCode syntax in the message is incorrect.',
+'BBCode error 1'		=>	'Missing start tag for [/quote].',
+'BBCode error 2'		=>	'Missing end tag for [code].',
+'BBCode error 3'		=>	'Missing start tag for [/code].',
+'BBCode error 4'		=>	'Missing one or more end tags for [quote].',
+'BBCode error 5'		=>	'Missing one or more start tags for [/quote].',
+
+// Stuff for the navigator (top of every page)
+'Index'					=>	'Index',
+'User list'				=>	'User list',
+'Rules'					=>  'Rules',
+'Search'				=>  'Search',
+'Register'				=>  'Register',
+'Login'					=>  'Login',
+'Not logged in'			=>  'You are not logged in.',
+'Profile'				=>	'Profile',
+'Logout'				=>	'Logout',
+'Logged in as'			=>	'Logged in as',
+'Admin'					=>	'Administration',
+'Last visit'			=>	'Last visit',
+'Show new posts'		=>	'Show new posts since last visit',
+'Mark all as read'		=>	'Mark all topics as read',
+'Link separator'		=>	'',	// The text that separates links in the navigator
+
+// Stuff for the page footer
+'Board footer'			=>	'Board footer',
+'Search links'			=>	'Search links',
+'Show recent posts'		=>	'Show recent posts',
+'Show unanswered posts'	=>	'Show unanswered posts',
+'Show your posts'		=>	'Show your posts',
+'Show subscriptions'	=>	'Show your subscribed topics',
+'Jump to'				=>	'Jump to',
+'Go'					=>	' Go ',		// submit button in forum jump
+'Move topic'			=>  'Move topic',
+'Open topic'			=>  'Open topic',
+'Close topic'			=>  'Close topic',
+'Unstick topic'			=>  'Unstick topic',
+'Stick topic'			=>  'Stick topic',
+'Moderate forum'		=>	'Moderate forum',
+'Delete posts'			=>	'Delete multiple posts',
+'Debug table'			=>	'Debug information',
+
+// For extern.php RSS feed
+'RSS Desc Active'		=>	'The most recently active topics at',	// board_title will be appended to this string
+'RSS Desc New'			=>	'The newest topics at',					// board_title will be appended to this string
+'Posted'				=>	'Posted'	// The date/time a topic was started
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/delete.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,12 @@
+<?php
+
+// Language definitions used in delete.php
+$lang_delete = array(
+
+'Delete post'			=>	'Delete post',
+'Warning'				=>	'Warning! If this is the first post in the topic, the whole topic will be deleted.',
+'Delete'				=>	'Delete',	// The submit button
+'Post del redirect'		=>	'Post deleted. Redirecting &hellip;',
+'Topic del redirect'	=>	'Topic deleted. Redirecting &hellip;'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/forum.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,12 @@
+<?php
+
+// Language definitions used in viewforum.php
+$lang_forum = array(
+
+'Post topic'	=>	'Post new topic',
+'Views'			=>	'Views',
+'Moved'			=>	'Moved',
+'Sticky'		=>	'Sticky',
+'Empty forum'	=>	'Forum is empty.'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/help.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,42 @@
+<?php
+
+// Language definitions used in help.php
+$lang_help = array(
+
+'Help'					=>	'Help',
+'produces'				=>	'produces',
+
+'BBCode info 1'			=>	'BBCode is a collection of formatting tags that are used to change the look of text in this forum. BBCode is based on the same principal as, and is very similar to, HTML. Below is a list of all the available BBCodes and instructions on how to use them.',
+'BBCode info 2'			=>	'Administrators have the ability to enable or disable BBCode. You can tell if BBCode is enabled or disabled out in the left margin whenever you post a message or edit your signature.',
+
+'Text style'			=>	'Text style',
+'Text style info'		=>	'The following tags change the appearance of text:',
+'Bold text'				=>	'Bold text',
+'Underlined text'		=>	'Underlined text',
+'Italic text'			=>	'Italic text',
+'Red text'				=>	'Red text',
+'Blue text'				=>	'Blue text',
+
+'Links and images'		=>	'Links and images',
+'Links info'			=>	'You can create links to other documents or to e-mail addresses using the following tags:',
+'My e-mail address'		=>	'My e-mail address',
+'Images info'			=>	'If you want to display an image you can use the img tag.',
+
+'Quotes'				=>	'Quotes',
+'Quotes info'			=>	'If you want to quote someone, you should use the quote tag.',
+'Quotes info 2'			=>	'If you don\'t want to quote anyone in particular, you can use the quote tag without specifying a name.',
+'Quote text'			=>	'This is the text i want to quote.',
+'produces quote box'	=>	'produces a quote box like this:',
+
+'Code'					=>	'Code',
+'Code info'				=>	'When displaying source code you should make sure that you use the code tag. Text displayed with the code tag will use a monospaced font and will not be affected by other tags.',
+'Code text'				=>	'This is some code.',
+'produces code box'		=>	'produces a code box like this:',
+
+'Nested tags'			=>	'Nested tags',
+'Nested tags info'		=>	'BBCode can be nested to create more advanced formatting. For example:',
+'Bold, underlined text'	=>	'Bold, underlined text',
+
+'Smilies info'			=>	'If you like (and if it is enabled), the forum can convert a series of smilies to images representations of that smiley. This forum recognizes the following smilies and replaces them with images:'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/index.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,21 @@
+<?php
+
+// Language definitions used in index.php
+$lang_index = array(
+
+'Topics'				=>  'Topics',
+'Moderators'			=>  'Moderators',
+'Link to'				=>	'Link to',	// As in "Link to http://www.punbb.org/"
+'Empty board'			=>	'Board is empty.',
+'Newest user'			=>	'Newest registered user',
+'Users online'			=>	'Registered users online',
+'Guests online'			=>	'Guests online',
+'No of users'			=>	'Total number of registered users',
+'No of topics'			=>	'Total number of topics',
+'No of posts'			=>	'Total number of posts',
+'Online'				=>	'Online',	// As in "Online: User A, User B etc."
+'Board info'			=>	'Board information',
+'Board stats'			=>	'Board statistics',
+'User info'				=>	'User information'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/login.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,22 @@
+<?php
+
+// Language definitions used in delete.php
+$lang_login = array(
+
+// Miscellaneous
+'Wrong user/pass'		=>	'Wrong username and/or password.',
+'Forgotten pass'		=>	'Forgotten your password?',
+'Login redirect'		=>	'Logged in successfully. Redirecting &hellip;',
+'Logout redirect'		=>	'Logged out. Redirecting &hellip;',
+'No e-mail match'		=>	'There is no user registered with the e-mail address',
+'Request pass'			=>	'Request password',
+'Request pass legend'	=>	'Enter the e-mail address with which you registered',
+'Request pass info'		=>	'A new password together with a link to activate the new password will be sent to that address.',
+'Not registered'		=>	'Not registered yet?',
+'Login legend'			=>	'Enter your username and password below',
+'Login info'			=>	'If you have not registered or have forgotten your password click on the appropriate link below.',
+
+// Forget password mail stuff
+'Forget mail'			=>	'An e-mail has been sent to the specified address with instructions on how to change your password. If it does not arrive you can contact the forum administrator at'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/mail_templates/activate_email.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,12 @@
+Subject: Change e-mail address requested
+
+Hello <username>,
+
+You have requested to have a new e-mail address assigned to your account in the discussion forum at <base_url>. If you didn't request this or if you don't want to change your e-mail address you should just ignore this message. Only if you visit the activation page below will your e-mail address be changed. In order for the activation page to work, you must be logged in to the forum.
+
+To change your e-mail address, please visit the following page:
+<activation_url>
+
+-- 
+<board_mailer>
+(Do not reply to this message)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/mail_templates/activate_password.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,14 @@
+Subject: New password requested
+
+Hello <username>,
+
+You have requested to have a new password assigned to your account in the discussion forum at <base_url>. If you didn't request this or if you don't want to change your password you should just ignore this message. Only if you visit the activation page below will your password be changed.
+
+Your new password is: <new_password>
+
+To change your password, please visit the following page:
+<activation_url>
+
+-- 
+<board_mailer>
+(Do not reply to this message)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/mail_templates/form_email.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,13 @@
+Subject: <mail_subject>
+
+<sender> from <board_title> has sent you a message. You can reply to <sender> by replying to this e-mail.
+
+The message reads as follows:
+-----------------------------------------------------------------------
+
+<mail_message>
+
+-----------------------------------------------------------------------
+
+-- 
+<board_mailer>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/mail_templates/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/mail_templates/new_reply.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,11 @@
+Subject: Reply to topic: <topic_subject>
+
+<replier> has replied to the topic <topic_subject> to which you are subscribed. There may be more new replies, but this is the only notification you will receive until you visit the board again.
+
+The post is located at <post_url>
+
+You can unsubscribe by going to <unsubscribe_url>
+
+-- 
+<board_mailer>
+(Do not reply to this message)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/mail_templates/new_reply_full.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,18 @@
+Subject: Reply to topic: <topic_subject>
+
+<replier> has replied to the topic <topic_subject> to which you are subscribed. There may be more new replies, but this is the only notification you will receive until you visit the board again.
+
+The message reads as follows:
+-----------------------------------------------------------------------
+
+<message>
+
+-----------------------------------------------------------------------
+
+The post is located at <post_url>
+
+You can unsubscribe by going to <unsubscribe_url>
+
+-- 
+<board_mailer>
+(Do not reply to this message)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/mail_templates/welcome.tpl	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,12 @@
+Subject: Welcome to <board_title>!
+
+Thank you for registering in the forums at <base_url>. Your account details are:
+
+Username: <username>
+Password: <password>
+
+Login at <login_url> to activate the account.
+
+--
+<board_mailer>
+(Do not reply to this message)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/misc.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,67 @@
+<?php
+
+// Language definitions used in various scripts
+$lang_misc = array(
+
+'Mark read redirect'		=>	'All topics and forums have been marked as read. Redirecting &hellip;',
+
+// Send e-mail
+'Form e-mail disabled'		=>	'The user you are trying to send an e-mail to has disabled form e-mail.',
+'No e-mail subject'			=>	'You must enter a subject.',
+'No e-mail message'			=>	'You must enter a message.',
+'Too long e-mail message'	=>	'Messages cannot be longer than 65535 characters (64 KB).',
+'E-mail sent redirect'		=>	'E-mail sent. Redirecting &hellip;',
+'Send e-mail to'			=>	'Send e-mail to',
+'E-mail subject'			=>	'Subject',
+'E-mail message'			=>	'Message',
+'E-mail disclosure note'	=>	'Please note that by using this form, your e-mail address will be disclosed to the recipient.',
+'Write e-mail'				=>	'Write and submit your e-mail message',
+
+// Report
+'No reason'					=>	'You must enter a reason.',
+'Report redirect'			=>	'Post reported. Redirecting &hellip;',
+'Report post'				=>	'Report post',
+'Reason'					=>	'Reason',
+'Reason desc'				=>	'Please enter a short reason why you are reporting this post',
+
+// Subscriptions
+'Already subscribed'		=>	'You are already subscribed to this topic.',
+'Subscribe redirect'		=>	'Your subscription has been added. Redirecting &hellip;',
+'Not subscribed'			=>	'You are not subscribed to this topic.',
+'Unsubscribe redirect'		=>	'Your subscription has been removed. Redirecting &hellip;',
+
+// General forum and topic moderation
+'Moderate'					=>	'Moderate',
+'Select'					=>	'Select',	// the header of a column of checkboxes
+'Move'						=>	'Move',
+'Delete'					=>	'Delete',
+
+// Moderate forum
+'Open'						=>	'Open',
+'Close'						=>	'Close',
+'Move topic'				=>	'Move topic',
+'Move topics'				=>	'Move topics',
+'Move legend'				=>	'Select destination of move',
+'Move to'					=>	'Move to',
+'Leave redirect'			=>	'Leave redirect topic(s)',
+'Move topic redirect'		=>	'Topic moved. Redirecting &hellip;',
+'Move topics redirect'		=>	'Topics moved. Redirecting &hellip;',
+'Confirm delete legend'		=>	'Please confirm deletion',
+'Delete topics'				=>	'Delete topics',
+'Delete topics comply'		=>	'Are you sure you want to delete the selected topics?',
+'Delete topics redirect'	=>	'Topics deleted. Redirecting &hellip;',
+'Open topic redirect'		=>	'Topic opened. Redirecting &hellip;',
+'Open topics redirect'		=>	'Topics opened. Redirecting &hellip;',
+'Close topic redirect'		=>	'Topic closed. Redirecting &hellip;',
+'Close topics redirect'		=>	'Topics closed. Redirecting &hellip;',
+'No topics selected'		=>	'You must select at least one topic for move/delete/open/close.',
+'Stick topic redirect'		=>	'Topic sticked. Redirecting &hellip;',
+'Unstick topic redirect'	=>	'Topic unsticked. Redirecting &hellip;',
+
+// Delete multiple posts in topic
+'Delete posts'				=>	'Delete posts',
+'Delete posts comply'		=>	'Are you sure you want to delete the selected posts?',
+'Delete posts redirect'		=>	'Posts deleted. Redirecting &hellip;',
+'No posts selected'			=>	'You must select at least one post to be deleted.'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/post.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,33 @@
+<?php
+
+// Language definitions used in post.php and edit.php
+$lang_post = array(
+
+// Post validation stuff (many are similiar to those in edit.php)
+'No subject'			=>	'Topics must contain a subject.',
+'Too long subject'		=>	'Subjects cannot be longer than 70 characters.',
+'No message'			=>	'You must enter a message.',
+'Too long message'		=>	'Posts cannot be longer that 65535 characters (64 KB).',
+
+// Posting
+'Post errors'			=>	'Post errors',
+'Post errors info'		=>	'The following errors need to be corrected before the message can be posted:',
+'Post preview'			=>	'Post preview',
+'Guest name'			=>	'Name',	// For guests (instead of Username)
+'Post redirect'			=>	'Post entered. Redirecting &hellip;',
+'Post a reply'			=>	'Post a reply',
+'Post new topic'		=>	'Post new topic',
+'Hide smilies'			=>	'Never show smilies as icons for this post',
+'Subscribe'				=>	'Subscribe to this topic',
+'Topic review'			=>	'Topic review (newest first)',
+'Flood start'			=>	'At least',
+'flood end'				=>	'seconds have to pass between posts. Please wait a little while and try posting again.',
+'Preview'				=>	'Preview',	// submit button to preview message
+
+// Edit post
+'Edit post legend'		=>	'Edit the post and submit changes',
+'Silent edit'			=>	'Silent edit (don\'t display "Edited by ..." in topic view)',
+'Edit post'				=>	'Edit post',
+'Edit redirect'			=>	'Post updated. Redirecting &hellip;'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/prof_reg.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,39 @@
+<?php
+
+// Language definitions used in both profile.php and register.php
+$lang_prof_reg = array(
+
+'E-mail legend'				=>	'Enter a valid e-mail address',
+'E-mail legend 2'			=>	'Enter and confirm a valid e-mail address',
+'Localisation legend'		=>	'Set your localisation options',
+'Timezone'					=>	'Timezone',
+'Timezone info'				=>	'For the forum to display times correctly you must select your local timezone.',
+'Language'					=>	'Language',
+'Language info'				=>	'You can choose which language you wish to use to view the forum.',
+'E-mail setting info'		=>	'Select whether you want your e-mail address to be viewable to other users or not and if you want other users to be able to send you e-mail via the forum (form e-mail) or not.',
+'E-mail setting 1'			=>	'Display your e-mail address.',
+'E-mail setting 2'			=>	'Hide your e-mail address but allow form e-mail.',
+'E-mail setting 3'			=>	'Hide your e-mail address and disallow form e-mail.',
+'Privacy options legend'	=>	'Set your privacy options',
+'Save user/pass'			=>	'Save username and password between visits.',
+'Save user/pass info'		=>	'This option sets whether the forum should "remember" you between visits. If enabled, you will not have to login every time you visit the forum. You will be logged in automatically. Recommended.',
+'Confirm pass'				=>	'Confirm password',
+
+'Username too short'		=>	'Usernames must be at least 2 characters long. Please choose another (longer) username.',
+'Username guest'			=>	'The username guest is reserved. Please choose another username.',
+'Username IP'				=>	'Usernames may not be in the form of an IP address. Please choose another username.',
+'Username reserved chars'	=>	'Usernames may not contain all the characters \', " and [ or ] at once. Please choose another username.',
+'Username BBCode'			=>	'Usernames may not contain any of the text formatting tags (BBCode) that the forum uses. Please choose another username.',
+'Dupe username'				=>	'Someone else has already registered with that username. Please choose another username.',
+'Pass too short'			=>	'Passwords must be at least 4 characters long. Please choose another (longer) password.',
+'Pass not match'			=>	'Passwords do not match. Please go back and correct.',
+'Banned e-mail'				=>	'The e-mail address you entered is banned in this forum. Please choose another e-mail address.',
+'Dupe e-mail'				=>	'Someone else is already registered with that e-mail address. Please choose another e-mail address.',
+'Sig too long'				=>	'Signatures cannot be longer than',
+'characters'				=>	'characters',
+'Sig too many lines'		=>	'Signatures cannot have more than',
+'lines'						=>	'lines',
+'Signature quote/code'		=>	'The quote and code BBCodes are not allowed in signatures. Please go back and correct.',
+'Bad ICQ'					=>	'You entered an invalid ICQ UIN. Please go back and correct.'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/profile.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,144 @@
+<?php
+
+// Language definitions used in profile.php
+$lang_profile = array(
+
+// Navigation and sections
+'Profile menu'				=>	'Profile menu',
+'Section essentials'		=>	'Essentials',
+'Section personal'			=>	'Personal',
+'Section messaging'			=>	'Messaging',
+'Section personality'		=>	'Personality',
+'Section display'			=>	'Display',
+'Section privacy'			=>	'Privacy',
+'Section admin'				=>	'Administration',
+
+// Miscellaneous
+'Username and pass legend'	=>	'Enter your username and password',
+'Personal details legend'	=>	'Enter your personal details',
+'Contact details legend'	=>	'Enter your messaging details',
+'Options display'			=>	'Set your display options',
+'Options post'				=>	'Set your post viewing options',
+'User activity'				=>	'User activity',
+'Paginate info'				=>	'Enter the number of topics and posts you wish to view on each page.',
+
+// Password stuff
+'Pass key bad'				=>	'The specified password activation key was incorrect or has expired. Please re-request a new password. If that fails, contact the forum administrator at',
+'Pass updated'				=>	'Your password has been updated. You can now login with your new password.',
+'Pass updated redirect'		=>	'Password updated. Redirecting &hellip;',
+'Wrong pass'				=>	'Wrong old password.',
+'Change pass'				=>	'Change password',
+'Change pass legend'		=>	'Enter and confirm your new password',
+'Old pass'					=>	'Old password',
+'New pass'					=>	'New password',
+'Confirm new pass'			=>	'Confirm new password',
+
+// E-mail stuff
+'E-mail key bad'			=>	'The specified e-mail activation key was incorrect or has expired. Please re-request change of e-mail address. If that fails, contact the forum administrator at',
+'E-mail updated'			=>	'Your e-mail address has been updated.',
+'Activate e-mail sent'		=>	'An email has been sent to the specified address with instructions on how to activate the new e-mail address. If it doesn\'t arrive you can contact the forum administrator at',
+'E-mail legend'				=>	'Enter your new e-mail address',
+'E-mail instructions'		=>	'An e-mail will be sent to your new address with an activation link. You must click the link in the e-mail you receive to activate the new address.',
+'Change e-mail'				=>	'Change e-mail address',
+'New e-mail'				=>	'New e-mail',
+
+// Avatar upload stuff
+'Avatars disabled'			=>	'The administrator has disabled avatar support.',
+'Too large ini'				=>	'The selected file was too large to upload. The server didn\'t allow the upload.',
+'Partial upload'			=>	'The selected file was only partially uploaded. Please try again.',
+'No tmp directory'			=>	'PHP was unable to save the uploaded file to a temporary location.',
+'No file'					=>	'You did not select a file for upload.',
+'Bad type'					=>	'The file you tried to upload is not of an allowed type. Allowed types are gif, jpeg and png.',
+'Too wide or high'			=>	'The file you tried to upload is wider and/or higher than the maximum allowed',
+'Too large'					=>	'The file you tried to upload is larger than the maximum allowed',
+'pixels'					=>	'pixels',
+'bytes'						=>	'bytes',
+'Move failed'				=>	'The server was unable to save the uploaded file. Please contact the forum administrator at',
+'Unknown failure'			=>	'An unknown error occurred. Please try again.',
+'Avatar upload redirect'	=>	'Avatar uploaded. Redirecting &hellip;',
+'Avatar deleted redirect'	=>	'Avatar deleted. Redirecting &hellip;',
+'Avatar desc'				=>	'An avatar is a small image that will be displayed under your username in your posts. It must not be any bigger than',
+'Upload avatar'				=>	'Upload avatar',
+'Upload avatar legend'		=>	'Enter an avatar file to upload',
+'Delete avatar'				=>	'Delete avatar',	// only for admins
+'File'						=>	'File',
+'Upload'					=>	'Upload',	// submit button
+
+// Form validation stuff
+'Dupe username'				=>	'Someone else has already registered with that username. Please go back and try a different username.',
+'Forbidden title'			=>	'The title you entered contains a forbidden word. You must choose a different title.',
+'Profile redirect'			=>	'Profile updated. Redirecting &hellip;',
+
+// Profile display stuff
+'Not activated'				=>	'This user hasn\'t activated his/her account yet. The account is activated when he/she logs in the first time.',
+'Unknown'					=>	'(Unknown)',	// This is displayed when a user hasn't filled out profile field (e.g. Location)
+'Private'					=>	'(Private)',	// This is displayed when a user does not want to receive e-mails
+'No avatar'					=>	'(No avatar)',
+'Show posts'				=>	'Show all posts',
+'Realname'					=>	'Real name',
+'Location'					=>	'Location',
+'Website'					=>	'Website',
+'Jabber'					=>	'Jabber',
+'ICQ'						=>	'ICQ',
+'MSN'						=>	'MSN Messenger',
+'AOL IM'					=>	'AOL IM',
+'Yahoo'						=>	'Yahoo! Messenger',
+'Avatar'					=>	'Avatar',
+'Signature'					=>	'Signature',
+'Sig max length'			=>	'Max length',
+'Sig max lines'				=>	'Max lines',
+'Avatar legend'				=>	'Set your avatar display options',
+'Avatar info'				=>	'An avatar is a small image that will be displayed with all your posts. You can upload an avatar by clicking the link below. The checkbox \'Use avatar\' below must be checked in order for the avatar to be visible in your posts.',
+'Change avatar'				=>	'Change avatar',
+'Use avatar'				=>	'Use avatar.',
+'Signature legend'			=>	'Compose your signature',
+'Signature info'			=>	'A signature is a small piece of text that is attached to your posts. In it, you can enter just about anything you like. Perhaps you would like to enter your favourite quote or your star sign. It\'s up to you! In your signature you can use BBCode if it is allowed in this particular forum. You can see the features that are allowed/enabled listed below whenever you edit your signature.',
+'Sig preview'				=>	'Current signature preview:',
+'No sig'					=>	'No signature currently stored in profile.',
+'Topics per page'			=>	'Topics',
+'Topics per page info'		=>	'This setting controls how many topics are displayed per page when you view a forum. If you are uncertain about what to use, you can just leave it blank and the forum default will be used.',
+'Posts per page'			=>	'Posts',
+'Posts per page info'		=>	'This setting controls how many posts are displayed per page when you view a topic. If you are uncertain about what to use, you can just leave it blank and the forum default will be used.',
+'Leave blank'				=>	'Leave blank to use forum default.',
+'Notify full'				=>	'Include post in subscription e-mails.',
+'Notify full info'			=>	'With this enabled, a plain text version of the new post will be included in subscription notification e-mails.',
+'Show smilies'				=>	'Show smilies as graphic icons',
+'Show smilies info'			=>	'If you enable this option, small images will be displayed instead of text smilies.',
+'Show images'				=>	'Show images in posts.',
+'Show images info'			=>	'Disable this if you don\'t want to see images in posts (i.e. images displayed with the [img]-tag).',
+'Show images sigs'			=>	'Show images in user signatures.',
+'Show images sigs info'		=>	'Disable this if you don\'t want to see images in signatures (i.e. images displayed with the [img]-tag).',
+'Show avatars'				=>	'Show user avatars in posts.',
+'Show avatars info'			=>	'This option toggles whether user avatar images will be displayed in posts or not.',
+'Show sigs'					=>	'Show user signatures.',
+'Show sigs info'			=>	'Enable if you would like to see user signatures.',
+'Style legend'				=>	'Select your preferred style',
+'Style info'				=>	'If you like you can use a different visual style for this forum.',
+'Admin note'				=>	'Admin note',
+'Pagination legend'			=>	'Enter your pagination options',
+'Post display legend'		=>	'Set your options for viewing posts',
+'Post display info'			=>	'If you are on a slow connection, disabling these options, particularly showing images in posts and signatures, will make pages load faster.',
+'Instructions'				=>	'When you update your profile, you will be redirected back to this page.',
+
+// Administration stuff
+'Group membership legend'	=>	'Choose user group',
+'Save'						=>	'Save',
+'Set mods legend'			=>	'Set moderator access',
+'Moderator in'				=>	'Moderator in',
+'Moderator in info'			=>	'Choose what forums this user should be allowed to moderate. Note: This only applies to moderators. Administrators always have full permissions in all forums.',
+'Update forums'				=>	'Update forums',
+'Delete ban legend'			=>	'Delete (administrators only) or ban user',
+'Delete user'				=>	'Delete user',
+'Ban user'					=>	'Ban user',
+'Confirm delete legend'		=>	'Important: read before deleting user',
+'Confirm delete user'		=>	'Confirm delete user',
+'Confirmation info'			=>	'Please confirm that you want to delete the user',	// the username will be appended to this string
+'Delete warning'			=>	'Warning! Deleted users and/or posts cannot be restored. If you choose not to delete the posts made by this user, the posts can only be deleted manually at a later time.',
+'Delete posts'				=>	'Delete any posts and topics this user has made.',
+'Delete'					=>	'Delete',		// submit button (confirm user delete)
+'User delete redirect'		=>	'User deleted. Redirecting &hellip;',
+'Group membership redirect'	=>	'Group membership saved. Redirecting &hellip;',
+'Update forums redirect'	=>	'Forum moderator rights updated. Redirecting &hellip;',
+'Ban redirect'				=>	'Redirecting &hellip;'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/register.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,35 @@
+<?php
+
+// Language definitions used in register.php
+$lang_register = array(
+
+// Miscellaneous
+'No new regs'				=>	'This forum is not accepting new registrations.',
+'Reg cancel redirect'		=>	'Registration cancelled. Redirecting &hellip;',
+'Forum rules'				=>	'Forum rules',
+'Rules legend'				=>	'You must agree to the following in order to register',
+'Agree'						=>	'Agree',
+'Cancel'					=>	'Cancel',
+'Register'					=>	'Register',
+
+// Form validation stuff (some of these are also used in post.php)
+'Username censor'			=>	'The username you entered contains one or more censored words. Please choose a different username.',
+'Username dupe 1'			=>	'Someone is already registered with the username',
+'Username dupe 2'			=>	'The username you entered is too similar. The username must differ from that by at least one alphanumerical character (a-z or 0-9). Please choose a different username.',
+'E-mail not match'			=>	'E-mail addresses do not match. Please go back and correct.',
+
+// Registration e-mail stuff
+'Reg e-mail'				=>	'Thank you for registering. Your password has been sent to the specified address. If it doesn\'t arrive you can contact the forum administrator at',
+'Reg complete'				=>	'Registration complete. Logging in and redirecting &hellip;',
+
+// Register info
+'Desc 1'					=>	'Registration will grant you access to a number of features and capabilities otherwise unavailable. These functions include the ability to edit and delete posts, design your own signature that accompanies your posts and much more. If you have any questions regarding this forum you should ask an administrator.',
+'Desc 2'					=>	'Below is a form you must fill out in order to register. Once you are registered you should visit your profile and review the different settings you can change. The fields below only make up a small part of all the settings you can alter in your profile.',
+'Username legend'			=>	'Please enter a username between 2 and 25 characters long',
+'Pass legend 1'				=>	'Please enter and confirm your chosen password',
+'Pass legend 2'				=>	'Please read the instructions below',
+'Pass info'					=>	'Passwords can be between 4 and 16 characters long. Passwords are case sensitive.',
+'E-mail info'				=>	'You must enter a valid e-mail address as your randomly generated password will be sent to that address.',
+'Confirm e-mail'			=>	'Confirm e-mail address',
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/search.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,47 @@
+<?php
+
+// Language definitions used in search.php
+$lang_search = array(
+
+// The search form
+'User search'				=>	'User search',
+'No search permission'		=>	'You do not have permission to use the search feature.',
+'Search'					=>	'Search',
+'Search criteria legend'	=>	'Enter your search criteria',
+'Search info'				=>	'To search by keyword, enter a term or terms to search for. Separate terms with spaces. Use AND, OR and NOT to refine your search. To search by author enter the username of the author whose posts you wish to search for. Use wildcard character * for partial matches.',
+'Keyword search'			=>	'Keyword search',
+'Author search'				=>	'Author search',
+'Search in legend'			=>	'Select where to search',
+'Search in info'			=>	'Choose in which forum you would like to search and if you want to search in topic subjects, message text or both.',
+'Forum search'				=>	'Forum',
+'All forums'				=>	'All forums',
+'Search in'					=>	'Search in',
+'Message and subject'		=>	'Message text and topic subject',
+'Message only'				=>	'Message text only',
+'Topic only'				=>	'Topic subject only',
+'Sort by'					=>	'Sort by',
+'Sort order'				=>	'Sort order',
+'Search results legend'		=>	'Select how to view search results',
+'Search results info'		=>	'You can choose how you wish to sort and show your results.',
+'Sort by post time'			=>	'Post time',
+'Sort by author'			=>	'Author',
+'Sort by subject'			=>	'Subject',
+'Sort by forum'				=>	'Forum',
+'Ascending'					=>	'Ascending',
+'Descending'				=>	'Descending',
+'Show as'					=>	'Show results as',
+'Show as topics'			=>	'Topics',
+'Show as posts'				=>	'Posts',
+
+// Results
+'Search results'			=>	'Search results',
+'No terms'					=>	'You have to enter at least one keyword and/or an author to search for.',
+'No hits'					=>	'Your search returned no hits.',
+'No user posts'				=>	'There are no posts by this user in this forum.',
+'No subscriptions'			=>	'You are currently not subscribed to any topics.',
+'No new posts'				=>	'There are no topics with new posts since your last visit.',
+'No recent posts'			=>	'No new posts have been made within the last 24 hours.',
+'No unanswered'				=>	'There are no unanswered posts in this forum.',
+'Go to post'				=>	'Go to post'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/stopwords.txt	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,150 @@
+about
+after
+ago
+all
+almost
+along
+also
+any
+anybody
+anywhere
+are
+arent
+around
+ask
+been
+before
+being
+between
+but
+came
+can
+cant
+come
+could
+couldnt
+did
+didnt
+does
+doesnt
+dont
+each
+either
+else
+even
+every
+everybody
+everyone
+find
+for
+from
+get
+going
+gone
+got
+had
+has
+have
+havent
+having
+her
+here
+hers
+him
+his
+how
+ill
+into
+isnt
+its
+ive
+just
+know
+less
+like
+make
+many
+may
+more
+most
+much
+must
+near
+never
+none
+nothing
+now
+off
+often
+once
+one
+only
+other
+our
+ours
+out
+over
+please
+rather
+really
+said
+see
+she
+should
+small
+some
+something
+sometime
+somewhere
+take
+than
+thank
+thanks
+that
+thats
+the
+their
+theirs
+them
+then
+there
+these
+they
+thing
+think
+this
+those
+though
+through
+thus
+too
+true
+two
+under
+until
+upon
+use
+very
+want
+was
+way
+well
+were
+what
+when
+where
+which
+who
+whom
+whose
+why
+will
+with
+within
+without
+would
+yes
+yet
+you
+your
+yours
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/topic.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,27 @@
+<?php
+
+// Language definitions used in viewtopic.php
+$lang_topic = array(
+
+'Post reply'		=>	'Post reply',
+'Topic closed'		=>	'Topic closed',
+'From'				=>	'From',				// User location
+'Note'				=>	'Note',				// Admin note
+'Website'			=>	'Website',
+'Guest'				=>	'Guest',
+'Online'			=>	'Online',
+'Offline'			=>	'Offline',
+'Last edit'			=>	'Last edited by',
+'Report'			=>	'Report',
+'Delete'			=>	'Delete',
+'Edit'				=>	'Edit',
+'Quote'				=>	'Quote',
+'Is subscribed'		=>	'You are currently subscribed to this topic',
+'Unsubscribe'		=>	'Unsubscribe',
+'Subscribe'			=>	'Subscribe to this topic',
+'Quick post'		=>	'Quick post',
+
+'Link separator'	=>	' | ',	// The text that separates links in posts (website, e-mail, report, edit etc.)
+'Mod controls'		=>	'Moderator controls'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/English/userlist.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,12 @@
+<?php
+
+// Language definitions used in userlist.php
+$lang_ul = array(
+
+'User find legend'		=>	'Find and sort users',
+'User search info'		=>	'Enter a username to search for and/or a user group to filter by. The username field can be left blank. Use the wildcard character * for partial matches. Sort users by name, date registered or number of posts and in ascending/descending order.',
+'User group'			=>	'User group',
+'No of posts'			=>	'No. of posts',
+'All users'				=>	'All'
+
+);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/lang/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/login.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,226 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+if (isset($_GET['action']))
+	define('PUN_QUIET_VISIT', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+// Load the login.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/login.php';
+
+$action = isset($_GET['action']) ? $_GET['action'] : null;
+
+if (isset($_POST['form_sent']) && $action == 'in')
+{
+	$form_username = trim($_POST['req_username']);
+	$form_password = trim($_POST['req_password']);
+
+	$username_sql = ($db_type == 'mysql' || $db_type == 'mysqli') ? 'username=\''.$db->escape($form_username).'\'' : 'LOWER(username)=LOWER(\''.$db->escape($form_username).'\')';
+
+	$result = $db->query('SELECT id, group_id, password, save_pass FROM '.$db->prefix.'users WHERE '.$username_sql) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+	list($user_id, $group_id, $db_password_hash, $save_pass) = $db->fetch_row($result);
+
+	$authorized = false;
+
+	if (!empty($db_password_hash))
+	{
+		$sha1_in_db = (strlen($db_password_hash) == 40) ? true : false;
+		$sha1_available = (function_exists('sha1') || function_exists('mhash')) ? true : false;
+
+		$form_password_hash = pun_hash($form_password);	// This could result in either an SHA-1 or an MD5 hash (depends on $sha1_available)
+
+		if ($sha1_in_db && $sha1_available && $db_password_hash == $form_password_hash)
+			$authorized = true;
+		else if (!$sha1_in_db && $db_password_hash == md5($form_password))
+		{
+			$authorized = true;
+
+			if ($sha1_available)	// There's an MD5 hash in the database, but SHA1 hashing is available, so we update the DB
+				$db->query('UPDATE '.$db->prefix.'users SET password=\''.$form_password_hash.'\' WHERE id='.$user_id) or error('Unable to update user password', __FILE__, __LINE__, $db->error());
+		}
+	}
+
+	if (!$authorized)
+		message($lang_login['Wrong user/pass'].' <a href="login.php?action=forget">'.$lang_login['Forgotten pass'].'</a>');
+
+	// Update the status if this is the first time the user logged in
+	if ($group_id == PUN_UNVERIFIED)
+		$db->query('UPDATE '.$db->prefix.'users SET group_id='.$pun_config['o_default_user_group'].' WHERE id='.$user_id) or error('Unable to update user status', __FILE__, __LINE__, $db->error());
+
+	// Remove this users guest entry from the online list
+	$db->query('DELETE FROM '.$db->prefix.'online WHERE ident=\''.$db->escape(get_remote_address()).'\'') or error('Unable to delete from online list', __FILE__, __LINE__, $db->error());
+
+	$expire = ($save_pass == '1') ? time() + 31536000 : 0;
+	pun_setcookie($user_id, $form_password_hash, $expire);
+
+	redirect(htmlspecialchars($_POST['redirect_url']), $lang_login['Login redirect']);
+}
+
+
+else if ($action == 'out')
+{
+	if ($pun_user['is_guest'] || !isset($_GET['id']) || $_GET['id'] != $pun_user['id'])
+	{
+		header('Location: index.php');
+		exit;
+	}
+
+	// Remove user from "users online" list.
+	$db->query('DELETE FROM '.$db->prefix.'online WHERE user_id='.$pun_user['id']) or error('Unable to delete from online list', __FILE__, __LINE__, $db->error());
+
+	// Update last_visit (make sure there's something to update it with)
+	if (isset($pun_user['logged']))
+		$db->query('UPDATE '.$db->prefix.'users SET last_visit='.$pun_user['logged'].' WHERE id='.$pun_user['id']) or error('Unable to update user visit data', __FILE__, __LINE__, $db->error());
+
+	pun_setcookie(1, random_pass(8), time() + 31536000);
+
+	redirect('index.php', $lang_login['Logout redirect']);
+}
+
+
+else if ($action == 'forget' || $action == 'forget_2')
+{
+	if (!$pun_user['is_guest'])
+		header('Location: index.php');
+
+	if (isset($_POST['form_sent']))
+	{
+		require PUN_ROOT.'include/email.php';
+
+		// Validate the email-address
+		$email = strtolower(trim($_POST['req_email']));
+		if (!is_valid_email($email))
+			message($lang_common['Invalid e-mail']);
+
+		$result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE email=\''.$db->escape($email).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+
+		if ($db->num_rows($result))
+		{
+			// Load the "activate password" template
+			$mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/activate_password.tpl'));
+
+			// The first row contains the subject
+			$first_crlf = strpos($mail_tpl, "\n");
+			$mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8));
+			$mail_message = trim(substr($mail_tpl, $first_crlf));
+
+			// Do the generic replacements first (they apply to all e-mails sent out here)
+			$mail_message = str_replace('<base_url>', $pun_config['o_base_url'].'/', $mail_message);
+			$mail_message = str_replace('<board_mailer>', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message);
+
+			// Loop through users we found
+			while ($cur_hit = $db->fetch_assoc($result))
+			{
+				// Generate a new password and a new password activation code
+				$new_password = random_pass(8);
+				$new_password_key = random_pass(8);
+
+				$db->query('UPDATE '.$db->prefix.'users SET activate_string=\''.pun_hash($new_password).'\', activate_key=\''.$new_password_key.'\' WHERE id='.$cur_hit['id']) or error('Unable to update activation data', __FILE__, __LINE__, $db->error());
+
+				// Do the user specific replacements to the template
+				$cur_mail_message = str_replace('<username>', $cur_hit['username'], $mail_message);
+				$cur_mail_message = str_replace('<activation_url>', $pun_config['o_base_url'].'/profile.php?id='.$cur_hit['id'].'&action=change_pass&key='.$new_password_key, $cur_mail_message);
+				$cur_mail_message = str_replace('<new_password>', $new_password, $cur_mail_message);
+
+				pun_mail($email, $mail_subject, $cur_mail_message);
+			}
+
+			message($lang_login['Forget mail'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.');
+		}
+		else
+			message($lang_login['No e-mail match'].' '.htmlspecialchars($email).'.');
+	}
+
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_login['Request pass'];
+	$required_fields = array('req_email' => $lang_common['E-mail']);
+	$focus_element = array('request_pass', 'req_email');
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_login['Request pass'] ?></span></h2>
+	<div class="box">
+		<form id="request_pass" method="post" action="login.php?action=forget_2" onsubmit="this.request_pass.disabled=true;if(process_form(this)){return true;}else{this.request_pass.disabled=false;return false;}">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_login['Request pass legend'] ?></legend>
+					<div class="infldset">
+						<input type="hidden" name="form_sent" value="1" />
+						<input id="req_email" type="text" name="req_email" size="50" maxlength="50" />
+						<p><?php echo $lang_login['Request pass info'] ?></p>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="request_pass" value="<?php echo $lang_common['Submit'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+if (!$pun_user['is_guest'])
+	header('Location: index.php');
+
+// Try to determine if the data in HTTP_REFERER is valid (if not, we redirect to index.php after login)
+$redirect_url = (isset($_SERVER['HTTP_REFERER']) && preg_match('#^'.preg_quote($pun_config['o_base_url']).'/(.*?)\.php#i', $_SERVER['HTTP_REFERER'])) ? htmlspecialchars($_SERVER['HTTP_REFERER']) : 'index.php';
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Login'];
+$required_fields = array('req_username' => $lang_common['Username'], 'req_password' => $lang_common['Password']);
+$focus_element = array('login', 'req_username');
+require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_common['Login'] ?></span></h2>
+	<div class="box">
+		<form id="login" method="post" action="login.php?action=in" onsubmit="return process_form(this)">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_login['Login legend'] ?></legend>
+						<div class="infldset">
+							<input type="hidden" name="form_sent" value="1" />
+							<input type="hidden" name="redirect_url" value="<?php echo $redirect_url ?>" />
+							<label class="conl"><strong><?php echo $lang_common['Username'] ?></strong><br /><input type="text" name="req_username" size="25" maxlength="25" tabindex="1" /><br /></label>
+							<label class="conl"><strong><?php echo $lang_common['Password'] ?></strong><br /><input type="password" name="req_password" size="16" maxlength="16" tabindex="2" /><br /></label>
+							<p class="clearb"><?php echo $lang_login['Login info'] ?></p>
+							<p><a href="register.php" tabindex="4"><?php echo $lang_login['Not registered'] ?></a>&nbsp;&nbsp;
+							<a href="login.php?action=forget" tabindex="5"><?php echo $lang_login['Forgotten pass'] ?></a></p>
+						</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="login" value="<?php echo $lang_common['Login'] ?>" tabindex="3" /></p>
+		</form>
+	</div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/misc.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,285 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+if (isset($_GET['action']))
+	define('PUN_QUIET_VISIT', 1);
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+// Load the misc.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/misc.php';
+
+$action = isset($_GET['action']) ? $_GET['action'] : null;
+
+
+if ($action == 'rules')
+{
+	// Load the register.php language file
+	require PUN_ROOT.'lang/'.$pun_user['language'].'/register.php';
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_register['Forum rules'];
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="block">
+	<h2><span><?php echo $lang_register['Forum rules'] ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<p><?php echo $pun_config['o_rules_message'] ?></p>
+		</div>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+else if ($action == 'markread')
+{
+	if ($pun_user['is_guest'])
+		message($lang_common['No permission']);
+
+	$db->query('UPDATE '.$db->prefix.'users SET last_visit='.$pun_user['logged'].' WHERE id='.$pun_user['id']) or error('Unable to update user last visit data', __FILE__, __LINE__, $db->error());
+
+	redirect('index.php', $lang_misc['Mark read redirect']);
+}
+
+
+else if (isset($_GET['email']))
+{
+	if ($pun_user['is_guest'])
+		message($lang_common['No permission']);
+
+	$recipient_id = intval($_GET['email']);
+	if ($recipient_id < 2)
+		message($lang_common['Bad request']);
+
+	$result = $db->query('SELECT username, email, email_setting FROM '.$db->prefix.'users WHERE id='.$recipient_id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+	if (!$db->num_rows($result))
+		message($lang_common['Bad request']);
+
+	list($recipient, $recipient_email, $email_setting) = $db->fetch_row($result);
+
+	if ($email_setting == 2 && $pun_user['g_id'] > PUN_MOD)
+		message($lang_misc['Form e-mail disabled']);
+
+
+	if (isset($_POST['form_sent']))
+	{
+		// Clean up message and subject from POST
+		$subject = pun_trim($_POST['req_subject']);
+		$message = pun_trim($_POST['req_message']);
+
+		if ($subject == '')
+			message($lang_misc['No e-mail subject']);
+		else if ($message == '')
+			message($lang_misc['No e-mail message']);
+		else if (strlen($message) > 65535)
+			message($lang_misc['Too long e-mail message']);
+
+		// Load the "form e-mail" template
+		$mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/form_email.tpl'));
+
+		// The first row contains the subject
+		$first_crlf = strpos($mail_tpl, "\n");
+		$mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8));
+		$mail_message = trim(substr($mail_tpl, $first_crlf));
+
+		$mail_subject = str_replace('<mail_subject>', $subject, $mail_subject);
+		$mail_message = str_replace('<sender>', $pun_user['username'], $mail_message);
+		$mail_message = str_replace('<board_title>', $pun_config['o_board_title'], $mail_message);
+		$mail_message = str_replace('<mail_message>', $message, $mail_message);
+		$mail_message = str_replace('<board_mailer>', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message);
+
+		require_once PUN_ROOT.'include/email.php';
+
+		pun_mail($recipient_email, $mail_subject, $mail_message, '"'.str_replace('"', '', $pun_user['username']).'" <'.$pun_user['email'].'>');
+
+		redirect(htmlspecialchars($_POST['redirect_url']), $lang_misc['E-mail sent redirect']);
+	}
+
+
+	// Try to determine if the data in HTTP_REFERER is valid (if not, we redirect to the users profile after the e-mail is sent)
+	$redirect_url = (isset($_SERVER['HTTP_REFERER']) && preg_match('#^'.preg_quote($pun_config['o_base_url']).'/(.*?)\.php#i', $_SERVER['HTTP_REFERER'])) ? htmlspecialchars($_SERVER['HTTP_REFERER']) : 'index.php';
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_misc['Send e-mail to'].' '.pun_htmlspecialchars($recipient);
+	$required_fields = array('req_subject' => $lang_misc['E-mail subject'], 'req_message' => $lang_misc['E-mail message']);
+	$focus_element = array('email', 'req_subject');
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_misc['Send e-mail to'] ?> <?php echo pun_htmlspecialchars($recipient) ?></span></h2>
+	<div class="box">
+		<form id="email" method="post" action="misc.php?email=<?php echo $recipient_id ?>" onsubmit="this.submit.disabled=true;if(process_form(this)){return true;}else{this.submit.disabled=false;return false;}">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_misc['Write e-mail'] ?></legend>
+					<div class="infldset txtarea">
+						<input type="hidden" name="form_sent" value="1" />
+						<input type="hidden" name="redirect_url" value="<?php echo $redirect_url ?>" />
+						<label><strong><?php echo $lang_misc['E-mail subject'] ?></strong><br />
+						<input class="longinput" type="text" name="req_subject" size="75" maxlength="70" tabindex="1" /><br /></label>
+						<label><strong><?php echo $lang_misc['E-mail message'] ?></strong><br />
+						<textarea name="req_message" rows="10" cols="75" tabindex="2"></textarea><br /></label>
+						<p><?php echo $lang_misc['E-mail disclosure note'] ?></p>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="submit" value="<?php echo $lang_common['Submit'] ?>" tabindex="3" accesskey="s" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+else if (isset($_GET['report']))
+{
+	if ($pun_user['is_guest'])
+		message($lang_common['No permission']);
+
+	$post_id = intval($_GET['report']);
+	if ($post_id < 1)
+		message($lang_common['Bad request']);
+
+	if (isset($_POST['form_sent']))
+	{
+		// Clean up reason from POST
+		$reason = pun_linebreaks(pun_trim($_POST['req_reason']));
+		if ($reason == '')
+			message($lang_misc['No reason']);
+
+		// Get the topic ID
+		$result = $db->query('SELECT topic_id FROM '.$db->prefix.'posts WHERE id='.$post_id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+		if (!$db->num_rows($result))
+			message($lang_common['Bad request']);
+
+		$topic_id = $db->result($result);
+
+		// Get the subject and forum ID
+		$result = $db->query('SELECT subject, forum_id FROM '.$db->prefix.'topics WHERE id='.$topic_id) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
+		if (!$db->num_rows($result))
+			message($lang_common['Bad request']);
+
+		list($subject, $forum_id) = $db->fetch_row($result);
+
+		// Should we use the internal report handling?
+		if ($pun_config['o_report_method'] == 0 || $pun_config['o_report_method'] == 2)
+			$db->query('INSERT INTO '.$db->prefix.'reports (post_id, topic_id, forum_id, reported_by, created, message) VALUES('.$post_id.', '.$topic_id.', '.$forum_id.', '.$pun_user['id'].', '.time().', \''.$db->escape($reason).'\')' ) or error('Unable to create report', __FILE__, __LINE__, $db->error());
+
+		// Should we e-mail the report?
+		if ($pun_config['o_report_method'] == 1 || $pun_config['o_report_method'] == 2)
+		{
+			// We send it to the complete mailing-list in one swoop
+			if ($pun_config['o_mailing_list'] != '')
+			{
+				$mail_subject = 'Report('.$forum_id.') - \''.$subject.'\'';
+				$mail_message = 'User \''.$pun_user['username'].'\' has reported the following message:'."\n".$pun_config['o_base_url'].'/viewtopic.php?pid='.$post_id.'#p'.$post_id."\n\n".'Reason:'."\n".$reason;
+
+				require PUN_ROOT.'include/email.php';
+
+				pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message);
+			}
+		}
+
+		redirect('viewtopic.php?pid='.$post_id.'#p'.$post_id, $lang_misc['Report redirect']);
+	}
+
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_misc['Report post'];
+	$required_fields = array('req_reason' => $lang_misc['Reason']);
+	$focus_element = array('report', 'req_reason');
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_misc['Report post'] ?></span></h2>
+	<div class="box">
+		<form id="report" method="post" action="misc.php?report=<?php echo $post_id ?>" onsubmit="this.submit.disabled=true;if(process_form(this)){return true;}else{this.submit.disabled=false;return false;}">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_misc['Reason desc'] ?></legend>
+					<div class="infldset txtarea">
+						<input type="hidden" name="form_sent" value="1" />
+						<label><strong><?php echo $lang_misc['Reason'] ?></strong><br /><textarea name="req_reason" rows="5" cols="60"></textarea><br /></label>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="submit" value="<?php echo $lang_common['Submit'] ?>" accesskey="s" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+else if (isset($_GET['subscribe']))
+{
+	if ($pun_user['is_guest'] || $pun_config['o_subscriptions'] != '1')
+		message($lang_common['No permission']);
+
+	$topic_id = intval($_GET['subscribe']);
+	if ($topic_id < 1)
+		message($lang_common['Bad request']);
+
+	$result = $db->query('SELECT 1 FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$topic_id) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error());
+	if ($db->num_rows($result))
+		message($lang_misc['Already subscribed']);
+
+	$db->query('INSERT INTO '.$db->prefix.'subscriptions (user_id, topic_id) VALUES('.$pun_user['id'].' ,'.$topic_id.')') or error('Unable to add subscription', __FILE__, __LINE__, $db->error());
+
+	redirect('viewtopic.php?id='.$topic_id, $lang_misc['Subscribe redirect']);
+}
+
+
+else if (isset($_GET['unsubscribe']))
+{
+	if ($pun_user['is_guest'] || $pun_config['o_subscriptions'] != '1')
+		message($lang_common['No permission']);
+
+	$topic_id = intval($_GET['unsubscribe']);
+	if ($topic_id < 1)
+		message($lang_common['Bad request']);
+
+	$result = $db->query('SELECT 1 FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$topic_id) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error());
+	if (!$db->num_rows($result))
+		message($lang_misc['Not subscribed']);
+
+	$db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$topic_id) or error('Unable to remove subscription', __FILE__, __LINE__, $db->error());
+
+	redirect('viewtopic.php?id='.$topic_id, $lang_misc['Unsubscribe redirect']);
+}
+
+
+else
+	message($lang_common['Bad request']);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/moderate.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,716 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+// This particular function doesn't require forum-based moderator access. It can be used
+// by all moderators and admins.
+if (isset($_GET['get_host']))
+{
+	if ($pun_user['g_id'] > PUN_MOD)
+		message($lang_common['No permission']);
+
+	// Is get_host an IP address or a post ID?
+	if (@preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $_GET['get_host']))
+		$ip = $_GET['get_host'];
+	else
+	{
+		$get_host = intval($_GET['get_host']);
+		if ($get_host < 1)
+			message($lang_common['Bad request']);
+
+		$result = $db->query('SELECT poster_ip FROM '.$db->prefix.'posts WHERE id='.$get_host) or error('Unable to fetch post IP address', __FILE__, __LINE__, $db->error());
+		if (!$db->num_rows($result))
+			message($lang_common['Bad request']);
+
+		$ip = $db->result($result);
+	}
+
+	message('The IP address is: '.$ip.'<br />The host name is: '.@gethostbyaddr($ip).'<br /><br /><a href="admin_users.php?show_users='.$ip.'">Show more users for this IP</a>');
+}
+
+
+// All other functions require moderator/admin access
+$fid = isset($_GET['fid']) ? intval($_GET['fid']) : 0;
+if ($fid < 1)
+	message($lang_common['Bad request']);
+
+$result = $db->query('SELECT moderators FROM '.$db->prefix.'forums WHERE id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error());
+
+$moderators = $db->result($result);
+$mods_array = ($moderators != '') ? unserialize($moderators) : array();
+
+if ($pun_user['g_id'] != PUN_ADMIN && ($pun_user['g_id'] != PUN_MOD || !array_key_exists($pun_user['username'], $mods_array)))
+	message($lang_common['No permission']);
+
+
+// Load the misc.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/misc.php';
+
+
+// All other topic moderation features require a topic id in GET
+if (isset($_GET['tid']))
+{
+	$tid = intval($_GET['tid']);
+	if ($tid < 1)
+		message($lang_common['Bad request']);
+
+	// Fetch some info about the topic
+	$result = $db->query('SELECT t.subject, t.num_replies, f.id AS forum_id, forum_name FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fid.' AND t.id='.$tid.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
+	if (!$db->num_rows($result))
+		message($lang_common['Bad request']);
+
+	$cur_topic = $db->fetch_assoc($result);
+
+
+	// Delete one or more posts
+	if (isset($_POST['delete_posts']) || isset($_POST['delete_posts_comply']))
+	{
+		$posts = $_POST['posts'];
+		if (empty($posts))
+			message($lang_misc['No posts selected']);
+
+		if (isset($_POST['delete_posts_comply']))
+		{
+			confirm_referrer('moderate.php');
+
+			if (@preg_match('/[^0-9,]/', $posts))
+				message($lang_common['Bad request']);
+
+			// Verify that the post IDs are valid
+			$result = $db->query('SELECT 1 FROM '.$db->prefix.'posts WHERE id IN('.$posts.') AND topic_id='.$tid) or error('Unable to check posts', __FILE__, __LINE__, $db->error());
+
+			if ($db->num_rows($result) != substr_count($posts, ',') + 1)
+				message($lang_common['Bad request']);
+
+			// Delete the posts
+			$db->query('DELETE FROM '.$db->prefix.'posts WHERE id IN('.$posts.')') or error('Unable to delete posts', __FILE__, __LINE__, $db->error());
+
+			require PUN_ROOT.'include/search_idx.php';
+			strip_search_index($posts);
+
+			// Get last_post, last_post_id, and last_poster for the topic after deletion
+			$result = $db->query('SELECT id, poster, posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+			$last_post = $db->fetch_assoc($result);
+
+			// How many posts did we just delete?
+			$num_posts_deleted = substr_count($posts, ',') + 1;
+
+			// Update the topic
+			$db->query('UPDATE '.$db->prefix.'topics SET last_post='.$last_post['posted'].', last_post_id='.$last_post['id'].', last_poster=\''.$db->escape($last_post['poster']).'\', num_replies=num_replies-'.$num_posts_deleted.' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
+
+			update_forum($fid);
+
+			redirect('viewtopic.php?id='.$tid, $lang_misc['Delete posts redirect']);
+		}
+
+
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_misc['Moderate'];
+		require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_misc['Delete posts'] ?></span></h2>
+	<div class="box">
+		<form method="post" action="moderate.php?fid=<?php echo $fid ?>&amp;tid=<?php echo $tid ?>">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_misc['Confirm delete legend'] ?></legend>
+					<div class="infldset">
+						<input type="hidden" name="posts" value="<?php echo implode(',', array_keys($posts)) ?>" />
+						<p><?php echo $lang_misc['Delete posts comply'] ?></p>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="delete_posts_comply" value="<?php echo $lang_misc['Delete'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+		require PUN_ROOT.'footer.php';
+	}
+
+
+	// Show the delete multiple posts view
+
+	// Load the viewtopic.php language file
+	require PUN_ROOT.'lang/'.$pun_user['language'].'/topic.php';
+
+	// Used to disable the Move and Delete buttons if there are no replies to this topic
+	$button_status = ($cur_topic['num_replies'] == 0) ? ' disabled' : '';
+
+
+	// Determine the post offset (based on $_GET['p'])
+	$num_pages = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']);
+
+	$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p'];
+	$start_from = $pun_user['disp_posts'] * ($p - 1);
+
+	// Generate paging links
+	$paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'moderate.php?fid='.$fid.'&amp;tid='.$tid);
+
+
+	if ($pun_config['o_censoring'] == '1')
+		$cur_topic['subject'] = censor_words($cur_topic['subject']);
+
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$cur_topic['subject'];
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<p class="pagelink conl"><?php echo $paging_links ?></p>
+		<ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li><li>&nbsp;&raquo;&nbsp;<a href="viewforum.php?id=<?php echo $fid ?>"><?php echo pun_htmlspecialchars($cur_topic['forum_name']) ?></a></li><li>&nbsp;&raquo;&nbsp;<?php echo pun_htmlspecialchars($cur_topic['subject']) ?></li></ul>
+		<div class="clearer"></div>
+	</div>
+</div>
+
+<form method="post" action="moderate.php?fid=<?php echo $fid ?>&amp;tid=<?php echo $tid ?>">
+<?php
+
+	require PUN_ROOT.'include/parser.php';
+
+	$bg_switch = true;	// Used for switching background color in posts
+	$post_count = 0;	// Keep track of post numbers
+
+	// Retrieve the posts (and their respective poster)
+	$result = $db->query('SELECT u.title, u.num_posts, g.g_id, g.g_user_title, p.id, p.poster, p.poster_id, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE p.topic_id='.$tid.' ORDER BY p.id LIMIT '.$start_from.','.$pun_user['disp_posts'], true) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+
+	while ($cur_post = $db->fetch_assoc($result))
+	{
+		$post_count++;
+
+		// If the poster is a registered user.
+		if ($cur_post['poster_id'] > 1)
+		{
+			$poster = '<a href="profile.php?id='.$cur_post['poster_id'].'">'.pun_htmlspecialchars($cur_post['poster']).'</a>';
+
+			// get_title() requires that an element 'username' be present in the array
+			$cur_post['username'] = $cur_post['poster'];
+			$user_title = get_title($cur_post);
+
+			if ($pun_config['o_censoring'] == '1')
+				$user_title = censor_words($user_title);
+		}
+		// If the poster is a guest (or a user that has been deleted)
+		else
+		{
+			$poster = pun_htmlspecialchars($cur_post['poster']);
+			$user_title = $lang_topic['Guest'];
+		}
+
+		// Switch the background color for every message.
+		$bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true;
+		$vtbg = ($bg_switch) ? ' roweven' : ' rowodd';
+
+		// Perform the main parsing of the message (BBCode, smilies, censor words etc)
+		$cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']);
+
+?>
+
+<div class="blockpost<?php echo $vtbg ?>">
+	<a name="<?php echo $cur_post['id'] ?>"></a>
+	<h2><span><span class="conr">#<?php echo ($start_from + $post_count) ?>&nbsp;</span><a href="viewtopic.php?pid=<?php echo $cur_post['id'].'#p'.$cur_post['id'] ?>"><?php echo format_time($cur_post['posted']) ?></a></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<div class="postleft">
+				<dl>
+					<dt><strong><?php echo $poster ?></strong></dt>
+					<dd><strong><?php echo $user_title ?></strong></dd>
+				</dl>
+			</div>
+			<div class="postright">
+				<h3 class="nosize"><?php echo $lang_common['Message'] ?></h3>
+				<div class="postmsg">
+					<?php echo $cur_post['message']."\n" ?>
+<?php if ($cur_post['edited'] != '') echo "\t\t\t\t\t".'<p class="postedit"><em>'.$lang_topic['Last edit'].' '.pun_htmlspecialchars($cur_post['edited_by']).' ('.format_time($cur_post['edited']).')</em></p>'."\n"; ?>
+				</div>
+				<?php if ($start_from + $post_count > 1) echo '<p class="multidelete"><label><strong>'.$lang_misc['Select'].'</strong>&nbsp;&nbsp;<input type="checkbox" name="posts['.$cur_post['id'].']" value="1" /></label></p>'."\n" ?>
+			</div>
+			<div class="clearer"></div>
+		</div>
+	</div>
+</div>
+
+
+
+
+<?php
+
+	}
+
+?>
+<div class="postlinksb">
+	<div class="inbox">
+		<p class="pagelink conl"><?php echo $paging_links ?></p>
+		<p class="conr"><input type="submit" name="delete_posts" value="<?php echo $lang_misc['Delete'] ?>"<?php echo $button_status ?> /></p>
+		<div class="clearer"></div>
+	</div>
+</div>
+</form>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+// Move one or more topics
+if (isset($_REQUEST['move_topics']) || isset($_POST['move_topics_to']))
+{
+	if (isset($_POST['move_topics_to']))
+	{
+		confirm_referrer('moderate.php');
+
+		if (@preg_match('/[^0-9,]/', $_POST['topics']))
+			message($lang_common['Bad request']);
+
+		$topics = explode(',', $_POST['topics']);
+		$move_to_forum = isset($_POST['move_to_forum']) ? intval($_POST['move_to_forum']) : 0;
+		if (empty($topics) || $move_to_forum < 1)
+			message($lang_common['Bad request']);
+
+		// Verify that the topic IDs are valid
+		$result = $db->query('SELECT 1 FROM '.$db->prefix.'topics WHERE id IN('.implode(',',$topics).') AND forum_id='.$fid) or error('Unable to check topics', __FILE__, __LINE__, $db->error());
+
+		if ($db->num_rows($result) != count($topics))
+			message($lang_common['Bad request']);
+
+		// Delete any redirect topics if there are any (only if we moved/copied the topic back to where it where it was once moved from)
+		$db->query('DELETE FROM '.$db->prefix.'topics WHERE forum_id='.$move_to_forum.' AND moved_to IN('.implode(',',$topics).')') or error('Unable to delete redirect topics', __FILE__, __LINE__, $db->error());
+
+		// Move the topic(s)
+		$db->query('UPDATE '.$db->prefix.'topics SET forum_id='.$move_to_forum.' WHERE id IN('.implode(',',$topics).')') or error('Unable to move topics', __FILE__, __LINE__, $db->error());
+
+		// Should we create redirect topics?
+		if (isset($_POST['with_redirect']))
+		{
+			while (list(, $cur_topic) = @each($topics))
+			{
+				// Fetch info for the redirect topic
+				$result = $db->query('SELECT poster, subject, posted, last_post FROM '.$db->prefix.'topics WHERE id='.$cur_topic) or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
+				$moved_to = $db->fetch_assoc($result);
+
+				// Create the redirect topic
+				$db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, moved_to, forum_id) VALUES(\''.$db->escape($moved_to['poster']).'\', \''.$db->escape($moved_to['subject']).'\', '.$moved_to['posted'].', '.$moved_to['last_post'].', '.$cur_topic.', '.$fid.')') or error('Unable to create redirect topic', __FILE__, __LINE__, $db->error());
+			}
+		}
+
+		update_forum($fid);				// Update the forum FROM which the topic was moved
+		update_forum($move_to_forum);	// Update the forum TO which the topic was moved
+
+		$redirect_msg = (count($topics) > 1) ? $lang_misc['Move topics redirect'] : $lang_misc['Move topic redirect'];
+		redirect('viewforum.php?id='.$move_to_forum, $redirect_msg);
+	}
+
+	if (isset($_POST['move_topics']))
+	{
+		$topics = isset($_POST['topics']) ? $_POST['topics'] : array();
+		if (empty($topics))
+			message($lang_misc['No topics selected']);
+
+		$topics = implode(',', array_keys($topics));
+		$action = 'multi';
+	}
+	else
+	{
+		$topics = intval($_GET['move_topics']);
+		if ($topics < 1)
+			message($lang_common['Bad request']);
+
+		$action = 'single';
+	}
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / Moderate';
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo ($action == 'single') ? $lang_misc['Move topic'] : $lang_misc['Move topics'] ?></span></h2>
+	<div class="box">
+		<form method="post" action="moderate.php?fid=<?php echo $fid ?>">
+			<div class="inform">
+			<input type="hidden" name="topics" value="<?php echo $topics ?>" />
+				<fieldset>
+					<legend><?php echo $lang_misc['Move legend'] ?></legend>
+					<div class="infldset">
+						<label><?php echo $lang_misc['Move to'] ?>
+						<br /><select name="move_to_forum">
+<?php
+
+	$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.redirect_url IS NULL ORDER BY c.disp_position, c.id, f.disp_position', true) or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
+
+	$cur_category = 0;
+	while ($cur_forum = $db->fetch_assoc($result))
+	{
+		if ($cur_forum['cid'] != $cur_category)	// A new category since last iteration?
+		{
+			if ($cur_category)
+				echo "\t\t\t\t\t\t\t".'</optgroup>'."\n";
+
+			echo "\t\t\t\t\t\t\t".'<optgroup label="'.pun_htmlspecialchars($cur_forum['cat_name']).'">'."\n";
+			$cur_category = $cur_forum['cid'];
+		}
+
+		if ($cur_forum['fid'] != $fid)
+			echo "\t\t\t\t\t\t\t\t".'<option value="'.$cur_forum['fid'].'">'.pun_htmlspecialchars($cur_forum['forum_name']).'</option>'."\n";
+	}
+
+?>
+							</optgroup>
+						</select>
+						<br /></label>
+						<div class="rbox">
+							<label><input type="checkbox" name="with_redirect" value="1"<?php if ($action == 'single') echo ' checked="checked"' ?> /><?php echo $lang_misc['Leave redirect'] ?><br /></label>
+						</div>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="move_topics_to" value="<?php echo $lang_misc['Move'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+// Delete one or more topics
+if (isset($_REQUEST['delete_topics']) || isset($_POST['delete_topics_comply']))
+{
+	$topics = isset($_POST['topics']) ? $_POST['topics'] : array();
+	if (empty($topics))
+		message($lang_misc['No topics selected']);
+
+	if (isset($_POST['delete_topics_comply']))
+	{
+		confirm_referrer('moderate.php');
+
+		if (@preg_match('/[^0-9,]/', $topics))
+			message($lang_common['Bad request']);
+
+		require PUN_ROOT.'include/search_idx.php';
+
+		// Verify that the topic IDs are valid
+		$result = $db->query('SELECT 1 FROM '.$db->prefix.'topics WHERE id IN('.$topics.') AND forum_id='.$fid) or error('Unable to check topics', __FILE__, __LINE__, $db->error());
+
+		if ($db->num_rows($result) != substr_count($topics, ',') + 1)
+			message($lang_common['Bad request']);
+
+		// Delete the topics and any redirect topics
+		$db->query('DELETE FROM '.$db->prefix.'topics WHERE id IN('.$topics.') OR moved_to IN('.$topics.')') or error('Unable to delete topic', __FILE__, __LINE__, $db->error());
+
+		// Delete any subscriptions
+		$db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE topic_id IN('.$topics.')') or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error());
+
+		// Create a list of the post ID's in this topic and then strip the search index
+		$result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id IN('.$topics.')') or error('Unable to fetch posts', __FILE__, __LINE__, $db->error());
+
+		$post_ids = '';
+		while ($row = $db->fetch_row($result))
+			$post_ids .= ($post_ids != '') ? ','.$row[0] : $row[0];
+
+		// We have to check that we actually have a list of post ID's since we could be deleting just a redirect topic
+		if ($post_ids != '')
+			strip_search_index($post_ids);
+
+		// Delete posts
+		$db->query('DELETE FROM '.$db->prefix.'posts WHERE topic_id IN('.$topics.')') or error('Unable to delete posts', __FILE__, __LINE__, $db->error());
+
+		update_forum($fid);
+
+		redirect('viewforum.php?id='.$fid, $lang_misc['Delete topics redirect']);
+	}
+
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_misc['Moderate'];
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><?php echo $lang_misc['Delete topics'] ?></h2>
+	<div class="box">
+		<form method="post" action="moderate.php?fid=<?php echo $fid ?>">
+			<input type="hidden" name="topics" value="<?php echo implode(',', array_keys($topics)) ?>" />
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_misc['Confirm delete legend'] ?></legend>
+					<div class="infldset">
+						<p><?php echo $lang_misc['Delete topics comply'] ?></p>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="delete_topics_comply" value="<?php echo $lang_misc['Delete'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+// Open or close one or more topics
+else if (isset($_REQUEST['open']) || isset($_REQUEST['close']))
+{
+	$action = (isset($_REQUEST['open'])) ? 0 : 1;
+
+	// There could be an array of topic ID's in $_POST
+	if (isset($_POST['open']) || isset($_POST['close']))
+	{
+		confirm_referrer('moderate.php');
+
+		$topics = isset($_POST['topics']) ? @array_map('intval', @array_keys($_POST['topics'])) : array();
+		if (empty($topics))
+			message($lang_misc['No topics selected']);
+
+		$db->query('UPDATE '.$db->prefix.'topics SET closed='.$action.' WHERE id IN('.implode(',', $topics).') AND forum_id='.$fid) or error('Unable to close topics', __FILE__, __LINE__, $db->error());
+
+		$redirect_msg = ($action) ? $lang_misc['Close topics redirect'] : $lang_misc['Open topics redirect'];
+		redirect('moderate.php?fid='.$fid, $redirect_msg);
+	}
+	// Or just one in $_GET
+	else
+	{
+		confirm_referrer('viewtopic.php');
+
+		$topic_id = ($action) ? intval($_GET['close']) : intval($_GET['open']);
+		if ($topic_id < 1)
+			message($lang_common['Bad request']);
+
+		$db->query('UPDATE '.$db->prefix.'topics SET closed='.$action.' WHERE id='.$topic_id.' AND forum_id='.$fid) or error('Unable to close topic', __FILE__, __LINE__, $db->error());
+
+		$redirect_msg = ($action) ? $lang_misc['Close topic redirect'] : $lang_misc['Open topic redirect'];
+		redirect('viewtopic.php?id='.$topic_id, $redirect_msg);
+	}
+}
+
+
+// Stick a topic
+else if (isset($_GET['stick']))
+{
+	confirm_referrer('viewtopic.php');
+
+	$stick = intval($_GET['stick']);
+	if ($stick < 1)
+		message($lang_common['Bad request']);
+
+	$db->query('UPDATE '.$db->prefix.'topics SET sticky=\'1\' WHERE id='.$stick.' AND forum_id='.$fid) or error('Unable to stick topic', __FILE__, __LINE__, $db->error());
+
+	redirect('viewtopic.php?id='.$stick, $lang_misc['Stick topic redirect']);
+}
+
+
+// Unstick a topic
+else if (isset($_GET['unstick']))
+{
+	confirm_referrer('viewtopic.php');
+
+	$unstick = intval($_GET['unstick']);
+	if ($unstick < 1)
+		message($lang_common['Bad request']);
+
+	$db->query('UPDATE '.$db->prefix.'topics SET sticky=\'0\' WHERE id='.$unstick.' AND forum_id='.$fid) or error('Unable to unstick topic', __FILE__, __LINE__, $db->error());
+
+	redirect('viewtopic.php?id='.$unstick, $lang_misc['Unstick topic redirect']);
+}
+
+
+// No specific forum moderation action was specified in the query string, so we'll display the moderator forum
+
+// Load the viewforum.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/forum.php';
+
+// Fetch some info about the forum
+$result = $db->query('SELECT f.forum_name, f.redirect_url, f.num_topics FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error());
+if (!$db->num_rows($result))
+	message($lang_common['Bad request']);
+
+$cur_forum = $db->fetch_assoc($result);
+
+// Is this a redirect forum? In that case, abort!
+if ($cur_forum['redirect_url'] != '')
+	message($lang_common['Bad request']);
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.pun_htmlspecialchars($cur_forum['forum_name']);
+require PUN_ROOT.'header.php';
+
+// Determine the topic offset (based on $_GET['p'])
+$num_pages = ceil($cur_forum['num_topics'] / $pun_user['disp_topics']);
+
+$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p'];
+$start_from = $pun_user['disp_topics'] * ($p - 1);
+
+// Generate paging links
+$paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'moderate.php?fid='.$fid)
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<p class="pagelink conl"><?php echo $paging_links ?></p>
+		<ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a>&nbsp;</li><li>&raquo;&nbsp;<?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?></li></ul>
+		<div class="clearer"></div>
+	</div>
+</div>
+
+<form method="post" action="moderate.php?fid=<?php echo $fid ?>">
+<div id="vf" class="blocktable">
+	<h2><span><?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<table cellspacing="0">
+			<thead>
+				<tr>
+					<th class="tcl" scope="col"><?php echo $lang_common['Topic'] ?></th>
+					<th class="tc2" scope="col"><?php echo $lang_common['Replies'] ?></th>
+					<th class="tc3" scope="col"><?php echo $lang_forum['Views'] ?></th>
+					<th class="tcr"><?php echo $lang_common['Last post'] ?></th>
+					<th class="tcmod" scope="col"><?php echo $lang_misc['Select'] ?></th>
+				</tr>
+			</thead>
+			<tbody>
+<?php
+
+// Select topics
+$result = $db->query('SELECT id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to FROM '.$db->prefix.'topics WHERE forum_id='.$fid.' ORDER BY sticky DESC, last_post DESC LIMIT '.$start_from.', '.$pun_user['disp_topics']) or error('Unable to fetch topic list for forum', __FILE__, __LINE__, $db->error());
+
+// If there are topics in this forum.
+if ($db->num_rows($result))
+{
+	$button_status = '';
+
+	while ($cur_topic = $db->fetch_assoc($result))
+	{
+
+		$icon_text = $lang_common['Normal icon'];
+		$item_status = '';
+		$icon_type = 'icon';
+
+		if ($cur_topic['moved_to'] == null)
+		{
+			$last_post = '<a href="viewtopic.php?pid='.$cur_topic['last_post_id'].'#p'.$cur_topic['last_post_id'].'">'.format_time($cur_topic['last_post']).'</a> '.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['last_poster']);
+			$ghost_topic = false;
+		}
+		else
+		{
+			$last_post = '&nbsp;';
+			$ghost_topic = true;
+		}
+
+		if ($pun_config['o_censoring'] == '1')
+			$cur_topic['subject'] = censor_words($cur_topic['subject']);
+
+		if ($cur_topic['moved_to'] != 0)
+			$subject = $lang_forum['Moved'].': <a href="viewtopic.php?id='.$cur_topic['moved_to'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span class="byuser">'.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).'</span>';
+		else if ($cur_topic['closed'] == '0')
+			$subject = '<a href="viewtopic.php?id='.$cur_topic['id'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span>'.$lang_common['by'].'&nbsp;'.pun_htmlspecialchars($cur_topic['poster']).'</span>';
+		else
+		{
+			$subject = '<a href="viewtopic.php?id='.$cur_topic['id'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span class="byuser">'.$lang_common['by'].' '.pun_htmlspecialchars($cur_topic['poster']).'</span>';
+			$icon_text = $lang_common['Closed icon'];
+			$item_status = 'iclosed';
+		}
+
+		if ($cur_topic['last_post'] > $pun_user['last_visit'] && !$ghost_topic)
+		{
+			$icon_text .= ' '.$lang_common['New icon'];
+			$item_status .= ' inew';
+			$icon_type = 'icon inew';
+			$subject = '<strong>'.$subject.'</strong>';
+			$subject_new_posts = '<span class="newtext">[&nbsp;<a href="viewtopic.php?id='.$cur_topic['id'].'&amp;action=new" title="'.$lang_common['New posts info'].'">'.$lang_common['New posts'].'</a>&nbsp;]</span>';
+		}
+		else
+			$subject_new_posts = null;
+
+		// We won't display "the dot", but we add the spaces anyway
+		if ($pun_config['o_show_dot'] == '1')
+			$subject = '&nbsp;&nbsp;'.$subject;
+
+		if ($cur_topic['sticky'] == '1')
+		{
+			$subject = '<span class="stickytext">'.$lang_forum['Sticky'].': </span>'.$subject;
+			$item_status .= ' isticky';
+			$icon_text .= ' '.$lang_forum['Sticky'];
+		}
+
+		$num_pages_topic = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']);
+
+		if ($num_pages_topic > 1)
+			$subject_multipage = '[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$cur_topic['id']).' ]';
+		else
+			$subject_multipage = null;
+
+		// Should we show the "New posts" and/or the multipage links?
+		if (!empty($subject_new_posts) || !empty($subject_multipage))
+		{
+			$subject .= '&nbsp; '.(!empty($subject_new_posts) ? $subject_new_posts : '');
+			$subject .= !empty($subject_multipage) ? ' '.$subject_multipage : '';
+		}
+
+?>
+				<tr<?php if ($item_status != '') echo ' class="'.trim($item_status).'"'; ?>>
+					<td class="tcl">
+						<div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo trim($icon_text) ?></div></div>
+						<div class="tclcon">
+							<?php echo $subject."\n" ?>
+						</div>
+					</td>
+					<td class="tc2"><?php echo (!$ghost_topic) ? $cur_topic['num_replies'] : '&nbsp;' ?></td>
+					<td class="tc3"><?php echo (!$ghost_topic) ? $cur_topic['num_views'] : '&nbsp;' ?></td>
+					<td class="tcr"><?php echo $last_post ?></td>
+					<td class="tcmod"><input type="checkbox" name="topics[<?php echo $cur_topic['id'] ?>]" value="1" /></td>
+				</tr>
+<?php
+
+	}
+}
+else
+{
+	$button_status = ' disabled';
+	echo "\t\t\t\t\t".'<tr><td class="tcl" colspan="5">'.$lang_forum['Empty forum'].'</td></tr>'."\n";
+}
+
+?>
+			</tbody>
+			</table>
+		</div>
+	</div>
+</div>
+
+<div class="linksb">
+	<div class="inbox">
+		<p class="pagelink conl"><?php echo $paging_links ?></p>
+		<p class="conr"><input type="submit" name="move_topics" value="<?php echo $lang_misc['Move'] ?>"<?php echo $button_status ?> />&nbsp;&nbsp;<input type="submit" name="delete_topics" value="<?php echo $lang_misc['Delete'] ?>"<?php echo $button_status ?> />&nbsp;&nbsp;<input type="submit" name="open" value="<?php echo $lang_misc['Open'] ?>"<?php echo $button_status ?> />&nbsp;&nbsp;<input type="submit" name="close" value="<?php echo $lang_misc['Close'] ?>"<?php echo $button_status ?> /></p>
+		<div class="clearer"></div>
+	</div>
+</div>
+</form>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/plugins/AMP_Example.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,145 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+##
+##
+##  A few notes of interest for aspiring plugin authors:
+##
+##  1. If you want to display a message via the message() function, you
+##     must do so before calling generate_admin_menu($plugin).
+##
+##  2. Plugins are loaded by admin_loader.php and must not be
+##     terminated (e.g. by calling exit()). After the plugin script has
+##     finished, the loader script displays the footer, so don't worry
+##     about that. Please note that terminating a plugin by calling
+##     message() or redirect() is fine though.
+##
+##  3. The action attribute of any and all <form> tags and the target
+##     URL for the redirect() function must be set to the value of
+##     $_SERVER['REQUEST_URI']. This URL can however be extended to
+##     include extra variables (like the addition of &amp;foo=bar in
+##     the form of this example plugin).
+##
+##  4. If your plugin is for administrators only, the filename must
+##     have the prefix "AP_". If it is for both administrators and
+##     moderators, use the prefix "AMP_". This example plugin has the
+##     prefix "AMP_" and is therefore available for both admins and
+##     moderators in the navigation menu.
+##
+##  5. Use _ instead of spaces in the file name.
+##
+##  6. Since plugin scripts are included from the PunBB script
+##     admin_loader.php, you have access to all PunBB functions and
+##     global variables (e.g. $db, $pun_config, $pun_user etc).
+##
+##  7. Do your best to keep the look and feel of your plugins' user
+##     interface similar to the rest of the admin scripts. Feel free to
+##     borrow markup and code from the admin scripts to use in your
+##     plugins. If you create your own styles they need to be added to
+##     the "base_admin" style sheet.
+##
+##  8. Plugins must be released under the GNU General Public License or
+##     a GPL compatible license. Copy the GPL preamble at the top of
+##     this file into your plugin script and alter the copyright notice
+##     to refrect the author of the plugin (i.e. you).
+##
+##
+
+
+// Make sure no one attempts to run this script "directly"
+if (!defined('PUN'))
+	exit;
+
+// Tell admin_loader.php that this is indeed a plugin and that it is loaded
+define('PUN_PLUGIN_LOADED', 1);
+
+//
+// The rest is up to you!
+//
+
+// If the "Show text" button was clicked
+if (isset($_POST['show_text']))
+{
+	// Make sure something something was entered
+	if (trim($_POST['text_to_show']) == '')
+		message('You didn\'t enter anything!');
+
+	// Display the admin navigation menu
+	generate_admin_menu($plugin);
+
+?>
+	<div class="block">
+		<h2><span>Example plugin</span></h2>
+		<div class="box">
+			<div class="inbox">
+				<p>You said "<?php echo pun_htmlspecialchars($_POST['text_to_show']) ?>". Great stuff.</p>
+				<p><a href="javascript: history.go(-1)">Go back</a></p>
+			</div>
+		</div>
+	</div>
+<?php
+
+}
+else	// If not, we show the "Show text" form
+{
+	// Display the admin navigation menu
+	generate_admin_menu($plugin);
+
+?>
+	<div id="exampleplugin" class="blockform">
+		<h2><span>Example plugin</span></h2>
+		<div class="box">
+			<div class="inbox">
+				<p>This plugin doesn't do anything useful. Hence the name "Example".</p>
+				<p>This would be a good spot to talk a little about your plugin. Describe what it does and how it should be used. Be brief, but informative.</p>
+			</div>
+		</div>
+
+		<h2 class="block2"><span>An example form</span></h2>
+		<div class="box">
+			<form id="example" method="post" action="<?php echo $_SERVER['REQUEST_URI'] ?>&amp;foo=bar">
+				<div class="inform">
+					<fieldset>
+						<legend>Enter a piece of text and hit "Show text"!</legend>
+						<div class="infldset">
+						<table class="aligntop" cellspacing="0">
+							<tr>
+								<th scope="row">Text to show<div><input type="submit" name="show_text" value="Show text" tabindex="2" /></div></th>
+								<td>
+									<input type="text" name="text_to_show" size="25" tabindex="1" />
+									<span>The text you want to display.</span>
+								</td>
+							</tr>
+						</table>
+						</div>
+					</fieldset>
+				</div>
+			</form>
+		</div>
+	</div>
+<?php
+
+}
+
+// Note that the script just ends here. The footer will be included by admin_loader.php.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/plugins/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/post.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,596 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+if ($pun_user['g_read_board'] == '0')
+	message($lang_common['No view']);
+
+
+$tid = isset($_GET['tid']) ? intval($_GET['tid']) : 0;
+$fid = isset($_GET['fid']) ? intval($_GET['fid']) : 0;
+if ($tid < 1 && $fid < 1 || $tid > 0 && $fid > 0)
+	message($lang_common['Bad request']);
+
+// Fetch some info about the topic and/or the forum
+if ($tid)
+	$result = $db->query('SELECT f.id, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics, t.subject, t.closed FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$tid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error());
+else
+	$result = $db->query('SELECT f.id, f.forum_name, f.moderators, f.redirect_url, fp.post_replies, fp.post_topics FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$fid) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error());
+
+if (!$db->num_rows($result))
+	message($lang_common['Bad request']);
+
+$cur_posting = $db->fetch_assoc($result);
+
+// Is someone trying to post into a redirect forum?
+if ($cur_posting['redirect_url'] != '')
+	message($lang_common['Bad request']);
+
+// Sort out who the moderators are and if we are currently a moderator (or an admin)
+$mods_array = ($cur_posting['moderators'] != '') ? unserialize($cur_posting['moderators']) : array();
+$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && array_key_exists($pun_user['username'], $mods_array))) ? true : false;
+
+// Do we have permission to post?
+if ((($tid && (($cur_posting['post_replies'] == '' && $pun_user['g_post_replies'] == '0') || $cur_posting['post_replies'] == '0')) ||
+	($fid && (($cur_posting['post_topics'] == '' && $pun_user['g_post_topics'] == '0') || $cur_posting['post_topics'] == '0')) ||
+	(isset($cur_posting['closed']) && $cur_posting['closed'] == '1')) &&
+	!$is_admmod)
+	message($lang_common['No permission']);
+
+// Load the post.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/post.php';
+
+// Start with a clean slate
+$errors = array();
+
+
+// Did someone just hit "Submit" or "Preview"?
+if (isset($_POST['form_sent']))
+{
+	// Make sure form_user is correct
+	if (($pun_user['is_guest'] && $_POST['form_user'] != 'Guest') || (!$pun_user['is_guest'] && $_POST['form_user'] != $pun_user['username']))
+		message($lang_common['Bad request']);
+
+	// Flood protection
+	if (!$pun_user['is_guest'] && !isset($_POST['preview']) && $pun_user['last_post'] != '' && (time() - $pun_user['last_post']) < $pun_user['g_post_flood'])
+		$errors[] = $lang_post['Flood start'].' '.$pun_user['g_post_flood'].' '.$lang_post['flood end'];
+
+	// If it's a new topic
+	if ($fid)
+	{
+		$subject = pun_trim($_POST['req_subject']);
+
+		if ($subject == '')
+			$errors[] = $lang_post['No subject'];
+		else if (pun_strlen($subject) > 70)
+			$errors[] = $lang_post['Too long subject'];
+		else if ($pun_config['p_subject_all_caps'] == '0' && strtoupper($subject) == $subject && $pun_user['g_id'] > PUN_MOD)
+			$subject = ucwords(strtolower($subject));
+	}
+
+	// If the user is logged in we get the username and e-mail from $pun_user
+	if (!$pun_user['is_guest'])
+	{
+		$username = $pun_user['username'];
+		$email = $pun_user['email'];
+	}
+	// Otherwise it should be in $_POST
+	else
+	{
+		$username = trim($_POST['req_username']);
+		$email = strtolower(trim(($pun_config['p_force_guest_email'] == '1') ? $_POST['req_email'] : $_POST['email']));
+
+		// Load the register.php/profile.php language files
+		require PUN_ROOT.'lang/'.$pun_user['language'].'/prof_reg.php';
+		require PUN_ROOT.'lang/'.$pun_user['language'].'/register.php';
+
+		// It's a guest, so we have to validate the username
+		if (strlen($username) < 2)
+			$errors[] = $lang_prof_reg['Username too short'];
+		else if (!strcasecmp($username, 'Guest') || !strcasecmp($username, $lang_common['Guest']))
+			$errors[] = $lang_prof_reg['Username guest'];
+		else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username))
+			$errors[] = $lang_prof_reg['Username IP'];
+
+		if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false)
+			$errors[] = $lang_prof_reg['Username reserved chars'];
+		if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[quote=|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $username))
+			$errors[] = $lang_prof_reg['Username BBCode'];
+
+		// Check username for any censored words
+		$temp = censor_words($username);
+		if ($temp != $username)
+			$errors[] = $lang_register['Username censor'];
+
+		// Check that the username (or a too similar username) is not already registered
+		$result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE (username=\''.$db->escape($username).'\' OR username=\''.$db->escape(preg_replace('/[^\w]/', '', $username)).'\') AND id>1') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+		if ($db->num_rows($result))
+		{
+			$busy = $db->result($result);
+			$errors[] = $lang_register['Username dupe 1'].' '.pun_htmlspecialchars($busy).'. '.$lang_register['Username dupe 2'];
+		}
+
+		if ($pun_config['p_force_guest_email'] == '1' || $email != '')
+		{
+			require PUN_ROOT.'include/email.php';
+			if (!is_valid_email($email))
+				$errors[] = $lang_common['Invalid e-mail'];
+		}
+	}
+
+	// Clean up message from POST
+	$message = pun_linebreaks(pun_trim($_POST['req_message']));
+
+	if ($message == '')
+		$errors[] = $lang_post['No message'];
+	else if (strlen($message) > 65535)
+		$errors[] = $lang_post['Too long message'];
+	else if ($pun_config['p_message_all_caps'] == '0' && strtoupper($message) == $message && $pun_user['g_id'] > PUN_MOD)
+		$message = ucwords(strtolower($message));
+
+	// Validate BBCode syntax
+	if ($pun_config['p_message_bbcode'] == '1' && strpos($message, '[') !== false && strpos($message, ']') !== false)
+	{
+		require PUN_ROOT.'include/parser.php';
+		$message = preparse_bbcode($message, $errors);
+	}
+
+
+	require PUN_ROOT.'include/search_idx.php';
+
+	$hide_smilies = isset($_POST['hide_smilies']) ? 1 : 0;
+	$subscribe = isset($_POST['subscribe']) ? 1 : 0;
+
+	$now = time();
+
+	// Did everything go according to plan?
+	if (empty($errors) && !isset($_POST['preview']))
+	{
+		// If it's a reply
+		if ($tid)
+		{
+			if (!$pun_user['is_guest'])
+			{
+				// Insert the new post
+				$db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_id, poster_ip, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', '.$pun_user['id'].', \''.get_remote_address().'\', \''.$db->escape($message).'\', \''.$hide_smilies.'\', '.$now.', '.$tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error());
+				$new_pid = $db->insert_id();
+
+				// To subscribe or not to subscribe, that ...
+				if ($pun_config['o_subscriptions'] == '1' && $subscribe)
+				{
+					$result = $db->query('SELECT 1 FROM '.$db->prefix.'subscriptions WHERE user_id='.$pun_user['id'].' AND topic_id='.$tid) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error());
+					if (!$db->num_rows($result))
+						$db->query('INSERT INTO '.$db->prefix.'subscriptions (user_id, topic_id) VALUES('.$pun_user['id'].' ,'.$tid.')') or error('Unable to add subscription', __FILE__, __LINE__, $db->error());
+				}
+			}
+			else
+			{
+				// It's a guest. Insert the new post
+				$email_sql = ($pun_config['p_force_guest_email'] == '1' || $email != '') ? '\''.$email.'\'' : 'NULL';
+				$db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_ip, poster_email, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', \''.get_remote_address().'\', '.$email_sql.', \''.$db->escape($message).'\', \''.$hide_smilies.'\', '.$now.', '.$tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error());
+				$new_pid = $db->insert_id();
+			}
+
+			// Count number of replies in the topic
+			$result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'posts WHERE topic_id='.$tid) or error('Unable to fetch post count for topic', __FILE__, __LINE__, $db->error());
+			$num_replies = $db->result($result, 0) - 1;
+
+			// Update topic
+			$db->query('UPDATE '.$db->prefix.'topics SET num_replies='.$num_replies.', last_post='.$now.', last_post_id='.$new_pid.', last_poster=\''.$db->escape($username).'\' WHERE id='.$tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
+
+			update_search_index('post', $new_pid, $message);
+
+			update_forum($cur_posting['id']);
+
+			// Should we send out notifications?
+			if ($pun_config['o_subscriptions'] == '1')
+			{
+				// Get the post time for the previous post in this topic
+				$result = $db->query('SELECT posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT 1, 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+				$previous_post_time = $db->result($result);
+
+				// Get any subscribed users that should be notified (banned users are excluded)
+				$result = $db->query('SELECT u.id, u.email, u.notify_with_post, u.language FROM '.$db->prefix.'users AS u INNER JOIN '.$db->prefix.'subscriptions AS s ON u.id=s.user_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id='.$cur_posting['id'].' AND fp.group_id=u.group_id) LEFT JOIN '.$db->prefix.'online AS o ON u.id=o.user_id LEFT JOIN '.$db->prefix.'bans AS b ON u.username=b.username WHERE b.username IS NULL AND COALESCE(o.logged, u.last_visit)>'.$previous_post_time.' AND (fp.read_forum IS NULL OR fp.read_forum=1) AND s.topic_id='.$tid.' AND u.id!='.intval($pun_user['id'])) or error('Unable to fetch subscription info', __FILE__, __LINE__, $db->error());
+				if ($db->num_rows($result))
+				{
+					require_once PUN_ROOT.'include/email.php';
+
+					$notification_emails = array();
+
+					// Loop through subscribed users and send e-mails
+					while ($cur_subscriber = $db->fetch_assoc($result))
+					{
+						// Is the subscription e-mail for $cur_subscriber['language'] cached or not?
+						if (!isset($notification_emails[$cur_subscriber['language']]))
+						{
+							if (file_exists(PUN_ROOT.'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply.tpl'))
+							{
+								// Load the "new reply" template
+								$mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply.tpl'));
+
+								// Load the "new reply full" template (with post included)
+								$mail_tpl_full = trim(file_get_contents(PUN_ROOT.'lang/'.$cur_subscriber['language'].'/mail_templates/new_reply_full.tpl'));
+
+								// The first row contains the subject (it also starts with "Subject:")
+								$first_crlf = strpos($mail_tpl, "\n");
+								$mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8));
+								$mail_message = trim(substr($mail_tpl, $first_crlf));
+
+								$first_crlf = strpos($mail_tpl_full, "\n");
+								$mail_subject_full = trim(substr($mail_tpl_full, 8, $first_crlf-8));
+								$mail_message_full = trim(substr($mail_tpl_full, $first_crlf));
+
+								$mail_subject = str_replace('<topic_subject>', '\''.$cur_posting['subject'].'\'', $mail_subject);
+								$mail_message = str_replace('<topic_subject>', '\''.$cur_posting['subject'].'\'', $mail_message);
+								$mail_message = str_replace('<replier>', $username, $mail_message);
+								$mail_message = str_replace('<post_url>', $pun_config['o_base_url'].'/viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $mail_message);
+								$mail_message = str_replace('<unsubscribe_url>', $pun_config['o_base_url'].'/misc.php?unsubscribe='.$tid, $mail_message);
+								$mail_message = str_replace('<board_mailer>', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message);
+
+								$mail_subject_full = str_replace('<topic_subject>', '\''.$cur_posting['subject'].'\'', $mail_subject_full);
+								$mail_message_full = str_replace('<topic_subject>', '\''.$cur_posting['subject'].'\'', $mail_message_full);
+								$mail_message_full = str_replace('<replier>', $username, $mail_message_full);
+								$mail_message_full = str_replace('<message>', $message, $mail_message_full);
+								$mail_message_full = str_replace('<post_url>', $pun_config['o_base_url'].'/viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $mail_message_full);
+								$mail_message_full = str_replace('<unsubscribe_url>', $pun_config['o_base_url'].'/misc.php?unsubscribe='.$tid, $mail_message_full);
+								$mail_message_full = str_replace('<board_mailer>', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message_full);
+
+								$notification_emails[$cur_subscriber['language']][0] = $mail_subject;
+								$notification_emails[$cur_subscriber['language']][1] = $mail_message;
+								$notification_emails[$cur_subscriber['language']][2] = $mail_subject_full;
+								$notification_emails[$cur_subscriber['language']][3] = $mail_message_full;
+
+								$mail_subject = $mail_message = $mail_subject_full = $mail_message_full = null;
+							}
+						}
+
+						// We have to double check here because the templates could be missing
+						if (isset($notification_emails[$cur_subscriber['language']]))
+						{
+							if ($cur_subscriber['notify_with_post'] == '0')
+								pun_mail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][0], $notification_emails[$cur_subscriber['language']][1]);
+							else
+								pun_mail($cur_subscriber['email'], $notification_emails[$cur_subscriber['language']][2], $notification_emails[$cur_subscriber['language']][3]);
+						}
+					}
+				}
+			}
+		}
+		// If it's a new topic
+		else if ($fid)
+		{
+			// Create the topic
+			$db->query('INSERT INTO '.$db->prefix.'topics (poster, subject, posted, last_post, last_poster, forum_id) VALUES(\''.$db->escape($username).'\', \''.$db->escape($subject).'\', '.$now.', '.$now.', \''.$db->escape($username).'\', '.$fid.')') or error('Unable to create topic', __FILE__, __LINE__, $db->error());
+			$new_tid = $db->insert_id();
+
+			if (!$pun_user['is_guest'])
+			{
+				// To subscribe or not to subscribe, that ...
+				if ($pun_config['o_subscriptions'] == '1' && (isset($_POST['subscribe']) && $_POST['subscribe'] == '1'))
+					$db->query('INSERT INTO '.$db->prefix.'subscriptions (user_id, topic_id) VALUES('.$pun_user['id'].' ,'.$new_tid.')') or error('Unable to add subscription', __FILE__, __LINE__, $db->error());
+
+				// Create the post ("topic post")
+				$db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_id, poster_ip, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', '.$pun_user['id'].', \''.get_remote_address().'\', \''.$db->escape($message).'\', \''.$hide_smilies.'\', '.$now.', '.$new_tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error());
+			}
+			else
+			{
+				// Create the post ("topic post")
+				$email_sql = ($pun_config['p_force_guest_email'] == '1' || $email != '') ? '\''.$email.'\'' : 'NULL';
+				$db->query('INSERT INTO '.$db->prefix.'posts (poster, poster_ip, poster_email, message, hide_smilies, posted, topic_id) VALUES(\''.$db->escape($username).'\', \''.get_remote_address().'\', '.$email_sql.', \''.$db->escape($message).'\', \''.$hide_smilies.'\', '.$now.', '.$new_tid.')') or error('Unable to create post', __FILE__, __LINE__, $db->error());
+			}
+			$new_pid = $db->insert_id();
+
+			// Update the topic with last_post_id
+			$db->query('UPDATE '.$db->prefix.'topics SET last_post_id='.$new_pid.' WHERE id='.$new_tid) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
+
+			update_search_index('post', $new_pid, $message, $subject);
+
+			update_forum($fid);
+		}
+
+		// If the posting user is logged in, increment his/her post count
+		if (!$pun_user['is_guest'])
+		{
+			$low_prio = ($db_type == 'mysql') ? 'LOW_PRIORITY ' : '';
+			$db->query('UPDATE '.$low_prio.$db->prefix.'users SET num_posts=num_posts+1, last_post='.$now.' WHERE id='.$pun_user['id']) or error('Unable to update user', __FILE__, __LINE__, $db->error());
+		}
+
+		redirect('viewtopic.php?pid='.$new_pid.'#p'.$new_pid, $lang_post['Post redirect']);
+	}
+}
+
+
+// If a topic id was specified in the url (it's a reply).
+if ($tid)
+{
+	$action = $lang_post['Post a reply'];
+	$form = '<form id="post" method="post" action="post.php?action=post&amp;tid='.$tid.'" onsubmit="this.submit.disabled=true;if(process_form(this)){return true;}else{this.submit.disabled=false;return false;}">';
+
+	// If a quote-id was specified in the url.
+	if (isset($_GET['qid']))
+	{
+		$qid = intval($_GET['qid']);
+		if ($qid < 1)
+			message($lang_common['Bad request']);
+
+		$result = $db->query('SELECT poster, message FROM '.$db->prefix.'posts WHERE id='.$qid.' AND topic_id='.$tid) or error('Unable to fetch quote info', __FILE__, __LINE__, $db->error());
+		if (!$db->num_rows($result))
+			message($lang_common['Bad request']);
+
+		list($q_poster, $q_message) = $db->fetch_row($result);
+
+		$q_message = str_replace('[img]', '[url]', $q_message);
+		$q_message = str_replace('[/img]', '[/url]', $q_message);
+		$q_message = pun_htmlspecialchars($q_message);
+
+		if ($pun_config['p_message_bbcode'] == '1')
+		{
+			// If username contains a square bracket, we add "" or '' around it (so we know when it starts and ends)
+			if (strpos($q_poster, '[') !== false || strpos($q_poster, ']') !== false)
+			{
+				if (strpos($q_poster, '\'') !== false)
+					$q_poster = '"'.$q_poster.'"';
+				else
+					$q_poster = '\''.$q_poster.'\'';
+			}
+			else
+			{
+				// Get the characters at the start and end of $q_poster
+				$ends = substr($q_poster, 0, 1).substr($q_poster, -1, 1);
+
+				// Deal with quoting "Username" or 'Username' (becomes '"Username"' or "'Username'")
+				if ($ends == '\'\'')
+					$q_poster = '"'.$q_poster.'"';
+				else if ($ends == '""')
+					$q_poster = '\''.$q_poster.'\'';
+			}
+
+			$quote = '[quote='.$q_poster.']'.$q_message.'[/quote]'."\n";
+		}
+		else
+			$quote = '> '.$q_poster.' '.$lang_common['wrote'].':'."\n\n".'> '.$q_message."\n";
+	}
+
+	$forum_name = '<a href="viewforum.php?id='.$cur_posting['id'].'">'.pun_htmlspecialchars($cur_posting['forum_name']).'</a>';
+}
+// If a forum_id was specified in the url (new topic).
+else if ($fid)
+{
+	$action = $lang_post['Post new topic'];
+	$form = '<form id="post" method="post" action="post.php?action=post&amp;fid='.$fid.'" onsubmit="return process_form(this)">';
+
+	$forum_name = pun_htmlspecialchars($cur_posting['forum_name']);
+}
+else
+	message($lang_common['Bad request']);
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$action;
+$required_fields = array('req_email' => $lang_common['E-mail'], 'req_subject' => $lang_common['Subject'], 'req_message' => $lang_common['Message']);
+$focus_element = array('post');
+
+if (!$pun_user['is_guest'])
+	$focus_element[] = ($fid) ? 'req_subject' : 'req_message';
+else
+{
+	$required_fields['req_username'] = $lang_post['Guest name'];
+	$focus_element[] = 'req_username';
+}
+
+require PUN_ROOT.'header.php';
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li><li>&nbsp;&raquo;&nbsp;<?php echo $forum_name ?><?php if (isset($cur_posting['subject'])) echo '</li><li>&nbsp;&raquo;&nbsp;'.pun_htmlspecialchars($cur_posting['subject']) ?></li></ul>
+	</div>
+</div>
+
+<?php
+
+// If there are errors, we display them
+if (!empty($errors))
+{
+
+?>
+<div id="posterror" class="block">
+	<h2><span><?php echo $lang_post['Post errors'] ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<p><?php echo $lang_post['Post errors info'] ?></p>
+			<ul>
+<?php
+
+	while (list(, $cur_error) = each($errors))
+		echo "\t\t\t\t".'<li><strong>'.$cur_error.'</strong></li>'."\n";
+?>
+			</ul>
+		</div>
+	</div>
+</div>
+
+<?php
+
+}
+else if (isset($_POST['preview']))
+{
+	require_once PUN_ROOT.'include/parser.php';
+	$preview_message = parse_message($message, $hide_smilies);
+
+?>
+<div id="postpreview" class="blockpost">
+	<h2><span><?php echo $lang_post['Post preview'] ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<div class="postright">
+				<div class="postmsg">
+					<?php echo $preview_message."\n" ?>
+				</div>
+			</div>
+		</div>
+	</div>
+</div>
+
+<?php
+
+}
+
+
+$cur_index = 1;
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $action ?></span></h2>
+	<div class="box">
+		<?php echo $form."\n" ?>
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_common['Write message legend'] ?></legend>
+					<div class="infldset txtarea">
+						<input type="hidden" name="form_sent" value="1" />
+						<input type="hidden" name="form_user" value="<?php echo (!$pun_user['is_guest']) ? pun_htmlspecialchars($pun_user['username']) : 'Guest'; ?>" />
+<?php
+
+if ($pun_user['is_guest'])
+{
+	$email_label = ($pun_config['p_force_guest_email'] == '1') ? '<strong>'.$lang_common['E-mail'].'</strong>' : $lang_common['E-mail'];
+	$email_form_name = ($pun_config['p_force_guest_email'] == '1') ? 'req_email' : 'email';
+
+?>						<label class="conl"><strong><?php echo $lang_post['Guest name'] ?></strong><br /><input type="text" name="req_username" value="<?php if (isset($_POST['req_username'])) echo pun_htmlspecialchars($username); ?>" size="25" maxlength="25" tabindex="<?php echo $cur_index++ ?>" /><br /></label>
+						<label class="conl"><?php echo $email_label ?><br /><input type="text" name="<?php echo $email_form_name ?>" value="<?php if (isset($_POST[$email_form_name])) echo pun_htmlspecialchars($email); ?>" size="50" maxlength="50" tabindex="<?php echo $cur_index++ ?>" /><br /></label>
+						<div class="clearer"></div>
+<?php
+
+}
+
+if ($fid): ?>
+						<label><strong><?php echo $lang_common['Subject'] ?></strong><br /><input class="longinput" type="text" name="req_subject" value="<?php if (isset($_POST['req_subject'])) echo pun_htmlspecialchars($subject); ?>" size="80" maxlength="70" tabindex="<?php echo $cur_index++ ?>" /><br /></label>
+<?php endif; ?>						<label><strong><?php echo $lang_common['Message'] ?></strong><br />
+						<textarea name="req_message" rows="20" cols="95" tabindex="<?php echo $cur_index++ ?>"><?php echo isset($_POST['req_message']) ? pun_htmlspecialchars($message) : (isset($quote) ? $quote : ''); ?></textarea><br /></label>
+						<ul class="bblinks">
+							<li><a href="help.php#bbcode" onclick="window.open(this.href); return false;"><?php echo $lang_common['BBCode'] ?></a>: <?php echo ($pun_config['p_message_bbcode'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+							<li><a href="help.php#img" onclick="window.open(this.href); return false;"><?php echo $lang_common['img tag'] ?></a>: <?php echo ($pun_config['p_message_img_tag'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+							<li><a href="help.php#smilies" onclick="window.open(this.href); return false;"><?php echo $lang_common['Smilies'] ?></a>: <?php echo ($pun_config['o_smilies'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+						</ul>
+					</div>
+				</fieldset>
+<?php
+
+$checkboxes = array();
+if (!$pun_user['is_guest'])
+{
+	if ($pun_config['o_smilies'] == '1')
+		$checkboxes[] = '<label><input type="checkbox" name="hide_smilies" value="1" tabindex="'.($cur_index++).'"'.(isset($_POST['hide_smilies']) ? ' checked="checked"' : '').' />'.$lang_post['Hide smilies'];
+
+	if ($pun_config['o_subscriptions'] == '1')
+		$checkboxes[] = '<label><input type="checkbox" name="subscribe" value="1" tabindex="'.($cur_index++).'"'.(isset($_POST['subscribe']) ? ' checked="checked"' : '').' />'.$lang_post['Subscribe'];
+}
+else if ($pun_config['o_smilies'] == '1')
+	$checkboxes[] = '<label><input type="checkbox" name="hide_smilies" value="1" tabindex="'.($cur_index++).'"'.(isset($_POST['hide_smilies']) ? ' checked="checked"' : '').' />'.$lang_post['Hide smilies'];
+
+if (!empty($checkboxes))
+{
+
+?>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_common['Options'] ?></legend>
+					<div class="infldset">
+						<div class="rbox">
+							<?php echo implode('<br /></label>'."\n\t\t\t\t", $checkboxes).'<br /></label>'."\n" ?>
+						</div>
+					</div>
+				</fieldset>
+<?php
+
+}
+
+?>
+			</div>
+			<p><input type="submit" name="submit" value="<?php echo $lang_common['Submit'] ?>" tabindex="<?php echo $cur_index++ ?>" accesskey="s" /><input type="submit" name="preview" value="<?php echo $lang_post['Preview'] ?>" tabindex="<?php echo $cur_index++ ?>" accesskey="p" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+
+<?php
+
+// Check to see if the topic review is to be displayed.
+if ($tid && $pun_config['o_topic_review'] != '0')
+{
+	require_once PUN_ROOT.'include/parser.php';
+
+	$result = $db->query('SELECT poster, message, hide_smilies, posted FROM '.$db->prefix.'posts WHERE topic_id='.$tid.' ORDER BY id DESC LIMIT '.$pun_config['o_topic_review']) or error('Unable to fetch topic review', __FILE__, __LINE__, $db->error());
+
+?>
+
+<div id="postreview" class="blockpost">
+	<h2><span><?php echo $lang_post['Topic review'] ?></span></h2>
+<?php
+
+	//Set background switching on
+	$bg_switch = true;
+	$post_count = 0;
+
+	while ($cur_post = $db->fetch_assoc($result))
+	{
+		// Switch the background color for every message.
+		$bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true;
+		$vtbg = ($bg_switch) ? ' roweven' : ' rowodd';
+		$post_count++;
+
+		$cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']);
+
+?>
+	<div class="box<?php echo $vtbg ?>">
+		<div class="inbox">
+			<div class="postleft">
+				<dl>
+					<dt><strong><?php echo pun_htmlspecialchars($cur_post['poster']) ?></strong></dt>
+					<dd><?php echo format_time($cur_post['posted']) ?></dd>
+				</dl>
+			</div>
+			<div class="postright">
+				<div class="postmsg">
+					<?php echo $cur_post['message'] ?>
+				</div>
+			</div>
+			<div class="clearer"></div>
+		</div>
+	</div>
+<?php
+
+	}
+
+?>
+</div>
+<?php
+
+}
+
+require PUN_ROOT.'footer.php';
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/profile.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,1616 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+$action = isset($_GET['action']) ? $_GET['action'] : null;
+$section = isset($_GET['section']) ? $_GET['section'] : null;
+$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
+if ($id < 2)
+	message($lang_common['Bad request']);
+
+if ($pun_user['g_read_board'] == '0' && ($action != 'change_pass' || !isset($_GET['key'])))
+	message($lang_common['No view']);
+
+// Load the profile.php/register.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/prof_reg.php';
+
+// Load the profile.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/profile.php';
+
+
+if ($action == 'change_pass')
+{
+	if (isset($_GET['key']))
+	{
+		// If the user is already logged in we shouldn't be here :)
+		if (!$pun_user['is_guest'])
+		{
+			header('Location: index.php');
+			exit;
+		}
+
+		$key = $_GET['key'];
+
+		$result = $db->query('SELECT activate_string, activate_key FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch new password', __FILE__, __LINE__, $db->error());
+		list($new_password_hash, $new_password_key) = $db->fetch_row($result);
+
+		if ($key == '' || $key != $new_password_key)
+			message($lang_profile['Pass key bad'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.');
+		else
+		{
+			$db->query('UPDATE '.$db->prefix.'users SET password=\''.$new_password_hash.'\', activate_string=NULL, activate_key=NULL WHERE id='.$id) or error('Unable to update password', __FILE__, __LINE__, $db->error());
+
+			message($lang_profile['Pass updated'], true);
+		}
+	}
+
+	// Make sure we are allowed to change this users password
+	if ($pun_user['id'] != $id)
+	{
+		if ($pun_user['g_id'] > PUN_MOD)	// A regular user trying to change another users password?
+			message($lang_common['No permission']);
+		else if ($pun_user['g_id'] == PUN_MOD)	// A moderator trying to change a users password?
+		{
+			$result = $db->query('SELECT group_id FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+			if (!$db->num_rows($result))
+				message($lang_common['Bad request']);
+
+			if ($pun_config['p_mod_edit_users'] == '0' || $pun_config['p_mod_change_passwords'] == '0' || $db->result($result) < PUN_GUEST)
+				message($lang_common['No permission']);
+		}
+	}
+
+	if (isset($_POST['form_sent']))
+	{
+		$old_password = isset($_POST['req_old_password']) ? trim($_POST['req_old_password']) : '';
+		$new_password1 = trim($_POST['req_new_password1']);
+		$new_password2 = trim($_POST['req_new_password2']);
+
+		if ($new_password1 != $new_password2)
+			message($lang_prof_reg['Pass not match']);
+		if (strlen($new_password1) < 4)
+			message($lang_prof_reg['Pass too short']);
+
+		$result = $db->query('SELECT password, save_pass FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch password', __FILE__, __LINE__, $db->error());
+		list($db_password_hash, $save_pass) = $db->fetch_row($result);
+
+		$authorized = false;
+
+		if (!empty($db_password_hash))
+		{
+			$sha1_in_db = (strlen($db_password_hash) == 40) ? true : false;
+			$sha1_available = (function_exists('sha1') || function_exists('mhash')) ? true : false;
+
+			$old_password_hash = pun_hash($old_password);	// This could result in either an SHA-1 or an MD5 hash
+
+			if (($sha1_in_db && $sha1_available && $db_password_hash == $old_password_hash) ||
+				(!$sha1_in_db && $db_password_hash == md5($old_password)) ||
+				$pun_user['g_id'] < PUN_GUEST)
+				$authorized = true;
+		}
+
+		if (!$authorized)
+			message($lang_profile['Wrong pass']);
+
+		$new_password_hash = pun_hash($new_password1);
+
+		$db->query('UPDATE '.$db->prefix.'users SET password=\''.$new_password_hash.'\' WHERE id='.$id) or error('Unable to update password', __FILE__, __LINE__, $db->error());
+
+		if ($pun_user['id'] == $id)
+		{
+			$expire = ($save_pass == '1') ? time() + 31536000 : 0;
+			pun_setcookie($pun_user['id'], $new_password_hash, $expire);
+		}
+
+		redirect('profile.php?section=essentials&amp;id='.$id, $lang_profile['Pass updated redirect']);
+	}
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+	$required_fields = array('req_old_password' => $lang_profile['Old pass'], 'req_new_password1' => $lang_profile['New pass'], 'req_new_password2' => $lang_profile['Confirm new pass']);
+	$focus_element = array('change_pass', (($pun_user['g_id'] > PUN_MOD) ? 'req_old_password' : 'req_new_password1'));
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_profile['Change pass'] ?></span></h2>
+	<div class="box">
+		<form id="change_pass" method="post" action="profile.php?action=change_pass&amp;id=<?php echo $id ?>" onsubmit="return process_form(this)">
+			<div class="inform">
+				<input type="hidden" name="form_sent" value="1" />
+				<fieldset>
+					<legend><?php echo $lang_profile['Change pass legend'] ?></legend>
+					<div class="infldset">
+<?php if ($pun_user['g_id'] > PUN_MOD): ?>						<label><strong><?php echo $lang_profile['Old pass'] ?></strong><br />
+						<input type="password" name="req_old_password" size="16" maxlength="16" /><br /></label>
+<?php endif; ?>						<label class="conl"><strong><?php echo $lang_profile['New pass'] ?></strong><br />
+						<input type="password" name="req_new_password1" size="16" maxlength="16" /><br /></label>
+						<label class="conl"><strong><?php echo $lang_profile['Confirm new pass'] ?></strong><br />
+						<input type="password" name="req_new_password2" size="16" maxlength="16" /><br /></label>
+						<div class="clearb"></div>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="update" value="<?php echo $lang_common['Submit'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+else if ($action == 'change_email')
+{
+	// Make sure we are allowed to change this users e-mail
+	if ($pun_user['id'] != $id)
+	{
+		if ($pun_user['g_id'] > PUN_MOD)	// A regular user trying to change another users e-mail?
+			message($lang_common['No permission']);
+		else if ($pun_user['g_id'] == PUN_MOD)	// A moderator trying to change a users e-mail?
+		{
+			$result = $db->query('SELECT group_id FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+			if (!$db->num_rows($result))
+				message($lang_common['Bad request']);
+
+			if ($pun_config['p_mod_edit_users'] == '0' || $db->result($result) < PUN_GUEST)
+				message($lang_common['No permission']);
+		}
+	}
+
+	if (isset($_GET['key']))
+	{
+		$key = $_GET['key'];
+
+		$result = $db->query('SELECT activate_string, activate_key FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch activation data', __FILE__, __LINE__, $db->error());
+		list($new_email, $new_email_key) = $db->fetch_row($result);
+
+		if ($key == '' || $key != $new_email_key)
+			message($lang_profile['E-mail key bad'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.');
+		else
+		{
+			$db->query('UPDATE '.$db->prefix.'users SET email=activate_string, activate_string=NULL, activate_key=NULL WHERE id='.$id) or error('Unable to update e-mail address', __FILE__, __LINE__, $db->error());
+
+			message($lang_profile['E-mail updated'], true);
+		}
+	}
+	else if (isset($_POST['form_sent']))
+	{
+		if (pun_hash($_POST['req_password']) !== $pun_user['password'])
+			message($lang_profile['Wrong pass']);
+
+		require PUN_ROOT.'include/email.php';
+
+		// Validate the email-address
+		$new_email = strtolower(trim($_POST['req_new_email']));
+		if (!is_valid_email($new_email))
+			message($lang_common['Invalid e-mail']);
+
+		// Check it it's a banned e-mail address
+		if (is_banned_email($new_email))
+		{
+			if ($pun_config['p_allow_banned_email'] == '0')
+				message($lang_prof_reg['Banned e-mail']);
+			else if ($pun_config['o_mailing_list'] != '')
+			{
+				$mail_subject = 'Alert - Banned e-mail detected';
+				$mail_message = 'User \''.$pun_user['username'].'\' changed to banned e-mail address: '.$new_email."\n\n".'User profile: '.$pun_config['o_base_url'].'/profile.php?id='.$id."\n\n".'-- '."\n".'Forum Mailer'."\n".'(Do not reply to this message)';
+
+				pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message);
+			}
+		}
+
+		// Check if someone else already has registered with that e-mail address
+		$result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE email=\''.$db->escape($new_email).'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+		if ($db->num_rows($result))
+		{
+			if ($pun_config['p_allow_dupe_email'] == '0')
+				message($lang_prof_reg['Dupe e-mail']);
+			else if ($pun_config['o_mailing_list'] != '')
+			{
+				while ($cur_dupe = $db->fetch_assoc($result))
+					$dupe_list[] = $cur_dupe['username'];
+
+				$mail_subject = 'Alert - Duplicate e-mail detected';
+				$mail_message = 'User \''.$pun_user['username'].'\' changed to an e-mail address that also belongs to: '.implode(', ', $dupe_list)."\n\n".'User profile: '.$pun_config['o_base_url'].'/profile.php?id='.$id."\n\n".'-- '."\n".'Forum Mailer'."\n".'(Do not reply to this message)';
+
+				pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message);
+			}
+		}
+
+
+		$new_email_key = random_pass(8);
+
+		$db->query('UPDATE '.$db->prefix.'users SET activate_string=\''.$db->escape($new_email).'\', activate_key=\''.$new_email_key.'\' WHERE id='.$id) or error('Unable to update activation data', __FILE__, __LINE__, $db->error());
+
+		// Load the "activate e-mail" template
+		$mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/activate_email.tpl'));
+
+		// The first row contains the subject
+		$first_crlf = strpos($mail_tpl, "\n");
+		$mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8));
+		$mail_message = trim(substr($mail_tpl, $first_crlf));
+
+		$mail_message = str_replace('<username>', $pun_user['username'], $mail_message);
+		$mail_message = str_replace('<base_url>', $pun_config['o_base_url'], $mail_message);
+		$mail_message = str_replace('<activation_url>', $pun_config['o_base_url'].'/profile.php?action=change_email&id='.$id.'&key='.$new_email_key, $mail_message);
+		$mail_message = str_replace('<board_mailer>', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message);
+
+		pun_mail($new_email, $mail_subject, $mail_message);
+
+		message($lang_profile['Activate e-mail sent'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.', true);
+	}
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+	$required_fields = array('req_new_email' => $lang_profile['New e-mail'], 'req_password' => $lang_common['Password']);
+	$focus_element = array('change_email', 'req_new_email');
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_profile['Change e-mail'] ?></span></h2>
+	<div class="box">
+		<form id="change_email" method="post" action="profile.php?action=change_email&amp;id=<?php echo $id ?>" id="change_email" onsubmit="return process_form(this)">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_profile['E-mail legend'] ?></legend>
+					<div class="infldset">
+						<input type="hidden" name="form_sent" value="1" />
+						<label><strong><?php echo $lang_profile['New e-mail'] ?></strong><br /><input type="text" name="req_new_email" size="50" maxlength="50" /><br /></label>
+						<label><strong><?php echo $lang_common['Password'] ?></strong><br /><input type="password" name="req_password" size="16" maxlength="16" /><br /></label>
+						<p><?php echo $lang_profile['E-mail instructions'] ?></p>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="new_email" value="<?php echo $lang_common['Submit'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+else if ($action == 'upload_avatar' || $action == 'upload_avatar2')
+{
+	if ($pun_config['o_avatars'] == '0')
+		message($lang_profile['Avatars disabled']);
+
+	if ($pun_user['id'] != $id && $pun_user['g_id'] > PUN_MOD)
+		message($lang_common['No permission']);
+
+	if (isset($_POST['form_sent']))
+	{
+		if (!isset($_FILES['req_file']))
+			message($lang_profile['No file']);
+			
+		$uploaded_file = $_FILES['req_file'];
+
+		// Make sure the upload went smooth
+		if (isset($uploaded_file['error']))
+		{
+			switch ($uploaded_file['error'])
+			{
+				case 1:	// UPLOAD_ERR_INI_SIZE
+				case 2:	// UPLOAD_ERR_FORM_SIZE
+					message($lang_profile['Too large ini']);
+					break;
+
+				case 3:	// UPLOAD_ERR_PARTIAL
+					message($lang_profile['Partial upload']);
+					break;
+
+				case 4:	// UPLOAD_ERR_NO_FILE
+					message($lang_profile['No file']);
+					break;
+
+				case 6:	// UPLOAD_ERR_NO_TMP_DIR
+					message($lang_profile['No tmp directory']);
+					break;
+
+				default:
+					// No error occured, but was something actually uploaded?
+					if ($uploaded_file['size'] == 0)
+						message($lang_profile['No file']);
+					break;
+			}
+		}
+
+		if (is_uploaded_file($uploaded_file['tmp_name']))
+		{
+			$allowed_types = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/png', 'image/x-png');
+			if (!in_array($uploaded_file['type'], $allowed_types))
+				message($lang_profile['Bad type']);
+
+			// Make sure the file isn't too big
+			if ($uploaded_file['size'] > $pun_config['o_avatars_size'])
+				message($lang_profile['Too large'].' '.$pun_config['o_avatars_size'].' '.$lang_profile['bytes'].'.');
+
+			// Determine type
+			$extensions = null;
+			if ($uploaded_file['type'] == 'image/gif')
+				$extensions = array('.gif', '.jpg', '.png');
+			else if ($uploaded_file['type'] == 'image/jpeg' || $uploaded_file['type'] == 'image/pjpeg')
+				$extensions = array('.jpg', '.gif', '.png');
+			else
+				$extensions = array('.png', '.gif', '.jpg');
+
+			// Move the file to the avatar directory. We do this before checking the width/height to circumvent open_basedir restrictions.
+			if (!@move_uploaded_file($uploaded_file['tmp_name'], $pun_config['o_avatars_dir'].'/'.$id.'.tmp'))
+				message($lang_profile['Move failed'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.');
+
+			// Now check the width/height
+			list($width, $height, $type,) = getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.tmp');
+			if (empty($width) || empty($height) || $width > $pun_config['o_avatars_width'] || $height > $pun_config['o_avatars_height'])
+			{
+				@unlink($pun_config['o_avatars_dir'].'/'.$id.'.tmp');
+				message($lang_profile['Too wide or high'].' '.$pun_config['o_avatars_width'].'x'.$pun_config['o_avatars_height'].' '.$lang_profile['pixels'].'.');
+			}
+			else if ($type == 1 && $uploaded_file['type'] != 'image/gif')	// Prevent dodgy uploads
+			{
+				@unlink($pun_config['o_avatars_dir'].'/'.$id.'.tmp');
+				message($lang_profile['Bad type']);
+			}			
+
+			// Delete any old avatars and put the new one in place
+			@unlink($pun_config['o_avatars_dir'].'/'.$id.$extensions[0]);
+			@unlink($pun_config['o_avatars_dir'].'/'.$id.$extensions[1]);
+			@unlink($pun_config['o_avatars_dir'].'/'.$id.$extensions[2]);
+			@rename($pun_config['o_avatars_dir'].'/'.$id.'.tmp', $pun_config['o_avatars_dir'].'/'.$id.$extensions[0]);
+			@chmod($pun_config['o_avatars_dir'].'/'.$id.$extensions[0], 0644);
+		}
+		else
+			message($lang_profile['Unknown failure']);
+
+		// Enable use_avatar (seems sane since the user just uploaded an avatar)
+		$db->query('UPDATE '.$db->prefix.'users SET use_avatar=1 WHERE id='.$id) or error('Unable to update avatar state', __FILE__, __LINE__, $db->error());
+
+		redirect('profile.php?section=personality&amp;id='.$id, $lang_profile['Avatar upload redirect']);
+	}
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+	$required_fields = array('req_file' => $lang_profile['File']);
+	$focus_element = array('upload_avatar', 'req_file');
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_profile['Upload avatar'] ?></span></h2>
+	<div class="box">
+		<form id="upload_avatar" method="post" enctype="multipart/form-data" action="profile.php?action=upload_avatar2&amp;id=<?php echo $id ?>" onsubmit="return process_form(this)">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_profile['Upload avatar legend'] ?></legend>
+					<div class="infldset">
+						<input type="hidden" name="form_sent" value="1" />
+						<input type="hidden" name="MAX_FILE_SIZE" value="<?php echo $pun_config['o_avatars_size'] ?>" />
+						<label><strong><?php echo $lang_profile['File'] ?></strong><br /><input name="req_file" type="file" size="40" /><br /></label>
+						<p><?php echo $lang_profile['Avatar desc'].' '.$pun_config['o_avatars_width'].' x '.$pun_config['o_avatars_height'].' '.$lang_profile['pixels'].' '.$lang_common['and'].' '.$pun_config['o_avatars_size'].' '.$lang_profile['bytes'].' ('.ceil($pun_config['o_avatars_size'] / 1024) ?> KB).</p>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="upload" value="<?php echo $lang_profile['Upload'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+else if ($action == 'delete_avatar')
+{
+	if ($pun_user['id'] != $id && $pun_user['g_id'] > PUN_MOD)
+		message($lang_common['No permission']);
+
+	confirm_referrer('profile.php');
+
+	@unlink($pun_config['o_avatars_dir'].'/'.$id.'.jpg');
+	@unlink($pun_config['o_avatars_dir'].'/'.$id.'.png');
+	@unlink($pun_config['o_avatars_dir'].'/'.$id.'.gif');
+
+	// Disable use_avatar
+	$db->query('UPDATE '.$db->prefix.'users SET use_avatar=0 WHERE id='.$id) or error('Unable to update avatar state', __FILE__, __LINE__, $db->error());
+
+	redirect('profile.php?section=personality&amp;id='.$id, $lang_profile['Avatar deleted redirect']);
+}
+
+
+else if (isset($_POST['update_group_membership']))
+{
+	if ($pun_user['g_id'] > PUN_ADMIN)
+		message($lang_common['No permission']);
+
+	confirm_referrer('profile.php');
+
+	$new_group_id = intval($_POST['group_id']);
+
+	$db->query('UPDATE '.$db->prefix.'users SET group_id='.$new_group_id.' WHERE id='.$id) or error('Unable to change user group', __FILE__, __LINE__, $db->error());
+
+	// If the user was a moderator or an administrator, we remove him/her from the moderator list in all forums as well
+	if ($new_group_id > PUN_MOD)
+	{
+		$result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
+
+		while ($cur_forum = $db->fetch_assoc($result))
+		{
+			$cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array();
+
+			if (in_array($id, $cur_moderators))
+			{
+				$username = array_search($id, $cur_moderators);
+				unset($cur_moderators[$username]);
+				$cur_moderators = (!empty($cur_moderators)) ? '\''.$db->escape(serialize($cur_moderators)).'\'' : 'NULL';
+
+				$db->query('UPDATE '.$db->prefix.'forums SET moderators='.$cur_moderators.' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
+			}
+		}
+	}
+
+	redirect('profile.php?section=admin&amp;id='.$id, $lang_profile['Group membership redirect']);
+}
+
+
+else if (isset($_POST['update_forums']))
+{
+	if ($pun_user['g_id'] > PUN_ADMIN)
+		message($lang_common['No permission']);
+
+	confirm_referrer('profile.php');
+
+	// Get the username of the user we are processing
+	$result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+	$username = $db->result($result);
+
+	$moderator_in = (isset($_POST['moderator_in'])) ? array_keys($_POST['moderator_in']) : array();
+
+	// Loop through all forums
+	$result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
+
+	while ($cur_forum = $db->fetch_assoc($result))
+	{
+		$cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array();
+		// If the user should have moderator access (and he/she doesn't already have it)
+		if (in_array($cur_forum['id'], $moderator_in) && !in_array($id, $cur_moderators))
+		{
+			$cur_moderators[$username] = $id;
+			ksort($cur_moderators);
+
+			$db->query('UPDATE '.$db->prefix.'forums SET moderators=\''.$db->escape(serialize($cur_moderators)).'\' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
+		}
+		// If the user shouldn't have moderator access (and he/she already has it)
+		else if (!in_array($cur_forum['id'], $moderator_in) && in_array($id, $cur_moderators))
+		{
+			unset($cur_moderators[$username]);
+			$cur_moderators = (!empty($cur_moderators)) ? '\''.$db->escape(serialize($cur_moderators)).'\'' : 'NULL';
+
+			$db->query('UPDATE '.$db->prefix.'forums SET moderators='.$cur_moderators.' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
+		}
+	}
+
+	redirect('profile.php?section=admin&amp;id='.$id, $lang_profile['Update forums redirect']);
+}
+
+
+else if (isset($_POST['ban']))
+{
+	if ($pun_user['g_id'] > PUN_MOD || ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_ban_users'] == '0'))
+		message($lang_common['No permission']);
+
+	redirect('admin_bans.php?add_ban='.$id, $lang_profile['Ban redirect']);
+}
+
+
+else if (isset($_POST['delete_user']) || isset($_POST['delete_user_comply']))
+{
+	if ($pun_user['g_id'] > PUN_ADMIN)
+		message($lang_common['No permission']);
+
+	confirm_referrer('profile.php');
+
+	// Get the username and group of the user we are deleting
+	$result = $db->query('SELECT group_id, username FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+	list($group_id, $username) = $db->fetch_row($result);
+
+	if ($group_id == PUN_ADMIN)
+		message('Administrators cannot be deleted. In order to delete this user, you must first move him/her to a different user group.');
+
+	if (isset($_POST['delete_user_comply']))
+	{
+		// If the user is a moderator or an administrator, we remove him/her from the moderator list in all forums as well
+		if ($group_id < PUN_GUEST)
+		{
+			$result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
+
+			while ($cur_forum = $db->fetch_assoc($result))
+			{
+				$cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array();
+
+				if (in_array($id, $cur_moderators))
+				{
+					unset($cur_moderators[$username]);
+					$cur_moderators = (!empty($cur_moderators)) ? '\''.$db->escape(serialize($cur_moderators)).'\'' : 'NULL';
+
+					$db->query('UPDATE '.$db->prefix.'forums SET moderators='.$cur_moderators.' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
+				}
+			}
+		}
+
+		// Delete any subscriptions
+		$db->query('DELETE FROM '.$db->prefix.'subscriptions WHERE user_id='.$id) or error('Unable to delete subscriptions', __FILE__, __LINE__, $db->error());
+
+		// Remove him/her from the online list (if they happen to be logged in)
+		$db->query('DELETE FROM '.$db->prefix.'online WHERE user_id='.$id) or error('Unable to remove user from online list', __FILE__, __LINE__, $db->error());
+
+		// Should we delete all posts made by this user?
+		if (isset($_POST['delete_posts']))
+		{
+			require PUN_ROOT.'include/search_idx.php';
+			@set_time_limit(0);
+
+			// Find all posts made by this user
+			$result = $db->query('SELECT p.id, p.topic_id, t.forum_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id WHERE p.poster_id='.$id) or error('Unable to fetch posts', __FILE__, __LINE__, $db->error());
+			if ($db->num_rows($result))
+			{
+				while ($cur_post = $db->fetch_assoc($result))
+				{
+					// Determine whether this post is the "topic post" or not
+					$result2 = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$cur_post['topic_id'].' ORDER BY posted LIMIT 1') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+
+					if ($db->result($result2) == $cur_post['id'])
+						delete_topic($cur_post['topic_id']);
+					else
+						delete_post($cur_post['id'], $cur_post['topic_id']);
+
+					update_forum($cur_post['forum_id']);
+				}
+			}
+		}
+		else
+			// Set all his/her posts to guest
+			$db->query('UPDATE '.$db->prefix.'posts SET poster_id=1 WHERE poster_id='.$id) or error('Unable to update posts', __FILE__, __LINE__, $db->error());
+
+		// Delete the user
+		$db->query('DELETE FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to delete user', __FILE__, __LINE__, $db->error());
+
+		redirect('index.php', $lang_profile['User delete redirect']);
+	}
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_profile['Confirm delete user'] ?></span></h2>
+	<div class="box">
+		<form id="confirm_del_user" method="post" action="profile.php?id=<?php echo $id ?>">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_profile['Confirm delete legend'] ?></legend>
+					<div class="infldset">
+						<p><?php echo $lang_profile['Confirmation info'].' '.pun_htmlspecialchars($username).'.' ?></p>
+						<div class="rbox">
+							<label><input type="checkbox" name="delete_posts" value="1" checked="checked" /><?php echo $lang_profile['Delete posts'] ?><br /></label>
+						</div>
+						<p class="warntext"><strong><?php echo $lang_profile['Delete warning'] ?></strong></p>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="delete_user_comply" value="<?php echo $lang_profile['Delete'] ?>" /><a href="javascript:history.go(-1)"><?php echo $lang_common['Go back'] ?></a></p>
+		</form>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+else if (isset($_POST['form_sent']))
+{
+	// Fetch the user group of the user we are editing
+	$result = $db->query('SELECT group_id FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+	if (!$db->num_rows($result))
+		message($lang_common['Bad request']);
+
+	$group_id = $db->result($result);
+
+	if ($pun_user['id'] != $id &&
+		($pun_user['g_id'] > PUN_MOD ||
+		($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_edit_users'] == '0') ||
+		($pun_user['g_id'] == PUN_MOD && $group_id < PUN_GUEST)))
+		message($lang_common['No permission']);
+
+	if ($pun_user['g_id'] < PUN_GUEST)
+		confirm_referrer('profile.php');
+
+	// Extract allowed elements from $_POST['form']
+	function extract_elements($allowed_elements)
+	{
+		$form = array();
+
+		while (list($key, $value) = @each($_POST['form']))
+		{
+		    if (in_array($key, $allowed_elements))
+		        $form[$key] = $value;
+		}
+
+		return $form;
+	}
+
+	$username_updated = false;
+
+	// Validate input depending on section
+	switch ($section)
+	{
+		case 'essentials':
+		{
+			$form = extract_elements(array('timezone', 'language'));
+
+			if ($pun_user['g_id'] < PUN_GUEST)
+			{
+				$form['admin_note'] = trim($_POST['admin_note']);
+
+				// Are we allowed to change usernames?
+				if ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_rename_users'] == '1'))
+				{
+					$form['username'] = trim($_POST['req_username']);
+					$old_username = trim($_POST['old_username']);
+
+					if (strlen($form['username']) < 2)
+						message($lang_prof_reg['Username too short']);
+					else if (pun_strlen($form['username']) > 25)	// This usually doesn't happen since the form element only accepts 25 characters
+					    message($lang_common['Bad request']);
+					else if (!strcasecmp($form['username'], 'Guest') || !strcasecmp($form['username'], $lang_common['Guest']))
+						message($lang_prof_reg['Username guest']);
+					else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $form['username']))
+						message($lang_prof_reg['Username IP']);
+					else if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[quote=|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $form['username']))
+						message($lang_prof_reg['Username BBCode']);
+
+					// Check that the username is not already registered
+					$result = $db->query('SELECT 1 FROM '.$db->prefix.'users WHERE username=\''.$db->escape($form['username']).'\' AND id!='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+					if ($db->num_rows($result))
+						message($lang_profile['Dupe username']);
+
+					if ($form['username'] != $old_username)
+						$username_updated = true;
+				}
+
+				// We only allow administrators to update the post count
+				if ($pun_user['g_id'] == PUN_ADMIN)
+					$form['num_posts'] = intval($_POST['num_posts']);
+			}
+
+			if ($pun_config['o_regs_verify'] == '0' || $pun_user['g_id'] < PUN_GUEST)
+			{
+				require PUN_ROOT.'include/email.php';
+
+				// Validate the email-address
+				$form['email'] = strtolower(trim($_POST['req_email']));
+				if (!is_valid_email($form['email']))
+					message($lang_common['Invalid e-mail']);
+			}
+
+			// Make sure we got a valid language string
+			if (isset($form['language']))
+			{
+				$form['language'] = preg_replace('#[\.\\\/]#', '', $form['language']);
+				if (!file_exists(PUN_ROOT.'lang/'.$form['language'].'/common.php'))
+						message($lang_common['Bad request']);
+			}
+
+			break;
+		}
+
+		case 'personal':
+		{
+			$form = extract_elements(array('realname', 'url', 'location'));
+
+			if ($pun_user['g_id'] == PUN_ADMIN)
+				$form['title'] = trim($_POST['title']);
+			else if ($pun_user['g_set_title'] == '1')
+			{
+				$form['title'] = trim($_POST['title']);
+
+				if ($form['title'] != '')
+				{
+					// A list of words that the title may not contain
+					// If the language is English, there will be some duplicates, but it's not the end of the world
+					$forbidden = array('Member', 'Moderator', 'Administrator', 'Banned', 'Guest', $lang_common['Member'], $lang_common['Moderator'], $lang_common['Administrator'], $lang_common['Banned'], $lang_common['Guest']);
+
+					if (in_array($form['title'], $forbidden))
+						message($lang_profile['Forbidden title']);
+				}
+			}
+
+			// Add http:// if the URL doesn't contain it already
+			if ($form['url'] != '' && strpos(strtolower($form['url']), 'http://') !== 0)
+				$form['url'] = 'http://'.$form['url'];
+
+			break;
+		}
+
+		case 'messaging':
+		{
+			$form = extract_elements(array('jabber', 'icq', 'msn', 'aim', 'yahoo'));
+
+			// If the ICQ UIN contains anything other than digits it's invalid
+			if ($form['icq'] != '' && @preg_match('/[^0-9]/', $form['icq']))
+				message($lang_prof_reg['Bad ICQ']);
+
+			break;
+		}
+
+		case 'personality':
+		{
+			$form = extract_elements(array('use_avatar'));
+
+			// Clean up signature from POST
+			$form['signature'] = pun_linebreaks(trim($_POST['signature']));
+
+			// Validate signature
+			if (pun_strlen($form['signature']) > $pun_config['p_sig_length'])
+				message($lang_prof_reg['Sig too long'].' '.$pun_config['p_sig_length'].' '.$lang_prof_reg['characters'].'.');
+			else if (substr_count($form['signature'], "\n") > ($pun_config['p_sig_lines']-1))
+				message($lang_prof_reg['Sig too many lines'].' '.$pun_config['p_sig_lines'].' '.$lang_prof_reg['lines'].'.');
+			else if ($form['signature'] && $pun_config['p_sig_all_caps'] == '0' && strtoupper($form['signature']) == $form['signature'] && $pun_user['g_id'] > PUN_MOD)
+				$form['signature'] = ucwords(strtolower($form['signature']));
+
+			// Validate BBCode syntax
+			if ($pun_config['p_sig_bbcode'] == '1' && strpos($form['signature'], '[') !== false && strpos($form['signature'], ']') !== false)
+			{
+				require PUN_ROOT.'include/parser.php';
+				$form['signature'] = preparse_bbcode($form['signature'], $foo, true);
+			}
+
+			if (!isset($form['use_avatar']) || $form['use_avatar'] != '1') $form['use_avatar'] = '0';
+
+			break;
+		}
+
+		case 'display':
+		{
+			$form = extract_elements(array('disp_topics', 'disp_posts', 'show_smilies', 'show_img', 'show_img_sig', 'show_avatars', 'show_sig', 'style'));
+
+			if ($form['disp_topics'] != '' && intval($form['disp_topics']) < 3) $form['disp_topics'] = 3;
+			if ($form['disp_topics'] != '' && intval($form['disp_topics']) > 75) $form['disp_topics'] = 75;
+			if ($form['disp_posts'] != '' && intval($form['disp_posts']) < 3) $form['disp_posts'] = 3;
+			if ($form['disp_posts'] != '' && intval($form['disp_posts']) > 75) $form['disp_posts'] = 75;
+
+			if (!isset($form['show_smilies']) || $form['show_smilies'] != '1') $form['show_smilies'] = '0';
+			if (!isset($form['show_img']) || $form['show_img'] != '1') $form['show_img'] = '0';
+			if (!isset($form['show_img_sig']) || $form['show_img_sig'] != '1') $form['show_img_sig'] = '0';
+			if (!isset($form['show_avatars']) || $form['show_avatars'] != '1') $form['show_avatars'] = '0';
+			if (!isset($form['show_sig']) || $form['show_sig'] != '1') $form['show_sig'] = '0';
+
+			break;
+		}
+
+		case 'privacy':
+		{
+			$form = extract_elements(array('email_setting', 'save_pass', 'notify_with_post'));
+
+			$form['email_setting'] = intval($form['email_setting']);
+			if ($form['email_setting'] < 0 && $form['email_setting'] > 2) $form['email_setting'] = 1;
+
+			if (!isset($form['save_pass']) || $form['save_pass'] != '1') $form['save_pass'] = '0';
+			if (!isset($form['notify_with_post']) || $form['notify_with_post'] != '1') $form['notify_with_post'] = '0';
+
+			// If the save_pass setting has changed, we need to set a new cookie with the appropriate expire date
+			if ($pun_user['id'] == $id && $form['save_pass'] != $pun_user['save_pass'])
+			{
+				$result = $db->query('SELECT password FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user password hash', __FILE__, __LINE__, $db->error());
+				pun_setcookie($id, $db->result($result), ($form['save_pass'] == '1') ? time() + 31536000 : 0);
+			}
+
+			break;
+		}
+
+		default:
+			message($lang_common['Bad request']);
+	}
+
+
+	// Singlequotes around non-empty values and NULL for empty values
+	$temp = array();
+	while (list($key, $input) = @each($form))
+	{
+		$value = ($input !== '') ? '\''.$db->escape($input).'\'' : 'NULL';
+
+		$temp[] = $key.'='.$value;
+	}
+
+	if (empty($temp))
+		message($lang_common['Bad request']);
+
+
+	$db->query('UPDATE '.$db->prefix.'users SET '.implode(',', $temp).' WHERE id='.$id) or error('Unable to update profile', __FILE__, __LINE__, $db->error());
+
+	// If we changed the username we have to update some stuff
+	if ($username_updated)
+	{
+		$db->query('UPDATE '.$db->prefix.'posts SET poster=\''.$db->escape($form['username']).'\' WHERE poster_id='.$id) or error('Unable to update posts', __FILE__, __LINE__, $db->error());
+		$db->query('UPDATE '.$db->prefix.'topics SET poster=\''.$db->escape($form['username']).'\' WHERE poster=\''.$db->escape($old_username).'\'') or error('Unable to update topics', __FILE__, __LINE__, $db->error());
+		$db->query('UPDATE '.$db->prefix.'topics SET last_poster=\''.$db->escape($form['username']).'\' WHERE last_poster=\''.$db->escape($old_username).'\'') or error('Unable to update topics', __FILE__, __LINE__, $db->error());
+		$db->query('UPDATE '.$db->prefix.'forums SET last_poster=\''.$db->escape($form['username']).'\' WHERE last_poster=\''.$db->escape($old_username).'\'') or error('Unable to update forums', __FILE__, __LINE__, $db->error());
+		$db->query('UPDATE '.$db->prefix.'online SET ident=\''.$db->escape($form['username']).'\' WHERE ident=\''.$db->escape($old_username).'\'') or error('Unable to update online list', __FILE__, __LINE__, $db->error());
+
+		// If the user is a moderator or an administrator we have to update the moderator lists
+		$result = $db->query('SELECT group_id FROM '.$db->prefix.'users WHERE id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+		$group_id = $db->result($result);
+
+		if ($group_id < PUN_GUEST)
+		{
+			$result = $db->query('SELECT id, moderators FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
+
+			while ($cur_forum = $db->fetch_assoc($result))
+			{
+				$cur_moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array();
+
+				if (in_array($id, $cur_moderators))
+				{
+					unset($cur_moderators[$old_username]);
+					$cur_moderators[$form['username']] = $id;
+					ksort($cur_moderators);
+
+					$db->query('UPDATE '.$db->prefix.'forums SET moderators=\''.$db->escape(serialize($cur_moderators)).'\' WHERE id='.$cur_forum['id']) or error('Unable to update forum', __FILE__, __LINE__, $db->error());
+				}
+			}
+		}
+	}
+
+	redirect('profile.php?section='.$section.'&amp;id='.$id, $lang_profile['Profile redirect']);
+}
+
+
+$result = $db->query('SELECT u.username, u.email, u.title, u.realname, u.url, u.jabber, u.icq, u.msn, u.aim, u.yahoo, u.location, u.use_avatar, u.signature, u.disp_topics, u.disp_posts, u.email_setting, u.save_pass, u.notify_with_post, u.show_smilies, u.show_img, u.show_img_sig, u.show_avatars, u.show_sig, u.timezone, u.language, u.style, u.num_posts, u.last_post, u.registered, u.registration_ip, u.admin_note, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id='.$id) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+if (!$db->num_rows($result))
+	message($lang_common['Bad request']);
+
+$user = $db->fetch_assoc($result);
+
+$last_post = format_time($user['last_post']);
+
+if ($user['signature'] != '')
+{
+	require PUN_ROOT.'include/parser.php';
+	$parsed_signature = parse_signature($user['signature']);
+}
+
+
+// View or edit?
+if ($pun_user['id'] != $id &&
+	($pun_user['g_id'] > PUN_MOD ||
+	($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_edit_users'] == '0') ||
+	($pun_user['g_id'] == PUN_MOD && $user['g_id'] < PUN_GUEST)))
+{
+	if ($user['email_setting'] == '0' && !$pun_user['is_guest'])
+		$email_field = '<a href="mailto:'.$user['email'].'">'.$user['email'].'</a>';
+	else if ($user['email_setting'] == '1' && !$pun_user['is_guest'])
+		$email_field = '<a href="misc.php?email='.$id.'">'.$lang_common['Send e-mail'].'</a>';
+	else
+		$email_field = $lang_profile['Private'];
+
+	$user_title_field = get_title($user);
+
+	if ($user['url'] != '')
+	{
+		$user['url'] = pun_htmlspecialchars($user['url']);
+
+		if ($pun_config['o_censoring'] == '1')
+			$user['url'] = censor_words($user['url']);
+
+		$url = '<a href="'.$user['url'].'">'.$user['url'].'</a>';
+	}
+	else
+		$url = $lang_profile['Unknown'];
+
+	if ($pun_config['o_avatars'] == '1')
+	{
+		if ($user['use_avatar'] == '1')
+		{
+			if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.gif'))
+				$avatar_field = '<img src="'.$pun_config['o_avatars_dir'].'/'.$id.'.gif" '.$img_size[3].' alt="" />';
+			else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.jpg'))
+				$avatar_field = '<img src="'.$pun_config['o_avatars_dir'].'/'.$id.'.jpg" '.$img_size[3].' alt="" />';
+			else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.png'))
+				$avatar_field = '<img src="'.$pun_config['o_avatars_dir'].'/'.$id.'.png" '.$img_size[3].' alt="" />';
+			else
+				$avatar_field = $lang_profile['No avatar'];
+		}
+		else
+			$avatar_field = $lang_profile['No avatar'];
+	}
+
+	$posts_field = '';
+	if ($pun_config['o_show_post_count'] == '1' || $pun_user['g_id'] < PUN_GUEST)
+		$posts_field = $user['num_posts'];
+	if ($pun_user['g_search'] == '1')
+		$posts_field .= (($posts_field != '') ? ' - ' : '').'<a href="search.php?action=show_user&amp;user_id='.$id.'">'.$lang_profile['Show posts'].'</a>';
+
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+	define('PUN_ALLOW_INDEX', 1);
+	require PUN_ROOT.'header.php';
+
+?>
+<div id="viewprofile" class="block">
+	<h2><span><?php echo $lang_common['Profile'] ?></span></h2>
+	<div class="box">
+		<div class="fakeform">
+			<div class="inform">
+				<fieldset>
+				<legend><?php echo $lang_profile['Section personal'] ?></legend>
+					<div class="infldset">
+						<dl>
+							<dt><?php echo $lang_common['Username'] ?>: </dt>
+							<dd><?php echo pun_htmlspecialchars($user['username']) ?></dd>
+							<dt><?php echo $lang_common['Title'] ?>: </dt>
+							<dd><?php echo ($pun_config['o_censoring'] == '1') ? censor_words($user_title_field) : $user_title_field; ?></dd>
+							<dt><?php echo $lang_profile['Realname'] ?>: </dt>
+							<dd><?php echo ($user['realname'] !='') ? pun_htmlspecialchars(($pun_config['o_censoring'] == '1') ? censor_words($user['realname']) : $user['realname']) : $lang_profile['Unknown']; ?></dd>
+							<dt><?php echo $lang_profile['Location'] ?>: </dt>
+							<dd><?php echo ($user['location'] !='') ? pun_htmlspecialchars(($pun_config['o_censoring'] == '1') ? censor_words($user['location']) : $user['location']) : $lang_profile['Unknown']; ?></dd>
+							<dt><?php echo $lang_profile['Website'] ?>: </dt>
+							<dd><?php echo $url ?>&nbsp;</dd>
+							<dt><?php echo $lang_common['E-mail'] ?>: </dt>
+							<dd><?php echo $email_field ?></dd>
+						</dl>
+						<div class="clearer"></div>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+				<legend><?php echo $lang_profile['Section messaging'] ?></legend>
+					<div class="infldset">
+						<dl>
+							<dt><?php echo $lang_profile['Jabber'] ?>: </dt>
+							<dd><?php echo ($user['jabber'] !='') ? pun_htmlspecialchars($user['jabber']) : $lang_profile['Unknown']; ?></dd>
+							<dt><?php echo $lang_profile['ICQ'] ?>: </dt>
+							<dd><?php echo ($user['icq'] !='') ? $user['icq'] : $lang_profile['Unknown']; ?></dd>
+							<dt><?php echo $lang_profile['MSN'] ?>: </dt>
+							<dd><?php echo ($user['msn'] !='') ? pun_htmlspecialchars(($pun_config['o_censoring'] == '1') ? censor_words($user['msn']) : $user['msn']) : $lang_profile['Unknown']; ?></dd>
+							<dt><?php echo $lang_profile['AOL IM'] ?>: </dt>
+							<dd><?php echo ($user['aim'] !='') ? pun_htmlspecialchars(($pun_config['o_censoring'] == '1') ? censor_words($user['aim']) : $user['aim']) : $lang_profile['Unknown']; ?></dd>
+							<dt><?php echo $lang_profile['Yahoo'] ?>: </dt>
+							<dd><?php echo ($user['yahoo'] !='') ? pun_htmlspecialchars(($pun_config['o_censoring'] == '1') ? censor_words($user['yahoo']) : $user['yahoo']) : $lang_profile['Unknown']; ?></dd>
+						</dl>
+						<div class="clearer"></div>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+				<legend><?php echo $lang_profile['Section personality'] ?></legend>
+					<div class="infldset">
+						<dl>
+<?php if ($pun_config['o_avatars'] == '1'): ?>							<dt><?php echo $lang_profile['Avatar'] ?>: </dt>
+							<dd><?php echo $avatar_field ?></dd>
+<?php endif; ?>							<dt><?php echo $lang_profile['Signature'] ?>: </dt>
+							<dd><div><?php echo isset($parsed_signature) ? $parsed_signature : $lang_profile['No sig']; ?></div></dd>
+						</dl>
+						<div class="clearer"></div>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+				<legend><?php echo $lang_profile['User activity'] ?></legend>
+					<div class="infldset">
+						<dl>
+<?php if ($posts_field != ''): ?>							<dt><?php echo $lang_common['Posts'] ?>: </dt>
+							<dd><?php echo $posts_field ?></dd>
+<?php endif; ?>							<dt><?php echo $lang_common['Last post'] ?>: </dt>
+							<dd><?php echo $last_post ?></dd>
+							<dt><?php echo $lang_common['Registered'] ?>: </dt>
+							<dd><?php echo format_time($user['registered'], true) ?></dd>
+						</dl>
+						<div class="clearer"></div>
+					</div>
+				</fieldset>
+			</div>
+		</div>
+	</div>
+</div>
+
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+else
+{
+	if (!$section || $section == 'essentials')
+	{
+		if ($pun_user['g_id'] < PUN_GUEST)
+		{
+			if ($pun_user['g_id'] == PUN_ADMIN || $pun_config['p_mod_rename_users'] == '1')
+				$username_field = '<input type="hidden" name="old_username" value="'.pun_htmlspecialchars($user['username']).'" /><label><strong>'.$lang_common['Username'].'</strong><br /><input type="text" name="req_username" value="'.pun_htmlspecialchars($user['username']).'" size="25" maxlength="25" /><br /></label>'."\n";
+			else
+				$username_field = '<p>'.$lang_common['Username'].': '.pun_htmlspecialchars($user['username']).'</p>'."\n";
+
+			$email_field = '<label><strong>'.$lang_common['E-mail'].'</strong><br /><input type="text" name="req_email" value="'.$user['email'].'" size="40" maxlength="50" /><br /></label><p><a href="misc.php?email='.$id.'">'.$lang_common['Send e-mail'].'</a></p>'."\n";
+		}
+		else
+		{
+			$username_field = '<p>'.$lang_common['Username'].': '.pun_htmlspecialchars($user['username']).'</p>'."\n";
+
+			if ($pun_config['o_regs_verify'] == '1')
+				$email_field = '<p>'.$lang_common['E-mail'].': '.$user['email'].'&nbsp;-&nbsp;<a href="profile.php?action=change_email&amp;id='.$id.'">'.$lang_profile['Change e-mail'].'</a></p>'."\n";
+			else
+				$email_field = '<label><strong>'.$lang_common['E-mail'].'</strong><br /><input type="text" name="req_email" value="'.$user['email'].'" size="40" maxlength="50" /><br /></label>'."\n";
+		}
+
+		if ($pun_user['g_id'] == PUN_ADMIN)
+			$posts_field = '<label>'.$lang_common['Posts'].'<br /><input type="text" name="num_posts" value="'.$user['num_posts'].'" size="8" maxlength="8" /><br /></label><p><a href="search.php?action=show_user&amp;user_id='.$id.'">'.$lang_profile['Show posts'].'</a></p>'."\n";
+		else if ($pun_config['o_show_post_count'] == '1' || $pun_user['g_id'] < PUN_GUEST)
+			$posts_field = '<p>'.$lang_common['Posts'].': '.$user['num_posts'].' - <a href="search.php?action=show_user&amp;user_id='.$id.'">'.$lang_profile['Show posts'].'</a></p>'."\n";
+		else
+			$posts_field = '<p><a href="search.php?action=show_user&amp;user_id='.$id.'">'.$lang_profile['Show posts'].'</a></p>'."\n";
+
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+		$required_fields = array('req_username' => $lang_common['Username'], 'req_email' => $lang_common['E-mail']);
+		require PUN_ROOT.'header.php';
+
+		generate_profile_menu('essentials');
+
+?>
+	<div class="blockform">
+		<h2><span><?php echo pun_htmlspecialchars($user['username']).' - '.$lang_profile['Section essentials'] ?></span></h2>
+		<div class="box">
+			<form id="profile1" method="post" action="profile.php?section=essentials&amp;id=<?php echo $id ?>" onsubmit="return process_form(this)">
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_profile['Username and pass legend'] ?></legend>
+						<div class="infldset">
+							<input type="hidden" name="form_sent" value="1" />
+							<?php echo $username_field ?>
+<?php if ($pun_user['id'] == $id || $pun_user['g_id'] == PUN_ADMIN || ($user['g_id'] > PUN_MOD && $pun_config['p_mod_change_passwords'] == '1')): ?><p><a href="profile.php?action=change_pass&amp;id=<?php echo $id ?>"><?php echo $lang_profile['Change pass'] ?></a></p>
+<?php endif; ?>					</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_prof_reg['E-mail legend'] ?></legend>
+						<div class="infldset">
+							<?php echo $email_field ?>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_prof_reg['Localisation legend'] ?></legend>
+						<div class="infldset">
+							<label><?php echo $lang_prof_reg['Timezone'] ?>: <?php echo $lang_prof_reg['Timezone info'] ?>
+							<br /><select name="form[timezone]">
+								<option value="-12"<?php if ($user['timezone'] == -12) echo ' selected="selected"' ?>>-12</option>
+								<option value="-11"<?php if ($user['timezone'] == -11) echo ' selected="selected"' ?>>-11</option>
+								<option value="-10"<?php if ($user['timezone'] == -10) echo ' selected="selected"' ?>>-10</option>
+								<option value="-9.5"<?php if ($user['timezone'] == -9.5) echo ' selected="selected"' ?>>-09.5</option>
+								<option value="-9"<?php if ($user['timezone'] == -9) echo ' selected="selected"' ?>>-09</option>
+								<option value="-8.5"<?php if ($user['timezone'] == -8.5) echo ' selected="selected"' ?>>-08.5</option>
+								<option value="-8"<?php if ($user['timezone'] == -8) echo ' selected="selected"' ?>>-08 PST</option>
+								<option value="-7"<?php if ($user['timezone'] == -7) echo ' selected="selected"' ?>>-07 MST</option>
+								<option value="-6"<?php if ($user['timezone'] == -6) echo ' selected="selected"' ?>>-06 CST</option>
+								<option value="-5"<?php if ($user['timezone'] == -5) echo ' selected="selected"' ?>>-05 EST</option>
+								<option value="-4"<?php if ($user['timezone'] == -4) echo ' selected="selected"' ?>>-04 AST</option>
+								<option value="-3.5"<?php if ($user['timezone'] == -3.5) echo ' selected="selected"' ?>>-03.5</option>
+								<option value="-3"<?php if ($user['timezone'] == -3) echo ' selected="selected"' ?>>-03 ADT</option>
+								<option value="-2"<?php if ($user['timezone'] == -2) echo ' selected="selected"' ?>>-02</option>
+								<option value="-1"<?php if ($user['timezone'] == -1) echo ' selected="selected"' ?>>-01</option>
+								<option value="0"<?php if ($user['timezone'] == 0) echo ' selected="selected"' ?>>00 GMT</option>
+								<option value="1"<?php if ($user['timezone'] == 1) echo ' selected="selected"' ?>>+01 CET</option>
+								<option value="2"<?php if ($user['timezone'] == 2) echo ' selected="selected"' ?>>+02</option>
+								<option value="3"<?php if ($user['timezone'] == 3) echo ' selected="selected"' ?>>+03</option>
+								<option value="3.5"<?php if ($user['timezone'] == 3.5) echo ' selected="selected"' ?>>+03.5</option>
+								<option value="4"<?php if ($user['timezone'] == 4) echo ' selected="selected"' ?>>+04</option>
+								<option value="4.5"<?php if ($user['timezone'] == 4.5) echo ' selected="selected"' ?>>+04.5</option>
+								<option value="5"<?php if ($user['timezone'] == 5) echo ' selected="selected"' ?>>+05</option>
+								<option value="5.5"<?php if ($user['timezone'] == 5.5) echo ' selected="selected"' ?>>+05.5</option>
+								<option value="6"<?php if ($user['timezone'] == 6) echo ' selected="selected"' ?>>+06</option>
+								<option value="6.5"<?php if ($user['timezone'] == 6.5) echo ' selected="selected"' ?>>+06.5</option>
+								<option value="7"<?php if ($user['timezone'] == 7) echo ' selected="selected"' ?>>+07</option>
+								<option value="8"<?php if ($user['timezone'] == 8) echo ' selected="selected"' ?>>+08</option>
+								<option value="9"<?php if ($user['timezone'] == 9) echo ' selected="selected"' ?>>+09</option>
+								<option value="9.5"<?php if ($user['timezone'] == 9.5) echo ' selected="selected"' ?>>+09.5</option>
+								<option value="10"<?php if ($user['timezone'] == 10) echo ' selected="selected"' ?>>+10</option>
+								<option value="10.5"<?php if ($user['timezone'] == 10.5) echo ' selected="selected"' ?>>+10.5</option>
+								<option value="11"<?php if ($user['timezone'] == 11) echo ' selected="selected"' ?>>+11</option>
+								<option value="11.5"<?php if ($user['timezone'] == 11.5) echo ' selected="selected"' ?>>+11.5</option>
+								<option value="12"<?php if ($user['timezone'] == 12) echo ' selected="selected"' ?>>+12</option>
+								<option value="13"<?php if ($user['timezone'] == 13) echo ' selected="selected"' ?>>+13</option>
+								<option value="14"<?php if ($user['timezone'] == 14) echo ' selected="selected"' ?>>+14</option>
+							</select>
+							<br /></label>
+<?php
+
+		$languages = array();
+		$d = dir(PUN_ROOT.'lang');
+		while (($entry = $d->read()) !== false)
+		{
+			if ($entry != '.' && $entry != '..' && is_dir(PUN_ROOT.'lang/'.$entry) && file_exists(PUN_ROOT.'lang/'.$entry.'/common.php'))
+				$languages[] = $entry;
+		}
+		$d->close();
+
+		// Only display the language selection box if there's more than one language available
+		if (count($languages) > 1)
+		{
+			natsort($languages);
+
+?>
+							<label><?php echo $lang_prof_reg['Language'] ?>: <?php echo $lang_prof_reg['Language info'] ?>
+							<br /><select name="form[language]">
+<?php
+
+			while (list(, $temp) = @each($languages))
+			{
+				if ($user['language'] == $temp)
+					echo "\t\t\t\t\t\t\t\t".'<option value="'.$temp.'" selected="selected">'.$temp.'</option>'."\n";
+				else
+					echo "\t\t\t\t\t\t\t\t".'<option value="'.$temp.'">'.$temp.'</option>'."\n";
+			}
+
+?>
+							</select>
+							<br /></label>
+<?php
+
+		}
+
+?>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_profile['User activity'] ?></legend>
+						<div class="infldset">
+							<p><?php echo $lang_common['Registered'] ?>: <?php echo format_time($user['registered'], true); if ($pun_user['g_id'] < PUN_GUEST) echo ' (<a href="moderate.php?get_host='.pun_htmlspecialchars($user['registration_ip']).'">'.pun_htmlspecialchars($user['registration_ip']).'</a>)'; ?></p>
+							<p><?php echo $lang_common['Last post'] ?>: <?php echo $last_post ?></p>
+								<?php echo $posts_field ?>
+<?php if ($pun_user['g_id'] < PUN_GUEST): ?>							<label><?php echo $lang_profile['Admin note'] ?><br />
+							<input id="admin_note" type="text" name="admin_note" value="<?php echo pun_htmlspecialchars($user['admin_note']) ?>" size="30" maxlength="30" /><br /></label>
+						</div>
+<?php endif; ?>					</fieldset>
+				</div>
+				<p><input type="submit" name="update" value="<?php echo $lang_common['Submit'] ?>" /><?php echo $lang_profile['Instructions'] ?></p>
+			</form>
+		</div>
+	</div>
+<?php
+
+	}
+	else if ($section == 'personal')
+	{
+		if ($pun_user['g_set_title'] == '1')
+			$title_field = '<label>'.$lang_common['Title'].'&nbsp;&nbsp;(<em>'.$lang_profile['Leave blank'].'</em>)<br /><input type="text" name="title" value="'.pun_htmlspecialchars($user['title']).'" size="30" maxlength="50" /><br /></label>'."\n";
+
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+		require PUN_ROOT.'header.php';
+
+		generate_profile_menu('personal');
+
+?>
+	<div class="blockform">
+		<h2><span><?php echo pun_htmlspecialchars($user['username']).' - '.$lang_profile['Section personal'] ?></span></h2>
+		<div class="box">
+			<form id="profile2" method="post" action="profile.php?section=personal&amp;id=<?php echo $id ?>">
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_profile['Personal details legend'] ?></legend>
+						<div class="infldset">
+							<input type="hidden" name="form_sent" value="1" />
+							<label><?php echo $lang_profile['Realname'] ?><br /><input type="text" name="form[realname]" value="<?php echo pun_htmlspecialchars($user['realname']) ?>" size="40" maxlength="40" /><br /></label>
+<?php if (isset($title_field)): ?>					<?php echo $title_field ?>
+<?php endif; ?>							<label><?php echo $lang_profile['Location'] ?><br /><input type="text" name="form[location]" value="<?php echo pun_htmlspecialchars($user['location']) ?>" size="30" maxlength="30" /><br /></label>
+							<label><?php echo $lang_profile['Website'] ?><br /><input type="text" name="form[url]" value="<?php echo pun_htmlspecialchars($user['url']) ?>" size="50" maxlength="80" /><br /></label>
+						</div>
+					</fieldset>
+				</div>
+				<p><input type="submit" name="update" value="<?php echo $lang_common['Submit'] ?>" /><?php echo $lang_profile['Instructions'] ?></p>
+			</form>
+		</div>
+	</div>
+<?php
+
+	}
+	else if ($section == 'messaging')
+	{
+
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+		require PUN_ROOT.'header.php';
+
+		generate_profile_menu('messaging');
+
+?>
+	<div class="blockform">
+		<h2><span><?php echo pun_htmlspecialchars($user['username']).' - '.$lang_profile['Section messaging'] ?></span></h2>
+		<div class="box">
+			<form id="profile3" method="post" action="profile.php?section=messaging&amp;id=<?php echo $id ?>">
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_profile['Contact details legend'] ?></legend>
+						<div class="infldset">
+							<input type="hidden" name="form_sent" value="1" />
+							<label><?php echo $lang_profile['Jabber'] ?><br /><input id="jabber" type="text" name="form[jabber]" value="<?php echo pun_htmlspecialchars($user['jabber']) ?>" size="40" maxlength="75" /><br /></label>
+							<label><?php echo $lang_profile['ICQ'] ?><br /><input id="icq" type="text" name="form[icq]" value="<?php echo $user['icq'] ?>" size="12" maxlength="12" /><br /></label>
+							<label><?php echo $lang_profile['MSN'] ?><br /><input id="msn" type="text" name="form[msn]" value="<?php echo pun_htmlspecialchars($user['msn']) ?>" size="40" maxlength="50" /><br /></label>
+							<label><?php echo $lang_profile['AOL IM'] ?><br /><input id="aim" type="text" name="form[aim]" value="<?php echo pun_htmlspecialchars($user['aim']) ?>" size="20" maxlength="30" /><br /></label>
+							<label><?php echo $lang_profile['Yahoo'] ?><br /><input id="yahoo" type="text" name="form[yahoo]" value="<?php echo pun_htmlspecialchars($user['yahoo']) ?>" size="20" maxlength="30" /><br /></label>
+						</div>
+					</fieldset>
+				</div>
+				<p><input type="submit" name="update" value="<?php echo $lang_common['Submit'] ?>" /><?php echo $lang_profile['Instructions'] ?></p>
+			</form>
+		</div>
+	</div>
+<?php
+
+	}
+	else if ($section == 'personality')
+	{
+		$avatar_field = '<a href="profile.php?action=upload_avatar&amp;id='.$id.'">'.$lang_profile['Change avatar'].'</a>';
+		if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.gif'))
+			$avatar_format = 'gif';
+		else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.jpg'))
+			$avatar_format = 'jpg';
+		else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$id.'.png'))
+			$avatar_format = 'png';
+		else
+			$avatar_field = '<a href="profile.php?action=upload_avatar&amp;id='.$id.'">'.$lang_profile['Upload avatar'].'</a>';
+
+		// Display the delete avatar link?
+		if ($img_size)
+			$avatar_field .= '&nbsp;&nbsp;&nbsp;<a href="profile.php?action=delete_avatar&amp;id='.$id.'">'.$lang_profile['Delete avatar'].'</a>';
+
+		if ($user['signature'] != '')
+			$signature_preview = '<p>'.$lang_profile['Sig preview'].'</p>'."\n\t\t\t\t\t".'<div class="postsignature">'."\n\t\t\t\t\t\t".'<hr />'."\n\t\t\t\t\t\t".$parsed_signature."\n\t\t\t\t\t".'</div>'."\n";
+		else
+			$signature_preview = '<p>'.$lang_profile['No sig'].'</p>'."\n";
+
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+		require PUN_ROOT.'header.php';
+
+		generate_profile_menu('personality');
+
+
+?>
+	<div class="blockform">
+		<h2><span><?php echo pun_htmlspecialchars($user['username']).' - '.$lang_profile['Section personality'] ?></span></h2>
+		<div class="box">
+			<form id="profile4" method="post" action="profile.php?section=personality&amp;id=<?php echo $id ?>">
+				<div><input type="hidden" name="form_sent" value="1" /></div>
+<?php if ($pun_config['o_avatars'] == '1'): ?>				<div class="inform">
+					<fieldset id="profileavatar">
+						<legend><?php echo $lang_profile['Avatar legend'] ?></legend>
+						<div class="infldset">
+<?php if (isset($avatar_format)): ?>					<img src="<?php echo $pun_config['o_avatars_dir'].'/'.$id.'.'.$avatar_format ?>" <?php echo $img_size[3] ?> alt="" />
+<?php endif; ?>					<p><?php echo $lang_profile['Avatar info'] ?></p>
+							<div class="rbox">
+								<label><input type="checkbox" name="form[use_avatar]" value="1"<?php if ($user['use_avatar'] == '1') echo ' checked="checked"' ?> /><?php echo $lang_profile['Use avatar'] ?><br /></label>
+							</div>
+							<p class="clearb"><?php echo $avatar_field ?></p>
+						</div>
+					</fieldset>
+				</div>
+<?php endif; ?>				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_profile['Signature legend'] ?></legend>
+						<div class="infldset">
+							<p><?php echo $lang_profile['Signature info'] ?></p>
+							<div class="txtarea">
+								<label><?php echo $lang_profile['Sig max length'] ?>: <?php echo $pun_config['p_sig_length'] ?> / <?php echo $lang_profile['Sig max lines'] ?>: <?php echo $pun_config['p_sig_lines'] ?><br />
+								<textarea name="signature" rows="4" cols="65"><?php echo pun_htmlspecialchars($user['signature']) ?></textarea><br /></label>
+							</div>
+							<ul class="bblinks">
+								<li><a href="help.php#bbcode" onclick="window.open(this.href); return false;"><?php echo $lang_common['BBCode'] ?></a>: <?php echo ($pun_config['p_sig_bbcode'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+								<li><a href="help.php#img" onclick="window.open(this.href); return false;"><?php echo $lang_common['img tag'] ?></a>: <?php echo ($pun_config['p_sig_img_tag'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+								<li><a href="help.php#smilies" onclick="window.open(this.href); return false;"><?php echo $lang_common['Smilies'] ?></a>: <?php echo ($pun_config['o_smilies_sig'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+							</ul>
+							<?php echo $signature_preview ?>
+						</div>
+					</fieldset>
+				</div>
+				<p><input type="submit" name="update" value="<?php echo $lang_common['Submit'] ?>" /><?php echo $lang_profile['Instructions'] ?></p>
+			</form>
+		</div>
+	</div>
+<?php
+
+	}
+	else if ($section == 'display')
+	{
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+		require PUN_ROOT.'header.php';
+
+		generate_profile_menu('display');
+
+?>
+	<div class="blockform">
+		<h2><span><?php echo pun_htmlspecialchars($user['username']).' - '.$lang_profile['Section display'] ?></span></h2>
+		<div class="box">
+			<form id="profile5" method="post" action="profile.php?section=display&amp;id=<?php echo $id ?>">
+				<div><input type="hidden" name="form_sent" value="1" /></div>
+<?php
+
+		$styles = array();
+		$d = dir(PUN_ROOT.'style');
+		while (($entry = $d->read()) !== false)
+		{
+			if (substr($entry, strlen($entry)-4) == '.css')
+				$styles[] = substr($entry, 0, strlen($entry)-4);
+		}
+		$d->close();
+
+		// Only display the style selection box if there's more than one style available
+		if (count($styles) == 1)
+			echo "\t\t\t".'<div><input type="hidden" name="form[style]" value="'.$styles[0].'" /></div>'."\n";
+		else if (count($styles) > 1)
+		{
+			natsort($styles);
+
+?>
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_profile['Style legend'] ?></legend>
+						<div class="infldset">
+							<label><?php echo $lang_profile['Style info'] ?><br />
+
+							<select name="form[style]">
+<?php
+
+			while (list(, $temp) = @each($styles))
+			{
+				if ($user['style'] == $temp)
+					echo "\t\t\t\t\t\t\t\t".'<option value="'.$temp.'" selected="selected">'.str_replace('_', ' ', $temp).'</option>'."\n";
+				else
+					echo "\t\t\t\t\t\t\t\t".'<option value="'.$temp.'">'.str_replace('_', ' ', $temp).'</option>'."\n";
+			}
+
+?>
+							</select>
+							<br /></label>
+						</div>
+					</fieldset>
+				</div>
+<?php
+
+		}
+
+?>
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_profile['Post display legend'] ?></legend>
+						<div class="infldset">
+							<p><?php echo $lang_profile['Post display info'] ?></p>
+							<div class="rbox">
+								<label><input type="checkbox" name="form[show_smilies]" value="1"<?php if ($user['show_smilies'] == '1') echo ' checked="checked"' ?> /><?php echo $lang_profile['Show smilies'] ?><br /></label>
+								<label><input type="checkbox" name="form[show_sig]" value="1"<?php if ($user['show_sig'] == '1') echo ' checked="checked"' ?> /><?php echo $lang_profile['Show sigs'] ?><br /></label>
+<?php if ($pun_config['o_avatars'] == '1'): ?>							<label><input type="checkbox" name="form[show_avatars]" value="1"<?php if ($user['show_avatars'] == '1') echo ' checked="checked"' ?> /><?php echo $lang_profile['Show avatars'] ?><br /></label>
+<?php endif; ?>								<label><input type="checkbox" name="form[show_img]" value="1"<?php if ($user['show_img'] == '1') echo ' checked="checked"' ?> /><?php echo $lang_profile['Show images'] ?><br /></label>
+								<label><input type="checkbox" name="form[show_img_sig]" value="1"<?php if ($user['show_img_sig'] == '1') echo ' checked="checked"' ?> /><?php echo $lang_profile['Show images sigs'] ?><br /></label>
+							</div>
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_profile['Pagination legend'] ?></legend>
+						<div class="infldset">
+							<label class="conl"><?php echo $lang_profile['Topics per page'] ?><br /><input type="text" name="form[disp_topics]" value="<?php echo $user['disp_topics'] ?>" size="6" maxlength="3" /><br /></label>
+							<label class="conl"><?php echo $lang_profile['Posts per page'] ?><br /><input type="text" name="form[disp_posts]" value="<?php echo $user['disp_posts'] ?>" size="6" maxlength="3" /><br /></label>
+							<p class="clearb"><?php echo $lang_profile['Paginate info'] ?> <?php echo $lang_profile['Leave blank'] ?></p>
+						</div>
+					</fieldset>
+				</div>
+				<p><input type="submit" name="update" value="<?php echo $lang_common['Submit'] ?>" />  <?php echo $lang_profile['Instructions'] ?></p>
+			</form>
+		</div>
+	</div>
+<?php
+
+	}
+	else if ($section == 'privacy')
+	{
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+		require PUN_ROOT.'header.php';
+
+		generate_profile_menu('privacy');
+
+?>
+	<div class="blockform">
+		<h2><span><?php echo pun_htmlspecialchars($user['username']).' - '.$lang_profile['Section privacy'] ?></span></h2>
+		<div class="box">
+			<form id="profile6" method="post" action="profile.php?section=privacy&amp;id=<?php echo $id ?>">
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_prof_reg['Privacy options legend'] ?></legend>
+						<div class="infldset">
+							<input type="hidden" name="form_sent" value="1" />
+							<p><?php echo $lang_prof_reg['E-mail setting info'] ?></p>
+							<div class="rbox">
+								<label><input type="radio" name="form[email_setting]" value="0"<?php if ($user['email_setting'] == '0') echo ' checked="checked"' ?> /><?php echo $lang_prof_reg['E-mail setting 1'] ?><br /></label>
+								<label><input type="radio" name="form[email_setting]" value="1"<?php if ($user['email_setting'] == '1') echo ' checked="checked"' ?> /><?php echo $lang_prof_reg['E-mail setting 2'] ?><br /></label>
+								<label><input type="radio" name="form[email_setting]" value="2"<?php if ($user['email_setting'] == '2') echo ' checked="checked"' ?> /><?php echo $lang_prof_reg['E-mail setting 3'] ?><br /></label>
+							</div>
+							<p><?php echo $lang_prof_reg['Save user/pass info'] ?></p>
+							<div class="rbox">
+								<label><input type="checkbox" name="form[save_pass]" value="1"<?php if ($user['save_pass'] == '1') echo ' checked="checked"' ?> /><?php echo $lang_prof_reg['Save user/pass'] ?><br /></label>
+							</div>
+							<p><?php echo $lang_profile['Notify full info'] ?></p>
+							<div class="rbox">
+								<label><input type="checkbox" name="form[notify_with_post]" value="1"<?php if ($user['notify_with_post'] == '1') echo ' checked="checked"' ?> /><?php echo $lang_profile['Notify full'] ?><br /></label>
+							</div>
+						</div>
+					</fieldset>
+				</div>
+				<p><input type="submit" name="update" value="<?php echo $lang_common['Submit'] ?>" /><?php echo $lang_profile['Instructions'] ?></p>
+			</form>
+		</div>
+	</div>
+<?php
+
+	}
+	else if ($section == 'admin')
+	{
+		if ($pun_user['g_id'] > PUN_MOD || ($pun_user['g_id'] == PUN_MOD && $pun_config['p_mod_ban_users'] == '0'))
+			message($lang_common['Bad request']);
+
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['Profile'];
+		require PUN_ROOT.'header.php';
+
+		generate_profile_menu('admin');
+
+?>
+	<div class="blockform">
+		<h2><span><?php echo pun_htmlspecialchars($user['username']).' - '.$lang_profile['Section admin'] ?></span></h2>
+		<div class="box">
+			<form id="profile7" method="post" action="profile.php?section=admin&amp;id=<?php echo $id ?>&amp;action=foo">
+				<div class="inform">
+				<input type="hidden" name="form_sent" value="1" />
+					<fieldset>
+<?php
+
+		if ($pun_user['g_id'] == PUN_MOD)
+		{
+
+?>
+						<legend><?php echo $lang_profile['Delete ban legend'] ?></legend>
+						<div class="infldset">
+							<p><input type="submit" name="ban" value="<?php echo $lang_profile['Ban user'] ?>" /></p>
+						</div>
+					</fieldset>
+				</div>
+<?php
+
+		}
+		else
+		{
+			if ($pun_user['id'] != $id)
+			{
+
+?>
+						<legend><?php echo $lang_profile['Group membership legend'] ?></legend>
+						<div class="infldset">
+							<select id="group_id" name="group_id">
+<?php
+
+				$result = $db->query('SELECT g_id, g_title FROM '.$db->prefix.'groups WHERE g_id!='.PUN_GUEST.' ORDER BY g_title') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+
+				while ($cur_group = $db->fetch_assoc($result))
+				{
+					if ($cur_group['g_id'] == $user['g_id'] || ($cur_group['g_id'] == $pun_config['o_default_user_group'] && $user['g_id'] == ''))
+						echo "\t\t\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'" selected="selected">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+					else
+						echo "\t\t\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+				}
+
+?>
+							</select>
+							<input type="submit" name="update_group_membership" value="<?php echo $lang_profile['Save'] ?>" />
+						</div>
+					</fieldset>
+				</div>
+				<div class="inform">
+					<fieldset>
+<?php
+
+			}
+
+?>
+						<legend><?php echo $lang_profile['Delete ban legend'] ?></legend>
+						<div class="infldset">
+							<input type="submit" name="delete_user" value="<?php echo $lang_profile['Delete user'] ?>" />&nbsp;&nbsp;<input type="submit" name="ban" value="<?php echo $lang_profile['Ban user'] ?>" />
+						</div>
+					</fieldset>
+				</div>
+<?php
+
+			if ($user['g_id'] == PUN_MOD || $user['g_id'] == PUN_ADMIN)
+			{
+
+?>
+				<div class="inform">
+					<fieldset>
+						<legend><?php echo $lang_profile['Set mods legend'] ?></legend>
+						<div class="infldset">
+							<p><?php echo $lang_profile['Moderator in info'] ?></p>
+<?php
+
+				$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.moderators FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id WHERE f.redirect_url IS NULL ORDER BY c.disp_position, c.id, f.disp_position') or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
+
+				$cur_category = 0;
+				while ($cur_forum = $db->fetch_assoc($result))
+				{
+					if ($cur_forum['cid'] != $cur_category)	// A new category since last iteration?
+					{
+						if ($cur_category)
+							echo "\n\t\t\t\t\t\t\t\t".'</div>';
+
+						if ($cur_category != 0)
+							echo "\n\t\t\t\t\t\t\t".'</div>'."\n";
+
+						echo "\t\t\t\t\t\t\t".'<div class="conl">'."\n\t\t\t\t\t\t\t\t".'<p><strong>'.$cur_forum['cat_name'].'</strong></p>'."\n\t\t\t\t\t\t\t\t".'<div class="rbox">';
+						$cur_category = $cur_forum['cid'];
+					}
+
+					$moderators = ($cur_forum['moderators'] != '') ? unserialize($cur_forum['moderators']) : array();
+
+					echo "\n\t\t\t\t\t\t\t\t\t".'<label><input type="checkbox" name="moderator_in['.$cur_forum['fid'].']" value="1"'.((in_array($id, $moderators)) ? ' checked="checked"' : '').' />'.pun_htmlspecialchars($cur_forum['forum_name']).'<br /></label>'."\n";
+				}
+
+?>
+								</div>
+							</div>
+							<br class="clearb" /><input type="submit" name="update_forums" value="<?php echo $lang_profile['Update forums'] ?>" />
+						</div>
+					</fieldset>
+				</div>
+<?php
+
+			}
+		}
+
+?>
+			</form>
+		</div>
+	</div>
+<?php
+
+	}
+
+?>
+	<div class="clearer"></div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/register.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,411 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+// If we are logged in, we shouldn't be here
+if (!$pun_user['is_guest'])
+{
+	header('Location: index.php');
+	exit;
+}
+
+// Load the register.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/register.php';
+
+// Load the register.php/profile.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/prof_reg.php';
+
+if ($pun_config['o_regs_allow'] == '0')
+	message($lang_register['No new regs']);
+
+
+// User pressed the cancel button
+if (isset($_GET['cancel']))
+	redirect('index.php', $lang_register['Reg cancel redirect']);
+
+
+else if ($pun_config['o_rules'] == '1' && !isset($_GET['agree']) && !isset($_POST['form_sent']))
+{
+	$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_register['Register'];
+	require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_register['Forum rules'] ?></span></h2>
+	<div class="box">
+		<form method="get" action="register.php">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_register['Rules legend'] ?></legend>
+					<div class="infldset">
+						<p><?php echo $pun_config['o_rules_message'] ?></p>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="agree" value="<?php echo $lang_register['Agree'] ?>" /><input type="submit" name="cancel" value="<?php echo $lang_register['Cancel'] ?>" /></p>
+		</form>
+	</div>
+</div>
+<?php
+
+	require PUN_ROOT.'footer.php';
+}
+
+
+else if (isset($_POST['form_sent']))
+{
+	// Check that someone from this IP didn't register a user within the last hour (DoS prevention)
+	$result = $db->query('SELECT 1 FROM '.$db->prefix.'users WHERE registration_ip=\''.get_remote_address().'\' AND registered>'.(time() - 3600)) or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+
+	if ($db->num_rows($result))
+		message('A new user was registered with the same IP address as you within the last hour. To prevent registration flooding, at least an hour has to pass between registrations from the same IP. Sorry for the inconvenience.');
+
+
+	$username = pun_trim($_POST['req_username']);
+	$email1 = strtolower(trim($_POST['req_email1']));
+
+	if ($pun_config['o_regs_verify'] == '1')
+	{
+		$email2 = strtolower(trim($_POST['req_email2']));
+
+		$password1 = random_pass(8);
+		$password2 = $password1;
+	}
+	else
+	{
+		$password1 = trim($_POST['req_password1']);
+		$password2 = trim($_POST['req_password2']);
+	}
+
+	// Convert multiple whitespace characters into one (to prevent people from registering with indistinguishable usernames)
+	$username = preg_replace('#\s+#s', ' ', $username);
+
+	// Validate username and passwords
+	if (strlen($username) < 2)
+		message($lang_prof_reg['Username too short']);
+	else if (pun_strlen($username) > 25)	// This usually doesn't happen since the form element only accepts 25 characters
+	    message($lang_common['Bad request']);
+	else if (strlen($password1) < 4)
+		message($lang_prof_reg['Pass too short']);
+	else if ($password1 != $password2)
+		message($lang_prof_reg['Pass not match']);
+	else if (!strcasecmp($username, 'Guest') || !strcasecmp($username, $lang_common['Guest']))
+		message($lang_prof_reg['Username guest']);
+	else if (preg_match('/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/', $username))
+		message($lang_prof_reg['Username IP']);
+	else if ((strpos($username, '[') !== false || strpos($username, ']') !== false) && strpos($username, '\'') !== false && strpos($username, '"') !== false)
+		message($lang_prof_reg['Username reserved chars']);
+	else if (preg_match('#\[b\]|\[/b\]|\[u\]|\[/u\]|\[i\]|\[/i\]|\[color|\[/color\]|\[quote\]|\[quote=|\[/quote\]|\[code\]|\[/code\]|\[img\]|\[/img\]|\[url|\[/url\]|\[email|\[/email\]#i', $username))
+		message($lang_prof_reg['Username BBCode']);
+
+	// Check username for any censored words
+	if ($pun_config['o_censoring'] == '1')
+	{
+		// If the censored username differs from the username
+		if (censor_words($username) != $username)
+			message($lang_register['Username censor']);
+	}
+
+	// Check that the username (or a too similar username) is not already registered
+	$result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE UPPER(username)=UPPER(\''.$db->escape($username).'\') OR UPPER(username)=UPPER(\''.$db->escape(preg_replace('/[^\w]/', '', $username)).'\')') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+
+	if ($db->num_rows($result))
+	{
+		$busy = $db->result($result);
+		message($lang_register['Username dupe 1'].' '.pun_htmlspecialchars($busy).'. '.$lang_register['Username dupe 2']);
+	}
+
+
+	// Validate e-mail
+	require PUN_ROOT.'include/email.php';
+
+	if (!is_valid_email($email1))
+		message($lang_common['Invalid e-mail']);
+	else if ($pun_config['o_regs_verify'] == '1' && $email1 != $email2)
+		message($lang_register['E-mail not match']);
+
+	// Check it it's a banned e-mail address
+	if (is_banned_email($email1))
+	{
+		if ($pun_config['p_allow_banned_email'] == '0')
+			message($lang_prof_reg['Banned e-mail']);
+
+		$banned_email = true;	// Used later when we send an alert e-mail
+	}
+	else
+		$banned_email = false;
+
+	// Check if someone else already has registered with that e-mail address
+	$dupe_list = array();
+
+	$result = $db->query('SELECT username FROM '.$db->prefix.'users WHERE email=\''.$email1.'\'') or error('Unable to fetch user info', __FILE__, __LINE__, $db->error());
+	if ($db->num_rows($result))
+	{
+		if ($pun_config['p_allow_dupe_email'] == '0')
+			message($lang_prof_reg['Dupe e-mail']);
+
+		while ($cur_dupe = $db->fetch_assoc($result))
+			$dupe_list[] = $cur_dupe['username'];
+	}
+
+	// Make sure we got a valid language string
+	if (isset($_POST['language']))
+	{
+		$language = preg_replace('#[\.\\\/]#', '', $_POST['language']);
+		if (!file_exists(PUN_ROOT.'lang/'.$language.'/common.php'))
+				message($lang_common['Bad request']);
+	}
+	else
+		$language = $pun_config['o_default_lang'];
+
+	$timezone = round($_POST['timezone'], 1);
+	$save_pass = (!isset($_POST['save_pass']) || $_POST['save_pass'] != '1') ? '0' : '1';
+
+	$email_setting = intval($_POST['email_setting']);
+	if ($email_setting < 0 || $email_setting > 2) $email_setting = 1;
+
+	// Insert the new user into the database. We do this now to get the last inserted id for later use.
+	$now = time();
+
+	$intial_group_id = ($pun_config['o_regs_verify'] == '0') ? $pun_config['o_default_user_group'] : PUN_UNVERIFIED;
+	$password_hash = pun_hash($password1);
+
+	// Add the user
+	$db->query('INSERT INTO '.$db->prefix.'users (username, group_id, password, email, email_setting, save_pass, timezone, language, style, registered, registration_ip, last_visit) VALUES(\''.$db->escape($username).'\', '.$intial_group_id.', \''.$password_hash.'\', \''.$email1.'\', '.$email_setting.', '.$save_pass.', '.$timezone.' , \''.$db->escape($language).'\', \''.$pun_config['o_default_style'].'\', '.$now.', \''.get_remote_address().'\', '.$now.')') or error('Unable to create user', __FILE__, __LINE__, $db->error());
+	$new_uid = $db->insert_id();
+
+
+	// If we previously found out that the e-mail was banned
+	if ($banned_email && $pun_config['o_mailing_list'] != '')
+	{
+		$mail_subject = 'Alert - Banned e-mail detected';
+		$mail_message = 'User \''.$username.'\' registered with banned e-mail address: '.$email1."\n\n".'User profile: '.$pun_config['o_base_url'].'/profile.php?id='.$new_uid."\n\n".'-- '."\n".'Forum Mailer'."\n".'(Do not reply to this message)';
+
+		pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message);
+	}
+
+	// If we previously found out that the e-mail was a dupe
+	if (!empty($dupe_list) && $pun_config['o_mailing_list'] != '')
+	{
+		$mail_subject = 'Alert - Duplicate e-mail detected';
+		$mail_message = 'User \''.$username.'\' registered with an e-mail address that also belongs to: '.implode(', ', $dupe_list)."\n\n".'User profile: '.$pun_config['o_base_url'].'/profile.php?id='.$new_uid."\n\n".'-- '."\n".'Forum Mailer'."\n".'(Do not reply to this message)';
+
+		pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message);
+	}
+
+	// Should we alert people on the admin mailing list that a new user has registered?
+	if ($pun_config['o_regs_report'] == '1')
+	{
+		$mail_subject = 'Alert - New registration';
+		$mail_message = 'User \''.$username.'\' registered in the forums at '.$pun_config['o_base_url']."\n\n".'User profile: '.$pun_config['o_base_url'].'/profile.php?id='.$new_uid."\n\n".'-- '."\n".'Forum Mailer'."\n".'(Do not reply to this message)';
+
+		pun_mail($pun_config['o_mailing_list'], $mail_subject, $mail_message);
+	}
+
+	// Must the user verify the registration or do we log him/her in right now?
+	if ($pun_config['o_regs_verify'] == '1')
+	{
+		// Load the "welcome" template
+		$mail_tpl = trim(file_get_contents(PUN_ROOT.'lang/'.$pun_user['language'].'/mail_templates/welcome.tpl'));
+
+		// The first row contains the subject
+		$first_crlf = strpos($mail_tpl, "\n");
+		$mail_subject = trim(substr($mail_tpl, 8, $first_crlf-8));
+		$mail_message = trim(substr($mail_tpl, $first_crlf));
+
+		$mail_subject = str_replace('<board_title>', $pun_config['o_board_title'], $mail_subject);
+		$mail_message = str_replace('<base_url>', $pun_config['o_base_url'].'/', $mail_message);
+		$mail_message = str_replace('<username>', $username, $mail_message);
+		$mail_message = str_replace('<password>', $password1, $mail_message);
+		$mail_message = str_replace('<login_url>', $pun_config['o_base_url'].'/login.php', $mail_message);
+		$mail_message = str_replace('<board_mailer>', $pun_config['o_board_title'].' '.$lang_common['Mailer'], $mail_message);
+
+		pun_mail($email1, $mail_subject, $mail_message);
+
+		message($lang_register['Reg e-mail'].' <a href="mailto:'.$pun_config['o_admin_email'].'">'.$pun_config['o_admin_email'].'</a>.', true);
+	}
+
+	pun_setcookie($new_uid, $password_hash, ($save_pass != '0') ? $now + 31536000 : 0);
+
+	redirect('index.php', $lang_register['Reg complete']);
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_register['Register'];
+$required_fields = array('req_username' => $lang_common['Username'], 'req_password1' => $lang_common['Password'], 'req_password2' => $lang_prof_reg['Confirm pass'], 'req_email1' => $lang_common['E-mail'], 'req_email2' => $lang_common['E-mail'].' 2');
+$focus_element = array('register', 'req_username');
+require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_register['Register'] ?></span></h2>
+	<div class="box">
+		<form id="register" method="post" action="register.php?action=register" onsubmit="this.register.disabled=true;if(process_form(this)){return true;}else{this.register.disabled=false;return false;}">
+			<div class="inform">
+				<div class="forminfo">
+					<h3><?php echo $lang_common['Important information'] ?></h3>
+					<p><?php echo $lang_register['Desc 1'] ?></p>
+					<p><?php echo $lang_register['Desc 2'] ?></p>
+				</div>
+				<fieldset>
+					<legend><?php echo $lang_register['Username legend'] ?></legend>
+					<div class="infldset">
+						<input type="hidden" name="form_sent" value="1" />
+						<label><strong><?php echo $lang_common['Username'] ?></strong><br /><input type="text" name="req_username" size="25" maxlength="25" /><br /></label>
+					</div>
+				</fieldset>
+			</div>
+<?php if ($pun_config['o_regs_verify'] == '0'): ?>			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_register['Pass legend 1'] ?></legend>
+					<div class="infldset">
+						<label class="conl"><strong><?php echo $lang_common['Password'] ?></strong><br /><input type="password" name="req_password1" size="16" maxlength="16" /><br /></label>
+						<label class="conl"><strong><?php echo $lang_prof_reg['Confirm pass'] ?></strong><br /><input type="password" name="req_password2" size="16" maxlength="16" /><br /></label>
+						<p class="clearb"><?php echo $lang_register['Pass info'] ?></p>
+					</div>
+				</fieldset>
+			</div>
+<?php endif; ?>			<div class="inform">
+				<fieldset>
+					<legend><?php echo ($pun_config['o_regs_verify'] == '1') ? $lang_prof_reg['E-mail legend 2'] : $lang_prof_reg['E-mail legend'] ?></legend>
+					<div class="infldset">
+<?php if ($pun_config['o_regs_verify'] == '1'): ?>			<p><?php echo $lang_register['E-mail info'] ?></p>
+<?php endif; ?>					<label><strong><?php echo $lang_common['E-mail'] ?></strong><br />
+						<input type="text" name="req_email1" size="50" maxlength="50" /><br /></label>
+<?php if ($pun_config['o_regs_verify'] == '1'): ?>						<label><strong><?php echo $lang_register['Confirm e-mail'] ?></strong><br />
+						<input type="text" name="req_email2" size="50" maxlength="50" /><br /></label>
+<?php endif; ?>					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_prof_reg['Localisation legend'] ?></legend>
+					<div class="infldset">
+						<label><?php echo $lang_prof_reg['Timezone'] ?>: <?php echo $lang_prof_reg['Timezone info'] ?>
+						<br /><select id="time_zone" name="timezone">
+							<option value="-12"<?php if ($pun_config['o_server_timezone'] == -12 ) echo ' selected="selected"' ?>>-12</option>
+							<option value="-11"<?php if ($pun_config['o_server_timezone'] == -11) echo ' selected="selected"' ?>>-11</option>
+							<option value="-10"<?php if ($pun_config['o_server_timezone'] == -10) echo ' selected="selected"' ?>>-10</option>
+							<option value="-9.5"<?php if ($pun_config['o_server_timezone'] == -9.5) echo ' selected="selected"' ?>>-9.5</option>
+							<option value="-9"<?php if ($pun_config['o_server_timezone'] == -9 ) echo ' selected="selected"' ?>>-09</option>
+							<option value="-8.5"<?php if ($pun_config['o_server_timezone'] == -8.5) echo ' selected="selected"' ?>>-8.5</option>
+							<option value="-8"<?php if ($pun_config['o_server_timezone'] == -8 ) echo ' selected="selected"' ?>>-08 PST</option>
+							<option value="-7"<?php if ($pun_config['o_server_timezone'] == -7 ) echo ' selected="selected"' ?>>-07 MST</option>
+							<option value="-6"<?php if ($pun_config['o_server_timezone'] == -6 ) echo ' selected="selected"' ?>>-06 CST</option>
+							<option value="-5"<?php if ($pun_config['o_server_timezone'] == -5 ) echo ' selected="selected"' ?>>-05 EST</option>
+							<option value="-4"<?php if ($pun_config['o_server_timezone'] == -4 ) echo ' selected="selected"' ?>>-04 AST</option>
+							<option value="-3.5"<?php if ($pun_config['o_server_timezone'] == -3.5) echo ' selected="selected"' ?>>-3.5</option>
+							<option value="-3"<?php if ($pun_config['o_server_timezone'] == -3 ) echo ' selected="selected"' ?>>-03 ADT</option>
+							<option value="-2"<?php if ($pun_config['o_server_timezone'] == -2 ) echo ' selected="selected"' ?>>-02</option>
+							<option value="-1"<?php if ($pun_config['o_server_timezone'] == -1) echo ' selected="selected"' ?>>-01</option>
+							<option value="0"<?php if ($pun_config['o_server_timezone'] == 0) echo ' selected="selected"' ?>>00 GMT</option>
+							<option value="1"<?php if ($pun_config['o_server_timezone'] == 1) echo ' selected="selected"' ?>>+01 CET</option>
+							<option value="2"<?php if ($pun_config['o_server_timezone'] == 2 ) echo ' selected="selected"' ?>>+02</option>
+							<option value="3"<?php if ($pun_config['o_server_timezone'] == 3 ) echo ' selected="selected"' ?>>+03</option>
+							<option value="3.5"<?php if ($pun_config['o_server_timezone'] == 3.5 ) echo ' selected="selected"' ?>>+03.5</option>
+							<option value="4"<?php if ($pun_config['o_server_timezone'] == 4 ) echo ' selected="selected"' ?>>+04</option>
+							<option value="4.5"<?php if ($pun_config['o_server_timezone'] == 4.5 ) echo ' selected="selected"' ?>>+04.5</option>
+							<option value="5"<?php if ($pun_config['o_server_timezone'] == 5 ) echo ' selected="selected"' ?>>+05</option>
+							<option value="5.5"<?php if ($pun_config['o_server_timezone'] == 5.5 ) echo ' selected="selected"' ?>>+05.5</option>
+							<option value="6"<?php if ($pun_config['o_server_timezone'] == 6 ) echo ' selected="selected"' ?>>+06</option>
+							<option value="6.5"<?php if ($pun_config['o_server_timezone'] == 6.5 ) echo ' selected="selected"' ?>>+06.5</option>
+							<option value="7"<?php if ($pun_config['o_server_timezone'] == 7 ) echo ' selected="selected"' ?>>+07</option>
+							<option value="8"<?php if ($pun_config['o_server_timezone'] == 8 ) echo ' selected="selected"' ?>>+08</option>
+							<option value="9"<?php if ($pun_config['o_server_timezone'] == 9 ) echo ' selected="selected"' ?>>+09</option>
+							<option value="9.5"<?php if ($pun_config['o_server_timezone'] == 9.5 ) echo ' selected="selected"' ?>>+09.5</option>
+							<option value="10"<?php if ($pun_config['o_server_timezone'] == 10) echo ' selected="selected"' ?>>+10</option>
+							<option value="10.5"<?php if ($pun_config['o_server_timezone'] == 10.5 ) echo ' selected="selected"' ?>>+10.5</option>
+							<option value="11"<?php if ($pun_config['o_server_timezone'] == 11) echo ' selected="selected"' ?>>+11</option>
+							<option value="11.5"<?php if ($pun_config['o_server_timezone'] == 11.5 ) echo ' selected="selected"' ?>>+11.5</option>
+							<option value="12"<?php if ($pun_config['o_server_timezone'] == 12 ) echo ' selected="selected"' ?>>+12</option>
+							<option value="13"<?php if ($pun_config['o_server_timezone'] == 13 ) echo ' selected="selected"' ?>>+13</option>
+							<option value="14"<?php if ($pun_config['o_server_timezone'] == 14 ) echo ' selected="selected"' ?>>+14</option>
+						</select>
+						<br /></label>
+<?php
+
+		$languages = array();
+		$d = dir(PUN_ROOT.'lang');
+		while (($entry = $d->read()) !== false)
+		{
+			if ($entry != '.' && $entry != '..' && is_dir(PUN_ROOT.'lang/'.$entry) && file_exists(PUN_ROOT.'lang/'.$entry.'/common.php'))
+				$languages[] = $entry;
+		}
+		$d->close();
+
+		// Only display the language selection box if there's more than one language available
+		if (count($languages) > 1)
+		{
+
+?>
+							<label><?php echo $lang_prof_reg['Language'] ?>: <?php echo $lang_prof_reg['Language info'] ?>
+							<br /><select name="language">
+<?php
+
+			while (list(, $temp) = @each($languages))
+			{
+				if ($pun_config['o_default_lang'] == $temp)
+					echo "\t\t\t\t\t\t\t\t".'<option value="'.$temp.'" selected="selected">'.$temp.'</option>'."\n";
+				else
+					echo "\t\t\t\t\t\t\t\t".'<option value="'.$temp.'">'.$temp.'</option>'."\n";
+			}
+
+?>
+							</select>
+							<br /></label>
+<?php
+
+		}
+?>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_prof_reg['Privacy options legend'] ?></legend>
+					<div class="infldset">
+						<p><?php echo $lang_prof_reg['E-mail setting info'] ?></p>
+						<div class="rbox">
+							<label><input type="radio" name="email_setting" value="0" /><?php echo $lang_prof_reg['E-mail setting 1'] ?><br /></label>
+							<label><input type="radio" name="email_setting" value="1" checked="checked" /><?php echo $lang_prof_reg['E-mail setting 2'] ?><br /></label>
+							<label><input type="radio" name="email_setting" value="2" /><?php echo $lang_prof_reg['E-mail setting 3'] ?><br /></label>
+						</div>
+						<p><?php echo $lang_prof_reg['Save user/pass info'] ?></p>
+						<div class="rbox">
+							<label><input type="checkbox" name="save_pass" value="1" checked="checked" /><?php echo $lang_prof_reg['Save user/pass'] ?><br /></label>
+						</div>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="register" value="<?php echo $lang_register['Register'] ?>" /></p>
+		</form>
+	</div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/search.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,775 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+// The contents of this file are very much inspired by the file search.php
+// from the phpBB Group forum software phpBB2 (http://www.phpbb.com).
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+// Load the search.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/search.php';
+
+
+if ($pun_user['g_read_board'] == '0')
+	message($lang_common['No view']);
+else if ($pun_user['g_search'] == '0')
+	message($lang_search['No search permission']);
+
+
+// Detect two byte character sets
+$multibyte = (isset($lang_common['lang_multibyte']) && $lang_common['lang_multibyte']) ? true : false;
+
+
+// Figure out what to do :-)
+if (isset($_GET['action']) || isset($_GET['search_id']))
+{
+	$action = (isset($_GET['action'])) ? $_GET['action'] : null;
+	$forum = (isset($_GET['forum'])) ? intval($_GET['forum']) : -1;
+	$sort_dir = (isset($_GET['sort_dir'])) ? (($_GET['sort_dir'] == 'DESC') ? 'DESC' : 'ASC') : 'DESC';
+	if (isset($search_id)) unset($search_id);
+
+	// If a search_id was supplied
+	if (isset($_GET['search_id']))
+	{
+		$search_id = intval($_GET['search_id']);
+		if ($search_id < 1)
+			message($lang_common['Bad request']);
+	}
+	// If it's a regular search (keywords and/or author)
+	else if ($action == 'search')
+	{
+		$keywords = (isset($_GET['keywords'])) ? strtolower(trim($_GET['keywords'])) : null;
+		$author = (isset($_GET['author'])) ? strtolower(trim($_GET['author'])) : null;
+
+		if (preg_match('#^[\*%]+$#', $keywords) || strlen(str_replace(array('*', '%'), '', $keywords)) < 3)
+			$keywords = '';
+
+		if (preg_match('#^[\*%]+$#', $author) || strlen(str_replace(array('*', '%'), '', $author)) < 3)
+			$author = '';
+
+		if (!$keywords && !$author)
+			message($lang_search['No terms']);
+
+		if ($author)
+			$author = str_replace('*', '%', $author);
+
+		$show_as = (isset($_GET['show_as'])) ? $_GET['show_as'] : 'posts';
+		$sort_by = (isset($_GET['sort_by'])) ? intval($_GET['sort_by']) : null;
+		$search_in = (!isset($_GET['search_in']) || $_GET['search_in'] == 'all') ? 0 : (($_GET['search_in'] == 'message') ? 1 : -1);
+	}
+	// If it's a user search (by id)
+	else if ($action == 'show_user')
+	{
+		$user_id = intval($_GET['user_id']);
+		if ($user_id < 2)
+			message($lang_common['Bad request']);
+	}
+	else
+	{
+		if ($action != 'show_new' && $action != 'show_24h' && $action != 'show_unanswered' && $action != 'show_subscriptions')
+			message($lang_common['Bad request']);
+	}
+
+
+	// If a valid search_id was supplied we attempt to fetch the search results from the db
+	if (isset($search_id))
+	{
+		$ident = ($pun_user['is_guest']) ? get_remote_address() : $pun_user['username'];
+
+		$result = $db->query('SELECT search_data FROM '.$db->prefix.'search_cache WHERE id='.$search_id.' AND ident=\''.$db->escape($ident).'\'') or error('Unable to fetch search results', __FILE__, __LINE__, $db->error());
+		if ($row = $db->fetch_assoc($result))
+		{
+			$temp = unserialize($row['search_data']);
+
+			$search_results = $temp['search_results'];
+			$num_hits = $temp['num_hits'];
+			$sort_by = $temp['sort_by'];
+			$sort_dir = $temp['sort_dir'];
+			$show_as = $temp['show_as'];
+
+			unset($temp);
+		}
+		else
+			message($lang_search['No hits']);
+	}
+	else
+	{
+		$keyword_results = $author_results = array();
+
+		// Search a specific forum?
+		$forum_sql = ($forum != -1 || ($forum == -1 && $pun_config['o_search_all_forums'] == '0')) ? ' AND t.forum_id = '.$forum : '';
+
+		if (!empty($author) || !empty($keywords))
+		{
+			// If it's a search for keywords
+			if ($keywords)
+			{
+				$stopwords = (array)@file(PUN_ROOT.'lang/'.$pun_user['language'].'/stopwords.txt');
+				$stopwords = array_map('trim', $stopwords);
+
+				// Are we searching for multibyte charset text?
+				if ($multibyte)
+				{
+					// Strip out excessive whitespace
+					$keywords = trim(preg_replace('#\s+#', ' ', $keywords));
+
+					$keywords_array = explode(' ', $keywords);
+				}
+				else
+				{
+					// Filter out non-alphabetical chars
+					$noise_match = array('^', '$', '&', '(', ')', '<', '>', '`', '\'', '"', '|', ',', '@', '_', '?', '%', '~', '[', ']', '{', '}', ':', '\\', '/', '=', '#', '\'', ';', '!', '¤');
+					$noise_replace = array(' ', ' ', ' ', ' ', ' ', ' ', ' ', '',  '',   ' ', ' ', ' ', ' ', '',  ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '' ,  ' ', ' ', ' ', ' ',  ' ', ' ', ' ');
+					$keywords = str_replace($noise_match, $noise_replace, $keywords);
+
+					// Strip out excessive whitespace
+					$keywords = trim(preg_replace('#\s+#', ' ', $keywords));
+
+					// Fill an array with all the words
+					$keywords_array = explode(' ', $keywords);
+
+					if (empty($keywords_array))
+						message($lang_search['No hits']);
+
+					while (list($i, $word) = @each($keywords_array))
+					{
+						$num_chars = pun_strlen($word);
+
+						if ($num_chars < 3 || $num_chars > 20 || in_array($word, $stopwords))
+							unset($keywords_array[$i]);
+					}
+
+					// Should we search in message body or topic subject specifically?
+					$search_in_cond = ($search_in) ? (($search_in > 0) ? ' AND m.subject_match = 0' : ' AND m.subject_match = 1') : '';
+				}
+
+				$word_count = 0;
+				$match_type = 'and';
+				$result_list = array();
+				@reset($keywords_array);
+				while (list(, $cur_word) = @each($keywords_array))
+				{
+					switch ($cur_word)
+					{
+						case 'and':
+						case 'or':
+						case 'not':
+							$match_type = $cur_word;
+							break;
+
+						default:
+						{
+							// Are we searching for multibyte charset text?
+							if ($multibyte)
+							{
+								$cur_word = $db->escape('%'.str_replace('*', '', $cur_word).'%');
+								$cur_word_like = ($db_type == 'pgsql') ? 'ILIKE \''.$cur_word.'\'' : 'LIKE \''.$cur_word.'\'';
+
+								if ($search_in > 0)
+									$sql = 'SELECT id FROM '.$db->prefix.'posts WHERE message '.$cur_word_like;
+								else if ($search_in < 0)
+									$sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE t.subject '.$cur_word_like.' GROUP BY p.id, t.id';
+								else
+									$sql = 'SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.message '.$cur_word_like.' OR t.subject '.$cur_word_like.' GROUP BY p.id, t.id';
+							}
+							else
+							{
+								$cur_word = str_replace('*', '%', $cur_word);
+								$sql = 'SELECT m.post_id FROM '.$db->prefix.'search_words AS w INNER JOIN '.$db->prefix.'search_matches AS m ON m.word_id = w.id WHERE w.word LIKE \''.$cur_word.'\''.$search_in_cond;
+							}
+
+							$result = $db->query($sql, true) or error('Unable to search for posts', __FILE__, __LINE__, $db->error());
+
+							$row = array();
+							while ($temp = $db->fetch_row($result))
+							{
+								$row[$temp[0]] = 1;
+
+								if (!$word_count)
+									$result_list[$temp[0]] = 1;
+								else if ($match_type == 'or')
+									$result_list[$temp[0]] = 1;
+								else if ($match_type == 'not')
+									$result_list[$temp[0]] = 0;
+							}
+
+							if ($match_type == 'and' && $word_count)
+							{
+								@reset($result_list);
+								while (list($post_id,) = @each($result_list))
+								{
+									if (!isset($row[$post_id]))
+										$result_list[$post_id] = 0;
+								}
+							}
+
+							++$word_count;
+							$db->free_result($result);
+
+							break;
+						}
+					}
+				}
+
+				@reset($result_list);
+				while (list($post_id, $matches) = @each($result_list))
+				{
+					if ($matches)
+						$keyword_results[] = $post_id;
+				}
+
+				unset($result_list);
+			}
+
+			// If it's a search for author name (and that author name isn't Guest)
+			if ($author && strcasecmp($author, 'Guest') && strcasecmp($author, $lang_common['Guest']))
+			{
+				switch ($db_type)
+				{
+					case 'pgsql':
+						$result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username ILIKE \''.$db->escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error());
+						break;
+
+					default:
+						$result = $db->query('SELECT id FROM '.$db->prefix.'users WHERE username LIKE \''.$db->escape($author).'\'') or error('Unable to fetch users', __FILE__, __LINE__, $db->error());
+						break;
+				}
+
+				if ($db->num_rows($result))
+				{
+					$user_ids = '';
+					while ($row = $db->fetch_row($result))
+						$user_ids .= (($user_ids != '') ? ',' : '').$row[0];
+
+					$result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE poster_id IN('.$user_ids.')') or error('Unable to fetch matched posts list', __FILE__, __LINE__, $db->error());
+
+					$search_ids = array();
+					while ($row = $db->fetch_row($result))
+						$author_results[] = $row[0];
+
+					$db->free_result($result);
+				}
+			}
+
+
+			if ($author && $keywords)
+			{
+				// If we searched for both keywords and author name we want the intersection between the results
+				$search_ids = array_intersect($keyword_results, $author_results);
+				unset($keyword_results, $author_results);
+			}
+			else if ($keywords)
+				$search_ids = $keyword_results;
+			else
+				$search_ids = $author_results;
+
+			$num_hits = count($search_ids);
+			if (!$num_hits)
+				message($lang_search['No hits']);
+
+
+			if ($show_as == 'topics')
+			{
+				$result = $db->query('SELECT t.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id IN('.implode(',', $search_ids).')'.$forum_sql.' GROUP BY t.id', true) or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
+
+				$search_ids = array();
+				while ($row = $db->fetch_row($result))
+					$search_ids[] = $row[0];
+
+				$db->free_result($result);
+
+				$num_hits = count($search_ids);
+			}
+			else
+			{
+				$result = $db->query('SELECT p.id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.id IN('.implode(',', $search_ids).')'.$forum_sql, true) or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
+
+				$search_ids = array();
+				while ($row = $db->fetch_row($result))
+					$search_ids[] = $row[0];
+
+				$db->free_result($result);
+
+				$num_hits = count($search_ids);
+			}
+		}
+		else if ($action == 'show_new' || $action == 'show_24h' || $action == 'show_user' || $action == 'show_subscriptions' || $action == 'show_unanswered')
+		{
+			// If it's a search for new posts
+			if ($action == 'show_new')
+			{
+				if ($pun_user['is_guest'])
+					message($lang_common['No permission']);
+
+				$result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.$pun_user['last_visit'].' AND t.moved_to IS NULL') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
+				$num_hits = $db->num_rows($result);
+
+				if (!$num_hits)
+					message($lang_search['No new posts']);
+			}
+			// If it's a search for todays posts
+			else if ($action == 'show_24h')
+			{
+				$result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.last_post>'.(time() - 86400).' AND t.moved_to IS NULL') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
+				$num_hits = $db->num_rows($result);
+
+				if (!$num_hits)
+					message($lang_search['No recent posts']);
+			}
+			// If it's a search for posts by a specific user ID
+			else if ($action == 'show_user')
+			{
+				$result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND p.poster_id='.$user_id.' GROUP BY t.id') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
+				$num_hits = $db->num_rows($result);
+
+				if (!$num_hits)
+					message($lang_search['No user posts']);
+			}
+			// If it's a search for subscribed topics
+			else if ($action == 'show_subscriptions')
+			{
+				if ($pun_user['is_guest'])
+					message($lang_common['Bad request']);
+
+				$result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1)') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
+				$num_hits = $db->num_rows($result);
+
+				if (!$num_hits)
+					message($lang_search['No subscriptions']);
+			}
+			// If it's a search for unanswered posts
+			else
+			{
+				$result = $db->query('SELECT t.id FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.num_replies=0 AND t.moved_to IS NULL') or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
+				$num_hits = $db->num_rows($result);
+
+				if (!$num_hits)
+					message($lang_search['No unanswered']);
+			}
+
+			// We want to sort things after last post
+			$sort_by = 4;
+
+			$search_ids = array();
+			while ($row = $db->fetch_row($result))
+				$search_ids[] = $row[0];
+
+			$db->free_result($result);
+
+			$show_as = 'topics';
+		}
+		else
+			message($lang_common['Bad request']);
+
+
+		// Prune "old" search results
+		$old_searches = array();
+		$result = $db->query('SELECT ident FROM '.$db->prefix.'online') or error('Unable to fetch online list', __FILE__, __LINE__, $db->error());
+
+		if ($db->num_rows($result))
+		{
+			while ($row = $db->fetch_row($result))
+				$old_searches[] = '\''.$db->escape($row[0]).'\'';
+
+			$db->query('DELETE FROM '.$db->prefix.'search_cache WHERE ident NOT IN('.implode(',', $old_searches).')') or error('Unable to delete search results', __FILE__, __LINE__, $db->error());
+		}
+
+		// Final search results
+		$search_results = implode(',', $search_ids);
+
+		// Fill an array with our results and search properties
+		$temp['search_results'] = $search_results;
+		$temp['num_hits'] = $num_hits;
+		$temp['sort_by'] = $sort_by;
+		$temp['sort_dir'] = $sort_dir;
+		$temp['show_as'] = $show_as;
+		$temp = serialize($temp);
+		$search_id = mt_rand(1, 2147483647);
+
+		$ident = ($pun_user['is_guest']) ? get_remote_address() : $pun_user['username'];
+
+		$db->query('INSERT INTO '.$db->prefix.'search_cache (id, ident, search_data) VALUES('.$search_id.', \''.$db->escape($ident).'\', \''.$db->escape($temp).'\')') or error('Unable to insert search results', __FILE__, __LINE__, $db->error());
+
+		if ($action != 'show_new' && $action != 'show_24h')
+		{
+			$db->end_transaction();
+			$db->close();
+
+			// Redirect the user to the cached result page
+			header('Location: search.php?search_id='.$search_id);
+			exit;
+		}
+	}
+
+
+	// Fetch results to display
+	if ($search_results != '')
+	{
+		switch ($sort_by)
+		{
+			case 1:
+				$sort_by_sql = ($show_as == 'topics') ? 't.poster' : 'p.poster';
+				break;
+
+			case 2:
+				$sort_by_sql = 't.subject';
+				break;
+
+			case 3:
+				$sort_by_sql = 't.forum_id';
+				break;
+
+			case 4:
+				$sort_by_sql = 't.last_post';
+				break;
+
+			default:
+				$sort_by_sql = ($show_as == 'topics') ? 't.posted' : 'p.posted';
+				break;
+		}
+
+		if ($show_as == 'posts')
+		{
+			$substr_sql = ($db_type != 'sqlite') ? 'SUBSTRING' : 'SUBSTR';
+			$sql = 'SELECT p.id AS pid, p.poster AS pposter, p.posted AS pposted, p.poster_id, '.$substr_sql.'(p.message, 1, 1000) AS message, t.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.forum_id FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'topics AS t ON t.id=p.topic_id WHERE p.id IN('.$search_results.') ORDER BY '.$sort_by_sql;
+		}
+		else
+			$sql = 'SELECT t.id AS tid, t.poster, t.subject, t.last_post, t.last_post_id, t.last_poster, t.num_replies, t.closed, t.forum_id FROM '.$db->prefix.'topics AS t WHERE t.id IN('.$search_results.') ORDER BY '.$sort_by_sql;
+
+
+		// Determine the topic or post offset (based on $_GET['p'])
+		$per_page = ($show_as == 'posts') ? $pun_user['disp_posts'] : $pun_user['disp_topics'];
+		$num_pages = ceil($num_hits / $per_page);
+
+		$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p'];
+		$start_from = $per_page * ($p - 1);
+
+		// Generate paging links
+		$paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'search.php?search_id='.$search_id);
+
+
+		$sql .= ' '.$sort_dir.' LIMIT '.$start_from.', '.$per_page;
+
+		$result = $db->query($sql) or error('Unable to fetch search results', __FILE__, __LINE__, $db->error());
+
+		$search_set = array();
+		while ($row = $db->fetch_assoc($result))
+			$search_set[] = $row;
+
+		$db->free_result($result);
+
+		$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_search['Search results'];
+		require PUN_ROOT.'header.php';
+
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<p class="pagelink"><?php echo $paging_links ?></p>
+	</div>
+</div>
+
+<?php
+
+		//Set background switching on for show as posts
+		$bg_switch = true;
+
+		if ($show_as == 'topics')
+		{
+
+?>
+<div id="vf" class="blocktable">
+	<h2><span><?php echo $lang_search['Search results']; ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<table cellspacing="0">
+			<thead>
+				<tr>
+					<th class="tcl" scope="col"><?php echo $lang_common['Topic']; ?></th>
+					<th class="tc2" scope="col"><?php echo $lang_common['Forum'] ?></th>
+					<th class="tc3" scope="col"><?php echo $lang_common['Replies'] ?></th>
+					<th class="tcr" scope="col"><?php echo $lang_common['Last post'] ?></th>
+				</tr>
+			</thead>
+			<tbody>
+<?php
+
+		}
+
+		// Fetch the list of forums
+		$result = $db->query('SELECT id, forum_name FROM '.$db->prefix.'forums') or error('Unable to fetch forum list', __FILE__, __LINE__, $db->error());
+
+		$forum_list = array();
+		while ($forum_list[] = $db->fetch_row($result))
+			;
+
+		// Finally, lets loop through the results and output them
+		for ($i = 0; $i < count($search_set); ++$i)
+		{
+			@reset($forum_list);
+			while (list(, $temp) = @each($forum_list))
+			{
+				if ($temp[0] == $search_set[$i]['forum_id'])
+					$forum = '<a href="viewforum.php?id='.$temp[0].'">'.pun_htmlspecialchars($temp[1]).'</a>';
+			}
+
+			if ($pun_config['o_censoring'] == '1')
+				$search_set[$i]['subject'] = censor_words($search_set[$i]['subject']);
+
+
+			if ($show_as == 'posts')
+			{
+				$icon = '<div class="icon"><div class="nosize">'.$lang_common['Normal icon'].'</div></div>'."\n";
+				$subject = '<a href="viewtopic.php?id='.$search_set[$i]['tid'].'">'.pun_htmlspecialchars($search_set[$i]['subject']).'</a>';
+
+				if (!$pun_user['is_guest'] && $search_set[$i]['last_post'] > $pun_user['last_visit'])
+					$icon = '<div class="icon inew"><div class="nosize">'.$lang_common['New icon'].'</div></div>'."\n";
+
+
+				if ($pun_config['o_censoring'] == '1')
+					$search_set[$i]['message'] = censor_words($search_set[$i]['message']);
+
+				$message = str_replace("\n", '<br />', pun_htmlspecialchars($search_set[$i]['message']));
+				$pposter = pun_htmlspecialchars($search_set[$i]['pposter']);
+
+				if ($search_set[$i]['poster_id'] > 1)
+					$pposter = '<strong><a href="profile.php?id='.$search_set[$i]['poster_id'].'">'.$pposter.'</a></strong>';
+
+				if (pun_strlen($message) >= 1000)
+					$message .= ' &hellip;';
+
+				$vtpost1 = ($i == 0) ? ' vtp1' : '';
+
+				// Switch the background color for every message.
+				$bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true;
+				$vtbg = ($bg_switch) ? ' rowodd' : ' roweven';
+
+
+?>
+<div class="blockpost searchposts<?php echo $vtbg ?>">
+	<h2><?php echo $forum ?>&nbsp;&raquo;&nbsp;<?php echo $subject ?>&nbsp;&raquo;&nbsp;<a href="viewtopic.php?pid=<?php echo $search_set[$i]['pid'].'#p'.$search_set[$i]['pid'] ?>"><?php echo format_time($search_set[$i]['pposted']) ?></a></h2>
+	<div class="box">
+		<div class="inbox">
+			<div class="postleft">
+				<dl>
+					<dt><?php echo $pposter ?></dt>
+					<dd>Replies: <?php echo $search_set[$i]['num_replies'] ?></dd>
+					<dd><?php echo $icon; ?></dd>
+					<dd><p class="clearb"><a href="viewtopic.php?pid=<?php echo $search_set[$i]['pid'].'#p'.$search_set[$i]['pid'] ?>"><?php echo $lang_search['Go to post'] ?></a></p></dd>
+				</dl>
+			</div>
+			<div class="postright">
+				<div class="postmsg">
+					<p><?php echo $message ?></p>
+				</div>
+			</div>
+			<div class="clearer"></div>
+		</div>
+	</div>
+</div>
+<?php
+
+			}
+			else
+			{
+				$icon = '<div class="icon"><div class="nosize">'.$lang_common['Normal icon'].'</div></div>'."\n";
+
+				$icon_text = $lang_common['Normal icon'];
+				$item_status = '';
+				$icon_type = 'icon';
+
+
+				$subject = '<a href="viewtopic.php?id='.$search_set[$i]['tid'].'">'.pun_htmlspecialchars($search_set[$i]['subject']).'</a> <span class="byuser">'.$lang_common['by'].'&nbsp;'.pun_htmlspecialchars($search_set[$i]['poster']).'</span>';
+
+				if ($search_set[$i]['closed'] != '0')
+				{
+					$icon_text = $lang_common['Closed icon'];
+					$item_status = 'iclosed';
+				}
+
+				if (!$pun_user['is_guest'] && $search_set[$i]['last_post'] > $pun_user['last_visit'])
+				{
+					$icon_text .= ' '.$lang_common['New icon'];
+					$item_status .= ' inew';
+					$icon_type = 'icon inew';
+					$subject = '<strong>'.$subject.'</strong>';
+					$subject_new_posts = '<span class="newtext">[&nbsp;<a href="viewtopic.php?id='.$search_set[$i]['tid'].'&amp;action=new" title="'.$lang_common['New posts info'].'">'.$lang_common['New posts'].'</a>&nbsp;]</span>';
+				}
+				else
+					$subject_new_posts = null;
+
+				$num_pages_topic = ceil(($search_set[$i]['num_replies'] + 1) / $pun_user['disp_posts']);
+
+				if ($num_pages_topic > 1)
+					$subject_multipage = '[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$search_set[$i]['tid']).' ]';
+				else
+					$subject_multipage = null;
+
+				// Should we show the "New posts" and/or the multipage links?
+				if (!empty($subject_new_posts) || !empty($subject_multipage))
+				{
+					$subject .= '&nbsp; '.(!empty($subject_new_posts) ? $subject_new_posts : '');
+					$subject .= !empty($subject_multipage) ? ' '.$subject_multipage : '';
+				}
+
+?>
+				<tr<?php if ($item_status != '') echo ' class="'.trim($item_status).'"'; ?>>
+					<td class="tcl">
+						<div class="intd">
+							<div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo trim($icon_text) ?></div></div>
+							<div class="tclcon">
+								<?php echo $subject."\n" ?>
+							</div>
+						</div>
+					</td>
+					<td class="tc2"><?php echo $forum ?></td>
+					<td class="tc3"><?php echo $search_set[$i]['num_replies'] ?></td>
+					<td class="tcr"><?php echo '<a href="viewtopic.php?pid='.$search_set[$i]['last_post_id'].'#p'.$search_set[$i]['last_post_id'].'">'.format_time($search_set[$i]['last_post']).'</a> '.$lang_common['by'].'&nbsp;'.pun_htmlspecialchars($search_set[$i]['last_poster']) ?></td>
+				</tr>
+<?php
+
+			}
+		}
+
+		if ($show_as == 'topics')
+			echo "\t\t\t".'</tbody>'."\n\t\t\t".'</table>'."\n\t\t".'</div>'."\n\t".'</div>'."\n".'</div>'."\n\n";
+
+?>
+<div class="<?php echo ($show_as == 'topics') ? 'linksb' : 'postlinksb'; ?>">
+	<div class="inbox">
+		<p class="pagelink"><?php echo $paging_links ?></p>
+	</div>
+</div>
+<?php
+
+		$footer_style = 'search';
+		require PUN_ROOT.'footer.php';
+	}
+	else
+		message($lang_search['No hits']);
+}
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_search['Search'];
+$focus_element = array('search', 'keywords');
+require PUN_ROOT.'header.php';
+
+?>
+<div id="searchform" class="blockform">
+	<h2><span><?php echo $lang_search['Search'] ?></span></h2>
+	<div class="box">
+		<form id="search" method="get" action="search.php">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_search['Search criteria legend'] ?></legend>
+					<div class="infldset">
+						<input type="hidden" name="action" value="search" />
+						<label class="conl"><?php echo $lang_search['Keyword search'] ?><br /><input type="text" name="keywords" size="40" maxlength="100" /><br /></label>
+						<label class="conl"><?php echo $lang_search['Author search'] ?><br /><input id="author" type="text" name="author" size="25" maxlength="25" /><br /></label>
+						<p class="clearb"><?php echo $lang_search['Search info'] ?></p>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_search['Search in legend'] ?></legend>
+					<div class="infldset">
+						<label class="conl"><?php echo $lang_search['Forum search'] ?>
+						<br /><select id="forum" name="forum">
+<?php
+
+if ($pun_config['o_search_all_forums'] == '1' || $pun_user['g_id'] < PUN_GUEST)
+	echo "\t\t\t\t\t\t\t".'<option value="-1">'.$lang_search['All forums'].'</option>'."\n";
+
+$result = $db->query('SELECT c.id AS cid, c.cat_name, f.id AS fid, f.forum_name, f.redirect_url FROM '.$db->prefix.'categories AS c INNER JOIN '.$db->prefix.'forums AS f ON c.id=f.cat_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.redirect_url IS NULL ORDER BY c.disp_position, c.id, f.disp_position', true) or error('Unable to fetch category/forum list', __FILE__, __LINE__, $db->error());
+
+$cur_category = 0;
+while ($cur_forum = $db->fetch_assoc($result))
+{
+	if ($cur_forum['cid'] != $cur_category)	// A new category since last iteration?
+	{
+		if ($cur_category)
+			echo "\t\t\t\t\t\t\t".'</optgroup>'."\n";
+
+		echo "\t\t\t\t\t\t\t".'<optgroup label="'.pun_htmlspecialchars($cur_forum['cat_name']).'">'."\n";
+		$cur_category = $cur_forum['cid'];
+	}
+
+	echo "\t\t\t\t\t\t\t\t".'<option value="'.$cur_forum['fid'].'">'.pun_htmlspecialchars($cur_forum['forum_name']).'</option>'."\n";
+}
+
+?>
+							</optgroup>
+						</select>
+						<br /></label>
+						<label class="conl"><?php echo $lang_search['Search in'] ?>
+						<br /><select id="search_in" name="search_in">
+							<option value="all"><?php echo $lang_search['Message and subject'] ?></option>
+							<option value="message"><?php echo $lang_search['Message only'] ?></option>
+							<option value="topic"><?php echo $lang_search['Topic only'] ?></option>
+						</select>
+						<br /></label>
+						<p class="clearb"><?php echo $lang_search['Search in info'] ?></p>
+					</div>
+				</fieldset>
+			</div>
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_search['Search results legend'] ?></legend>
+					<div class="infldset">
+						<label class="conl"><?php echo $lang_search['Sort by'] ?>
+						<br /><select name="sort_by">
+							<option value="0"><?php echo $lang_search['Sort by post time'] ?></option>
+							<option value="1"><?php echo $lang_search['Sort by author'] ?></option>
+							<option value="2"><?php echo $lang_search['Sort by subject'] ?></option>
+							<option value="3"><?php echo $lang_search['Sort by forum'] ?></option>
+						</select>
+						<br /></label>
+						<label class="conl"><?php echo $lang_search['Sort order'] ?>
+						<br /><select name="sort_dir">
+							<option value="DESC"><?php echo $lang_search['Descending'] ?></option>
+							<option value="ASC"><?php echo $lang_search['Ascending'] ?></option>
+						</select>
+						<br /></label>
+						<label class="conl"><?php echo $lang_search['Show as'] ?>
+						<br /><select name="show_as">
+							<option value="topics"><?php echo $lang_search['Show as topics'] ?></option>
+							<option value="posts"><?php echo $lang_search['Show as posts'] ?></option>
+						</select>
+						<br /></label>
+						<p class="clearb"><?php echo $lang_search['Search results info'] ?></p>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="search" value="<?php echo $lang_common['Submit'] ?>" accesskey="s" /></p>
+		</form>
+	</div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/Cobalt.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,258 @@
+/****************************************************************/
+/* 1. IMPORTED STYLESHEETS */
+/****************************************************************/
+
+/* Import the basic setup styles */
+@import url(imports/base.css);
+/* Import the colour scheme */
+@import url(imports/Cobalt_cs.css);
+
+/****************************************************************/
+/* 2. TEXT SETTINGS */
+/****************************************************************/
+
+/* 2.1 This sets the default Font Group */
+
+.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP {
+	FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
+}
+
+.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal}
+
+/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/
+* HTML .pun {FONT-SIZE: 68.75%}
+/* End IE Win Font Size */
+
+/* Set font size for tables because IE requires it */
+.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em}
+
+/* 2.2 Set the font-size for preformatted text i.e in code boxes */
+
+.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace}
+
+/* 2.3 Font size for headers */
+
+.pun H2, .pun H4 {FONT-SIZE: 1em}
+.pun H3 {FONT-SIZE: 1.1em}
+#brdtitle H1 {FONT-SIZE: 1.4em}
+
+/* 2.4 Larger text for particular items */
+DIV.postmsg P {LINE-HEIGHT: 1.4}
+DIV.postleft DT {FONT-SIZE: 1.1em}
+.pun PRE {FONT-SIZE: 1.2em}
+
+/* 2.5 Bold text */
+
+DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI,
+DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold}
+
+/****************************************************************/
+/* 3. LINKS */
+/****************************************************************/
+
+/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */
+
+#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link,
+.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited,
+.blockmenu A:link, .blockmenu A:visited {
+	TEXT-DECORATION: none
+}
+
+/* 3.2 Underline on hover for links in headers and main menu */
+
+#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline}
+
+/****************************************************************/
+/* 4. BORDER WIDTH AND STYLE */
+/****************************************************************/
+
+/* 4.1 By default borders are 1px solid */
+
+DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/* 4.2 Special settings for the board header. */
+
+#brdheader DIV.box {BORDER-TOP-WIDTH: 4px}
+
+/* 4.3 Borders for table cells */
+
+.pun TD, .pun TH {
+	BORDER-BOTTOM: none;
+	BORDER-RIGHT: none
+}
+
+.pun .tcl {BORDER-LEFT: none}
+
+/* 4.4 Special setting for fieldsets to preserve IE defaults */
+
+DIV>FIELDSET {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/****************************************************************/
+/* 5. VERTICAL AND PAGE SPACING */
+/****************************************************************/
+
+/* 5.1 Page margins */
+
+HTML, BODY {MARGIN: 0; PADDING: 0}
+#punwrap {margin:12px 20px}
+
+/* 5.2 Creates vertical space between main board elements (Margins) */
+
+DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px}
+#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px}
+DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px}
+
+/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */
+
+DIV.linkst, DIV.linksb {MARGIN-TOP: -12px}
+DIV.postlinksb {MARGIN-TOP: -6px}
+
+/* 5.4 Put a 12px gap above the board information box in index because the category tables only
+have a 6px space beneath them */
+
+#brdstats {MARGIN-TOP: 12px}
+
+/****************************************************************/
+/* 6. SPACING AROUND CONTENT */
+/****************************************************************/
+
+/* 6.1 Default padding for main items */
+
+DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px}
+.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0}
+.pun H2 {PADDING: 4px 6px}
+
+/* 6.2 Special spacing for various elements */
+
+.pun H1 {PADDING: 3px 0px 0px 0}
+#brdtitle P {PADDING-TOP: 0px}
+DIV.linkst {PADDING: 8px 6px 3px 6px}
+DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px}
+#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT  {LINE-HEIGHT: 1.4em}
+#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em}
+
+/* 6.4 Create some horizontal spacing for various elements */
+
+#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT  {MARGIN-RIGHT: 12px}
+
+/****************************************************************/
+/* 7. SPACING FOR TABLES */
+/****************************************************************/
+
+.pun TH, .pun TD {PADDING: 4px 6px}
+.pun TD P {PADDING: 5px 0 0 0}
+
+/****************************************************************/
+/* 8. SPACING FOR POSTS */
+/****************************************************************/
+
+/* 8.1 Padding around left and right columns in viewtopic */
+
+DIV.postleft DL, DIV.postright {PADDING: 6px}
+
+/* 8.2 Extra spacing for poster contact details and avatar */
+
+DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px}
+DD.postavatar {MARGIN-BOTTOM: 5px}
+
+/* 8.3 Extra top spacing for signatures and edited by */
+
+DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px}
+
+/* 8.4 Spacing for code and quote boxes */
+
+DIV.postmsg H4 {MARGIN-BOTTOM: 10px}
+.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px}
+
+/* 8.5 Padding for the action links and online indicator in viewtopic */
+
+DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px}
+
+/* 8.6 This is the input on moderators multi-delete view */
+
+DIV.blockpost INPUT, DIV.blockpost LABEL {
+	PADDING: 3px;
+	DISPLAY: inline
+}
+
+P.multidelete {
+	PADDING-TOP: 15px;
+	PADDING-BOTTOM: 5px
+}
+
+/* 8.7 Make sure paragraphs in posts don't get any padding */
+
+DIV.postmsg P {PADDING: 0}
+
+/****************************************************************/
+/* 9. SPECIAL SPACING FOR FORMS */
+/****************************************************************/
+
+/* 9.1 Padding around fieldsets */
+
+DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px}
+DIV.inform {PADDING-BOTTOM: 12px}
+
+/* 9.2 Padding inside fieldsets */
+
+.pun FIELDSET {PADDING: 0px 12px 0px 12px}
+DIV.infldset {PADDING: 9px 0px 12px 0}
+.pun LEGEND {PADDING: 0px 6px}
+
+/* 9.3 The information box at the top of the registration form and elsewhere */
+
+DIV.forminfo {
+	MARGIN-BOTTOM: 12px;
+	PADDING: 9px 10px
+}
+
+/* 9.4 BBCode help links in post forms */
+
+UL.bblinks LI {PADDING-RIGHT: 20px}
+
+UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px}
+
+/* 9.5 Horizontal positioning for the submit button on forms */
+
+DIV.blockform P INPUT {MARGIN-LEFT: 12px}
+
+/****************************************************************/
+/* 10. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* 10.1 These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. By default only .inew is different from the default.*/
+
+DIV.icon {
+	FLOAT: left;
+	MARGIN-TOP: 0.1em;
+	MARGIN-LEFT: 0.2em;
+	DISPLAY: block;
+	BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em;
+	BORDER-STYLE: solid
+}
+
+DIV.searchposts DIV.icon {MARGIN-LEFT: 0}
+
+/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The
+margin creates space for the post status indicator */
+
+TD DIV.tclcon {MARGIN-LEFT: 2.3em}
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/Lithium.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,258 @@
+/****************************************************************/
+/* 1. IMPORTED STYLESHEETS */
+/****************************************************************/
+
+/* Import the basic setup styles */
+@import url(imports/base.css);
+/* Import the colour scheme */
+@import url(imports/Lithium_cs.css);
+
+/****************************************************************/
+/* 2. TEXT SETTINGS */
+/****************************************************************/
+
+/* 2.1 This sets the default Font Group */
+
+.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP {
+	FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
+}
+
+.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal}
+
+/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/
+* HTML .pun {FONT-SIZE: 68.75%}
+/* End IE Win Font Size */
+
+/* Set font size for tables because IE requires it */
+.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em}
+
+/* 2.2 Set the font-size for preformatted text i.e in code boxes */
+
+.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace}
+
+/* 2.3 Font size for headers */
+
+.pun H2, .pun H4 {FONT-SIZE: 1em}
+.pun H3 {FONT-SIZE: 1.1em}
+#brdtitle H1 {FONT-SIZE: 1.4em}
+
+/* 2.4 Larger text for particular items */
+DIV.postmsg P {LINE-HEIGHT: 1.4}
+DIV.postleft DT {FONT-SIZE: 1.1em}
+.pun PRE {FONT-SIZE: 1.2em}
+
+/* 2.5 Bold text */
+
+DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI,
+DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold}
+
+/****************************************************************/
+/* 3. LINKS */
+/****************************************************************/
+
+/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */
+
+#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link,
+.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited,
+.blockmenu A:link, .blockmenu A:visited {
+	TEXT-DECORATION: none
+}
+
+/* 3.2 Underline on hover for links in headers and main menu */
+
+#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline}
+
+/****************************************************************/
+/* 4. BORDER WIDTH AND STYLE */
+/****************************************************************/
+
+/* 4.1 By default borders are 1px solid */
+
+DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/* 4.2 Special settings for the board header. */
+
+#brdheader DIV.box {BORDER-TOP-WIDTH: 4px}
+
+/* 4.3 Borders for table cells */
+
+.pun TD, .pun TH {
+	BORDER-BOTTOM: none;
+	BORDER-RIGHT: none
+}
+
+.pun .tcl {BORDER-LEFT: none}
+
+/* 4.4 Special setting for fieldsets to preserve IE defaults */
+
+DIV>FIELDSET {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/****************************************************************/
+/* 5. VERTICAL AND PAGE SPACING */
+/****************************************************************/
+
+/* 5.1 Page margins */
+
+HTML, BODY {MARGIN: 0; PADDING: 0}
+#punwrap {margin:12px 20px}
+
+/* 5.2 Creates vertical space between main board elements (Margins) */
+
+DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px}
+#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px}
+DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px}
+
+/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */
+
+DIV.linkst, DIV.linksb {MARGIN-TOP: -12px}
+DIV.postlinksb {MARGIN-TOP: -6px}
+
+/* 5.4 Put a 12px gap above the board information box in index because the category tables only
+have a 6px space beneath them */
+
+#brdstats {MARGIN-TOP: 12px}
+
+/****************************************************************/
+/* 6. SPACING AROUND CONTENT */
+/****************************************************************/
+
+/* 6.1 Default padding for main items */
+
+DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px}
+.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0}
+.pun H2 {PADDING: 4px 6px}
+
+/* 6.2 Special spacing for various elements */
+
+.pun H1 {PADDING: 3px 0px 0px 0}
+#brdtitle P {PADDING-TOP: 0px}
+DIV.linkst {PADDING: 8px 6px 3px 6px}
+DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px}
+#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT  {LINE-HEIGHT: 1.4em}
+#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em}
+
+/* 6.4 Create some horizontal spacing for various elements */
+
+#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT  {MARGIN-RIGHT: 12px}
+
+/****************************************************************/
+/* 7. SPACING FOR TABLES */
+/****************************************************************/
+
+.pun TH, .pun TD {PADDING: 4px 6px}
+.pun TD P {PADDING: 5px 0 0 0}
+
+/****************************************************************/
+/* 8. SPACING FOR POSTS */
+/****************************************************************/
+
+/* 8.1 Padding around left and right columns in viewtopic */
+
+DIV.postleft DL, DIV.postright {PADDING: 6px}
+
+/* 8.2 Extra spacing for poster contact details and avatar */
+
+DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px}
+DD.postavatar {MARGIN-BOTTOM: 5px}
+
+/* 8.3 Extra top spacing for signatures and edited by */
+
+DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px}
+
+/* 8.4 Spacing for code and quote boxes */
+
+DIV.postmsg H4 {MARGIN-BOTTOM: 10px}
+.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px}
+
+/* 8.5 Padding for the action links and online indicator in viewtopic */
+
+DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px}
+
+/* 8.6 This is the input on moderators multi-delete view */
+
+DIV.blockpost INPUT, DIV.blockpost LABEL {
+	PADDING: 3px;
+	DISPLAY: inline
+}
+
+P.multidelete {
+	PADDING-TOP: 15px;
+	PADDING-BOTTOM: 5px
+}
+
+/* 8.7 Make sure paragraphs in posts don't get any padding */
+
+DIV.postmsg P {PADDING: 0}
+
+/****************************************************************/
+/* 9. SPECIAL SPACING FOR FORMS */
+/****************************************************************/
+
+/* 9.1 Padding around fieldsets */
+
+DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px}
+DIV.inform {PADDING-BOTTOM: 12px}
+
+/* 9.2 Padding inside fieldsets */
+
+.pun FIELDSET {PADDING: 0px 12px 0px 12px}
+DIV.infldset {PADDING: 9px 0px 12px 0}
+.pun LEGEND {PADDING: 0px 6px}
+
+/* 9.3 The information box at the top of the registration form and elsewhere */
+
+DIV.forminfo {
+	MARGIN-BOTTOM: 12px;
+	PADDING: 9px 10px
+}
+
+/* 9.4 BBCode help links in post forms */
+
+UL.bblinks LI {PADDING-RIGHT: 20px}
+
+UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px}
+
+/* 9.5 Horizontal positioning for the submit button on forms */
+
+DIV.blockform P INPUT {MARGIN-LEFT: 12px}
+
+/****************************************************************/
+/* 10. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* 10.1 These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. By default only .inew is different from the default.*/
+
+DIV.icon {
+	FLOAT: left;
+	MARGIN-TOP: 0.1em;
+	MARGIN-LEFT: 0.2em;
+	DISPLAY: block;
+	BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em;
+	BORDER-STYLE: solid
+}
+
+DIV.searchposts DIV.icon {MARGIN-LEFT: 0}
+
+/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The
+margin creates space for the post status indicator */
+
+TD DIV.tclcon {MARGIN-LEFT: 2.3em}
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/Mercury.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,258 @@
+/****************************************************************/
+/* 1. IMPORTED STYLESHEETS */
+/****************************************************************/
+
+/* Import the basic setup styles */
+@import url(imports/base.css);
+/* Import the colour scheme */
+@import url(imports/Mercury_cs.css);
+
+/****************************************************************/
+/* 2. TEXT SETTINGS */
+/****************************************************************/
+
+/* 2.1 This sets the default Font Group */
+
+.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP {
+	FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
+}
+
+.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal}
+
+/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/
+* HTML .pun {FONT-SIZE: 68.75%}
+/* End IE Win Font Size */
+
+/* Set font size for tables because IE requires it */
+.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em}
+
+/* 2.2 Set the font-size for preformatted text i.e in code boxes */
+
+.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace}
+
+/* 2.3 Font size for headers */
+
+.pun H2, .pun H4 {FONT-SIZE: 1em}
+.pun H3 {FONT-SIZE: 1.1em}
+#brdtitle H1 {FONT-SIZE: 1.4em}
+
+/* 2.4 Larger text for particular items */
+DIV.postmsg P {LINE-HEIGHT: 1.4}
+DIV.postleft DT {FONT-SIZE: 1.1em}
+.pun PRE {FONT-SIZE: 1.2em}
+
+/* 2.5 Bold text */
+
+DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI,
+DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold}
+
+/****************************************************************/
+/* 3. LINKS */
+/****************************************************************/
+
+/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */
+
+#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link,
+.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited,
+.blockmenu A:link, .blockmenu A:visited {
+	TEXT-DECORATION: none
+}
+
+/* 3.2 Underline on hover for links in headers and main menu */
+
+#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline}
+
+/****************************************************************/
+/* 4. BORDER WIDTH AND STYLE */
+/****************************************************************/
+
+/* 4.1 By default borders are 1px solid */
+
+DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/* 4.2 Special settings for the board header. */
+
+#brdheader DIV.box {BORDER-TOP-WIDTH: 4px}
+
+/* 4.3 Borders for table cells */
+
+.pun TD, .pun TH {
+	BORDER-BOTTOM: none;
+	BORDER-RIGHT: none
+}
+
+.pun .tcl {BORDER-LEFT: none}
+
+/* 4.4 Special setting for fieldsets to preserve IE defaults */
+
+DIV>FIELDSET {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/****************************************************************/
+/* 5. VERTICAL AND PAGE SPACING */
+/****************************************************************/
+
+/* 5.1 Page margins */
+
+HTML, BODY {MARGIN: 0; PADDING: 0}
+#punwrap {margin:12px 20px}
+
+/* 5.2 Creates vertical space between main board elements (Margins) */
+
+DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px}
+#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px}
+DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px}
+
+/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */
+
+DIV.linkst, DIV.linksb {MARGIN-TOP: -12px}
+DIV.postlinksb {MARGIN-TOP: -6px}
+
+/* 5.4 Put a 12px gap above the board information box in index because the category tables only
+have a 6px space beneath them */
+
+#brdstats {MARGIN-TOP: 12px}
+
+/****************************************************************/
+/* 6. SPACING AROUND CONTENT */
+/****************************************************************/
+
+/* 6.1 Default padding for main items */
+
+DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px}
+.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0}
+.pun H2 {PADDING: 4px 6px}
+
+/* 6.2 Special spacing for various elements */
+
+.pun H1 {PADDING: 3px 0px 0px 0}
+#brdtitle P {PADDING-TOP: 0px}
+DIV.linkst {PADDING: 8px 6px 3px 6px}
+DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px}
+#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT  {LINE-HEIGHT: 1.4em}
+#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em}
+
+/* 6.4 Create some horizontal spacing for various elements */
+
+#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT  {MARGIN-RIGHT: 12px}
+
+/****************************************************************/
+/* 7. SPACING FOR TABLES */
+/****************************************************************/
+
+.pun TH, .pun TD {PADDING: 4px 6px}
+.pun TD P {PADDING: 5px 0 0 0}
+
+/****************************************************************/
+/* 8. SPACING FOR POSTS */
+/****************************************************************/
+
+/* 8.1 Padding around left and right columns in viewtopic */
+
+DIV.postleft DL, DIV.postright {PADDING: 6px}
+
+/* 8.2 Extra spacing for poster contact details and avatar */
+
+DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px}
+DD.postavatar {MARGIN-BOTTOM: 5px}
+
+/* 8.3 Extra top spacing for signatures and edited by */
+
+DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px}
+
+/* 8.4 Spacing for code and quote boxes */
+
+DIV.postmsg H4 {MARGIN-BOTTOM: 10px}
+.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px}
+
+/* 8.5 Padding for the action links and online indicator in viewtopic */
+
+DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px}
+
+/* 8.6 This is the input on moderators multi-delete view */
+
+DIV.blockpost INPUT, DIV.blockpost LABEL {
+	PADDING: 3px;
+	DISPLAY: inline
+}
+
+P.multidelete {
+	PADDING-TOP: 15px;
+	PADDING-BOTTOM: 5px
+}
+
+/* 8.7 Make sure paragraphs in posts don't get any padding */
+
+DIV.postmsg P {PADDING: 0}
+
+/****************************************************************/
+/* 9. SPECIAL SPACING FOR FORMS */
+/****************************************************************/
+
+/* 9.1 Padding around fieldsets */
+
+DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px}
+DIV.inform {PADDING-BOTTOM: 12px}
+
+/* 9.2 Padding inside fieldsets */
+
+.pun FIELDSET {PADDING: 0px 12px 0px 12px}
+DIV.infldset {PADDING: 9px 0px 12px 0}
+.pun LEGEND {PADDING: 0px 6px}
+
+/* 9.3 The information box at the top of the registration form and elsewhere */
+
+DIV.forminfo {
+	MARGIN-BOTTOM: 12px;
+	PADDING: 9px 10px
+}
+
+/* 9.4 BBCode help links in post forms */
+
+UL.bblinks LI {PADDING-RIGHT: 20px}
+
+UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px}
+
+/* 9.5 Horizontal positioning for the submit button on forms */
+
+DIV.blockform P INPUT {MARGIN-LEFT: 12px}
+
+/****************************************************************/
+/* 10. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* 10.1 These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. By default only .inew is different from the default.*/
+
+DIV.icon {
+	FLOAT: left;
+	MARGIN-TOP: 0.1em;
+	MARGIN-LEFT: 0.2em;
+	DISPLAY: block;
+	BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em;
+	BORDER-STYLE: solid
+}
+
+DIV.searchposts DIV.icon {MARGIN-LEFT: 0}
+
+/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The
+margin creates space for the post status indicator */
+
+TD DIV.tclcon {MARGIN-LEFT: 2.3em}
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/Oxygen.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,258 @@
+/****************************************************************/
+/* 1. IMPORTED STYLESHEETS */
+/****************************************************************/
+
+/* Import the basic setup styles */
+@import url(imports/base.css);
+/* Import the colour scheme */
+@import url(imports/Oxygen_cs.css);
+
+/****************************************************************/
+/* 2. TEXT SETTINGS */
+/****************************************************************/
+
+/* 2.1 This sets the default Font Group */
+
+.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP {
+	FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
+}
+
+.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal}
+
+/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/
+* HTML .pun {FONT-SIZE: 68.75%}
+/* End IE Win Font Size */
+
+/* Set font size for tables because IE requires it */
+.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em}
+
+/* 2.2 Set the font-size for preformatted text i.e in code boxes */
+
+.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace}
+
+/* 2.3 Font size for headers */
+
+.pun H2, .pun H4 {FONT-SIZE: 1em}
+.pun H3 {FONT-SIZE: 1.1em}
+#brdtitle H1 {FONT-SIZE: 1.4em}
+
+/* 2.4 Larger text for particular items */
+
DIV.postmsg P {LINE-HEIGHT: 1.4}
+DIV.postleft DT {FONT-SIZE: 1.1em}
+.pun PRE {FONT-SIZE: 1.2em}
+
+/* 2.5 Bold text */
+
+DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI,
+DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold}
+
+/****************************************************************/
+/* 3. LINKS */
+/****************************************************************/
+
+/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */
+
+#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link,
+.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited,
+.blockmenu A:link, .blockmenu A:visited {
+	TEXT-DECORATION: none
+}
+
+/* 3.2 Underline on hover for links in headers and main menu */
+
+#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline}
+
+/****************************************************************/
+/* 4. BORDER WIDTH AND STYLE */
+/****************************************************************/
+
+/* 4.1 By default borders are 1px solid */
+
+DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/* 4.2 Special settings for the board header. */
+
+#brdheader DIV.box {BORDER-TOP-WIDTH: 4px}
+
+/* 4.3 Borders for table cells */
+
+.pun TD, .pun TH {
+	BORDER-BOTTOM: none;
+	BORDER-RIGHT: none
+}
+
+.pun .tcl {BORDER-LEFT: none}
+
+/* 4.4 Special setting for fieldsets to preserve IE defaults */
+
+DIV>FIELDSET {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/****************************************************************/
+/* 5. VERTICAL AND PAGE SPACING */
+/****************************************************************/
+
+/* 5.1 Page margins */
+
+HTML, BODY {MARGIN: 0; PADDING: 0}
+#punwrap {margin:12px 20px}
+
+/* 5.2 Creates vertical space between main board elements (Margins) */
+
+DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px}
+#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px}
+DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px}
+
+/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */
+
+DIV.linkst, DIV.linksb {MARGIN-TOP: -12px}
+DIV.postlinksb {MARGIN-TOP: -6px}
+
+/* 5.4 Put a 12px gap above the board information box in index because the category tables only
+have a 6px space beneath them */
+
+#brdstats {MARGIN-TOP: 12px}
+
+/****************************************************************/
+/* 6. SPACING AROUND CONTENT */
+/****************************************************************/
+
+/* 6.1 Default padding for main items */
+
+DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px}
+.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0}
+.pun H2 {PADDING: 4px 6px}
+
+/* 6.2 Special spacing for various elements */
+
+.pun H1 {PADDING: 3px 0px 0px 0}
+#brdtitle P {PADDING-TOP: 0px}
+DIV.linkst {PADDING: 8px 6px 3px 6px}
+DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px}
+#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT  {LINE-HEIGHT: 1.4em}
+#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em}
+
+/* 6.4 Create some horizontal spacing for various elements */
+
+#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT  {MARGIN-RIGHT: 12px}
+
+/****************************************************************/
+/* 7. SPACING FOR TABLES */
+/****************************************************************/
+
+.pun TH, .pun TD {PADDING: 4px 6px}
+.pun TD P {PADDING: 5px 0 0 0}
+
+/****************************************************************/
+/* 8. SPACING FOR POSTS */
+/****************************************************************/
+
+/* 8.1 Padding around left and right columns in viewtopic */
+
+DIV.postleft DL, DIV.postright {PADDING: 6px}
+
+/* 8.2 Extra spacing for poster contact details and avatar */
+
+DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px}
+DD.postavatar {MARGIN-BOTTOM: 5px}
+
+/* 8.3 Extra top spacing for signatures and edited by */
+
+DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px}
+
+/* 8.4 Spacing for code and quote boxes */
+
+DIV.postmsg H4 {MARGIN-BOTTOM: 10px}
+.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px}
+
+/* 8.5 Padding for the action links and online indicator in viewtopic */
+
+DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px}
+
+/* 8.6 This is the input on moderators multi-delete view */
+
+DIV.blockpost INPUT, DIV.blockpost LABEL {
+	PADDING: 3px;
+	DISPLAY: inline
+}
+
+P.multidelete {
+	PADDING-TOP: 15px;
+	PADDING-BOTTOM: 5px
+}
+
+/* 8.7 Make sure paragraphs in posts don't get any padding */
+
+DIV.postmsg P {PADDING: 0}
+
+/****************************************************************/
+/* 9. SPECIAL SPACING FOR FORMS */
+/****************************************************************/
+
+/* 9.1 Padding around fieldsets */
+
+DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px}
+DIV.inform {PADDING-BOTTOM: 12px}
+
+/* 9.2 Padding inside fieldsets */
+
+.pun FIELDSET {PADDING: 0px 12px 0px 12px}
+DIV.infldset {PADDING: 9px 0px 12px 0}
+.pun LEGEND {PADDING: 0px 6px}
+
+/* 9.3 The information box at the top of the registration form and elsewhere */
+
+DIV.forminfo {
+	MARGIN-BOTTOM: 12px;
+	PADDING: 9px 10px
+}
+
+/* 9.4 BBCode help links in post forms */
+
+UL.bblinks LI {PADDING-RIGHT: 20px}
+
+UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px}
+
+/* 9.5 Horizontal positioning for the submit button on forms */
+
+DIV.blockform P INPUT {MARGIN-LEFT: 12px}
+
+/****************************************************************/
+/* 10. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* 10.1 These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. By default only .inew is different from the default.*/
+
+DIV.icon {
+	FLOAT: left;
+	MARGIN-TOP: 0.1em;
+	MARGIN-LEFT: 0.2em;
+	DISPLAY: block;
+	BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em;
+	BORDER-STYLE: solid
+}
+
+DIV.searchposts DIV.icon {MARGIN-LEFT: 0}
+
+/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The
+margin creates space for the post status indicator */
+
+TD DIV.tclcon {MARGIN-LEFT: 2.3em}
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/Radium.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,258 @@
+/****************************************************************/
+/* 1. IMPORTED STYLESHEETS */
+/****************************************************************/
+
+/* Import the basic setup styles */
+@import url(imports/base.css);
+/* Import the colour scheme */
+@import url(imports/Radium_cs.css);
+
+/****************************************************************/
+/* 2. TEXT SETTINGS */
+/****************************************************************/
+
+/* 2.1 This sets the default Font Group */
+
+.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP {
+	FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
+}
+
+.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal}
+
+/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/
+* HTML .pun {FONT-SIZE: 68.75%}
+/* End IE Win Font Size */
+
+/* Set font size for tables because IE requires it */
+.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em}
+
+/* 2.2 Set the font-size for preformatted text i.e in code boxes */
+
+.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace}
+
+/* 2.3 Font size for headers */
+
+.pun H2, .pun H4 {FONT-SIZE: 1em}
+.pun H3 {FONT-SIZE: 1.1em}
+#brdtitle H1 {FONT-SIZE: 1.4em}
+
+/* 2.4 Larger text for particular items */
+DIV.postmsg P {LINE-HEIGHT: 1.4}
+DIV.postleft DT {FONT-SIZE: 1.1em}
+.pun PRE {FONT-SIZE: 1.2em}
+
+/* 2.5 Bold text */
+
+DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI,
+DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold}
+
+/****************************************************************/
+/* 3. LINKS */
+/****************************************************************/
+
+/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */
+
+#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link,
+.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited,
+.blockmenu A:link, .blockmenu A:visited {
+	TEXT-DECORATION: none
+}
+
+/* 3.2 Underline on hover for links in headers and main menu */
+
+#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline}
+
+/****************************************************************/
+/* 4. BORDER WIDTH AND STYLE */
+/****************************************************************/
+
+/* 4.1 By default borders are 1px solid */
+
+DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/* 4.2 Special settings for the board header. */
+
+#brdheader DIV.box {BORDER-TOP-WIDTH: 4px}
+
+/* 4.3 Borders for table cells */
+
+.pun TD, .pun TH {
+	BORDER-BOTTOM: none;
+	BORDER-RIGHT: none
+}
+
+.pun .tcl {BORDER-LEFT: none}
+
+/* 4.4 Special setting for fieldsets to preserve IE defaults */
+
+DIV>FIELDSET {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/****************************************************************/
+/* 5. VERTICAL AND PAGE SPACING */
+/****************************************************************/
+
+/* 5.1 Page margins */
+
+HTML, BODY {MARGIN: 0; PADDING: 0}
+#punwrap {margin:12px 20px}
+
+/* 5.2 Creates vertical space between main board elements (Margins) */
+
+DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px}
+#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px}
+DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px}
+
+/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */
+
+DIV.linkst, DIV.linksb {MARGIN-TOP: -12px}
+DIV.postlinksb {MARGIN-TOP: -6px}
+
+/* 5.4 Put a 12px gap above the board information box in index because the category tables only
+have a 6px space beneath them */
+
+#brdstats {MARGIN-TOP: 12px}
+
+/****************************************************************/
+/* 6. SPACING AROUND CONTENT */
+/****************************************************************/
+
+/* 6.1 Default padding for main items */
+
+DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px}
+.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0}
+.pun H2 {PADDING: 4px 6px}
+
+/* 6.2 Special spacing for various elements */
+
+.pun H1 {PADDING: 3px 0px 0px 0}
+#brdtitle P {PADDING-TOP: 0px}
+DIV.linkst {PADDING: 8px 6px 3px 6px}
+DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px}
+#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT  {LINE-HEIGHT: 1.4em}
+#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em}
+
+/* 6.4 Create some horizontal spacing for various elements */
+
+#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT  {MARGIN-RIGHT: 12px}
+
+/****************************************************************/
+/* 7. SPACING FOR TABLES */
+/****************************************************************/
+
+.pun TH, .pun TD {PADDING: 4px 6px}
+.pun TD P {PADDING: 5px 0 0 0}
+
+/****************************************************************/
+/* 8. SPACING FOR POSTS */
+/****************************************************************/
+
+/* 8.1 Padding around left and right columns in viewtopic */
+
+DIV.postleft DL, DIV.postright {PADDING: 6px}
+
+/* 8.2 Extra spacing for poster contact details and avatar */
+
+DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px}
+DD.postavatar {MARGIN-BOTTOM: 5px}
+
+/* 8.3 Extra top spacing for signatures and edited by */
+
+DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px}
+
+/* 8.4 Spacing for code and quote boxes */
+
+DIV.postmsg H4 {MARGIN-BOTTOM: 10px}
+.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px}
+
+/* 8.5 Padding for the action links and online indicator in viewtopic */
+
+DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px}
+
+/* 8.6 This is the input on moderators multi-delete view */
+
+DIV.blockpost INPUT, DIV.blockpost LABEL {
+	PADDING: 3px;
+	DISPLAY: inline
+}
+
+P.multidelete {
+	PADDING-TOP: 15px;
+	PADDING-BOTTOM: 5px
+}
+
+/* 8.7 Make sure paragraphs in posts don't get any padding */
+
+DIV.postmsg P {PADDING: 0}
+
+/****************************************************************/
+/* 9. SPECIAL SPACING FOR FORMS */
+/****************************************************************/
+
+/* 9.1 Padding around fieldsets */
+
+DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px}
+DIV.inform {PADDING-BOTTOM: 12px}
+
+/* 9.2 Padding inside fieldsets */
+
+.pun FIELDSET {PADDING: 0px 12px 0px 12px}
+DIV.infldset {PADDING: 9px 0px 12px 0}
+.pun LEGEND {PADDING: 0px 6px}
+
+/* 9.3 The information box at the top of the registration form and elsewhere */
+
+DIV.forminfo {
+	MARGIN-BOTTOM: 12px;
+	PADDING: 9px 10px
+}
+
+/* 9.4 BBCode help links in post forms */
+
+UL.bblinks LI {PADDING-RIGHT: 20px}
+
+UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px}
+
+/* 9.5 Horizontal positioning for the submit button on forms */
+
+DIV.blockform P INPUT {MARGIN-LEFT: 12px}
+
+/****************************************************************/
+/* 10. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* 10.1 These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. By default only .inew is different from the default.*/
+
+DIV.icon {
+	FLOAT: left;
+	MARGIN-TOP: 0.1em;
+	MARGIN-LEFT: 0.2em;
+	DISPLAY: block;
+	BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em;
+	BORDER-STYLE: solid
+}
+
+DIV.searchposts DIV.icon {MARGIN-LEFT: 0}
+
+/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The
+margin creates space for the post status indicator */
+
+TD DIV.tclcon {MARGIN-LEFT: 2.3em}
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/Sulfur.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,258 @@
+/****************************************************************/
+/* 1. IMPORTED STYLESHEETS */
+/****************************************************************/
+
+/* Import the basic setup styles */
+@import url(imports/base.css);
+/* Import the colour scheme */
+@import url(imports/Sulfur_cs.css);
+
+/****************************************************************/
+/* 2. TEXT SETTINGS */
+/****************************************************************/
+
+/* 2.1 This sets the default Font Group */
+
+.pun, .pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP {
+	FONT-FAMILY: Verdana, Arial, Helvetica, sans-serif
+}
+
+.pun {FONT-SIZE: 11px; LINE-HEIGHT: normal}
+
+/* IEWin Font Size only - to allow IEWin to zoom. Do not remove comments \*/
+* HTML .pun {FONT-SIZE: 68.75%}
+/* End IE Win Font Size */
+
+/* Set font size for tables because IE requires it */
+.pun TABLE, .pun INPUT, .pun SELECT, .pun OPTGROUP, .pun TEXTAREA, DIV.postmsg P.postedit {FONT-SIZE: 1em}
+
+/* 2.2 Set the font-size for preformatted text i.e in code boxes */
+
+.pun PRE {FONT-FAMILY: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace}
+
+/* 2.3 Font size for headers */
+
+.pun H2, .pun H4 {FONT-SIZE: 1em}
+.pun H3 {FONT-SIZE: 1.1em}
+#brdtitle H1 {FONT-SIZE: 1.4em}
+
+/* 2.4 Larger text for particular items */
+DIV.postmsg P {LINE-HEIGHT: 1.4}
+DIV.postleft DT {FONT-SIZE: 1.1em}
+.pun PRE {FONT-SIZE: 1.2em}
+
+/* 2.5 Bold text */
+
+DIV.postleft DT, DIV.postmsg H4, TD.tcl H3, DIV.forminfo H3, P.postlink, DIV.linkst LI,
+DIV.linksb LI, DIV.postlinksb LI, .blockmenu LI, #brdtitle H1, .pun SPAN.warntext, .pun P.warntext {FONT-WEIGHT: bold}
+
+/****************************************************************/
+/* 3. LINKS */
+/****************************************************************/
+
+/* 3.1 Remove underlining for main menu, post header links, post links and vertical menus */
+
+#brdmenu A:link, #brdmenu A:visited, .blockpost DT A:link, .blockpost DT A:visited, .blockpost H2 A:link,
+.blockpost H2 A:visited, .postlink A:link, .postlink A:visited, .postfootright A:link, .postfootright A:visited,
+.blockmenu A:link, .blockmenu A:visited {
+	TEXT-DECORATION: none
+}
+
+/* 3.2 Underline on hover for links in headers and main menu */
+
+#brdmenu A:hover, .blockpost H2 A:hover {TEXT-DECORATION: underline}
+
+/****************************************************************/
+/* 4. BORDER WIDTH AND STYLE */
+/****************************************************************/
+
+/* 4.1 By default borders are 1px solid */
+
+DIV.box, .pun TD, .pun TH, .pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/* 4.2 Special settings for the board header. */
+
+#brdheader DIV.box {BORDER-TOP-WIDTH: 4px}
+
+/* 4.3 Borders for table cells */
+
+.pun TD, .pun TH {
+	BORDER-BOTTOM: none;
+	BORDER-RIGHT: none
+}
+
+.pun .tcl {BORDER-LEFT: none}
+
+/* 4.4 Special setting for fieldsets to preserve IE defaults */
+
+DIV>FIELDSET {
+	BORDER-STYLE: solid;
+	BORDER-WIDTH: 1px
+}
+
+/****************************************************************/
+/* 5. VERTICAL AND PAGE SPACING */
+/****************************************************************/
+
+/* 5.1 Page margins */
+
+HTML, BODY {MARGIN: 0; PADDING: 0}
+#punwrap {margin:12px 20px}
+
+/* 5.2 Creates vertical space between main board elements (Margins) */
+
+DIV.blocktable, DIV.block, DIV.blockform, DIV.block2col, #postreview {MARGIN-BOTTOM: 12px}
+#punindex DIV.blocktable, DIV.blockpost {MARGIN-BOTTOM: 6px}
+DIV.block2col DIV.blockform, DIV.block2col DIV.block {MARGIN-BOTTOM: 0px}
+
+/* 5.3 Remove space above breadcrumbs, postlinks and pagelinks with a negative top margin */
+
+DIV.linkst, DIV.linksb {MARGIN-TOP: -12px}
+DIV.postlinksb {MARGIN-TOP: -6px}
+
+/* 5.4 Put a 12px gap above the board information box in index because the category tables only
+have a 6px space beneath them */
+
+#brdstats {MARGIN-TOP: 12px}
+
+/****************************************************************/
+/* 6. SPACING AROUND CONTENT */
+/****************************************************************/
+
+/* 6.1 Default padding for main items */
+
+DIV.block DIV.inbox, DIV.blockmenu DIV.inbox {PADDING: 3px 6px}
+.pun P, .pun UL, .pun DL, DIV.blockmenu LI, .pun LABEL, #announce DIV.inbox DIV {PADDING: 3px 0}
+.pun H2 {PADDING: 4px 6px}
+
+/* 6.2 Special spacing for various elements */
+
+.pun H1 {PADDING: 3px 0px 0px 0}
+#brdtitle P {PADDING-TOP: 0px}
+DIV.linkst {PADDING: 8px 6px 3px 6px}
+DIV.linksb, DIV.postlinksb {PADDING: 3px 6px 8px 6px}
+#brdwelcome, #brdfooter DL A, DIV.blockmenu LI, DIV.rbox INPUT  {LINE-HEIGHT: 1.4em}
+#viewprofile DT, #viewprofile DD {PADDING: 0 3px; LINE-HEIGHT: 2em}
+
+/* 6.4 Create some horizontal spacing for various elements */
+
+#brdmenu LI, DIV.rbox INPUT, DIV.blockform P INPUT  {MARGIN-RIGHT: 12px}
+
+/****************************************************************/
+/* 7. SPACING FOR TABLES */
+/****************************************************************/
+
+.pun TH, .pun TD {PADDING: 4px 6px}
+.pun TD P {PADDING: 5px 0 0 0}
+
+/****************************************************************/
+/* 8. SPACING FOR POSTS */
+/****************************************************************/
+
+/* 8.1 Padding around left and right columns in viewtopic */
+
+DIV.postleft DL, DIV.postright {PADDING: 6px}
+
+/* 8.2 Extra spacing for poster contact details and avatar */
+
+DD.usercontacts, DD.postavatar {MARGIN-TOP: 5px}
+DD.postavatar {MARGIN-BOTTOM: 5px}
+
+/* 8.3 Extra top spacing for signatures and edited by */
+
+DIV.postsignature, DIV.postmsg P.postedit {PADDING-TOP: 15px}
+
+/* 8.4 Spacing for code and quote boxes */
+
+DIV.postmsg H4 {MARGIN-BOTTOM: 10px}
+.pun BLOCKQUOTE, DIV.codebox {MARGIN: 5px 15px 15px 15px; PADDING: 8px}
+
+/* 8.5 Padding for the action links and online indicator in viewtopic */
+
+DIV.postfootleft P, DIV.postfootright UL, DIV.postfootright DIV {PADDING: 10px 6px 5px 6px}
+
+/* 8.6 This is the input on moderators multi-delete view */
+
+DIV.blockpost INPUT, DIV.blockpost LABEL {
+	PADDING: 3px;
+	DISPLAY: inline
+}
+
+P.multidelete {
+	PADDING-TOP: 15px;
+	PADDING-BOTTOM: 5px
+}
+
+/* 8.7 Make sure paragraphs in posts don't get any padding */
+
+DIV.postmsg P {PADDING: 0}
+
+/****************************************************************/
+/* 9. SPECIAL SPACING FOR FORMS */
+/****************************************************************/
+
+/* 9.1 Padding around fieldsets */
+
+DIV.blockform FORM, DIV.fakeform {PADDING: 20px 20px 15px 20px}
+DIV.inform {PADDING-BOTTOM: 12px}
+
+/* 9.2 Padding inside fieldsets */
+
+.pun FIELDSET {PADDING: 0px 12px 0px 12px}
+DIV.infldset {PADDING: 9px 0px 12px 0}
+.pun LEGEND {PADDING: 0px 6px}
+
+/* 9.3 The information box at the top of the registration form and elsewhere */
+
+DIV.forminfo {
+	MARGIN-BOTTOM: 12px;
+	PADDING: 9px 10px
+}
+
+/* 9.4 BBCode help links in post forms */
+
+UL.bblinks LI {PADDING-RIGHT: 20px}
+
+UL.bblinks {PADDING-BOTTOM: 10px; PADDING-LEFT: 4px}
+
+/* 9.5 Horizontal positioning for the submit button on forms */
+
+DIV.blockform P INPUT {MARGIN-LEFT: 12px}
+
+/****************************************************************/
+/* 10. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* 10.1 These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. By default only .inew is different from the default.*/
+
+DIV.icon {
+	FLOAT: left;
+	MARGIN-TOP: 0.1em;
+	MARGIN-LEFT: 0.2em;
+	DISPLAY: block;
+	BORDER-WIDTH: 0.6em 0.6em 0.6em 0.6em;
+	BORDER-STYLE: solid
+}
+
+DIV.searchposts DIV.icon {MARGIN-LEFT: 0}
+
+/* 10.2 Class .tclcon is a div inside the first column of tables with post indicators. The
+margin creates space for the post status indicator */
+
+TD DIV.tclcon {MARGIN-LEFT: 2.3em}
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/imports/Cobalt_cs.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,117 @@
+/****************************************************************/
+/* 1. BACKGROUND AND TEXT COLOURS */
+/****************************************************************/
+
+/* 1.1 Default background colour and text colour */
+
+BODY {BACKGROUND-COLOR: #2A2A2A}
+
+.pun {COLOR: #D4D4D4}
+
+DIV.box,  #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #383838}
+#adminconsole TD, #adminconsole TH {BORDER-COLOR: #383838}
+
+/* 1. 2 Darker background colours */
+
+TD.tc2, TD.tc3, TD.tcmod, #brdfooter DIV.box {BACKGROUND-COLOR: #424242}
+#adminconsole FIELDSET TD, #viewprofile DD, DIV.forminfo, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #484848}
+
+.pun BLOCKQUOTE, DIV.codebox {BACKGROUND-COLOR: #353533}
+
+/* 1.3 Main headers and navigation bar background and text colour */
+
+.pun H2, #brdmenu {BACKGROUND-COLOR: #565656; COLOR: #D4D4D4}
+
+/* 1.4 Table header rows */
+
+.pun TH, .bgc4 {BACKGROUND-COLOR: #484848}
+
+/* 1.5 Fieldset legend text colour */
+
+.pun LEGEND {COLOR: #60A0DC}
+
+/* 1.6 Highlighted text for various items */
+
+.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #D4D4D4}
+
+/* 1.7 Dark background for form elements */
+
+.pun TEXTAREA, .pun INPUT, .pun SELECT {BACKGROUND-COLOR: #2A2A2A; COLOR: #D4D4D4}
+
+/****************************************************************/
+/* 2. POST BACKGROUNDS AND TEXT */
+/****************************************************************/
+
+/* 2.1 This is the setup for posts. */
+
+DIV.blockpost DIV.box, DIV.postright, DIV.postfootright, #postpreview {BACKGROUND-COLOR: #383838}
+DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #424242}
+DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #424242}
+
+/* 2.2 Background for post headers and text colour for post numbers in viewtopic */
+
+DIV.blockpost H2 {BACKGROUND-COLOR: #565656}
+DIV.blockpost H2 SPAN.conr {COLOR: #A19E96}
+
+/* 2.3 This is the line above the signature in posts. Colour and background should be the same */
+
+.pun HR {BACKGROUND-COLOR: #606060; COLOR: #606060}
+
+/****************************************************************/
+/* 3. BORDER COLOURS */
+/****************************************************************/
+
+/* 3.1 All external borders (H1 is the board title) */
+
+DIV.box {BORDER-COLOR: #565656}
+
+/* 3.2 Makes the top border of posts match the colour used for post headers */
+
+DIV.blockpost DIV.box {BORDER-COLOR: #565656 #525252 #525252}
+
+/* 3.3 Table internal borders. By default TH is same as background so border is invisible */
+
+.pun TD {BORDER-COLOR: #565656}
+.pun TH {BORDER-COLOR: #484848}
+
+/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */
+
+.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #606060}
+
+/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour
+without interferring with IE's rather nice default */
+
+.pun DIV>FIELDSET {BORDER-COLOR: #ACA899}
+
+/****************************************************************/
+/* 4. LINK COLOURS */
+/****************************************************************/
+
+/* 4.1 This is the default for all links */
+
+.pun A:link, .pun A:visited {COLOR: #60A0DC}
+.pun A:hover {COLOR: #80D6FF}
+
+/* 4.2 This is the colour for links in header rows and the navigation bar */
+
+.pun H2 A:link, .pun H2 A:visited {COLOR: #D4D4D4}
+.pun H2 A:hover {COLOR: #D4D4D4}
+
+/* 4.3 This is for closed topics and "hot" links */
+
+LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888}
+LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA}
+LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #FF4000}
+LI.maintenancelink A:hover {COLOR: #FF5010}
+
+/****************************************************************/
+/* 5. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. The default is "icon". By default only .inew is different.*/
+
+DIV.icon {BORDER-COLOR: #484848 #404040 #3C3C3C #444444}
+TR.iredirect DIV.icon {BORDER-COLOR: #383838 #383838 #383838 #383838}
+DIV.inew {BORDER-COLOR: #5496D8 #4B85C0 #4377AC #4F8DCB}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/imports/Lithium_cs.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,111 @@
+/****************************************************************/
+/* 1. BACKGROUND AND TEXT COLOURS */
+/****************************************************************/
+
+/* 1.1 Default background colour and text colour */
+
+BODY {BACKGROUND-COLOR: #FFF}
+
+.pun {COLOR: #333}
+
+DIV.box, .pun BLOCKQUOTE, DIV.codebox, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #F1F1F1}
+#adminconsole TD, #adminconsole TH {BORDER-COLOR: #F1F1F1}
+
+/* 1. 2 Darker background colours */
+
+TD.tc2, TD.tc3, TD.tcmod, #postpreview, #viewprofile DD, DIV.forminfo,
+#adminconsole FIELDSET TD, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #DEDFDF}
+
+/* 1.3 Main headers and navigation bar background and text colour */
+
+.pun H2, #brdmenu {BACKGROUND-COLOR: #6C8A3F; COLOR: #FFF}
+
+/* 1.4 Table header rows */
+
+.pun TH, .bgc4 {BACKGROUND-COLOR: #D1D1D1}
+
+/* 1.5 Fieldset legend text colour */
+
+.pun LEGEND {COLOR: #6C8A3F}
+
+/* 1.6 Highlighted text for various items */
+
+.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #333}
+
+/****************************************************************/
+/* 2. POST BACKGROUNDS AND TEXT */
+/****************************************************************/
+
+/* 2.1 This is the setup for posts. */
+
+DIV.blockpost DIV.box, DIV.postright, DIV.postfootright {BACKGROUND-COLOR: #DEDFDF}
+DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #F1F1F1}
+DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #F1F1F1}
+
+/* 2.2 Background for post headers and text colour for post numbers in viewtopic */
+
+DIV.blockpost H2 {BACKGROUND-COLOR: #7EA34B}
+DIV.blockpost H2 SPAN.conr {COLOR: #B7D094}
+
+/* 2.3 This is the line above the signature in posts. Colour and background should be the same */
+
+.pun HR {BACKGROUND-COLOR: #333; COLOR: #333}
+
+/****************************************************************/
+/* 3. BORDER COLOURS */
+/****************************************************************/
+
+/* 3.1 All external borders */
+
+DIV.box {BORDER-COLOR: #6C8A3F}
+
+/* 3.2 Makes the top border of posts match the colour used for post headers */
+
+DIV.blockpost DIV.box {BORDER-COLOR: #7EA34B #6C8A3F #6C8A3F}
+
+/* 3.3 Table internal borders. By default TH is same as background so border is invisible */
+
+.pun TD {BORDER-COLOR: #CEDEB9}
+.pun TH {BORDER-COLOR: #D1D1D1}
+
+/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */
+
+.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #ACA899 #FFF #FFF #ACA899}
+
+/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour
+without interferring with IE's rather nice default */
+
+.pun DIV>FIELDSET {BORDER-COLOR: #ACA899}
+
+/****************************************************************/
+/* 4. LINK COLOURS */
+/****************************************************************/
+
+/* 4.1 This is the default for all links */
+
+.pun A:link, .pun A:visited {COLOR: #638137}
+.pun A:hover {COLOR: #8EB653}
+
+/* 4.2 This is the colour for links in header rows and the navigation bar */
+
+.pun H2 A:link, .pun H2 A:visited, #brdmenu A:link, #brdmenu A:visited {COLOR: #FFF}
+.pun H2 A:hover, #brdmenu A:hover {COLOR: #FFF}
+
+/* 4.3 This is for closed topics and "hot" links */
+
+LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888}
+LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA}
+LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #B42000}
+LI.maintenancelink A:hover {COLOR: #B42000}
+
+/****************************************************************/
+/* 5. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. The default is "icon". By default only .inew is different.*/
+
+DIV.icon {BORDER-COLOR: #E6E6E6 #DEDEDE #DADADA #E2E2E2}
+TR.iredirect DIV.icon {BORDER-COLOR: #F1F1F1 #F1F1F1 #F1F1F1 #F1F1F1}
+DIV.inew {BORDER-COLOR: #8BB453 #7A9E48 #709142 #799C47}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/imports/Mercury_cs.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,117 @@
+/****************************************************************/
+/* 1. BACKGROUND AND TEXT COLOURS */
+/****************************************************************/
+
+/* 1.1 Default background colour and text colour */
+
+BODY {BACKGROUND-COLOR: #2A2A2A}
+
+.pun {COLOR: #D4D4D4}
+
+DIV.box,  #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #383838}
+#adminconsole TD, #adminconsole TH {BORDER-COLOR: #383838}
+
+/* 1. 2 Darker background colours */
+
+TD.tc2, TD.tc3, TD.tcmod, #brdfooter DIV.box {BACKGROUND-COLOR: #424242}
+#adminconsole FIELDSET TD, #viewprofile DD, DIV.forminfo, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #484848}
+
+.pun BLOCKQUOTE, DIV.codebox {BACKGROUND-COLOR: #353533}
+
+/* 1.3 Main headers and navigation bar background and text colour */
+
+.pun H2, #brdmenu {BACKGROUND-COLOR: #565656; COLOR: #D4D4D4}
+
+/* 1.4 Table header rows */
+
+.pun TH {BACKGROUND-COLOR: #484848}
+
+/* 1.5 Fieldset legend text colour */
+
+.pun LEGEND {COLOR: #F6B620}
+
+/* 1.6 Highlighted text for various items */
+
+.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #D4D4D4}
+
+/* 1.7 Dark background for form elements */
+
+.pun TEXTAREA, .pun INPUT, .pun SELECT {BACKGROUND-COLOR: #2A2A2A; COLOR: #D4D4D4}
+
+/****************************************************************/
+/* 2. POST BACKGROUNDS AND TEXT */
+/****************************************************************/
+
+/* 2.1 This is the setup for posts. */
+
+DIV.blockpost DIV.box, DIV.postright, DIV.postfootright, #postpreview {BACKGROUND-COLOR: #383838}
+DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #424242}
+DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #424242}
+
+/* 2.2 Background for post headers and text colour for post numbers in viewtopic */
+
+DIV.blockpost H2 {BACKGROUND-COLOR: #565656}
+DIV.blockpost H2 SPAN.conr {COLOR: #A19E96}
+
+/* 2.3 This is the line above the signature in posts. Colour and background should be the same */
+
+.pun HR {BACKGROUND-COLOR: #606060;	COLOR: #606060}
+
+/****************************************************************/
+/* 3. BORDER COLOURS */
+/****************************************************************/
+
+/* 3.1 All external borders (H1 is the board title) */
+
+DIV.box {BORDER-COLOR: #565656}
+
+/* 3.2 Makes the top border of posts match the colour used for post headers */
+
+DIV.blockpost DIV.box {BORDER-COLOR: #565656 #525252 #525252}
+
+/* 3.3 Table internal borders. By default TH is same as background so border is invisible */
+
+.pun TD {BORDER-COLOR: #565656}
+.pun TH {BORDER-COLOR: #484848}
+
+/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */
+
+.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #565656}
+
+/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour
+without interferring with IE's rather nice default */
+
+.pun DIV>FIELDSET {BORDER-COLOR: #909090}
+
+/****************************************************************/
+/* 4. LINK COLOURS */
+/****************************************************************/
+
+/* 4.1 This is the default for all links */
+
+.pun A:link, .pun A:visited {COLOR: #F6B620}
+.pun A:hover {COLOR: #FFEE40}
+
+/* 4.2 This is the colour for links in header rows and the navigation bar */
+
+.pun H2 A:link, .pun H2 A:visited {COLOR: #D4D4D4}
+.pun H2 A:hover {COLOR: #D4D4D4}
+
+/* 4.3 This is for closed topics and "hot" links */
+
+LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888}
+LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA}
+LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #FF4000}
+LI.maintenancelink A:hover {COLOR: #FF5010}
+
+/****************************************************************/
+/* 5. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. The default is "icon". By default only .inew is different.*/
+
+DIV.icon {BORDER-COLOR: #484848 #404040 #3C3C3C #444444}
+TR.iredirect DIV.icon {BORDER-COLOR: #383838 #383838 #383838 #383838}
+DIV.inew {BORDER-COLOR: #F6B620 #ECAE1F #D09A1B #E1A61D}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/imports/Oxygen_cs.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,111 @@
+/****************************************************************/
+/* 1. BACKGROUND AND TEXT COLOURS */
+/****************************************************************/
+
+/* 1.1 Default background colour and text colour */
+
+BODY {BACKGROUND-COLOR: #FFF}
+
+.pun {COLOR: #333}
+
+DIV.box, .pun BLOCKQUOTE, DIV.codebox, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #F1F1F1}
+#adminconsole TD, #adminconsole TH {BORDER-COLOR: #F1F1F1}
+
+/* 1. 2 Darker background colours */
+
+TD.tc2, TD.tc3, TD.tcmod, #postpreview, #viewprofile DD, DIV.forminfo,
+#adminconsole FIELDSET TD, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #DEDFDF}
+
+/* 1.3 Main headers and navigation bar background and text colour */
+
+.pun H2, #brdmenu {BACKGROUND-COLOR: #0066B9; COLOR: #FFF}
+
+/* 1.4 Table header rows */
+
+.pun TH {BACKGROUND-COLOR: #D1D1D1}
+
+/* 1.5 Fieldset legend text colour */
+
+.pun LEGEND {COLOR: #005CB1}
+
+/* 1.6 Highlighted text for various items */
+
+.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #333}
+
+/****************************************************************/
+/* 2. POST BACKGROUNDS AND TEXT */
+/****************************************************************/
+
+/* 2.1 This is the setup for posts. */
+
+DIV.blockpost DIV.box, DIV.postright, DIV.postfootright {BACKGROUND-COLOR: #DEDFDF}
+DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #f1f1f1}
+DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #F1F1F1}
+
+/* 2.2 Background for post headers and text colour for post numbers in viewtopic */
+
+DIV.blockpost H2 {BACKGROUND-COLOR: #006FC9}
+DIV.blockpost H2 SPAN.conr {COLOR: #AABDCD}
+
+/* 2.3 This is the line above the signature in posts. Colour and background should be the same */
+
+.pun HR {BACKGROUND-COLOR: #333; COLOR: #333}
+
+/****************************************************************/
+/* 3. BORDER COLOURS */
+/****************************************************************/
+
+/* 3.1 All external borders */
+
+DIV.box {BORDER-COLOR: #0066B9}
+
+/* 3.2 Makes the top border of posts match the colour used for post headers */
+
+DIV.blockpost DIV.box {BORDER-COLOR: #006fC9 #0066B9 #0066B9}
+
+/* 3.3 Table internal borders. By default TH is same as background so border is invisible */
+
+.pun TD {BORDER-COLOR: #BBCEDE}
+.pun TH {BORDER-COLOR: #D1D1D1}
+
+/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */
+
+.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #ACA899 #FFF #FFF #ACA899}
+
+/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour
+without interferring with IE's rather nice default */
+
+.pun DIV>FIELDSET {BORDER-COLOR: #ACA899}
+
+/****************************************************************/
+/* 4. LINK COLOURS */
+/****************************************************************/
+
+/* 4.1 This is the default for all links */
+
+.pun A:link, .pun A:visited {COLOR: #005CB1}
+.pun A:hover {COLOR: #B42000}
+
+/* 4.2 This is the colour for links in header rows and the navigation bar */
+
+.pun H2 A:link, .pun H2 A:visited, #brdmenu A:link, #brdmenu A:visited {COLOR: #FFF}
+.pun H2 A:hover, #brdmenu A:hover {COLOR: #FFF}
+
+/* 4.3 This is for closed topics and "hot" links */
+
+LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888}
+LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA}
+LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #B42000}
+LI.maintenancelink A:hover {COLOR: #B42000}
+
+/****************************************************************/
+/* 5. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. The default is "icon". By default only .inew is different.*/
+
+DIV.icon {BORDER-COLOR: #E6E6E6 #DEDEDE #DADADA #E2E2E2}
+TR.iredirect DIV.icon {BORDER-COLOR: #F1F1F1 #F1F1F1 #F1F1F1 #F1F1F1}
+DIV.inew {BORDER-COLOR: #0080D7 #0065C0 #0058B3 #0072CA}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/imports/Radium_cs.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,122 @@
+/****************************************************************/
+/* 1. BACKGROUND AND TEXT COLOURS */
+/****************************************************************/
+
+/* 1.1 Default background colour and text colour */
+
+BODY {BACKGROUND-COLOR: #2A2A2A}
+
+.pun {COLOR: #D4D4D4}
+
+DIV.box,  #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #383838}
+#adminconsole TD, #adminconsole TH {BORDER-COLOR: #383838}
+
+/* 1. 2 Darker background colours */
+
+TD.tc2, TD.tc3, TD.tcmod, #brdfooter DIV.box {BACKGROUND-COLOR: #424242}
+#adminconsole FIELDSET TD, #viewprofile DD, DIV.forminfo, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #484848}
+
+.pun BLOCKQUOTE, DIV.codebox {BACKGROUND-COLOR: #353533}
+
+/* 1.3 Main headers and navigation bar background and text colour */
+
+.pun H2, #brdmenu {BACKGROUND-COLOR: #565656; COLOR: #D4D4D4}
+
+/* 1.4 Table header rows */
+
+.pun TH, .bgc4 {BACKGROUND-COLOR: #484848}
+
+/* 1.5 Fieldset legend text colour */
+
+.pun LEGEND {COLOR: #60C860}
+
+/* 1.6 Highlighted text for various items */
+
+.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #D4D4D4}
+
+/* 1.7 Dark background for form elements */
+
+.pun TEXTAREA, .pun INPUT, .pun SELECT {BACKGROUND-COLOR: #2A2A2A; COLOR: #D4D4D4}
+
+/****************************************************************/
+/* 2. POST BACKGROUNDS AND TEXT */
+/****************************************************************/
+
+/* 2.1 This is the setup for posts. */
+
+DIV.blockpost DIV.box, DIV.postright, DIV.postfootright, #postpreview {BACKGROUND-COLOR: #383838}
+DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #424242}
+DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #424242}
+
+/* 2.2 Background for post headers and text colour for post numbers in viewtopic */
+
+DIV.blockpost H2 {BACKGROUND-COLOR: #565656}
+DIV.blockpost H2 SPAN.conr {COLOR: #A19E96}
+
+/* 2.3 This is the line above the signature in posts. Colour and background should be the same */
+
+.pun HR {BACKGROUND-COLOR: #606060; COLOR: #606060} 
+
+/****************************************************************/
+/* 3. BORDER COLOURS */
+/****************************************************************/
+
+/* 3.1 All external borders (H1 is the board title) */
+
+DIV.box {BORDER-COLOR: #565656}
+
+/* 3.2 Makes the top border of posts match the colour used for post headers */
+
+DIV.blockpost DIV.box {BORDER-COLOR: #565656 #525252 #525252}
+
+/* 3.3 Table internal borders. By default TH is same as background so border is invisible */
+
+.pun TD {BORDER-COLOR: #565656}
+.pun TH {BORDER-COLOR: #484848}
+
+/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */
+
+.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #606060}
+
+/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour
+without interferring with IE's rather nice default */
+
+.pun DIV>FIELDSET {BORDER-COLOR: #ACA899}
+
+/****************************************************************/
+/* 4. LINK COLOURS */
+/****************************************************************/
+
+/* 4.1 This is the default for all links */
+
+.pun A:link, .pun A:visited {COLOR: #60C860}
+.pun A:hover {COLOR: #80EE80}
+
+/* 4.2 This is the colour for links in header rows and the navigation bar */
+
+.pun H2 A:link, .pun H2 A:visited {COLOR: #D4D4D4}
+.pun H2 A:hover {COLOR: #D4D4D4}
+
+/* 4.3 This is for closed topics and "hot" links */
+
+LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888}
+LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA}
+LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #FF4000}
+LI.maintenancelink A:hover {COLOR: #FF5010}
+
+/****************************************************************/
+/* 5. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. The default is "icon". By default only .inew is different.*/
+
+DIV.icon {BORDER-COLOR: #484848 #404040 #3C3C3C #444444}
+TR.iredirect DIV.icon {BORDER-COLOR: #383838 #383838 #383838 #383838}
+DIV.inew {BORDER-COLOR: #60C860 #54AF54 #499849 #59B657}
+
+/* 5.2 Class .tclcon is a div inside the first column of tables with post indicators. The
+margin creates space for the post status indicator */
+
+TD DIV.tclcon {MARGIN-LEFT: 2.3em}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/imports/Sulfur_cs.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,111 @@
+/****************************************************************/
+/* 1. BACKGROUND AND TEXT COLOURS */
+/****************************************************************/
+
+/* 1.1 Default background colour and text colour */
+
+BODY {BACKGROUND-COLOR: #FFF}
+
+.pun {COLOR: #333}
+
+DIV.box, .pun BLOCKQUOTE, DIV.codebox, #adminconsole FIELDSET TH, .rowodd, .roweven {BACKGROUND-COLOR: #F1F1F1}
+#adminconsole TD, #adminconsole TH {BORDER-COLOR: #F1F1F1}
+
+/* 1. 2 Darker background colours */
+
+TD.tc2, TD.tc3, TD.tcmod, #postpreview, #viewprofile DD, DIV.forminfo,
+#adminconsole FIELDSET TD, DIV.blockmenu DIV.box, #adstats DD {BACKGROUND-COLOR: #DEDFDF}
+
+/* 1.3 Main headers and navigation bar background and text colour */
+
+.pun H2, #brdmenu {BACKGROUND-COLOR: #B84623; COLOR: #FFF}
+
+/* 1.4 Table header rows */
+
+.pun TH {BACKGROUND-COLOR: #D1D1D1}
+
+/* 1.5 Fieldset legend text colour */
+
+.pun LEGEND {COLOR: #822100}
+
+/* 1.6 Highlighted text for various items */
+
+.pun DIV.blockmenu LI.isactive A, #posterror LI STRONG {COLOR: #333}
+
+/****************************************************************/
+/* 2. POST BACKGROUNDS AND TEXT */
+/****************************************************************/
+
+/* 2.1 This is the setup for posts. */
+
+DIV.blockpost DIV.box, DIV.postright, DIV.postfootright {BACKGROUND-COLOR: #DEDFDF}
+DIV.postright, DIV.postfootright {BORDER-LEFT-COLOR: #F1F1F1}
+DIV.postleft, DIV.postfootleft, DIV.blockpost LABEL {BACKGROUND-COLOR: #F1F1F1}
+
+/* 2.2 Background for post headers and text colour for post numbers in viewtopic */
+
+DIV.blockpost H2 {BACKGROUND-COLOR: #D25028}
+DIV.blockpost H2 SPAN.conr {COLOR: #FCCFC1}
+
+/* 2.3 This is the line above the signature in posts. Colour and background should be the same */
+
+.pun HR {BACKGROUND-COLOR: #333; COLOR: #333}
+
+/****************************************************************/
+/* 3. BORDER COLOURS */
+/****************************************************************/
+
+/* 3.1 All external borders */
+
+DIV.box {BORDER-COLOR: #B84623}
+
+/* 3.2 Makes the top border of posts match the colour used for post headers */
+
+DIV.blockpost DIV.box {BORDER-COLOR: #D25028 #B84623 #B84623}
+
+/* 3.3 Table internal borders. By default TH is same as background so border is invisible */
+
+.pun TD {BORDER-COLOR: #E1C3C3}
+.pun TH {BORDER-COLOR: #D1D1D1}
+
+/* 3.4 Creates the inset border for quote boxes, code boxes and form info boxes */
+
+.pun BLOCKQUOTE, DIV.codebox, DIV.forminfo, DIV.blockpost LABEL {BORDER-COLOR: #ACA899 #FFF #FFF #ACA899}
+
+/* 3.5 Gecko's default fieldset borders are really nasty so this gives them a colour
+without interferring with IE's rather nice default */
+
+.pun DIV>FIELDSET {BORDER-COLOR: #ACA899}
+
+/****************************************************************/
+/* 4. LINK COLOURS */
+/****************************************************************/
+
+/* 4.1 This is the default for all links */
+
+.pun A:link, .pun A:visited {COLOR: #822100}
+.pun A:hover {COLOR: #CA3300}
+
+/* 4.2 This is the colour for links in header rows and the navigation bar */
+
+.pun H2 A:link, .pun H2 A:visited, #brdmenu A:link, #brdmenu A:visited {COLOR: #FFF}
+.pun H2 A:hover, #brdmenu A:hover {COLOR: #FFF}
+
+/* 4.3 This is for closed topics and "hot" links */
+
+LI.postreport A:link, LI.postreport A:visited, TR.iclosed TD.tcl A:link, TR.iclosed TD.tcl A:visited {COLOR: #888}
+LI.postreport A:hover, TR.iclosed TD.tcl A:hover {COLOR: #AAA}
+LI.maintenancelink A:link, LI.maintenancelink A:visited {COLOR: #B42000}
+LI.maintenancelink A:hover {COLOR: #B42000}
+
+/****************************************************************/
+/* 5. POST STATUS INDICATORS */
+/****************************************************************/
+
+/* These are the post status indicators which appear at the left of some tables. 
+.inew = new posts, .iredirect = redirect forums, .iclosed = closed topics and
+.isticky = sticky topics. The default is "icon". By default only .inew is different.*/
+
+DIV.icon {BORDER-COLOR: #E6E6E6 #DEDEDE #DADADA #E2E2E2}
+TR.iredirect DIV.icon {BORDER-COLOR: #F1F1F1 #F1F1F1 #F1F1F1 #F1F1F1}
+DIV.inew {BORDER-COLOR: #C23000 #AF2C00 #992600 #AC2B00}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/imports/base.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,273 @@
+/****************************************************************/
+/* 1. INITIAL SETTINGS */
+/****************************************************************/
+
+.pun TABLE, .pun DIV, .pun FORM, .pun P, .pun H1, .pun H2, .pun H3,
+.pun H4, .pun PRE, .pun BLOCKQUOTE, .pun UL, .pun OL, .pun LI, .pun DL,
+.pun DT, .pun DD, .pun TH, .pun TD, .pun FIELDSET, .pun IMG {
+	MARGIN: 0px;
+	PADDING: 0px;
+	FONT-WEIGHT: normal;
+	LIST-STYLE: none;
+}
+
+.pun IMG {BORDER: none}
+
+.pun INPUT, .pun SELECT, .pun TEXTAREA, .pun OPTGROUP {MARGIN: 0}
+
+/****************************************************************/
+/* 2. STRUCTURAL SETTINGS - VERY IMPORTANT - DO NOT CHANGE */
+/****************************************************************/
+
+/* 2.1 Clearing floats and invisible items */
+.pun .clearer, .pun .nosize {
+	HEIGHT: 0;
+	WIDTH: 0;
+	LINE-HEIGHT: 0;
+	FONT-SIZE: 0;
+	OVERFLOW: hidden
+}
+
+.pun .clearer, .pun .clearb {CLEAR: both}
+.pun .nosize {POSITION: absolute; LEFT: -10000px}
+
+/* 2.2 Overflow settings for posts */
+
+DIV.blockpost DIV.box, DIV.postleft, DIV.postsignature, DIV.postmsg {OVERFLOW: hidden}
+
+/****************************************************************/
+/* 3. BUG FIXES - VERY IMPORTANT - DO NOT CHANGE */
+/****************************************************************/
+
+/* 3.1 This attempts to eliminate rounding errors in Gecko browsers. */
+
+DIV>DIV>DIV.postfootleft, DIV>DIV>DIV.postfootright {PADDING-TOP: 1px; MARGIN-TOP: -1px}
+
+/* 3.2 This is only visible to IE6 Windows and cures various bugs. Do not alter comments */
+
+/* Begin IE6Win Fix \*/
+* HTML .inbox, * HTML .inform, * HTML .pun, * HTML .intd, * HTML .tclcon {HEIGHT: 1px}
+* HTML .inbox DIV.postmsg {WIDTH: 98%}
+/* End of IE6Win Fix */
+
+/* 3.3 This is the equivelant of 3.2 but for IE7. It is visible to other browsers
+but does no harm */
+
+/*Begin IE7Win Fix */
+.pun, .pun .inbox, .pun .inform, .pun .intd, .pun .tclcon {min-height: 1px}
+/* End of IE7Win Fix */
+
+/****************************************************************/
+/* 4. HIDDEN ELEMENTS */
+/****************************************************************/
+
+/* These are hidden in normal display. Add comments to make them visible */
+
+#brdfooter H2, #brdstats H2, #brdstats .conl DT, #brdstats .conr DT,
+#modcontrols DT, #searchlinks DT, DIV.postright H3 {
+	POSITION: absolute;
+	DISPLAY: block;
+	OVERFLOW: hidden;
+	WIDTH: 1em;
+	LEFT: -999em
+}
+
+/****************************************************************/
+/* 5. BOX CONTAINERS AND FLOATS */
+/****************************************************************/
+
+/* 5.1. Setup all left and right content using floats. */  
+
+.conr {
+	FLOAT: right;
+	TEXT-ALIGN: right;
+	CLEAR: right;
+	WIDTH: 40%
+}
+
+.conl {
+	FLOAT: left;
+	WIDTH: 55%;
+	OVERFLOW: hidden;
+	WHITE-SPACE: nowrap
+}
+
+LABEL.conl {
+	WIDTH: auto;
+	OVERFLOW: visible;
+	MARGIN-RIGHT: 10px
+}
+
+/* 5.2 Set up page numbering and posts links */
+
+DIV.linkst .conl, DIV.linksb .conl, DIV.postlinksb .conl {WIDTH:18em}
+
+DIV.linkst .conr, DIV.linksb .conr, DIV.postlinksb .conr {WIDTH:16em}
+
+FORM DIV.linksb .conr {WIDTH: 32em}
+
+/* 5.3 Keep breadcrumbs from shifting to the right when wrapping */
+
+.linkst UL, linksb UL, .postlinksb UL {MARGIN-LEFT: 18em}
+
+/* 5.4 Settings for Profile and Admin interface.*/
+
+DIV.block2col {PADDING-BOTTOM: 1px}
+
+DIV.block2col DIV.blockform, DIV.block2col DIV.block, #viewprofile DD {MARGIN-LEFT: 14em}
+
+DIV.blockmenu, #viewprofile DT {
+	FLOAT:left;
+	WIDTH: 13em
+}
+
+#profileavatar IMG {
+	FLOAT: right;
+	MARGIN-LEFT: 1em
+}
+
+#viewprofile DL {FLOAT: left; WIDTH: 100%; OVERFLOW: hidden}
+
+/****************************************************************/
+/* 6. TABLE SETUP */
+/****************************************************************/
+
+/* 6.1 Table Basic Setup */
+
+.pun TABLE {WIDTH: 100%}
+
+/* 6.2 Fixed Table Setup */
+
+#punindex TABLE, #vf TABLE {TABLE-LAYOUT: fixed}
+
+.tcl {TEXT-ALIGN: left; WIDTH: 50%}
+
+.tc2, .tc3, .tcmod {WIDTH: 9%; TEXT-ALIGN: center}
+
+.tcr {WIDTH: 32%; TEXT-ALIGN: left}
+
+#punsearch #vf .tcl, #punmoderate #vf .tcl {WIDTH: 41%}
+
+#punsearch #vf .tc2 {WIDTH: 18%; TEXT-ALIGN: left}
+
+.tcl, .tcr {OVERFLOW: HIDDEN}
+
+/* 6.3 Other Table Setup */
+
+#users1 .tcl {WIDTH: 40%}
+
+#users1 .tcr {WIDTH: 25%}
+
+#users1 .tc2 {WIDTH: 25%; TEXT-ALIGN: left}
+
+#users1 .tc3 {WIDTH: 10%; TEXT-ALIGN: center}
+
+#debug .tcr {WIDTH: 85%; WHITE-SPACE: normal}
+
+#punindex TD.tcr SPAN.byuser {DISPLAY: block}
+
+/****************************************************************/
+/* 7. VIEWTOPIC SETUP */
+/****************************************************************/
+
+/* 7.1 This is the basic structure. */
+
+DIV.postleft, DIV.postfootleft {
+	FLOAT:left;
+	WIDTH: 18em;
+	OVERFLOW: hidden;
+	POSITION: relative;
+}
+	
+DIV.postright, DIV.postfootright {
+	BORDER-LEFT-WIDTH: 18em;
+	BORDER-LEFT-STYLE: solid
+}
+
+DIV.postfootright, P.multidelete {TEXT-ALIGN: right}
+
+DIV.blockpost>DIV>DIV.inbox {PADDING-BOTTOM: 1px}
+
+/* 7.3 This is the div which actually contains the post and is inside .postright */
+
+DIV.postmsg {WIDTH:100%}
+
+/* 7.4 These items control overflow and scrolling within posts. */
+
+DIV.incqbox {WIDTH: 100%; OVERFLOW: hidden}
+DIV.scrollbox {WIDTH: 100%; OVERFLOW: auto}
+IMG.postimg {max-width: 100%}
+A .postimg {max-width: 100%}
+
+/* 7.5 Turn off the poster information column for preview */
+
+#postpreview DIV.postright {BORDER-LEFT: none}
+
+/* 7.6 Create the horizontal line above signatures */
+
+DIV.postsignature HR {
+	MARGIN-LEFT: 0px;
+	WIDTH: 200px;
+	TEXT-ALIGN: left;
+	HEIGHT: 1px;
+	BORDER:none
+}
+
+/* 7.7 Maximum height for search results as posts. Position go to post link */
+
+DIV.searchposts DIV.postmsg {HEIGHT: 8em}
+DIV.searchposts DD P {PADDING-TOP: 3em}
+
+/* 7.8 Class for bbcode [u] */
+
+SPAN.bbu {TEXT-DECORATION: underline}
+
+/****************************************************************/
+/* 8. LISTS SPECIAL SETTINGS */
+/****************************************************************/
+
+/* 8.1 Horizontal display of online list, main navigation menu and breadcrumbs */
+
+#onlinelist DD, #onlinelist DT, #brdmenu LI, DIV.linkst LI, DIV.linksb LI, DIV.postlinksb LI,
+DIV.postfootright LI, UL.bblinks LI {
+	DISPLAY: inline;
+	HEIGHT: 0
+}
+
+/* 8.2 Turn on square icon for posterror list */
+
+#posterror UL LI {LIST-STYLE: square inside}
+
+/* 8.3 Right alignment of descriptions in ordinary member view of other members profiles */
+
+#viewprofile DT {TEXT-ALIGN: right}
+
+/****************************************************************/
+/* 9. FORM SETTINGS */
+/****************************************************************/
+
+/* 9.1 Makes textareas and long text inputs shrink with page */
+
+DIV.txtarea {WIDTH: 75%}
+
+DIV.txtarea TEXTAREA, INPUT.longinput {WIDTH: 100%}
+
+.pun LABEL {DISPLAY: block}
+
+#qjump SELECT {WIDTH: 50%}
+
+/****************************************************************/
+/* 10. HELP FILES AND MISC. */
+/****************************************************************/
+
+/* 10.1 Put some space between sections of the help file */
+
+#helpfile H2 {MARGIN-TOP: 12px}
+
+/* 10.2 Internal padding */
+
+#helpfile DIV.box {PADDING: 10px}
+
+/* 10.3 Other templates */
+
+#punredirect DIV.block, #punmaint DIV.block {MARGIN: 50px 20% 12px 20%}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/imports/base_admin.css	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,45 @@
+#adminconsole .block2 {MARGIN-TOP: 12px}
+
+/*** Admin Main Content ***/
+* HTML #adstats DD {HEIGHT: 1%}
+#adstats DD {MARGIN-LEFT: 14em; PADDING: 3px; MARGIN-BOTTOM: 5px; LINE-HEIGHT: 1.5em}
+#adstats DT {FLOAT:left; WIDTH: 13em; PADDING: 3px; line-height: 1.5em}
+#adstats {PADDING: 15px 15px 5px 10px}
+#adintro {PADDING: 5px}
+#adintro P {PADDING: 10px}
+#adstats DL {PADDING: 5px 0 10px 5px}
+
+#adminconsole FIELDSET TD {TEXT-ALIGN: left; PADDING: 4px; WHITE-SPACE: normal}
+#adminconsole FIELDSET TH {TEXT-ALIGN: left; PADDING: 4px; WHITE-SPACE: normal}
+#adminconsole FIELDSET TD SPAN, #adminconsole FIELDSET TH SPAN {DISPLAY: block; FONT-SIZE: 1em; FONT-WEIGHT: normal}
+#adminconsole TH {WIDTH: 15em; FONT-WEIGHT: bold}
+#adminconsole INPUT, #adminconsole SELECT, #adminconsole TEXTAREA {MARGIN-BOTTOM: 0; MARGIN-TOP: 0; FONT-WEIGHT: normal}
+#adminconsole TABLE.aligntop TH, #adminconsole TABLE.aligntop TD {VERTICAL-ALIGN: top}
+#adminconsole TABLE.aligntop TH {PADDING-TOP: 0.7em}
+#adminconsole TD, #adminconsole TH {BORDER-STYLE: solid; BORDER-WIDTH: 3px 0px 3px 0px}
+#adminconsole P {PADDING-BOTTOM: 6px}
+#adminconsole .topspace {PADDING-TOP: 6px}
+#adminconsole P.submittop, #adminconsole P.submitend {TEXT-ALIGN: center}
+#adminconsole TH.hidehead {COLOR: #f1f1f1}
+#adminconsole THEAD TH {PADDING-BOTTOM: 0px}
+#adminconsole P.linkactions {FONT-WEIGHT: bold; PADDING-LEFT: 5px}
+#adminconsole TH INPUT, #adminconsole DIV.fsetsubmit {MARGIN-TOP: 6px}
+
+/*** Particular table settings ***/
+#categoryedit .tcl {WIDTH: 25%}
+#censoring .tcl, #censoring .tc2, #ranks .tcl, #ranks .tc2 {WIDTH: 20%}
+TABLE#forumperms TH, TABLE#forumperms TD {WHITE-SPACE: normal; WIDTH: auto; TEXT-ALIGN: center}
+TABLE#forumperms .atcl {TEXT-ALIGN: left; WIDTH: 15em; WHITE-SPACE: nowrap}
+#adminconsole TD.nodefault {BACKGROUND-COLOR: #D59B9B}
+
+/*** User Search Result Tables ***/
+#users2 TH, #users2 TH {TEXT-ALIGN: left}
+#users2 .tcl, #users2 .tc3, #users2 .tc5 {WIDTH: 15%; TEXT-ALIGN: left}
+#users2 .tc2 {WIDTH: 22%; TEXT-ALIGN: left}
+#users2 .tc4 {WIDTH: 8%}
+#users2 .tc4 {TEXT-ALIGN: center}
+#users2 .tcr {WHITE-SPACE: nowrap}
+#adminconsole #linkst, #adminconsole #linksb A {FONT-WEIGHT: bold}
+
+/*** Plugins ***/
+#exampleplugin .inbox {PADDING: 6px 6px 0px 6px}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/imports/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/imports/minmax.js	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,84 @@
+// minmax.js - written by Andrew Clover <and@doxdesk.com>
+// Adapted for PunBB by Rickard Andersson and Paul Sullivan
+
+/*@cc_on
+@if (@_win32 && @_jscript_version>4)
+
+var minmax_elements;
+
+function minmax_bind(el) {
+	var em, ms;
+	var st= el.style, cs= el.currentStyle;
+
+	if (minmax_elements==window.undefined) {
+		if (!document.body || !document.body.currentStyle) return;
+		minmax_elements= new Array();
+		window.attachEvent('onresize', minmax_delayout);
+	}
+
+	if (cs['max-width'])
+		st['maxWidth']= cs['max-width'];
+
+	ms= cs['maxWidth'];
+	if (ms && ms!='auto' && ms!='none' && ms!='0' && ms!='') {
+		st.minmaxWidth= cs.width;
+		minmax_elements[minmax_elements.length]= el;
+		minmax_delayout();
+	}
+}
+
+var minmax_delaying= false;
+function minmax_delayout() {
+	if (minmax_delaying) return;
+	minmax_delaying= true;
+	window.setTimeout(minmax_layout, 0);
+}
+
+function minmax_stopdelaying() {
+	minmax_delaying= false;
+}
+
+function minmax_layout() {
+	window.setTimeout(minmax_stopdelaying, 100);
+	var i, el, st, cs, optimal, inrange;
+	for (i= minmax_elements.length; i-->0;) {
+		el= minmax_elements[i]; st= el.style; cs= el.currentStyle;
+
+		st.width= st.minmaxWidth; optimal= el.offsetWidth;
+		inrange= true;
+		if (inrange && cs.minWidth && cs.minWidth!='0' && cs.minWidth!='auto' && cs.minWidth!='') {
+			st.width= cs.minWidth;
+			inrange= (el.offsetWidth<optimal);
+		}
+		if (inrange && cs.maxWidth && cs.maxWidth!='none' && cs.maxWidth!='auto' && cs.maxWidth!='') {
+			st.width= cs.maxWidth;
+			inrange= (el.offsetWidth>optimal);
+		}
+		if (inrange) st.width= st.minmaxWidth;
+	}
+}
+
+var minmax_SCANDELAY= 500;
+
+function minmax_scan() {
+	var el;
+	for (var i= 0; i<document.all.length; i++) {
+		el= document.all[i];
+		if (!el.minmax_bound) {
+			el.minmax_bound= true;
+			minmax_bind(el);
+		}
+	}
+}
+
+var minmax_scanner;
+function minmax_stop() {
+	window.clearInterval(minmax_scanner);
+	minmax_scan();
+}
+
+minmax_scan();
+minmax_scanner= window.setInterval(minmax_scan, minmax_SCANDELAY);
+window.attachEvent('onload', minmax_stop);
+
+@end @*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/style/index.html	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,8 @@
+<html>
+<head>
+<title>.</title>
+</head>
+<body>
+.
+</body>
+</html>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/userlist.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,193 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+if ($pun_user['g_read_board'] == '0')
+	message($lang_common['No view']);
+
+
+// Load the userlist.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/userlist.php';
+
+// Load the search.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/search.php';
+
+
+// Determine if we are allowed to view post counts
+$show_post_count = ($pun_config['o_show_post_count'] == '1' || $pun_user['g_id'] < PUN_GUEST) ? true : false;
+
+$username = (isset($_GET['username']) && $pun_user['g_search_users'] == '1') ? pun_trim($_GET['username']) : '';
+$show_group = (!isset($_GET['show_group']) || intval($_GET['show_group']) < -1 && intval($_GET['show_group']) > 2) ? -1 : intval($_GET['show_group']);
+$sort_by = (!isset($_GET['sort_by']) || $_GET['sort_by'] != 'username' && $_GET['sort_by'] != 'registered' && ($_GET['sort_by'] != 'num_posts' || !$show_post_count)) ? 'username' : $_GET['sort_by'];
+$sort_dir = (!isset($_GET['sort_dir']) || $_GET['sort_dir'] != 'ASC' && $_GET['sort_dir'] != 'DESC') ? 'ASC' : strtoupper($_GET['sort_dir']);
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title']).' / '.$lang_common['User list'];
+if ($pun_user['g_search_users'] == '1')
+	$focus_element = array('userlist', 'username');
+
+define('PUN_ALLOW_INDEX', 1);
+require PUN_ROOT.'header.php';
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_search['User search'] ?></span></h2>
+	<div class="box">
+	<form id="userlist" method="get" action="userlist.php">
+		<div class="inform">
+			<fieldset>
+				<legend><?php echo $lang_ul['User find legend'] ?></legend>
+				<div class="infldset">
+<?php if ($pun_user['g_search_users'] == '1'): ?>					<label class="conl"><?php echo $lang_common['Username'] ?><br /><input type="text" name="username" value="<?php echo pun_htmlspecialchars($username) ?>" size="25" maxlength="25" /><br /></label>
+<?php endif; ?>					<label class="conl"><?php echo $lang_ul['User group']."\n" ?>
+					<br /><select name="show_group">
+						<option value="-1"<?php if ($show_group == -1) echo ' selected="selected"' ?>><?php echo $lang_ul['All users'] ?></option>
+<?php
+
+$result = $db->query('SELECT g_id, g_title FROM '.$db->prefix.'groups WHERE g_id!='.PUN_GUEST.' ORDER BY g_id') or error('Unable to fetch user group list', __FILE__, __LINE__, $db->error());
+
+while ($cur_group = $db->fetch_assoc($result))
+{
+	if ($cur_group['g_id'] == $show_group)
+		echo "\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'" selected="selected">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+	else
+		echo "\t\t\t\t\t\t".'<option value="'.$cur_group['g_id'].'">'.pun_htmlspecialchars($cur_group['g_title']).'</option>'."\n";
+}
+
+?>
+					</select>
+					<br /></label>
+					<label class="conl"><?php echo $lang_search['Sort by']."\n" ?>
+					<br /><select name="sort_by">
+						<option value="username"<?php if ($sort_by == 'username') echo ' selected="selected"' ?>><?php echo $lang_common['Username'] ?></option>
+						<option value="registered"<?php if ($sort_by == 'registered') echo ' selected="selected"' ?>><?php echo $lang_common['Registered'] ?></option>
+<?php if ($show_post_count): ?>						<option value="num_posts"<?php if ($sort_by == 'num_posts') echo ' selected="selected"' ?>><?php echo $lang_ul['No of posts'] ?></option>
+<?php endif; ?>					</select>
+					<br /></label>
+					<label class="conl"><?php echo $lang_search['Sort order']."\n" ?>
+					<br /><select name="sort_dir">
+						<option value="ASC"<?php if ($sort_dir == 'ASC') echo ' selected="selected"' ?>><?php echo $lang_search['Ascending'] ?></option>
+						<option value="DESC"<?php if ($sort_dir == 'DESC') echo ' selected="selected"' ?>><?php echo $lang_search['Descending'] ?></option>
+					</select>
+					<br /></label>
+					<p class="clearb"><?php echo $lang_ul['User search info'] ?></p>
+				</div>
+			</fieldset>
+		</div>
+		<p><input type="submit" name="search" value="<?php echo $lang_common['Submit'] ?>" accesskey="s" /></p>
+	</form>
+	</div>
+</div>
+<?php
+
+
+// Create any SQL for the WHERE clause
+$where_sql = array();
+$like_command = ($db_type == 'pgsql') ? 'ILIKE' : 'LIKE';
+
+if ($pun_user['g_search_users'] == '1' && $username != '')
+	$where_sql[] = 'u.username '.$like_command.' \''.$db->escape(str_replace('*', '%', $username)).'\'';
+if ($show_group > -1)
+	$where_sql[] = 'u.group_id='.$show_group;
+
+// Fetch user count
+$result = $db->query('SELECT COUNT(id) FROM '.$db->prefix.'users AS u WHERE u.id>1'.(!empty($where_sql) ? ' AND '.implode(' AND ', $where_sql) : '')) or error('Unable to fetch user list count', __FILE__, __LINE__, $db->error());
+$num_users = $db->result($result);
+
+
+// Determine the user offset (based on $_GET['p'])
+$num_pages = ceil($num_users / 50);
+
+$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p'];
+$start_from = 50 * ($p - 1);
+
+// Generate paging links
+$paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'userlist.php?username='.urlencode($username).'&amp;show_group='.$show_group.'&amp;sort_by='.$sort_by.'&amp;sort_dir='.strtoupper($sort_dir));
+
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<p class="pagelink"><?php echo $paging_links ?></p>
+	</div>
+</div>
+
+<div id="users1" class="blocktable">
+	<h2><span><?php echo $lang_common['User list'] ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+		<table cellspacing="0">
+		<thead>
+			<tr>
+				<th class="tcl" scope="col"><?php echo $lang_common['Username'] ?></th>
+				<th class="tc2" scope="col"><?php echo $lang_common['Title'] ?></th>
+<?php if ($show_post_count): ?>				<th class="tc3" scope="col"><?php echo $lang_common['Posts'] ?></th>
+<?php endif; ?>				<th class="tcr" scope="col"><?php echo $lang_common['Registered'] ?></th>
+			</tr>
+		</thead>
+		<tbody>
+<?php
+
+// Grab the users
+$result = $db->query('SELECT u.id, u.username, u.title, u.num_posts, u.registered, g.g_id, g.g_user_title FROM '.$db->prefix.'users AS u LEFT JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id WHERE u.id>1'.(!empty($where_sql) ? ' AND '.implode(' AND ', $where_sql) : '').' ORDER BY '.$sort_by.' '.$sort_dir.' LIMIT '.$start_from.', 50') or error('Unable to fetch user list', __FILE__, __LINE__, $db->error());
+if ($db->num_rows($result))
+{
+	while ($user_data = $db->fetch_assoc($result))
+	{
+		$user_title_field = get_title($user_data);
+
+?>
+				<tr>
+					<td class="tcl"><?php echo '<a href="profile.php?id='.$user_data['id'].'">'.pun_htmlspecialchars($user_data['username']).'</a>' ?></td>
+					<td class="tc2"><?php echo $user_title_field ?></td>
+<?php if ($show_post_count): ?>					<td class="tc3"><?php echo $user_data['num_posts'] ?></td>
+<?php endif; ?>
+					<td class="tcr"><?php echo format_time($user_data['registered'], true) ?></td>
+				</tr>
+<?php
+
+	}
+}
+else
+	echo "\t\t\t".'<tr>'."\n\t\t\t\t\t".'<td class="tcl" colspan="'.(($show_post_count) ? 4 : 3).'">'.$lang_search['No hits'].'</td></tr>'."\n";
+
+?>
+			</tbody>
+			</table>
+		</div>
+	</div>
+</div>
+
+<div class="linksb">
+	<div class="inbox">
+		<p class="pagelink"><?php echo $paging_links ?></p>
+	</div>
+</div>
+<?php
+
+require PUN_ROOT.'footer.php';
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/viewforum.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,256 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+if ($pun_user['g_read_board'] == '0')
+	message($lang_common['No view']);
+
+
+$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
+if ($id < 1)
+	message($lang_common['Bad request']);
+
+// Load the viewforum.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/forum.php';
+
+// Fetch some info about the forum
+$result = $db->query('SELECT f.forum_name, f.redirect_url, f.moderators, f.num_topics, f.sort_by, fp.post_topics FROM '.$db->prefix.'forums AS f LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND f.id='.$id) or error('Unable to fetch forum info', __FILE__, __LINE__, $db->error());
+if (!$db->num_rows($result))
+	message($lang_common['Bad request']);
+
+$cur_forum = $db->fetch_assoc($result);
+
+// Is this a redirect forum? In that case, redirect!
+if ($cur_forum['redirect_url'] != '')
+{
+	header('Location: '.$cur_forum['redirect_url']);
+	exit;
+}
+
+// Sort out who the moderators are and if we are currently a moderator (or an admin)
+$mods_array = array();
+if ($cur_forum['moderators'] != '')
+	$mods_array = unserialize($cur_forum['moderators']);
+
+$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && array_key_exists($pun_user['username'], $mods_array))) ? true : false;
+
+// Can we or can we not post new topics?
+if (($cur_forum['post_topics'] == '' && $pun_user['g_post_topics'] == '1') || $cur_forum['post_topics'] == '1' || $is_admmod)
+	$post_link = "\t\t".'<p class="postlink conr"><a href="post.php?fid='.$id.'">'.$lang_forum['Post topic'].'</a></p>'."\n";
+else
+	$post_link = '';
+
+
+// Determine the topic offset (based on $_GET['p'])
+$num_pages = ceil($cur_forum['num_topics'] / $pun_user['disp_topics']);
+
+$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p'];
+$start_from = $pun_user['disp_topics'] * ($p - 1);
+
+// Generate paging links
+$paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'viewforum.php?id='.$id);
+
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title'].' / '.$cur_forum['forum_name']);
+define('PUN_ALLOW_INDEX', 1);
+require PUN_ROOT.'header.php';
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<p class="pagelink conl"><?php echo $paging_links ?></p>
+<?php echo $post_link ?>
+		<ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a>&nbsp;</li><li>&raquo;&nbsp;<?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?></li></ul>
+		<div class="clearer"></div>
+	</div>
+</div>
+
+<div id="vf" class="blocktable">
+	<h2><span><?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<table cellspacing="0">
+			<thead>
+				<tr>
+					<th class="tcl" scope="col"><?php echo $lang_common['Topic'] ?></th>
+					<th class="tc2" scope="col"><?php echo $lang_common['Replies'] ?></th>
+					<th class="tc3" scope="col"><?php echo $lang_forum['Views'] ?></th>
+					<th class="tcr" scope="col"><?php echo $lang_common['Last post'] ?></th>
+				</tr>
+			</thead>
+			<tbody>
+<?php
+
+// Fetch list of topics to display on this page
+if ($pun_user['is_guest'] || $pun_config['o_show_dot'] == '0')
+{
+	// Without "the dot"
+	$sql = 'SELECT id, poster, subject, posted, last_post, last_post_id, last_poster, num_views, num_replies, closed, sticky, moved_to FROM '.$db->prefix.'topics WHERE forum_id='.$id.' ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics'];
+}
+else
+{
+	// With "the dot"
+	switch ($db_type)
+	{
+		case 'mysql':
+		case 'mysqli':
+			$sql = 'SELECT p.poster_id AS has_posted, t.id, t.subject, t.poster, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_views, t.num_replies, t.closed, t.sticky, t.moved_to FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id AND p.poster_id='.$pun_user['id'].' WHERE t.forum_id='.$id.' GROUP BY t.id ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics'];
+			break;
+
+		case 'sqlite':
+			$sql = 'SELECT p.poster_id AS has_posted, t.id, t.subject, t.poster, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_views, t.num_replies, t.closed, t.sticky, t.moved_to FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id AND p.poster_id='.$pun_user['id'].' WHERE t.id IN(SELECT id FROM '.$db->prefix.'topics WHERE forum_id='.$id.' ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics'].') GROUP BY t.id ORDER BY t.sticky DESC, t.last_post DESC';
+			break;
+
+		default:
+			$sql = 'SELECT p.poster_id AS has_posted, t.id, t.subject, t.poster, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_views, t.num_replies, t.closed, t.sticky, t.moved_to FROM '.$db->prefix.'topics AS t LEFT JOIN '.$db->prefix.'posts AS p ON t.id=p.topic_id AND p.poster_id='.$pun_user['id'].' WHERE t.forum_id='.$id.' GROUP BY t.id, t.subject, t.poster, t.posted, t.last_post, t.last_post_id, t.last_poster, t.num_views, t.num_replies, t.closed, t.sticky, t.moved_to, p.poster_id ORDER BY sticky DESC, '.(($cur_forum['sort_by'] == '1') ? 'posted' : 'last_post').' DESC LIMIT '.$start_from.', '.$pun_user['disp_topics'];
+			break;
+
+	}
+}
+
+$result = $db->query($sql) or error('Unable to fetch topic list', __FILE__, __LINE__, $db->error());
+
+// If there are topics in this forum.
+if ($db->num_rows($result))
+{
+	while ($cur_topic = $db->fetch_assoc($result))
+	{
+		$icon_text = $lang_common['Normal icon'];
+		$item_status = '';
+		$icon_type = 'icon';
+
+		if ($cur_topic['moved_to'] == null)
+			$last_post = '<a href="viewtopic.php?pid='.$cur_topic['last_post_id'].'#p'.$cur_topic['last_post_id'].'">'.format_time($cur_topic['last_post']).'</a> <span class="byuser">'.$lang_common['by'].'&nbsp;'.pun_htmlspecialchars($cur_topic['last_poster']).'</span>';
+		else
+			$last_post = '&nbsp;';
+
+		if ($pun_config['o_censoring'] == '1')
+			$cur_topic['subject'] = censor_words($cur_topic['subject']);
+
+		if ($cur_topic['moved_to'] != 0)
+			$subject = $lang_forum['Moved'].': <a href="viewtopic.php?id='.$cur_topic['moved_to'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span class="byuser">'.$lang_common['by'].'&nbsp;'.pun_htmlspecialchars($cur_topic['poster']).'</span>';
+		else if ($cur_topic['closed'] == '0')
+			$subject = '<a href="viewtopic.php?id='.$cur_topic['id'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span class="byuser">'.$lang_common['by'].'&nbsp;'.pun_htmlspecialchars($cur_topic['poster']).'</span>';
+		else
+		{
+			$subject = '<a href="viewtopic.php?id='.$cur_topic['id'].'">'.pun_htmlspecialchars($cur_topic['subject']).'</a> <span class="byuser">'.$lang_common['by'].'&nbsp;'.pun_htmlspecialchars($cur_topic['poster']).'</span>';
+			$icon_text = $lang_common['Closed icon'];
+			$item_status = 'iclosed';
+		}
+
+		if (!$pun_user['is_guest'] && $cur_topic['last_post'] > $pun_user['last_visit'] && $cur_topic['moved_to'] == null)
+		{
+			$icon_text .= ' '.$lang_common['New icon'];
+			$item_status .= ' inew';
+			$icon_type = 'icon inew';
+			$subject = '<strong>'.$subject.'</strong>';
+			$subject_new_posts = '<span class="newtext">[&nbsp;<a href="viewtopic.php?id='.$cur_topic['id'].'&amp;action=new" title="'.$lang_common['New posts info'].'">'.$lang_common['New posts'].'</a>&nbsp;]</span>';
+		}
+		else
+			$subject_new_posts = null;
+
+		// Should we display the dot or not? :)
+		if (!$pun_user['is_guest'] && $pun_config['o_show_dot'] == '1')
+		{
+			if ($cur_topic['has_posted'] == $pun_user['id'])
+				$subject = '<strong>&middot;</strong>&nbsp;'.$subject;
+			else
+				$subject = '&nbsp;&nbsp;'.$subject;
+		}
+
+		if ($cur_topic['sticky'] == '1')
+		{
+			$subject = '<span class="stickytext">'.$lang_forum['Sticky'].': </span>'.$subject;
+			$item_status .= ' isticky';
+			$icon_text .= ' '.$lang_forum['Sticky'];
+		}
+
+		$num_pages_topic = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']);
+
+		if ($num_pages_topic > 1)
+			$subject_multipage = '[ '.paginate($num_pages_topic, -1, 'viewtopic.php?id='.$cur_topic['id']).' ]';
+		else
+			$subject_multipage = null;
+
+		// Should we show the "New posts" and/or the multipage links?
+		if (!empty($subject_new_posts) || !empty($subject_multipage))
+		{
+			$subject .= '&nbsp; '.(!empty($subject_new_posts) ? $subject_new_posts : '');
+			$subject .= !empty($subject_multipage) ? ' '.$subject_multipage : '';
+		}
+
+?>
+				<tr<?php if ($item_status != '') echo ' class="'.trim($item_status).'"'; ?>>
+					<td class="tcl">
+						<div class="intd">
+							<div class="<?php echo $icon_type ?>"><div class="nosize"><?php echo trim($icon_text) ?></div></div>
+							<div class="tclcon">
+								<?php echo $subject."\n" ?>
+							</div>
+						</div>
+					</td>
+					<td class="tc2"><?php echo ($cur_topic['moved_to'] == null) ? $cur_topic['num_replies'] : '&nbsp;' ?></td>
+					<td class="tc3"><?php echo ($cur_topic['moved_to'] == null) ? $cur_topic['num_views'] : '&nbsp;' ?></td>
+					<td class="tcr"><?php echo $last_post ?></td>
+				</tr>
+<?php
+
+	}
+}
+else
+{
+
+?>
+				<tr>
+					<td class="tcl" colspan="4"><?php echo $lang_forum['Empty forum'] ?></td>
+				</tr>
+<?php
+
+}
+
+?>
+			</tbody>
+			</table>
+		</div>
+	</div>
+</div>
+
+<div class="linksb">
+	<div class="inbox">
+		<p class="pagelink conl"><?php echo $paging_links ?></p>
+<?php echo $post_link ?>
+		<ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a>&nbsp;</li><li>&raquo;&nbsp;<?php echo pun_htmlspecialchars($cur_forum['forum_name']) ?></li></ul>
+		<div class="clearer"></div>
+	</div>
+</div>
+<?php
+
+$forum_id = $id;
+$footer_style = 'viewforum';
+require PUN_ROOT.'footer.php';
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/punbb/viewtopic.php	Wed Jul 11 21:01:48 2007 -0400
@@ -0,0 +1,395 @@
+<?php
+/***********************************************************************
+
+  Copyright (C) 2002-2005  Rickard Andersson (rickard@punbb.org)
+
+  This file is part of PunBB.
+
+  PunBB is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published
+  by the Free Software Foundation; either version 2 of the License,
+  or (at your option) any later version.
+
+  PunBB is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+  MA  02111-1307  USA
+
+************************************************************************/
+
+
+define('PUN_ROOT', './');
+require PUN_ROOT.'include/common.php';
+
+
+if ($pun_user['g_read_board'] == '0')
+	message($lang_common['No view']);
+
+
+$action = isset($_GET['action']) ? $_GET['action'] : null;
+$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
+$pid = isset($_GET['pid']) ? intval($_GET['pid']) : 0;
+if ($id < 1 && $pid < 1)
+	message($lang_common['Bad request']);
+
+// Load the viewtopic.php language file
+require PUN_ROOT.'lang/'.$pun_user['language'].'/topic.php';
+
+
+// If a post ID is specified we determine topic ID and page number so we can redirect to the correct message
+if ($pid)
+{
+	$result = $db->query('SELECT topic_id FROM '.$db->prefix.'posts WHERE id='.$pid) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+	if (!$db->num_rows($result))
+		message($lang_common['Bad request']);
+
+	$id = $db->result($result);
+
+	// Determine on what page the post is located (depending on $pun_user['disp_posts'])
+	$result = $db->query('SELECT id FROM '.$db->prefix.'posts WHERE topic_id='.$id.' ORDER BY posted') or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+	$num_posts = $db->num_rows($result);
+
+	for ($i = 0; $i < $num_posts; ++$i)
+	{
+		$cur_id = $db->result($result, $i);
+		if ($cur_id == $pid)
+			break;
+	}
+	++$i;	// we started at 0
+
+	$_GET['p'] = ceil($i / $pun_user['disp_posts']);
+}
+
+// If action=new, we redirect to the first new post (if any)
+else if ($action == 'new' && !$pun_user['is_guest'])
+{
+	$result = $db->query('SELECT MIN(id) FROM '.$db->prefix.'posts WHERE topic_id='.$id.' AND posted>'.$pun_user['last_visit']) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+	$first_new_post_id = $db->result($result);
+
+	if ($first_new_post_id)
+		header('Location: viewtopic.php?pid='.$first_new_post_id.'#p'.$first_new_post_id);
+	else	// If there is no new post, we go to the last post
+		header('Location: viewtopic.php?id='.$id.'&action=last');
+
+	exit;
+}
+
+// If action=last, we redirect to the last post
+else if ($action == 'last')
+{
+	$result = $db->query('SELECT MAX(id) FROM '.$db->prefix.'posts WHERE topic_id='.$id) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+	$last_post_id = $db->result($result);
+
+	if ($last_post_id)
+	{
+		header('Location: viewtopic.php?pid='.$last_post_id.'#p'.$last_post_id);
+		exit;
+	}
+}
+
+
+// Fetch some info about the topic
+if (!$pun_user['is_guest'])
+	$result = $db->query('SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, s.user_id AS is_subscribed FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'subscriptions AS s ON (t.id=s.topic_id AND s.user_id='.$pun_user['id'].') LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
+else
+	$result = $db->query('SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, 0 FROM '.$db->prefix.'topics AS t INNER JOIN '.$db->prefix.'forums AS f ON f.id=t.forum_id LEFT JOIN '.$db->prefix.'forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id='.$pun_user['g_id'].') WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id='.$id.' AND t.moved_to IS NULL') or error('Unable to fetch topic info', __FILE__, __LINE__, $db->error());
+
+if (!$db->num_rows($result))
+	message($lang_common['Bad request']);
+
+$cur_topic = $db->fetch_assoc($result);
+
+// Sort out who the moderators are and if we are currently a moderator (or an admin)
+$mods_array = ($cur_topic['moderators'] != '') ? unserialize($cur_topic['moderators']) : array();
+$is_admmod = ($pun_user['g_id'] == PUN_ADMIN || ($pun_user['g_id'] == PUN_MOD && array_key_exists($pun_user['username'], $mods_array))) ? true : false;
+
+// Can we or can we not post replies?
+if ($cur_topic['closed'] == '0')
+{
+	if (($cur_topic['post_replies'] == '' && $pun_user['g_post_replies'] == '1') || $cur_topic['post_replies'] == '1' || $is_admmod)
+		$post_link = '<a href="post.php?tid='.$id.'">'.$lang_topic['Post reply'].'</a>';
+	else
+		$post_link = '&nbsp;';
+}
+else
+{
+	$post_link = $lang_topic['Topic closed'];
+
+	if ($is_admmod)
+		$post_link .= ' / <a href="post.php?tid='.$id.'">'.$lang_topic['Post reply'].'</a>';
+}
+
+
+// Determine the post offset (based on $_GET['p'])
+$num_pages = ceil(($cur_topic['num_replies'] + 1) / $pun_user['disp_posts']);
+
+$p = (!isset($_GET['p']) || $_GET['p'] <= 1 || $_GET['p'] > $num_pages) ? 1 : $_GET['p'];
+$start_from = $pun_user['disp_posts'] * ($p - 1);
+
+// Generate paging links
+$paging_links = $lang_common['Pages'].': '.paginate($num_pages, $p, 'viewtopic.php?id='.$id);
+
+
+if ($pun_config['o_censoring'] == '1')
+	$cur_topic['subject'] = censor_words($cur_topic['subject']);
+
+
+$quickpost = false;
+if ($pun_config['o_quickpost'] == '1' &&
+	!$pun_user['is_guest'] &&
+	($cur_topic['post_replies'] == '1' || ($cur_topic['post_replies'] == '' && $pun_user['g_post_replies'] == '1')) &&
+	($cur_topic['closed'] == '0' || $is_admmod))
+{
+	$required_fields = array('req_message' => $lang_common['Message']);
+	$quickpost = true;
+}
+
+if (!$pun_user['is_guest'] && $pun_config['o_subscriptions'] == '1')
+{
+	if ($cur_topic['is_subscribed'])
+		// I apologize for the variable naming here. It's a mix of subscription and action I guess :-)
+		$subscraction = '<p class="subscribelink clearb">'.$lang_topic['Is subscribed'].' - <a href="misc.php?unsubscribe='.$id.'">'.$lang_topic['Unsubscribe'].'</a></p>'."\n";
+	else
+		$subscraction = '<p class="subscribelink clearb"><a href="misc.php?subscribe='.$id.'">'.$lang_topic['Subscribe'].'</a></p>'."\n";
+}
+else
+	$subscraction = '<div class="clearer"></div>'."\n";
+
+$page_title = pun_htmlspecialchars($pun_config['o_board_title'].' / '.$cur_topic['subject']);
+define('PUN_ALLOW_INDEX', 1);
+require PUN_ROOT.'header.php';
+
+?>
+<div class="linkst">
+	<div class="inbox">
+		<p class="pagelink conl"><?php echo $paging_links ?></p>
+		<p class="postlink conr"><?php echo $post_link ?></p>
+		<ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li><li>&nbsp;&raquo;&nbsp;<a href="viewforum.php?id=<?php echo $cur_topic['forum_id'] ?>"><?php echo pun_htmlspecialchars($cur_topic['forum_name']) ?></a></li><li>&nbsp;&raquo;&nbsp;<?php echo pun_htmlspecialchars($cur_topic['subject']) ?></li></ul>
+		<div class="clearer"></div>
+	</div>
+</div>
+
+<?php
+
+
+require PUN_ROOT.'include/parser.php';
+
+$bg_switch = true;	// Used for switching background color in posts
+$post_count = 0;	// Keep track of post numbers
+
+// Retrieve the posts (and their respective poster/online status)
+$result = $db->query('SELECT u.email, u.title, u.url, u.location, u.use_avatar, u.signature, u.email_setting, u.num_posts, u.registered, u.admin_note, p.id, p.poster AS username, p.poster_id, p.poster_ip, p.poster_email, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by, g.g_id, g.g_user_title, o.user_id AS is_online FROM '.$db->prefix.'posts AS p INNER JOIN '.$db->prefix.'users AS u ON u.id=p.poster_id INNER JOIN '.$db->prefix.'groups AS g ON g.g_id=u.group_id LEFT JOIN '.$db->prefix.'online AS o ON (o.user_id=u.id AND o.user_id!=1 AND o.idle=0) WHERE p.topic_id='.$id.' ORDER BY p.id LIMIT '.$start_from.','.$pun_user['disp_posts'], true) or error('Unable to fetch post info', __FILE__, __LINE__, $db->error());
+while ($cur_post = $db->fetch_assoc($result))
+{
+	$post_count++;
+	$user_avatar = '';
+	$user_info = array();
+	$user_contacts = array();
+	$post_actions = array();
+	$is_online = '';
+	$signature = '';
+
+	// If the poster is a registered user.
+	if ($cur_post['poster_id'] > 1)
+	{
+		$username = '<a href="profile.php?id='.$cur_post['poster_id'].'">'.pun_htmlspecialchars($cur_post['username']).'</a>';
+		$user_title = get_title($cur_post);
+
+		if ($pun_config['o_censoring'] == '1')
+			$user_title = censor_words($user_title);
+
+		// Format the online indicator
+		$is_online = ($cur_post['is_online'] == $cur_post['poster_id']) ? '<strong>'.$lang_topic['Online'].'</strong>' : $lang_topic['Offline'];
+
+		if ($pun_config['o_avatars'] == '1' && $cur_post['use_avatar'] == '1' && $pun_user['show_avatars'] != '0')
+		{
+			if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.gif'))
+				$user_avatar = '<img src="'.$pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.gif" '.$img_size[3].' alt="" />';
+			else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.jpg'))
+				$user_avatar = '<img src="'.$pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.jpg" '.$img_size[3].' alt="" />';
+			else if ($img_size = @getimagesize($pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.png'))
+				$user_avatar = '<img src="'.$pun_config['o_avatars_dir'].'/'.$cur_post['poster_id'].'.png" '.$img_size[3].' alt="" />';
+		}
+		else
+			$user_avatar = '';
+
+		// We only show location, register date, post count and the contact links if "Show user info" is enabled
+		if ($pun_config['o_show_user_info'] == '1')
+		{
+			if ($cur_post['location'] != '')
+			{
+				if ($pun_config['o_censoring'] == '1')
+					$cur_post['location'] = censor_words($cur_post['location']);
+
+				$user_info[] = '<dd>'.$lang_topic['From'].': '.pun_htmlspecialchars($cur_post['location']);
+			}
+
+			$user_info[] = '<dd>'.$lang_common['Registered'].': '.date($pun_config['o_date_format'], $cur_post['registered']);
+
+			if ($pun_config['o_show_post_count'] == '1' || $pun_user['g_id'] < PUN_GUEST)
+				$user_info[] = '<dd>'.$lang_common['Posts'].': '.$cur_post['num_posts'];
+
+			// Now let's deal with the contact links (E-mail and URL)
+			if (($cur_post['email_setting'] == '0' && !$pun_user['is_guest']) || $pun_user['g_id'] < PUN_GUEST)
+				$user_contacts[] = '<a href="mailto:'.$cur_post['email'].'">'.$lang_common['E-mail'].'</a>';
+			else if ($cur_post['email_setting'] == '1' && !$pun_user['is_guest'])
+				$user_contacts[] = '<a href="misc.php?email='.$cur_post['poster_id'].'">'.$lang_common['E-mail'].'</a>';
+
+			if ($cur_post['url'] != '')
+				$user_contacts[] = '<a href="'.pun_htmlspecialchars($cur_post['url']).'">'.$lang_topic['Website'].'</a>';
+		}
+
+		if ($pun_user['g_id'] < PUN_GUEST)
+		{
+			$user_info[] = '<dd>IP: <a href="moderate.php?get_host='.$cur_post['id'].'">'.$cur_post['poster_ip'].'</a>';
+
+			if ($cur_post['admin_note'] != '')
+				$user_info[] = '<dd>'.$lang_topic['Note'].': <strong>'.pun_htmlspecialchars($cur_post['admin_note']).'</strong>';
+		}
+	}
+	// If the poster is a guest (or a user that has been deleted)
+	else
+	{
+		$username = pun_htmlspecialchars($cur_post['username']);
+		$user_title = get_title($cur_post);
+
+		if ($pun_user['g_id'] < PUN_GUEST)
+			$user_info[] = '<dd>IP: <a href="moderate.php?get_host='.$cur_post['id'].'">'.$cur_post['poster_ip'].'</a>';
+
+		if ($pun_config['o_show_user_info'] == '1' && $cur_post['poster_email'] != '' && !$pun_user['is_guest'])
+			$user_contacts[] = '<a href="mailto:'.$cur_post['poster_email'].'">'.$lang_common['E-mail'].'</a>';
+	}
+
+	// Generation post action array (quote, edit, delete etc.)
+	if (!$is_admmod)
+	{
+		if (!$pun_user['is_guest'])
+			$post_actions[] = '<li class="postreport"><a href="misc.php?report='.$cur_post['id'].'">'.$lang_topic['Report'].'</a>';
+
+		if ($cur_topic['closed'] == '0')
+		{
+			if ($cur_post['poster_id'] == $pun_user['id'])
+			{
+				if ((($start_from + $post_count) == 1 && $pun_user['g_delete_topics'] == '1') || (($start_from + $post_count) > 1 && $pun_user['g_delete_posts'] == '1'))
+					$post_actions[] = '<li class="postdelete"><a href="delete.php?id='.$cur_post['id'].'">'.$lang_topic['Delete'].'</a>';
+				if ($pun_user['g_edit_posts'] == '1')
+					$post_actions[] = '<li class="postedit"><a href="edit.php?id='.$cur_post['id'].'">'.$lang_topic['Edit'].'</a>';
+			}
+
+			if (($cur_topic['post_replies'] == '' && $pun_user['g_post_replies'] == '1') || $cur_topic['post_replies'] == '1')
+				$post_actions[] = '<li class="postquote"><a href="post.php?tid='.$id.'&amp;qid='.$cur_post['id'].'">'.$lang_topic['Quote'].'</a>';
+		}
+	}
+	else
+		$post_actions[] = '<li class="postreport"><a href="misc.php?report='.$cur_post['id'].'">'.$lang_topic['Report'].'</a>'.$lang_topic['Link separator'].'</li><li class="postdelete"><a href="delete.php?id='.$cur_post['id'].'">'.$lang_topic['Delete'].'</a>'.$lang_topic['Link separator'].'</li><li class="postedit"><a href="edit.php?id='.$cur_post['id'].'">'.$lang_topic['Edit'].'</a>'.$lang_topic['Link separator'].'</li><li class="postquote"><a href="post.php?tid='.$id.'&amp;qid='.$cur_post['id'].'">'.$lang_topic['Quote'].'</a>';
+
+
+	// Switch the background color for every message.
+	$bg_switch = ($bg_switch) ? $bg_switch = false : $bg_switch = true;
+	$vtbg = ($bg_switch) ? ' roweven' : ' rowodd';
+
+
+	// Perform the main parsing of the message (BBCode, smilies, censor words etc)
+	$cur_post['message'] = parse_message($cur_post['message'], $cur_post['hide_smilies']);
+
+	// Do signature parsing/caching
+	if ($cur_post['signature'] != '' && $pun_user['show_sig'] != '0')
+	{
+		if (isset($signature_cache[$cur_post['poster_id']]))
+			$signature = $signature_cache[$cur_post['poster_id']];
+		else
+		{
+			$signature = parse_signature($cur_post['signature']);
+			$signature_cache[$cur_post['poster_id']] = $signature;
+		}
+	}
+
+?>
+<div id="p<?php echo $cur_post['id'] ?>" class="blockpost<?php echo $vtbg ?><?php if (($post_count + $start_from) == 1) echo ' firstpost'; ?>">
+	<h2><span><span class="conr">#<?php echo ($start_from + $post_count) ?>&nbsp;</span><a href="viewtopic.php?pid=<?php echo $cur_post['id'].'#p'.$cur_post['id'] ?>"><?php echo format_time($cur_post['posted']) ?></a></span></h2>
+	<div class="box">
+		<div class="inbox">
+			<div class="postleft">
+				<dl>
+					<dt><strong><?php echo $username ?></strong></dt>
+					<dd class="usertitle"><strong><?php echo $user_title ?></strong></dd>
+					<dd class="postavatar"><?php echo $user_avatar ?></dd>
+<?php if (count($user_info)) echo "\t\t\t\t\t".implode('</dd>'."\n\t\t\t\t\t", $user_info).'</dd>'."\n"; ?>
+<?php if (count($user_contacts)) echo "\t\t\t\t\t".'<dd class="usercontacts">'.implode('&nbsp;&nbsp;', $user_contacts).'</dd>'."\n"; ?>
+				</dl>
+			</div>
+			<div class="postright">
+				<h3><?php if (($post_count + $start_from) > 1) echo ' Re: '; ?><?php echo pun_htmlspecialchars($cur_topic['subject']) ?></h3>
+				<div class="postmsg">
+					<?php echo $cur_post['message']."\n" ?>
+<?php if ($cur_post['edited'] != '') echo "\t\t\t\t\t".'<p class="postedit"><em>'.$lang_topic['Last edit'].' '.pun_htmlspecialchars($cur_post['edited_by']).' ('.format_time($cur_post['edited']).')</em></p>'."\n"; ?>
+				</div>
+<?php if ($signature != '') echo "\t\t\t\t".'<div class="postsignature"><hr />'.$signature.'</div>'."\n"; ?>
+			</div>
+			<div class="clearer"></div>
+			<div class="postfootleft"><?php if ($cur_post['poster_id'] > 1) echo '<p>'.$is_online.'</p>'; ?></div>
+			<div class="postfootright"><?php echo (count($post_actions)) ? '<ul>'.implode($lang_topic['Link separator'].'</li>', $post_actions).'</li></ul></div>'."\n" : '<div>&nbsp;</div></div>'."\n" ?>
+		</div>
+	</div>
+</div>
+
+<?php
+
+}
+
+?>
+<div class="postlinksb">
+	<div class="inbox">
+		<p class="postlink conr"><?php echo $post_link ?></p>
+		<p class="pagelink conl"><?php echo $paging_links ?></p>
+		<ul><li><a href="index.php"><?php echo $lang_common['Index'] ?></a></li><li>&nbsp;&raquo;&nbsp;<a href="viewforum.php?id=<?php echo $cur_topic['forum_id'] ?>"><?php echo pun_htmlspecialchars($cur_topic['forum_name']) ?></a></li><li>&nbsp;&raquo;&nbsp;<?php echo pun_htmlspecialchars($cur_topic['subject']) ?></li></ul>
+		<?php echo $subscraction ?>
+	</div>
+</div>
+
+<?php
+
+// Display quick post if enabled
+if ($quickpost)
+{
+
+?>
+<div class="blockform">
+	<h2><span><?php echo $lang_topic['Quick post'] ?></span></h2>
+	<div class="box">
+		<form method="post" action="post.php?tid=<?php echo $id ?>" onsubmit="this.submit.disabled=true;if(process_form(this)){return true;}else{this.submit.disabled=false;return false;}">
+			<div class="inform">
+				<fieldset>
+					<legend><?php echo $lang_common['Write message legend'] ?></legend>
+					<div class="infldset txtarea">
+						<input type="hidden" name="form_sent" value="1" />
+						<input type="hidden" name="form_user" value="<?php echo (!$pun_user['is_guest']) ? pun_htmlspecialchars($pun_user['username']) : 'Guest'; ?>" />
+						<label><textarea name="req_message" rows="7" cols="75" tabindex="1"></textarea></label>
+						<ul class="bblinks">
+							<li><a href="help.php#bbcode" onclick="window.open(this.href); return false;"><?php echo $lang_common['BBCode'] ?></a>: <?php echo ($pun_config['p_message_bbcode'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+							<li><a href="help.php#img" onclick="window.open(this.href); return false;"><?php echo $lang_common['img tag'] ?></a>: <?php echo ($pun_config['p_message_img_tag'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+							<li><a href="help.php#smilies" onclick="window.open(this.href); return false;"><?php echo $lang_common['Smilies'] ?></a>: <?php echo ($pun_config['o_smilies'] == '1') ? $lang_common['on'] : $lang_common['off']; ?></li>
+						</ul>
+					</div>
+				</fieldset>
+			</div>
+			<p><input type="submit" name="submit" tabindex="2" value="<?php echo $lang_common['Submit'] ?>" accesskey="s" /></p>
+		</form>
+	</div>
+</div>
+<?php
+
+}
+
+// Increment "num_views" for topic
+$low_prio = ($db_type == 'mysql') ? 'LOW_PRIORITY ' : '';
+$db->query('UPDATE '.$low_prio.$db->prefix.'topics SET num_views=num_views+1 WHERE id='.$id) or error('Unable to update topic', __FILE__, __LINE__, $db->error());
+
+$forum_id = $cur_topic['forum_id'];
+$footer_style = 'viewtopic';
+require PUN_ROOT.'footer.php';