diff --git a/css/burichan.css b/css/burichan.css index 41ac12f..46db906 100644 --- a/css/burichan.css +++ b/css/burichan.css @@ -27,10 +27,7 @@ a:hover { text-decoration:underline; } .adminbar { - text-align:right; background:inherit; - clear:both; - float:right; } .logo { clear:both; @@ -45,6 +42,11 @@ a:hover { color:#FFFFFF; width:100%; } +.manageinfo { + background:#00B930; + color:#FFFFFF; + width:100%; +} .catalogmode { background:#0040E0; color:#FFFFFF; diff --git a/css/futaba.css b/css/futaba.css index cdae14a..d7f17e3 100644 --- a/css/futaba.css +++ b/css/futaba.css @@ -11,11 +11,6 @@ a:hover { .reflink a:hover{ font-weight: bold; } -.adminbar { - text-align:right; - clear:both; - float:right; -} .logo { clear:both; text-align:center; @@ -30,6 +25,13 @@ a:hover { color:#FFFFFF; width:100%; } +.manageinfo { + background:#00B930; + text-align:center; + padding:2px; + color:#FFFFFF; + width:100%; +} .catalogmode { background:#0040E0; text-align:center; diff --git a/css/global.css b/css/global.css index 877f7e4..ebc4b23 100644 --- a/css/global.css +++ b/css/global.css @@ -99,4 +99,12 @@ form { .login { text-align: center; -} \ No newline at end of file +} + +.adminbar { + text-align: right; + clear: both; + float: right; +} + +.adminbar a:link, .adminbar a:visited, .adminbar a:active, .adminbar a:hover { text-decoration: none; } \ No newline at end of file diff --git a/imgboard.php b/imgboard.php index 9bef66e..b7123ba 100644 --- a/imgboard.php +++ b/imgboard.php @@ -14,7 +14,7 @@ if (get_magic_quotes_gpc()) { if (get_magic_quotes_runtime()) { set_magic_quotes_runtime(0); } function fancyDie($message) { - die('
' . $message . '

- Click here to go back -'); + die('
' . $message . '


- Click here to go back -'); } if (!file_exists('settings.php')) { @@ -27,11 +27,11 @@ $writedirs = array("res", "src", "thumb"); if (TINYIB_DBMODE == 'flatfile') { $writedirs[] = "inc/flatfile"; } foreach ($writedirs as $dir) { if (!is_writable($dir)) { - fancyDie("Directory '" . $dir . "' can not be written to! Please modify its permissions."); + fancyDie("Directory '" . $dir . "' can not be written to. Please modify its permissions."); } } -$includes = array("inc/functions.php", "inc/html.php"); +$includes = array("inc/defines.php", "inc/functions.php", "inc/html.php"); if (in_array(TINYIB_DBMODE, array('flatfile', 'mysql', 'sqlite'))) { $includes[] = 'inc/database_' . TINYIB_DBMODE . '.php'; } else { @@ -43,22 +43,21 @@ foreach ($includes as $include) { } if (TINYIB_TRIPSEED == '' || TINYIB_ADMINPASS == '') { - fancyDie('TINYIB_TRIPSEED and TINYIB_ADMINPASS must be configured!'); + fancyDie('TINYIB_TRIPSEED and TINYIB_ADMINPASS must be configured'); } $redirect = true; // Check if the request is to make a post if (isset($_POST["message"]) || isset($_POST["file"])) { list($loggedin, $isadmin) = manageCheckLogIn(); - $modpost = isModPost(); + $rawpost = isRawPost(); if (!$loggedin) { checkBanned(); checkMessageSize(); checkFlood(); } - $post = newPost(); - $post['parent'] = setParent(); + $post = newPost(setParent()); $post['ip'] = $_SERVER['REMOTE_ADDR']; list($post['name'], $post['tripcode']) = nameAndTripcode($_POST["name"]); @@ -66,11 +65,11 @@ if (isset($_POST["message"]) || isset($_POST["file"])) { $post['name'] = cleanString(substr($post['name'], 0, 75)); $post['email'] = cleanString(str_replace('"', '"', substr($_POST["email"], 0, 75))); $post['subject'] = cleanString(substr($_POST["subject"], 0, 75)); - if ($modpost) { - $modposttext = ($isadmin) ? ' ## Admin' : ' ## Mod'; + if ($rawpost) { + $rawposttext = ($isadmin) ? ' ## Admin' : ' ## Mod'; $post['message'] = $_POST["message"]; // Treat message as raw HTML } else { - $modposttext = ''; + $rawposttext = ''; $post['message'] = str_replace("\n", "
", colorQuote(postLink(cleanString(rtrim($_POST["message"]))))); } $post['password'] = ($_POST['password'] != '') ? md5(md5($_POST['password'])) : ''; @@ -80,7 +79,7 @@ if (isset($_POST["message"]) || isset($_POST["file"])) { } else { $noko = false; } - $post['nameblock'] = nameBlock($post['name'], $post['tripcode'], $post['email'], time(), $modposttext); + $post['nameblock'] = nameBlock($post['name'], $post['tripcode'], $post['email'], time(), $rawposttext); if (isset($_FILES['file'])) { if ($_FILES['file']['name'] != "") { @@ -90,16 +89,20 @@ if (isset($_POST["message"]) || isset($_POST["file"])) { fancyDie("File transfer failure. Please retry the submission."); } - $post['file_original'] = substr(htmlentities($_FILES['file']['name'], ENT_QUOTES), 0, 50); + if ((TINYIB_MAXKB > 0) && (filesize($_FILES['file']['tmp_name']) > (TINYIB_MAXKB * 1024))) { + fancyDie("That file is larger than " . TINYIB_MAXKBDESC . "."); + } + + $post['file_original'] = htmlentities(substr($_FILES['file']['name'], 0, 50), ENT_QUOTES); $post['file_hex'] = md5_file($_FILES['file']['tmp_name']); $post['file_size'] = $_FILES['file']['size']; $post['file_size_formatted'] = convertBytes($post['file_size']); $file_type = strtolower(preg_replace('/.*(\..+)/', '\1', $_FILES['file']['name'])); if ($file_type == '.jpeg') { $file_type = '.jpg'; } - $file_name = time() . mt_rand(1, 99); - $post['thumb'] = $file_name . "s" . $file_type; + $file_name = time() . substr(microtime(), 2, 3); $post['file'] = $file_name . $file_type; - $thumb_location = "thumb/" . $post['thumb']; + $post['thumb'] = $file_name . "s" . $file_type; $file_location = "src/" . $post['file']; + $thumb_location = "thumb/" . $post['thumb']; if (!($file_type == '.jpg' || $file_type == '.gif' || $file_type == '.png')) { fancyDie("Only GIF, JPG, and PNG files are allowed."); @@ -128,7 +131,7 @@ if (isset($_POST["message"]) || isset($_POST["file"])) { $post['image_width'] = $file_info[0]; $post['image_height'] = $file_info[1]; list($thumb_maxwidth, $thumb_maxheight) = thumbnailDimensions($post['image_width'], $post['image_height']); - + if (!createThumbnail($file_location, $thumb_location, $thumb_maxwidth, $thumb_maxheight)) { fancyDie("Could not create thumbnail."); } @@ -139,21 +142,23 @@ if (isset($_POST["message"]) || isset($_POST["file"])) { } if ($post['file'] == '') { // No file uploaded - if ($post['parent'] == '0') { + if ($post['parent'] == TINYIB_NEWTHREAD) { fancyDie("An image is required to start a thread."); } if (str_replace('
', '', $post['message']) == "") { fancyDie("Please enter a message and/or upload an image to make a reply."); } + } else { + echo $post['file_original'] . ' uploaded.
'; } $post['id'] = insertPost($post); if ($noko) { - $redirect = 'res/' . ($post['parent'] == '0' ? $post['id'] : $post['parent']) . '.html#' . $post['id']; + $redirect = 'res/' . ($post['parent'] == TINYIB_NEWTHREAD ? $post['id'] : $post['parent']) . '.html#' . $post['id']; } trimThreads(); echo 'Updating thread page...
'; - if ($post['parent'] != '0') { + if ($post['parent'] != TINYIB_NEWTHREAD) { rebuildThread($post['parent']); if (strtolower($post['email']) != "sage") { @@ -170,10 +175,15 @@ if (isset($_POST["message"]) || isset($_POST["file"])) { if (isset($_POST['delete'])) { $post = postByID($_POST['delete']); if ($post) { - if ($post['password'] != '' && md5(md5($_POST['password'])) == $post['password']) { + list($loggedin, $isadmin) = manageCheckLogIn(); + + if ($loggedin && $_POST['password'] == '') { + // Redirect to post moderation page + echo '--> --> -->'; + } elseif ($post['password'] != '' && md5(md5($_POST['password'])) == $post['password']) { deletePostByID($post['id']); - if ($post['parent'] == 0) { threadUpdated($post['id']); } else { threadUpdated($post['parent']); } - echo 'Post successfully deleted.'; + if ($post['parent'] == TINYIB_NEWTHREAD) { threadUpdated($post['id']); } else { threadUpdated($post['parent']); } + fancyDie('Post deleted.'); } else { fancyDie('Invalid password.'); } @@ -200,7 +210,7 @@ if (isset($_POST["message"]) || isset($_POST["file"])) { rebuildThread($thread["id"]); } rebuildIndexes(); - $text .= "Rebuilt board."; + $text .= manageInfo('Rebuilt board.'); } elseif (isset($_GET["bans"])) { clearExpiredBans(); @@ -217,13 +227,13 @@ if (isset($_POST["message"]) || isset($_POST["file"])) { $ban['reason'] = $_POST['reason']; insertBan($ban); - $text .= 'Successfully added a ban record for ' . $ban['ip'] . '
'; + $text .= manageInfo('Ban record added for ' . $ban['ip']); } } elseif (isset($_GET['lift'])) { $ban = banByID($_GET['lift']); if ($ban) { deleteBanByID($_GET['lift']); - $text .= 'Successfully lifted ban on ' . $ban['ip'] . '
'; + $text .= manageInfo('Ban record lifted for ' . $ban['ip']); } } @@ -238,10 +248,10 @@ if (isset($_POST["message"]) || isset($_POST["file"])) { if ($post) { deletePostByID($post['id']); rebuildIndexes(); - if ($post['parent'] > 0) { + if ($post['parent'] != TINYIB_NEWTHREAD) { rebuildThread($post['parent']); } - $text .= 'Post No.' . $post['id'] . ' successfully deleted.'; + $text .= manageInfo('Post No.' . $post['id'] . ' deleted.'); } else { fancyDie("Sorry, there doesn't appear to be a post with that ID."); } @@ -257,18 +267,16 @@ if (isset($_POST["message"]) || isset($_POST["file"])) { $onload = manageOnLoad('moderate'); $text .= manageModeratePostForm(); } - } elseif (isset($_GET["modpost"])) { - $onload = manageOnLoad('modpost'); - $text .= manageModpostForm(); + } elseif (isset($_GET["rawpost"])) { + $onload = manageOnLoad("rawpost"); + $text .= manageRawPostForm(); } elseif (isset($_GET["logout"])) { $_SESSION['tinyib'] = ''; session_destroy(); die('--> --> -->'); } if ($text == '') { - $threads = countThreads(); - $bans = count(allBans()); - $text = $threads . ' ' . plural('thread', $threads) . ', ' . $bans . ' ' . plural('ban', $bans) . '.'; + $text = manageStatus(); } } else { $onload = manageOnLoad('login'); diff --git a/inc/database_flatfile.php b/inc/database_flatfile.php index 83f4006..e5a6570 100644 --- a/inc/database_flatfile.php +++ b/inc/database_flatfile.php @@ -127,7 +127,7 @@ function convertPostsToSQLStyle($posts, $singlepost=false) { $post['thumb_height'] = $oldpost[POST_THUMB_HEIGHT]; if ($post['parent'] == '') { - $post['parent'] = '0'; + $post['parent'] = TINYIB_NEWTHREAD; } if ($singlepost) { return $post; } @@ -160,6 +160,11 @@ function postsByHex($hex) { return convertPostsToSQLStyle($rows); } +function latestPosts() { + $rows = $GLOBALS['db']->selectWhere(POSTS_FILE, NULL, 10, new OrderBy(POST_TIMESTAMP, DESCENDING, INTEGER_COMPARISON)); + return convertPostsToSQLStyle($rows); +} + function deletePostByID($id) { $posts = postsInThreadByID($id); foreach ($posts as $post) { diff --git a/inc/database_mysql.php b/inc/database_mysql.php index 2fb6876..92d35dc 100644 --- a/inc/database_mysql.php +++ b/inc/database_mysql.php @@ -130,6 +130,17 @@ function postsByHex($hex) { return $posts; } +function latestPosts() { + $posts = array(); + $result = mysql_query("SELECT * FROM `" . TINYIB_DBPOSTS . "` ORDER BY `timestamp` DESC LIMIT 10"); + if ($result) { + while ($post = mysql_fetch_assoc($result)) { + $posts[] = $post; + } + } + return $posts; +} + function deletePostByID($id) { $posts = postsInThreadByID($id); foreach ($posts as $post) { @@ -141,7 +152,7 @@ function deletePostByID($id) { } } if (isset($thispost)) { - if ($thispost['parent'] == 0) { + if ($thispost['parent'] == TINYIB_NEWTHREAD) { @unlink('res/' . $thispost['id'] . '.html'); } deletePostImages($thispost); diff --git a/inc/database_sqlite.php b/inc/database_sqlite.php index 6719816..eaf5167 100644 --- a/inc/database_sqlite.php +++ b/inc/database_sqlite.php @@ -111,6 +111,15 @@ function postsByHex($hex) { return $posts; } +function latestPosts() { + $posts = array(); + $result = sqlite_fetch_all(sqlite_query($GLOBALS["db"], "SELECT * FROM " . TINYIB_DBPOSTS . " ORDER BY timestamp DESC LIMIT 10"), SQLITE_ASSOC); + foreach ($result as $post) { + $posts[] = $post; + } + return $posts; +} + function deletePostByID($id) { $posts = postsInThreadByID($id); foreach ($posts as $post) { @@ -122,7 +131,7 @@ function deletePostByID($id) { } } if (isset($thispost)) { - if ($thispost['parent'] == 0) { + if ($thispost['parent'] == TINYIB_NEWTHREAD) { @unlink('res/' . $thispost['id'] . '.html'); } deletePostImages($thispost); diff --git a/inc/defines.php b/inc/defines.php new file mode 100644 index 0000000..832d607 --- /dev/null +++ b/inc/defines.php @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/inc/functions.php b/inc/functions.php index 0bcbe17..6d16ea7 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -20,8 +20,8 @@ function threadUpdated($id) { rebuildIndexes(); } -function newPost() { - return array('parent' => '0', +function newPost($parent = TINYIB_NEWTHREAD) { + return array('parent' => $parent, 'timestamp' => '0', 'bumped' => '0', 'ip' => '', @@ -109,7 +109,7 @@ function nameAndTripcode($name) { return array($name, ""); } -function nameBlock($name, $tripcode, $email, $timestamp, $modposttext) { +function nameBlock($name, $tripcode, $email, $timestamp, $rawposttext) { $output = ''; $output .= ($name == "" && $tripcode == "") ? "Anonymous" : $name; @@ -123,7 +123,7 @@ function nameBlock($name, $tripcode, $email, $timestamp, $modposttext) { $output = '' . $output . ''; } - return $output . $modposttext . ' ' . date('y/m/d(D)H:i:s', $timestamp); + return $output . $rawposttext . ' ' . date('y/m/d(D)H:i:s', $timestamp); } function writePage($filename, $contents) { @@ -150,7 +150,7 @@ function fixLinksInRes($html) { function _postLink($matches) { $post = postByID($matches[1]); if ($post) { - return '' . $matches[0] . ''; + return '' . $matches[0] . ''; } return $matches[0]; } @@ -173,9 +173,9 @@ function checkBanned() { $ban = banByIP($_SERVER['REMOTE_ADDR']); if ($ban) { if ($ban['expire'] == 0 || $ban['expire'] > time()) { - $expire = ($ban['expire'] > 0) ? ('Your ban will expire ' . date('y/m/d(D)H:i:s', $ban['expire'])) : 'The ban on your IP address is permanent and will not expire.'; - $reason = ($ban['reason'] == '') ? '' : ('
The reason provided was: ' . $ban['reason']); - fancyDie('Sorry, it appears that you have been banned from posting on this image board. ' . $expire . $reason); + $expire = ($ban['expire'] > 0) ? ('
This ban will expire ' . date('y/m/d(D)H:i:s', $ban['expire'])) : '
This ban is permanent and will not expire.'; + $reason = ($ban['reason'] == '') ? '' : ('
Reason: ' . $ban['reason']); + fancyDie('Your IP address ' . $ban['ip'] . ' has been banned from posting on this image board. ' . $expire . $reason); } else { clearExpiredBans(); } @@ -183,10 +183,12 @@ function checkBanned() { } function checkFlood() { - $lastpost = lastPostByIP(); - if ($lastpost) { - if ((time() - $lastpost['timestamp']) < 30) { - fancyDie("Please wait a moment before posting again. You will be able to make another post in " . (30 - (time() - $lastpost['timestamp'])) . " " . plural("second", (30 - (time() - $lastpost['timestamp']))) . "."); + if (TINYIB_DELAY > 0) { + $lastpost = lastPostByIP(); + if ($lastpost) { + if ((time() - $lastpost['timestamp']) < TINYIB_DELAY) { + fancyDie("Please wait a moment before posting again. You will be able to make another post in " . (TINYIB_DELAY - (time() - $lastpost['timestamp'])) . " " . plural("second", (TINYIB_DELAY - (time() - $lastpost['timestamp']))) . "."); + } } } } @@ -221,7 +223,7 @@ function manageCheckLogIn() { function setParent() { if (isset($_POST["parent"])) { - if ($_POST["parent"] != "0") { + if ($_POST["parent"] != TINYIB_NEWTHREAD) { if (!threadExistsByID($_POST['parent'])) { fancyDie("Invalid parent thread ID supplied, unable to create post."); } @@ -230,11 +232,11 @@ function setParent() { } } - return "0"; + return TINYIB_NEWTHREAD; } -function isModPost() { - if (isset($_POST['modpost'])) { +function isRawPost() { + if (isset($_POST['rawpost'])) { list($loggedin, $isadmin) = manageCheckLogIn(); if ($loggedin) { return true; @@ -249,7 +251,7 @@ function validateFileUpload() { case UPLOAD_ERR_OK: break; case UPLOAD_ERR_FORM_SIZE: - fancyDie("That file is larger than 2 MB."); + fancyDie("That file is larger than " . TINYIB_MAXKBDESC . "."); break; case UPLOAD_ERR_INI_SIZE: fancyDie("The uploaded file exceeds the upload_max_filesize directive (" . ini_get('upload_max_filesize') . ") in php.ini."); @@ -275,13 +277,13 @@ function checkDuplicateImage($hex) { $hexmatches = postsByHex($hex); if (count($hexmatches) > 0) { foreach ($hexmatches as $hexmatch) { - fancyDie("Duplicate file uploaded. That file has already been posted here."); + fancyDie("Duplicate file uploaded. That file has already been posted here."); } } } function thumbnailDimensions($width, $height) { - return ($width > 250 || $height > 250) ? array(250, 250) : array($width, $height); + return ($width > TINYIB_MAXW || $height > TINYIB_MAXH) ? array(TINYIB_MAXW, TINYIB_MAXH) : array($width, $height); } function createThumbnail($name, $filename, $new_w, $new_h) { @@ -354,4 +356,19 @@ function fastImageCopyResampled(&$dst_image, &$src_image, $dst_x, $dst_y, $src_x return true; } +function strallpos($haystack, $needle, $offset = 0) { + $result = array(); + for ($i = $offset;$i= $i) { + $i = $offset; + $result[] = $offset; + } + } + } + return $result; +} + ?> \ No newline at end of file diff --git a/inc/html.php b/inc/html.php index e576eb9..23c7a5f 100644 --- a/inc/html.php +++ b/inc/html.php @@ -32,12 +32,13 @@ function pageFooter() { EOF; } -function buildPost($post, $isrespage) { +function buildPost($post, $res) { $return = ""; - $threadid = ($post['parent'] == 0) ? $post['id'] : $post['parent']; - $postlink = ($isrespage) ? ($threadid . '.html#' . $post['id']) : ('res/' . $threadid . '.html#' . $post['id']); + $threadid = ($post['parent'] == TINYIB_NEWTHREAD) ? $post['id'] : $post['parent']; + $postlink = ($res == TINYIB_RESPAGE) ? ($threadid . '.html#' . $post['id']) : ('res/' . $threadid . '.html#' . $post['id']); + if (!isset($post["omitted"])) { $post["omitted"] = 0; } - if ($post["parent"] != 0) { + if ($post["parent"] != TINYIB_NEWTHREAD) { $return .= << @@ -75,7 +76,7 @@ ${post["nameblock"]}
EOF; - if ($post['parent'] != 0 && $post["file"] != "") { + if ($post['parent'] != TINYIB_NEWTHREAD && $post["file"] != "") { $return .= << ${post["file"]}–(${post["file_size_formatted"]}, ${post["image_width"]}x${post["image_height"]}, ${post["file_original"]}) @@ -86,18 +87,23 @@ EOF; EOF; } - if ($post['parent'] == 0 && !$isrespage) { + if ($post['parent'] == TINYIB_NEWTHREAD && $res == TINYIB_INDEXPAGE) { $return .= " [Reply]"; } + if (TINYIB_TRUNCATE > 0 && !$res && substr_count($post['message'], "
") > TINYIB_TRUNCATE) { // Truncate messages on board index pages for readability + $br_offsets = strallpos($post['message'], "
"); + $post['message'] = substr($post['message'], 0, $br_offsets[TINYIB_TRUNCATE - 1]); + $post['message'] .= '
Post truncated. Click Reply to view.
'; + } $return .= << ${post["message"]} EOF; - if ($post['parent'] == 0) { - if (!$isrespage && $post["omitted"] > 0) { + if ($post['parent'] == TINYIB_NEWTHREAD) { + if ($res == TINYIB_INDEXPAGE && $post["omitted"] > 0) { $return .= '' . $post['omitted'] . ' ' . plural("post", $post["omitted"]) . ' omitted. Click Reply to view.'; } } else { @@ -114,10 +120,12 @@ EOF; function buildPage($htmlposts, $parent, $pages=0, $thispage=0) { $managelink = basename($_SERVER['PHP_SELF']) . "?manage"; + $maxdimensions = TINYIB_MAXW . 'x' . TINYIB_MAXH; + $maxfilesize = TINYIB_MAXKB * 1024; $postingmode = ""; $pagenavigator = ""; - if ($parent == 0) { + if ($parent == TINYIB_NEWTHREAD) { $pages = max($pages, 0); $previous = ($thispage == 1) ? "index" : $thispage - 1; $next = $thispage + 1; @@ -153,13 +161,18 @@ EOF; $unique_posts_html = ''; $unique_posts = uniquePosts(); if ($unique_posts > 0) { - $unique_posts_html = "
  • Currently $unique_posts unique user posts.
  • "; + $unique_posts_html = "
  • Currently $unique_posts unique user posts.
  • \n"; + } + + $max_file_size_html = ''; + if (TINYIB_MAXKB > 0) { + $max_file_size_html = "
  • Maximum file size allowed is " . TINYIB_MAXKBDESC . ".
  • \n"; } $body = <<
    - [Manage] + [Manage]