"," ";
if ($pageno > 0) echo "Previous Page";
if ($pageno > 0 && $pageno < floor(($postcount-1)/$postsperpage)) echo " | ";
if ($pageno < floor(($postcount-1)/$postsperpage)) echo "Next Page";
echo " ";
if ($pageno > 0) echo "Previous Page";
if ($pageno > 0 && $pageno < floor(($postcount-1)/$postsperpage)) echo " | ";
if ($pageno < floor(($postcount-1)/$postsperpage)) echo "Next Page";
echo " Showing " . ($lowr + 1) . " - $highr out of $nresults posts
",
 "    ",
 "\\2",
 "",
 "\\1",
 "\\1",
 "\\1",
 "\\1",
 "\\1",
 "\\1;",
);
$tags_decode_search=array(
 "/
/",
 "/    /",
 "/(.*?)<\/a>/",
 "/(.*?)<\/a>/",
 "//",
 "/(.*?)<\/i>/",
 "/(.*?)<\/u>/",
 "/(.*?)<\/b>/",
 "/(.*?)<\/em>/",
 "/(.*?)<\/small>/",
);
$tags_decode_replace=array(
 "\n",
 "\t",
 "[url=\\1]\\2[/url]",
 "[url=\\1]\\2[/url]",
 "[img=\\1]",
 "[i]\\1[/i]",
 "[u]\\1[/u]",
 "[b]\\1[/b]",
 "[em]\\1[/em]",
 "[small]\\1[/small]",
);
function pageheader($title=NULL) {
   $messages=array(
   "So, you wanted a message board, eh?",
   "Keep It Simple, Stupid",
   "Minimalist, yet functional (barely)",
   "It's one of the places to be! :)",
   "It's like eating",
   "The world is corrupt!",
   "Not even remotely secure",
   "Brute force ROMhacking since 2004",
   "With a side of search",
   "It's like you want",
   "Anything else is gaslight",
   "take that, morning-me",
   "obscure enough to be secure?",
   "Welcome to the Blast Radius",
   "Therefore you are wrong.",
   "it shifts to attack mode",
   "activate, resonate, precipitate",
   "wow, what a hole!",
   "with a capital F",
   "The wizard makes no changes without your permission.",
   "My Honda is erratic",
   "and California Dreamin' has become a liability",
   "photograph the five birds"
   );
   echo "";
   echo '';
   echo '';
   echo "
Tags: 
bold: [b]bold[/b]
italics: [i]italics[/i]
emphasis: [em]emphasis[/em]
underline: [u]underline[/u]
small: [small]small[/small]
Link: [url=http://www.google.com]Link[/url]

[img=https://www.hcs64.com/images/mm1.png]
\n";
if( $ppage > 0) {
	echo " \n";
}
// authenticate by user name/pass or by cookies
// return user id, die if authentication fails
function authenticate($dbh,$use_cookies,$user,$pass) {
global $cookie_uname,$cookie_token;
if (isset($user) && $user!='' && isset($pass) && $pass!='') {
   $query=mysqli_prepare($dbh,"
    SELECT idx, pass_hash
    FROM users
    WHERE uname = ?
   ") or die("auth attempt: ".mysqli_error($dbh));
   mysqli_stmt_bind_param($query,'s',$user);
   mysqli_stmt_execute($query) or die(mysqli_error($dbh));
   mysqli_stmt_bind_result($query,$uid,$pass_hash);
   if (!mysqli_stmt_fetch($query)) die("User lookup failed ".mysqli_error($dbh));
   if (!password_verify($pass,$pass_hash)) die("Authentication failed.");
   mysqli_stmt_close($query);
} else if ($use_cookies && isset($_COOKIE[$cookie_uname]) && isset($_COOKIE[$cookie_token])) {
   $query=mysqli_prepare($dbh,"
    SELECT idx
    FROM users
    WHERE uname = ? AND logintoken <> '' AND logintoken = ?
   ") or die("auth attempt: ".mysqli_error($dbh));
   mysqli_stmt_bind_param($query,'ss',$_COOKIE[$cookie_uname],$_COOKIE[$cookie_token]);
   mysqli_stmt_execute($query) or die(mysqli_error($dbh));
   mysqli_stmt_bind_result($query,$uid);
   if (!mysqli_stmt_fetch($query)) die ("Authentication failed".mysqli_error($dbh));
   mysqli_stmt_close($query);
} else die("Authentication failed (incomplete data).");
return $uid;
}
// update the last updated timestamp for a post/thread
function update_post_time($dbh,$idx) {
   $query = mysqli_prepare($dbh,"
    UPDATE board
    SET lasttime = NOW()
    WHERE idx = ?
    LIMIT 1
   ") or die("update error: ".mysqli_error($dbh));
   mysqli_stmt_bind_param($query,'i',$idx);
   mysqli_stmt_execute($query) or die(mysqli_error($dbh));
   mysqli_stmt_close($query);
}
// ***************************** Top of code ********************************
if (!isset($_SERVER['HTTPS']) || !$_SERVER['HTTPS']) {
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: https://" . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']);
    exit();
}
require("dblogin.php");
require("dblogin_write.php");
$dbh = dblogin();
if (isset($_GET['login'])) {
// **** Display login form
pageheader();
?>
 10 ]);
      $dbh_write = dblogin_write();
      $query = mysqli_prepare($dbh_write,"INSERT INTO users SET idx=NULL, joined=NOW(), uname=?, pass_hash=?");
      mysqli_stmt_bind_param($query,'ss',$_POST['uname'],$pass_hash);
      mysqli_stmt_execute($query) or die (mysqli_error($dbh_write));
      mysqli_stmt_close($query);
      mysqli_close($dbh_write);
      echo "Welcome to the forum!";
   } else echo "the passwords did not match";
} else echo "User name {$_POST['uname']} already exists.";
} else if (isset($_GET['userinfo'])) {
// **** User info page
// get info from users database
$query= mysqli_prepare($dbh,"SELECT uname, UNIX_TIMESTAMP(joined) as joindate, logintoken, UNIX_TIMESTAMP(lastlogin) as login FROM users
                       WHERE idx = ?");
mysqli_stmt_bind_param($query,'i',$_GET['userinfo']);
mysqli_stmt_execute($query) or die(mysqli_error($dbh));
mysqli_stmt_store_result($query);
if (mysqli_stmt_num_rows($query) != 1) die("no such user");
mysqli_stmt_bind_result($query,$uname,$joindate,$logintoken,$login);
mysqli_stmt_fetch($query) or die(mysqli_error($dbh));
mysqli_stmt_close($query);
// get post count, last post
$query = mysqli_prepare($dbh,"SELECT COUNT(*) AS postcount, UNIX_TIMESTAMP(MAX(postedtime)) as lasttime FROM board WHERE author = ?");
mysqli_stmt_bind_param($query,'i',$_GET['userinfo']);
mysqli_stmt_execute($query) or die(mysqli_error($dbh));
mysqli_stmt_bind_result($query,$postcount,$lasttime);
mysqli_stmt_fetch($query) or die(mysqli_error($dbh));
mysqli_stmt_close($query);
pageheader($uname." user info");
echo "Info for user "$uname":";
	echo "\n";
	echo " \n";
}
if(($highr) < $nresults) {
	echo "";
	echo "\n";
	echo " \n";
}
echo "
";
echo "Joined: ".date($datefmt,$joindate)."
";
echo "Posts: $postcount";
if ($postcount > 0) echo ", last posted ".date("$datefmt $timefmt",$lasttime)."
";
if (isset($logintoken) && $logintoken != "") echo "Logged in ".date("$datefmt $timefmt",$login)."
";
else if ($login > 0) echo "Last logged in ".date("$datefmt $timefmt",$login)."
";
else echo "Never logged in.
";
echo "
";
} else if (isset($_GET['chpass'])) {
// **** Change password form
pageheader();
?>
Change Password:
 10 ]);
mysqli_stmt_bind_param($query,'sss',$newpass_hash,$uid,$_POST['uname']);
mysqli_stmt_execute($query) or die(mysqli_error($dbh_write));
if (mysqli_stmt_affected_rows($query) != 1) die ("password change failed");
mysqli_stmt_close($query);
mysqli_close($dbh_write);
echo "Password Changed.";
} else if (isset($_GET['newthread'])) {
pageheader();
echo "Create A New Thread!
";
NewPostForm(0);
} else if (isset($_GET['showthread'])) {
// **** Show a single thread
// put thread subject in title
$query = mysqli_prepare($dbh,"SELECT subject FROM board WHERE idx = ?") or die(mysqli_error());
mysqli_stmt_bind_param($query,'i',$_GET['showthread']);
mysqli_stmt_execute($query) or die(mysqli_error($dbh));
mysqli_stmt_bind_result($query,$subject);
mysqli_stmt_fetch($query) or die("no such post found".mysqli_error($dbh));
pageheader($subject);
mysqli_stmt_close($query);
// count posts in thread
$query = mysqli_prepare($dbh,"SELECT COUNT(*) FROM board WHERE board.replyto = ? OR board.idx = ?") or die(mysql_error());
mysqli_stmt_bind_param($query,'ii',$_GET['showthread'],$_GET['showthread']);
mysqli_stmt_execute($query) or die(mysqli_error($dbh));
mysqli_stmt_bind_result($query,$postcount);
mysqli_stmt_fetch($query) or die(mysqli_error($dbh));
mysqli_stmt_close($query);
$pageno = $_GET['showpage'] ?? 0;
$lastpage = floor(($postcount-1)/$postsperpage);
if (isset($_GET['lastpage'])) $pageno = $lastpage;
$firstonpage = $pageno*$postsperpage;
// get user's last login time
if (isset($_COOKIE[$cookie_uname]) && isset($_COOKIE[$cookie_token])) {
   $query = mysqli_prepare($dbh,"SELECT UNIX_TIMESTAMP(prevlogin) AS llstamp
                           FROM users WHERE uname = ? AND logintoken = ?") or die(mysqli_error($dbh));
   mysqli_stmt_bind_param($query,'ss',$_COOKIE[$cookie_uname],$_COOKIE[$cookie_token]);
   mysqli_stmt_execute($query) or die(mysqli_error($dbh));
   mysqli_stmt_bind_result($query,$lastlogin);
   if (!mysqli_stmt_fetch($query)) $lastlogin=0;
   mysqli_stmt_close($query);
} else $lastlogin=0;
echo "\n";
$firstpost=1;
while (mysqli_stmt_fetch($query)) {
   echo "
\n";
echo "
[edit] ($timeleft_str left)";
   }
   echo "
";
echo "Go to Page ";
for ($i = 0; $i <= $lastpage; $i++)
{
   if ($pageno != $i)
      echo "";
   echo "$i";
   if ($pageno != $i)
      echo "";
    echo " ";
}
echo "
";
echo "Search this thread";
echo "
";
echo "Show all threads
";
echo "Reply to this thread:
";
NewPostForm($_GET['showthread']);
echo "
";
// update thread last updated time
if ($_POST['inresponseto'] != 0) {
   update_post_time($dbh_write,$_POST['inresponseto']);
   echo "Return to thread
";
}   echo "Return to forum";
mysqli_close($dbh_write);
} else if (isset($_GET['editpost'])) {
// **** Display post edit form
pageheader();
$query = mysqli_prepare($dbh,"
 SELECT subject,message
 FROM board
 WHERE idx = ?") or die(mysqli_error($dbh));
mysqli_stmt_bind_param($query,'i',$_GET['editpost']);
mysqli_stmt_execute($query) or die(mysqli_error($dbh));
mysqli_stmt_bind_result($query,$subject,$message);
if (!mysqli_stmt_fetch($query)) die("no such post ".mysqli_error($dbh));
mysqli_stmt_close($query);
EditPostForm($_GET['editpost'],preg_replace($tags_decode_search,$tags_decode_replace,$message),$subject);
} else if (isset($_GET['editpost2'])) {
// **** Commit an edited post
pageheader();
$posttoedit = intval($_POST['posttoupdate']);
// look up what post this reponds to and when it was first posted
$query = mysqli_prepare($dbh,"SELECT replyto, UNIX_TIMESTAMP(postedtime) FROM board WHERE idx = ? LIMIT 1") or die(mysqli_error($dbh));
mysqli_stmt_bind_param($query,'i',$_POST['posttoupdate']);
mysqli_stmt_execute($query) or die(mysqli_error($dbh));
mysqli_stmt_bind_result($query,$inresponseto,$postedtime);
mysqli_stmt_fetch($query) or die("couldn't find first post in thread".mysqli_error($dbh));
mysqli_stmt_close($query);
if (!in_array($posttoedit, $editable_whitelist) && time()-$postedtime >= $editexpire) die("edit time for this post has expired ($editexpire seconds)");
$uid = authenticate($dbh,true,$_POST['author'] ?? '',$_POST['pass'] ?? '');
if ($inresponseto=="0" && (!isset($_POST['subject']) || $_POST['subject']=="" || ctype_space($_POST['subject']))) die("Thread cannot have empty subject");
if ((!isset($_POST['message']) || $_POST['message']=="" || ctype_space($_POST['message']))) die("empty message not allowed!");
$dbh_write = dblogin_write();
$query = mysqli_prepare($dbh_write,"
 UPDATE board
 SET subject = ?,
     message = ?,
     ip = ?,
     lasttime = NOW()
 WHERE idx = ? AND author = ? 
 LIMIT 1
") or die (mysqli_error($dbh_write));
$newmessage = preg_replace($tags_search,$tags_replace,htmlspecialchars($_POST['message'],ENT_QUOTES))."
edited ".date($timefmt." ".$datefmt)."";
$subject=htmlspecialchars($_POST['subject'],ENT_QUOTES);
mysqli_stmt_bind_param($query,'sssii',$subject,$newmessage,$_SERVER['REMOTE_ADDR'],$_POST['posttoupdate'],$uid);
mysqli_stmt_execute($query) or die(mysqli_error($dbh_write));
if (mysqli_stmt_affected_rows($query) != 1) die("no such post by you");
mysqli_stmt_close($query);
echo "Updated.
";
if ($inresponseto != 0) {
   update_post_time($dbh_write,$inresponseto);
   echo "Return to thread
";
   echo "Return to forum";
}
mysqli_close($dbh_write);
} else if (isset($_GET['searchmode'])) {
// **** Searching (largely ripped off from Josh W)
pageheader();
 
$post_action = "$my_path?searchmode";
if(isset($_GET['threadid'])) {
    $post_action .= "&threadid=${_GET['threadid']}";
}
echo "\n";
if(isset($_POST['query'])) {
	if(isset($_POST['page']))
		$lowr = ($_POST['page']-1)*$postsperpage;
	else
		$lowr = 0;
	$highr = $lowr + $postsperpage;
	switch ($searchwhere) {
	case "message":
		$field = "message";
		break;
	case "subject":
		$field = "subject";
		break;
	case "uname":
		$field = "users.uname";
		break;
	default:
		$field = "message";
	}	
	switch ($searchhow) {
    case "exact":
		$query_sql = "$field LIKE ?";
		$query = mysqli_real_escape_string($dbh,htmlspecialchars($_POST['query'],ENT_QUOTES));
        break;
	case "phrase":
		$query_sql = "$field LIKE ?";
		$query = "%" . mysqli_real_escape_string($dbh,htmlspecialchars($_POST['query'],ENT_QUOTES)) . "%";
		break;
	case "anywords":
		$word_count = substr_count($_POST['query']," ")+1;
        if ($word_count > 4) {
            echo("max 4 words");
            exit();
        }
		$query_sql = "$field LIKE ?" . str_repeat(" OR $field LIKE ?",$word_count-1);
		$query = explode(" ",
		"%" . str_replace(" ","% %",htmlspecialchars($_POST['query'],ENT_QUOTES)) . "%"
		);
		break;
	case "allwords":
		$word_count = substr_count($_POST['query']," ")+1;
        if ($word_count > 4) {
            echo("max 4 words");
            exit();
        }
		$query_sql = "$field LIKE ?" . str_repeat(" AND $field LIKE ?",$word_count-1);
		$query = explode(" ",
		"%" . str_replace(" ","% %",htmlspecialchars($_POST['query'],ENT_QUOTES)) . "%"
		);
		break;
	default:
		$query = "'%mothballs%'";
		break;
	}
    $full_query = "SELECT
	    board.idx AS idx
		FROM board";
        
    if ($field == "users.uname")
    {
        $full_query .= ",users";
    }
    $full_query .= "
		WHERE ( $query_sql )";
        
    if ($field == "users.uname")
    {
        $full_query .= " AND board.author = users.idx";
    }
    if (isset($_GET['threadid']))
    {
        $threadid = intval($_GET['threadid']);
        $full_query .= " AND ( board.idx = $threadid OR board.replyto = $threadid )";
    }
    $full_query .= "
        ORDER BY board.postedtime ";
    if (!isset($_POST['order']) || $_POST['order'] == "ASC")
    {
        $full_query .= "ASC\n";
    } else {
        $full_query .= "DESC\n";
    }
    $stmt=mysqli_prepare($dbh,$full_query) or die (mysqli_error($dbh));
	if ($searchhow == "anywords" || $searchhow == "allwords")
	{
		$i = 2;
		$query2[0] = $stmt;
		$query2[1] = str_repeat('s',$word_count);
		foreach ($query as $q)
		{
			$query2[$i] = &$query[$i-2];
			$i++;
		}
		call_user_func_array('mysqli_stmt_bind_param',$query2);
	} else {
		mysqli_stmt_bind_param($stmt,'s',$query) or die (mysqli_error($dbh));
	}
	mysqli_stmt_execute($stmt) or die(mysqli_error($dbh));
	mysqli_stmt_bind_result($stmt,$message_idx) or die(mysqli_error($dbh));
	mysqli_stmt_store_result($stmt);
	$nresults = mysqli_stmt_num_rows($stmt);
	for($i = 0; $i < $nresults && $i < $lowr; $i++)
		if (!mysqli_stmt_fetch($stmt)) die(mysqli_error($dbh));
	for($i = $lowr; $i < $nresults && $i < $highr && mysqli_stmt_fetch($stmt); $i++)
	{
		$indexes[$i] = $message_idx;
	}
	mysqli_stmt_close($stmt);
	$npage = (int)(($highr+$postsperpage) / $postsperpage);
	$ppage = $npage - 2;
	$highr3 = $highr;
	if($highr > $nresults) $highr = $nresults;
	$test2 = preg_replace(array("[ ]"),array("+") ,$_POST['query']);
	echo "
\n";
	PrevNext($post_action,$ppage,$npage,$highr3,$nresults);
	echo "\n";
	for($i = $lowr; $i < $highr; $i++) {
	    $post_index = $indexes[$i];
	    // fetch the thread index
	    $stmt = mysqli_prepare($dbh,"SELECT replyto FROM board WHERE idx = ?") or die (mysqli_error($dbh));
	    mysqli_stmt_bind_param($stmt,'i',$post_index) or die(mysqli_error($dbh));
	    mysqli_stmt_execute($stmt) or die(mysqli_error($dbh));
	    mysqli_stmt_bind_result($stmt,$thread_index) or die(mysqli_error($dbh));
	    mysqli_stmt_fetch($stmt) or die ("error fetching a post".mysqli_error($dbh));
	    mysqli_stmt_close($stmt);
	    if ($thread_index != 0)
	    {
		    // fetch the thread title and index
		    $stmt = mysqli_prepare($dbh,"SELECT subject FROM board
		    WHERE idx = ?") or die(mysqli_error($dbh));
		    mysqli_stmt_bind_param($stmt,'i',$thread_index) or die(mysqli_error($dbh));
		    mysqli_stmt_execute($stmt) or die (mysqli_error($dbh));
            mysqli_stmt_store_result($stmt) or die (mysqli_error($dbh));
            if (mysqli_stmt_num_rows($stmt) != 0)
            {
                mysqli_stmt_bind_result($stmt,$thread_subject) or die(mysqli_error($dbh));
                mysqli_stmt_fetch($stmt) or die ("error fetching thread title and index $thread_index ".mysqli_error($dbh));
            }
            else
            {
                $thread_index = 0;
            }
            mysqli_stmt_close($stmt);
        }
        if ($thread_index != 0)
        {
		    // count how many posts come before this one
		    $stmt = mysqli_prepare($dbh,"SELECT COUNT(*) FROM board
		    WHERE (replyto = ? OR idx = ?) AND board.idx < ?") or die(mysqli_error($dbh));
		    mysqli_stmt_bind_param($stmt,'iii',$thread_index,$thread_index,$post_index) or die (mysqli_error($dbh));
		    mysqli_stmt_execute($stmt) or die (mysqli_error($dbh));
		    mysqli_stmt_bind_result($stmt,$postcount) or die(mysqli_error($dbh));
		    mysqli_stmt_fetch($stmt) or die(mysqli_error($dbh));
		    mysqli_stmt_close($stmt);
		
		    $pageno = floor(($postcount) / $postsperpage);
	    }
	    // retrieve details of this post
	    $stmt = mysqli_prepare($dbh,"SELECT board.subject, board.message, UNIX_TIMESTAMP(board.postedtime), users.idx, users.uname
	    	FROM board, users
		WHERE board.idx = ? AND users.idx = board.author") or die(mysqli_error($dbh));
	    mysqli_stmt_bind_param($stmt,'i',$post_index);
	    mysqli_stmt_execute($stmt) or die (mysqli_error($dbh));
	    mysqli_stmt_bind_result($stmt,$subject,$message,$postedtime,$uid,$uname);
	    mysqli_stmt_fetch($stmt) or die ("error getting post details ".mysqli_error($dbh));
	    mysqli_stmt_close($stmt);
	    if($thread_index != 0)
		    echo "Thread: $thread_subject
";
	    else
		    echo "Thread: $subject
";
	    echo "
| Threadses | |||
|---|---|---|---|
| Subject | Updated | Updated by | Posts | 
| "; if ($lastlogin > 0 && $thread_lasttime > $lastlogin) echo "* "; echo "$subject"; if ($pinned) { $saw_pinned = 1; echo " (pin'd)"; } $lastpage = 0; if ($postcount > $postsperpage) { $lastpage = floor(($postcount-1) / $postsperpage); echo " (last page)"; } echo ""; echo " | ".date($timefmt." ".$datefmt,$thread_lasttime).""; echo " | $last_uname | $postcount | 
";
$showpage = intval($_GET['showpage'] ?? '0');
$showprev = $showpage > 0;
$shownext = ($firstonpage+$threadsonthispage < $count);
if ($showprev) echo "Previous Page";
if ($showprev && $shownext) echo " | ";
if ($shownext) echo "Next Page";
echo "
";
echo "Create a new thread | ";
echo "Search
";
if (!isset($_COOKIE[$cookie_uname]) || !isset($_COOKIE[$cookie_token])) {
    echo "Create an account | ";
}
echo "Change Password | ";
if (!isset($_COOKIE[$cookie_uname]) || !isset($_COOKIE[$cookie_token])) {
   echo "Log In";
} else {
   echo "Log Out";
}
}
mysqli_close($dbh);
?>